]> git.sur5r.net Git - openldap/commitdiff
Add -U and -G options to set user and group id.
authorHallvard Furuseth <hallvard@openldap.org>
Sat, 3 Apr 1999 03:19:07 +0000 (03:19 +0000)
committerHallvard Furuseth <hallvard@openldap.org>
Sat, 3 Apr 1999 03:19:07 +0000 (03:19 +0000)
Move socket setup to set_socket(), called before the uid/gid change.

configure
configure.in
doc/man/man8/slapd.8
include/portable.h.in
servers/slapd/Makefile.in
servers/slapd/daemon.c
servers/slapd/main.c
servers/slapd/proto-slap.h
servers/slapd/user.c [new file with mode: 0644]

index da27db8ec736f0d10475422ca4149cfb38bc8a68..5a0e5e994c97e2420854025f0ee44b4c5a6dbdf3 100755 (executable)
--- a/configure
+++ b/configure
@@ -8945,6 +8945,7 @@ for ac_hdr in \
        fcntl.h                 \
        filio.h                 \
        getopt.h                \
+       grp.h                   \
        libutil.h               \
        limits.h                \
        locale.h                \
 
 for ac_func in \
        bcopy                   \
+       endgrent                \
+       endpwent                \
        flock                   \
        getdtablesize           \
+       getgrgid                \
        gethostname             \
        getpass                 \
        getpwuid                \
index 7b772d6995b472be7640411598820325f0a67ce3..19f2a6d3e228e3228e33bd45cb8e221d594c91f2 100644 (file)
@@ -1634,6 +1634,7 @@ AC_CHECK_HEADERS( \
        fcntl.h                 \
        filio.h                 \
        getopt.h                \
+       grp.h                   \
        libutil.h               \
        limits.h                \
        locale.h                \
@@ -1707,8 +1708,11 @@ fi
 
 AC_CHECK_FUNCS(                \
        bcopy                   \
+       endgrent                \
+       endpwent                \
        flock                   \
        getdtablesize           \
+       getgrgid                \
        gethostname             \
        getpass                 \
        getpwuid                \
index 36bd63c5883ae19077e1e9191ef394c63edcf7b8..f1b89126a98852fe369e39e987105aca61ad3c10 100644 (file)
@@ -1,10 +1,11 @@
-.TH SLAPD 8C "20 January 1999" "OpenLDAP LDVERSION"
+.TH SLAPD 8C "3 April 1999" "OpenLDAP LDVERSION"
 .SH NAME
 slapd \- Stand-alone LDAP Daemon
 .SH SYNOPSIS
 .B LIBEXECDIR/slapd [\-d debug\-level]
 .B [\-f slapd\-config\-file] [\-a address] [\-p port\-number]
 .B [\-s syslog\-level] [\-l syslog\-local\-user] [\-i]
+.B [\-U user] [\-G group]
 .B 
 .SH DESCRIPTION
 .LP
@@ -98,12 +99,27 @@ Internet standard '.' format.
 will listen on the default LDAP port (389) unless this option is given
 to override the default.  A numeric port number is expected.
 .TP
+.BI \-U " user"
+.B slapd
+will run slapd with the specified user name or id, and that user's
+supplementary group access list as set with initgroups(3).  The group ID
+is also changed to this user's gid, unless the -G option is used to
+override.
+.TP
+.BI \-G " group"
+.B slapd
+will run with the specified group name or id.
+.TP
 .B \-i
 This option tells
 .B slapd
 that it is being run from
 .BR inetd(8) ,
 the Internet protocol daemon.
+.LP
+Note that on some systems, running as a non-privileged user will prevent
+passwd back-ends from accessing the encrypted passwords.  Note also that
+any shell back-ends will run as the specified non-privileged user.
 .SH EXAMPLES
 To start 
 .I slapd
index 1d6fa18936fb6867f05624f2cca4d87be414fe98..77a7280ef8b6519dc2ea687ca999903573fff6fc 100644 (file)
 /* Define if you have the ctime_r function.  */
 #undef HAVE_CTIME_R
 
+/* Define if you have the endgrent function.  */
+#undef HAVE_ENDGRENT
+
+/* Define if you have the endpwent function.  */
+#undef HAVE_ENDPWENT
+
 /* Define if you have the flock function.  */
 #undef HAVE_FLOCK
 
 /* Define if you have the getdtablesize function.  */
 #undef HAVE_GETDTABLESIZE
 
+/* Define if you have the getgrgid function.  */
+#undef HAVE_GETGRGID
+
 /* Define if you have the gethostbyaddr_r function.  */
 #undef HAVE_GETHOSTBYADDR_R
 
 /* Define if you have the gettimeofday function.  */
 #undef HAVE_GETTIMEOFDAY
 
+/* Define if you have the <grp.h> header file.  */
+#undef HAVE_GRP_H
+
 /* Define if you have the lockf function.  */
 #undef HAVE_LOCKF
 
index b1e51d9624a14c695c6e4ddfefe0beb99d5f244a..11030fac1aa234e65ee2a7b844031cdcab10b878 100644 (file)
@@ -8,14 +8,14 @@ SRCS  = main.c daemon.c connection.c search.c filter.c add.c charray.c \
                attr.c entry.c config.c backend.c result.c operation.c \
                dn.c compare.c modify.c delete.c modrdn.c ch_malloc.c \
                value.c ava.c bind.c unbind.c abandon.c filterentry.c \
-               phonetic.c acl.c str2filter.c aclparse.c init.c \
+               phonetic.c acl.c str2filter.c aclparse.c init.c user.c \
                repl.c lock.c \
                suffixalias.c schema.c schemaparse.c monitor.c configinfo.c
 OBJS   = main.o daemon.o connection.o search.o filter.o add.o charray.o \
                attr.o entry.o config.o backend.o result.o operation.o \
                dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
                value.o ava.o bind.o unbind.o abandon.o filterentry.o \
-               phonetic.o acl.o str2filter.o aclparse.o init.o \
+               phonetic.o acl.o str2filter.o aclparse.o init.o user.o \
                repl.o lock.o \
                suffixalias.o schema.o schemaparse.o monitor.o configinfo.o
 
index 15a8bf8efa71cb531cdc2dd5c510ffd30134e8aa..2fd3116b434deb29df00fcbd7bcb9b9c46ad42f5 100644 (file)
@@ -146,12 +146,9 @@ static void slapd_close(int s) {
        tcp_close(s);
 }
 
-static void *
-slapd_daemon_task(
-       void *ptr
-)
+int
+set_socket( struct sockaddr_in *addr )
 {
-       struct sockaddr_in *addr = ptr;
        int     tcps = -1;
 
 #ifdef HAVE_SYSCONF
@@ -177,12 +174,6 @@ slapd_daemon_task(
        }
 #endif
 
-       connections_init();
-
-       ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
-       FD_ZERO( &slap_daemon.sd_readers );
-       FD_ZERO( &slap_daemon.sd_writers );
-
        if( addr != NULL ) {
                int     tmp;
 
@@ -223,7 +214,27 @@ slapd_daemon_task(
                                        ? sys_errlist[errno] : "unknown" );
                        exit( 1 );
                }
+       }
+
+       return tcps;
+}
+
+static void *
+slapd_daemon_task(
+       void *ptr
+)
+{
+       int inetd = ((int *)ptr) [0];
+       int tcps  = ((int *)ptr) [1];
+       free( ptr );
+
+       connections_init();
+
+       ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
+       FD_ZERO( &slap_daemon.sd_readers );
+       FD_ZERO( &slap_daemon.sd_writers );
 
+       if( !inetd ) {
                if ( listen( tcps, 5 ) == -1 ) {
                        Debug( LDAP_DEBUG_ANY,
                                "daemon: listen(%d, 5) failed errno %d (%s)\n",
@@ -569,12 +580,15 @@ slapd_daemon_task(
        return NULL;
 }
 
-int slapd_daemon( struct sockaddr_in *addr )
+int slapd_daemon( int inetd, int tcps )
 {
        int status;
+       int *args = ch_malloc( sizeof( int[2] ) );
+       args[0] = inetd;
+       args[1] = tcps;
 
        status = ldap_pvt_thread_create( &listener_tid, 0,
-                slapd_daemon_task, addr );
+                                        slapd_daemon_task, args );
 
        if ( status != 0 ) {
                Debug( LDAP_DEBUG_ANY,
index b18db5651ca97b33b6f1cb3710100a6307d063f3..a3cbae3b2d26b175c8655149b8d96d6d58684e2c 100644 (file)
@@ -63,6 +63,9 @@ usage( char *name )
 #endif
 #ifdef LOG_LOCAL4
     fprintf( stderr, " [-l sysloguser]" );
+#endif
+#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
+    fprintf( stderr, " [-U user] [-G group]" );
 #endif
     fprintf( stderr, "\n" );
 }
@@ -75,10 +78,14 @@ main( int argc, char **argv )
        int             i;
        int             inetd = 0;
        int             rc;
-       struct sockaddr_in      bind_addr, *slapd_addr;
+       struct sockaddr_in      bind_addr;
+       int             tcps;
        int             udp;
 #ifdef LOG_LOCAL4
     int     syslogUser = DEFAULT_SYSLOG_USER;
+#endif
+#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
+       char            *username = NULL, *groupname = NULL;
 #endif
        char            *configfile;
        char        *serverName;
@@ -101,6 +108,9 @@ main( int argc, char **argv )
 #endif
 #ifdef SLAPD_BDB2
                             "t"
+#endif
+#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
+                            "U:G:"
 #endif
                             )) != EOF ) {
                switch ( i ) {
@@ -195,6 +205,16 @@ main( int argc, char **argv )
                        break;
 #endif
 
+#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
+               case 'U':       /* user name */
+                       username = ch_strdup( optarg );
+                       break;
+
+               case 'G':       /* group name */
+                       groupname = ch_strdup( optarg );
+                       break;
+#endif /* HAVE_PWD_H && HAVE_GRP_H */
+
                default:
                        usage( argv[0] );
                        exit( 1 );
@@ -219,6 +239,13 @@ main( int argc, char **argv )
        openlog( serverName, OPENLOG_OPTIONS );
 #endif
 
+       tcps = set_socket( inetd ? NULL : &bind_addr );
+
+#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
+       if ( username != NULL || groupname != NULL )
+               slap_init_user( username, groupname );
+#endif
+
        if ( slap_init( serverMode, serverName ) != 0 ) {
                rc = 1;
                goto destroy;
@@ -261,8 +288,6 @@ main( int argc, char **argv )
        if(!inetd) {
                FILE *fp;
 
-               slapd_addr = &bind_addr;
-
                Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
 
                if (( slapd_pid_file != NULL ) &&
@@ -281,14 +306,11 @@ main( int argc, char **argv )
                        fprintf( fp, "\n" );
                        fclose( fp );
                }
-
-       } else {
-               slapd_addr = NULL;
        }
 
        time( &starttime );
 
-       rc = slapd_daemon( slapd_addr );
+       rc = slapd_daemon( inetd, tcps );
 
 shutdown:
        /* remember an error during shutdown */
index 7907d6a623cddbf1ccd05ab2a5c822d15771e70f..72f4b115c661815f040d0dae1eab48da1b998bf2 100644 (file)
@@ -256,6 +256,13 @@ int value_find LDAP_P(( struct berval **vals, struct berval *v, int syntax,
  */
 char *suffixAlias LDAP_P(( char *dn, Operation *op, Backend *be ));
 
+/*
+ * user.c
+ */
+#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
+void slap_init_user LDAP_P(( char *username, char *groupname ));
+#endif
+
 /*
  * Other...
  */
@@ -308,7 +315,8 @@ extern int  slap_shutdown LDAP_P((int dbnum));
 extern int     slap_destroy LDAP_P((void));
 
 struct sockaddr_in;
-extern int slapd_daemon LDAP_P((struct sockaddr_in *addr));
+extern int     set_socket LDAP_P((struct sockaddr_in *addr));
+extern int     slapd_daemon LDAP_P((int inetd, int tcps));
 
 extern void slapd_set_write LDAP_P((int s, int wake));
 extern void slapd_clr_write LDAP_P((int s, int wake));
diff --git a/servers/slapd/user.c b/servers/slapd/user.c
new file mode 100644 (file)
index 0000000..e7d7252
--- /dev/null
@@ -0,0 +1,128 @@
+/* user.c - set user id, group id and group access list
+ *
+ * Copyright 1999 by PM Lashley and The OpenLDAP Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted only
+ * as authorized by the OpenLDAP Public License.  A copy of this
+ * license is available at http://www.OpenLDAP.org/license.html or
+ * in file LICENSE in the top-level directory of the distribution.
+*/
+
+#include "portable.h"
+
+#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <ac/ctype.h>
+#include <ac/unistd.h>
+
+#include "slap.h"
+
+
+/*
+ * Set real and effective user id and group id, and group access list
+ */
+
+void
+slap_init_user( char *user, char *group )
+{
+    uid_t      uid = (gid_t) -1;
+    gid_t      gid = (gid_t) -1;
+
+    if ( user ) {
+       struct passwd *pwd;
+       if ( isdigit( (unsigned char) *user )) {
+           uid = atoi( user );
+#ifdef HAVE_GETPWUID
+           pwd = getpwuid( uid );
+           goto did_getpw;
+#endif
+       } else {
+           pwd = getpwnam( user );
+       did_getpw:
+           if ( pwd == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "No passwd entry for user %s\n",
+                      user, 0, 0 );
+               exit( 1 );
+           }
+           if ( uid >= 0 ) {
+               free( user );
+               user = (pwd != NULL ? ch_strdup( pwd->pw_name ) : NULL);
+           } else {
+               uid = pwd->pw_uid;
+           }
+           gid = pwd->pw_gid;
+#ifdef HAVE_ENDPWENT
+           endpwent();
+#endif
+       }
+    }
+
+    if ( group ) {
+       struct group *grp;
+       if ( isdigit( (unsigned char) *group )) {
+           gid = atoi( group );
+#ifdef HAVE_GETGRGID
+           grp = getgrgid( gid );
+           goto did_group;
+#endif
+       } else {
+           grp = getgrnam( group );
+           if ( grp != NULL )
+               gid = grp->gr_gid;
+       did_group:
+           if ( grp == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "No group entry for group %s\n",
+                      group, 0, 0 );
+               exit( 1 );
+           }
+       }
+       free( group );
+    }
+
+    if ( user ) {
+       if ( getuid() == 0 && initgroups( user, gid ) != 0 ) {
+           Debug( LDAP_DEBUG_ANY,
+                  "Could not set the group access (gid) list\n", 0, 0, 0 );
+           exit( 1 );
+       }
+       free( user );
+    }
+
+#ifdef HAVE_ENDGRENT
+    endgrent();
+#endif
+
+    if ( gid >= 0 ) {
+       if ( setgid( gid ) != 0 ) {
+           Debug( LDAP_DEBUG_ANY, "Could not set real group id to %d\n",
+                  gid, 0, 0 );
+           exit( 1 );
+       }
+       if ( setegid( gid ) != 0 ) {
+           Debug( LDAP_DEBUG_ANY, "Could not set effective group id to %d\n",
+                  gid, 0, 0 );
+           exit( 1 );
+       }
+    }
+
+    if ( uid >= 0 ) {
+       if ( setuid( uid ) != 0 ) {
+           Debug( LDAP_DEBUG_ANY, "Could not set effective user id to %d\n",
+                  uid, 0, 0 );
+           exit( 1 );
+       }
+       if ( seteuid( uid ) != 0 ) {
+           Debug( LDAP_DEBUG_ANY, "Could not set real user id to %d\n",
+                  uid, 0, 0 );
+           exit( 1 );
+       }
+    }
+}
+
+#endif /* HAVE_PWD_H && HAVE_GRP_H */