[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.



-Pat
diff -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() );