[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
UID patch for stable
Attached is a patch against stable-980929. The patch adds a config
file command to specify a new uid, and optionally gid, under which
slapd should run once it has bound to the privileged port.
Notes:
1. This patch was built and tested on FreeBSD 2.2.7R. It should
be compatible with all other flavors of BSD; but there may
need to be some #ifs to deal with other environments.
2. The new command takes the form:
user <uid or name> [<gid or name>]
and must occur -before- the first database definition.
If a user name is specified, it will be translated to a number
via getpwnam(3). Group names are looked up via getgrnam(3).
If a uid or user name is specified without a gid or group name,
the default gid for that user will be used.
If the specified uid resolves to zero, the uid will not be
changed. Similarly for the gid. In the absence of a 'user'
command, no attempt will be made to set uid or gid. (This
is the current pre-patch behavour.)
Real, effective, and saved ids are all set to the new value.
3. The patch includes updates to the slapd.conf(5) man page; but
not the necessary changes to the Admin Guide.
4. Using the user command to select a non-privileged uid may
prevent password verification when using a passwd back end;
especially on systems that use a shadow password system.
It might also impact the ability to run shell back-ends
that require some privilege.
5. The new uid and gid are set before the pid and log files are
opened; so they must be writable by the new user or group. If
they do not yet exist, the directory must be writeable by the
selected user or group.
-Patdiff -b -B -P -u -r stable-19980929/doc/man/man5/slapd.conf.5 stable-19980929-UID/doc/man/man5/slapd.conf.5
--- stable-19980929/doc/man/man5/slapd.conf.5 Sat Aug 8 15:43:13 1998
+++ stable-19980929-UID/doc/man/man5/slapd.conf.5 Wed Oct 14 22:24:21 1998
@@ -184,6 +184,12 @@
.TP
.B timelimit <integer>
Specify the maximum number of seconds (in real time)
+.TP
+.B user <uid or name> [<gid or name>]
+Specify the UID, and optionally GID, under which slapd is to run after
+binding to the socket. These values may be either numeric uid (gid)
+values or names to be looked up via getpwnam(3) (getgrnam(3)). If not
+specified here or at compile time, the uid and gid will not be changed.
.B slapd
will spend answering a search request. The default time limit is 3600.
.SH GENERAL BACKEND OPTIONS
diff -b -B -P -u -r stable-19980929/include/ldapconfig.h stable-19980929-UID/include/ldapconfig.h
--- stable-19980929/include/ldapconfig.h Mon Oct 12 18:51:28 1998
+++ stable-19980929-UID/include/ldapconfig.h Wed Oct 14 22:42:54 1998
@@ -305,5 +305,9 @@
#define SLAPD_CONFIG_DN "cn=config"
/* minimum max ids that a single index entry can map to in ldbm */
#define SLAPD_LDBM_MIN_MAXIDS 4000
+ /* uid to use after binding to socket - if 0 do not change uid */
+#define SLAPD_DEFAULT_UID 0
+ /* gid to use after binding to socket - if 0 do not change gid */
+#define SLAPD_DEFAULT_GID 0
#endif /* _LDAP_CONFIG_H */
diff -b -B -P -u -r stable-19980929/include/ldapconfig.h.edit stable-19980929-UID/include/ldapconfig.h.edit
--- stable-19980929/include/ldapconfig.h.edit Mon Oct 5 23:32:53 1998
+++ stable-19980929-UID/include/ldapconfig.h.edit Wed Oct 14 22:27:02 1998
@@ -299,5 +299,9 @@
#define SLAPD_CONFIG_DN "cn=config"
/* minimum max ids that a single index entry can map to in ldbm */
#define SLAPD_LDBM_MIN_MAXIDS 4000
+ /* uid to use after binding to socket - if 0 do not change uid */
+#define SLAPD_DEFAULT_UID 0
+ /* gid to use after binding to socket - if 0 do not change gid */
+#define SLAPD_DEFAULT_GID 0
#endif /* _LDAP_CONFIG_H */
diff -b -B -P -u -r stable-19980929/servers/slapd/config.c stable-19980929-UID/servers/slapd/config.c
--- stable-19980929/servers/slapd/config.c Sat Aug 8 15:43:13 1998
+++ stable-19980929-UID/servers/slapd/config.c Wed Oct 14 22:52:16 1998
@@ -4,6 +4,8 @@
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <pwd.h>
+#include <grp.h>
#include "slap.h"
#include "ldapconfig.h"
@@ -24,6 +26,8 @@
char *replogfile;
int global_lastmod;
char *ldap_srvtab = "";
+uid_t run_uid = SLAPD_DEFAULT_UID;
+gid_t run_gid = SLAPD_DEFAULT_GID;
static char *fp_getline();
static void fp_getline_init();
@@ -364,6 +368,50 @@
exit( 1 );
}
ldap_srvtab = strdup( cargv[1] );
+
+ /* UID to run as after binding to the socket */
+ } else if ( strcasecmp( cargv[0], "user" ) == 0 ) {
+ if ( cargc < 2) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing user name or id in \"user <uid-or-name> [<gid-or-name>]\" line\n",
+ fname, lineno, 0 );
+ exit( 1 );
+ }
+ if ( be != NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+"%s: line %d: user line must appear before the database definitions (ignored)\n",
+ fname, lineno, 0 );
+ } else if ( isdigit( cargv[1] )) {
+ run_uid = atoi( cargv[1] );
+ } else {
+ struct passwd *user = getpwnam( cargv[1] );
+
+ if ( user == NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: could not find password entry for user \"%s\n",
+ fname, lineno, cargv[1] );
+ exit( 1 );
+ }
+ run_uid = user->pw_uid;
+ run_gid = user->pw_gid;
+ }
+
+ /* If a second arg is given, it is the group id/name */
+ if (cargc > 2) {
+ if ( isdigit( cargv[2] )) {
+ run_gid = atoi( cargv[2] );
+ } else {
+ struct group* grp = getgrnam( cargv[2] );
+
+ if ( grp == NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: could not find group entry for \"%s\n",
+ fname, lineno, cargv[2] );
+ exit( 1 );
+ }
+ run_gid = grp->gr_gid ;
+ }
+ }
/* pass anything else to the current backend config routine */
} else {
diff -b -B -P -u -r stable-19980929/servers/slapd/daemon.c stable-19980929-UID/servers/slapd/daemon.c
--- stable-19980929/servers/slapd/daemon.c Sat Sep 5 10:39:31 1998
+++ stable-19980929-UID/servers/slapd/daemon.c Wed Oct 14 22:42:34 1998
@@ -54,6 +54,8 @@
extern pthread_mutex_t ops_mutex;
extern int g_argc;
extern char **g_argv;
+extern uid_t run_uid;
+extern gid_t run_gid;
int dtblsize;
Connection *c;
@@ -164,7 +166,37 @@
(void) SIGNAL( SIGINT, (void *) set_shutdown );
(void) SIGNAL( SIGHUP, (void *) set_shutdown );
+ if ( run_gid != 0 ) {
+ if ( setgid( run_gid ) != 0 ) {
+ Debug (LDAP_DEBUG_ANY,
+ "Could not set real group id to %d",
+ run_gid, 0, 0) ;
+ exit( 1 );
+ }
+ if ( setegid( run_gid ) != 0 ) {
+ Debug (LDAP_DEBUG_ANY,
+ "Could not set effective group id to %d",
+ run_gid, 0, 0) ;
+ exit( 1 );
+ }
+ }
+ if ( run_uid != 0 ) {
+ if ( setuid( run_uid ) != 0 ) {
+ Debug (LDAP_DEBUG_ANY,
+ "Could not set effective user id to %d",
+ run_gid, 0, 0) ;
+ exit( 1 );
+ }
+ if ( seteuid( run_uid ) != 0) {
+ Debug (LDAP_DEBUG_ANY,
+ "Could not set real UID to %d",
+ run_gid, 0, 0) ;
+ exit( 1 );
+ }
+ }
+
Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
+
#ifdef SLAPD_PIDFILE
if ( (fp = fopen( SLAPD_PIDFILE, "w" )) != NULL ) {
fprintf( fp, "%d\n", getpid() );