Move socket setup to set_socket(), called before the uid/gid change.
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 \
fcntl.h \
filio.h \
getopt.h \
+ grp.h \
libutil.h \
limits.h \
locale.h \
AC_CHECK_FUNCS( \
bcopy \
+ endgrent \
+ endpwent \
flock \
getdtablesize \
+ getgrgid \
gethostname \
getpass \
getpwuid \
-.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
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
/* 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
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
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
}
#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;
? 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",
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,
#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" );
}
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;
#endif
#ifdef SLAPD_BDB2
"t"
+#endif
+#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
+ "U:G:"
#endif
)) != EOF ) {
switch ( i ) {
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 );
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;
if(!inetd) {
FILE *fp;
- slapd_addr = &bind_addr;
-
Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
if (( slapd_pid_file != NULL ) &&
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 */
*/
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...
*/
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));
--- /dev/null
+/* 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 */