1/* user.c - set user id, group id and group access list */
2/* $OpenLDAP$ */
3/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 *
5 * Copyright 1998-2011 The OpenLDAP Foundation.
6 * Portions Copyright 1999 PM Lashley.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17
18#include "portable.h"
19
20#if defined(HAVE_SETUID) && defined(HAVE_SETGID)
21
22#include <stdio.h>
23
24#include <ac/stdlib.h>
25
26#ifdef HAVE_PWD_H
27#include <pwd.h>
28#endif
29#ifdef HAVE_GRP_H
30#include <grp.h>
31#endif
32
33#include <ac/ctype.h>
34#include <ac/unistd.h>
35
36#include "slap.h"
37#include "lutil.h"
38
39/*
40 * Set real and effective user id and group id, and group access list
41 * The user and group arguments are freed.
42 */
43
44void
45slap_init_user( char *user, char *group )
46{
47    uid_t	uid = 0;
48    gid_t	gid = 0;
49    int		got_uid = 0, got_gid = 0;
50
51    if ( user ) {
52	struct passwd *pwd;
53	if ( isdigit( (unsigned char) *user ) ) {
54	    unsigned u;
55
56	    got_uid = 1;
57	    if ( lutil_atou( &u, user ) != 0 ) {
58		Debug( LDAP_DEBUG_ANY, "Unble to parse user %s\n",
59		       user, 0, 0 );
60
61		exit( EXIT_FAILURE );
62	    }
63	    uid = (uid_t)u;
64#ifdef HAVE_GETPWUID
65	    pwd = getpwuid( uid );
66	    goto did_getpw;
67#else
68	    free( user );
69	    user = NULL;
70#endif
71	} else {
72	    pwd = getpwnam( user );
73	did_getpw:
74	    if ( pwd == NULL ) {
75		Debug( LDAP_DEBUG_ANY, "No passwd entry for user %s\n",
76		       user, 0, 0 );
77
78		exit( EXIT_FAILURE );
79	    }
80	    if ( got_uid ) {
81		free( user );
82		user = (pwd != NULL ? ch_strdup( pwd->pw_name ) : NULL);
83	    } else {
84		got_uid = 1;
85		uid = pwd->pw_uid;
86	    }
87	    got_gid = 1;
88	    gid = pwd->pw_gid;
89#ifdef HAVE_ENDPWENT
90	    endpwent();
91#endif
92	}
93    }
94
95    if ( group ) {
96	struct group *grp;
97	if ( isdigit( (unsigned char) *group )) {
98	    unsigned g;
99
100	    if ( lutil_atou( &g, group ) != 0 ) {
101		Debug( LDAP_DEBUG_ANY, "Unble to parse group %s\n",
102		       group, 0, 0 );
103
104		exit( EXIT_FAILURE );
105	    }
106	    gid = (uid_t)g;
107#ifdef HAVE_GETGRGID
108	    grp = getgrgid( gid );
109	    goto did_group;
110#endif
111	} else {
112	    grp = getgrnam( group );
113	    if ( grp != NULL )
114		gid = grp->gr_gid;
115	did_group:
116	    if ( grp == NULL ) {
117		Debug( LDAP_DEBUG_ANY, "No group entry for group %s\n",
118		       group, 0, 0 );
119
120		exit( EXIT_FAILURE );
121	    }
122	}
123	free( group );
124	got_gid = 1;
125    }
126
127    if ( user ) {
128	if ( getuid() == 0 && initgroups( user, gid ) != 0 ) {
129	    Debug( LDAP_DEBUG_ANY,
130		   "Could not set the group access (gid) list\n", 0, 0, 0 );
131
132	    exit( EXIT_FAILURE );
133	}
134	free( user );
135    }
136
137#ifdef HAVE_ENDGRENT
138    endgrent();
139#endif
140
141    if ( got_gid ) {
142	if ( setgid( gid ) != 0 ) {
143	    Debug( LDAP_DEBUG_ANY, "Could not set real group id to %d\n",
144		       (int) gid, 0, 0 );
145
146	    exit( EXIT_FAILURE );
147	}
148#ifdef HAVE_SETEGID
149	if ( setegid( gid ) != 0 ) {
150	    Debug( LDAP_DEBUG_ANY, "Could not set effective group id to %d\n",
151		       (int) gid, 0, 0 );
152
153	    exit( EXIT_FAILURE );
154	}
155#endif
156    }
157
158    if ( got_uid ) {
159	if ( setuid( uid ) != 0 ) {
160	    Debug( LDAP_DEBUG_ANY, "Could not set real user id to %d\n",
161		       (int) uid, 0, 0 );
162
163	    exit( EXIT_FAILURE );
164	}
165#ifdef HAVE_SETEUID
166	if ( seteuid( uid ) != 0 ) {
167	    Debug( LDAP_DEBUG_ANY, "Could not set effective user id to %d\n",
168		       (int) uid, 0, 0 );
169
170	    exit( EXIT_FAILURE );
171	}
172#endif
173    }
174}
175
176#endif /* HAVE_PWD_H && HAVE_GRP_H */
177