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