xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/user.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /*	$NetBSD: user.c,v 1.2 2020/08/11 13:15:39 christos Exp $	*/
2 
3 /* user.c - set user id, group id and group access list */
4 /* $OpenLDAP$ */
5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6  *
7  * Copyright 1998-2020 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 <sys/cdefs.h>
21 __RCSID("$NetBSD: user.c,v 1.2 2020/08/11 13:15:39 christos Exp $");
22 
23 #include "portable.h"
24 
25 #if defined(HAVE_SETUID) && defined(HAVE_SETGID)
26 
27 #include <stdio.h>
28 
29 #include <ac/stdlib.h>
30 
31 #ifdef HAVE_PWD_H
32 #include <pwd.h>
33 #endif
34 #ifdef HAVE_GRP_H
35 #include <grp.h>
36 #endif
37 
38 #include <ac/ctype.h>
39 #include <ac/unistd.h>
40 
41 #include "slap.h"
42 #include "lutil.h"
43 
44 /*
45  * Set real and effective user id and group id, and group access list
46  * The user and group arguments are freed.
47  */
48 
49 void
50 slap_init_user( char *user, char *group )
51 {
52     uid_t	uid = 0;
53     gid_t	gid = 0;
54     int		got_uid = 0, got_gid = 0;
55 
56     if ( user ) {
57 	struct passwd *pwd;
58 	if ( isdigit( (unsigned char) *user ) ) {
59 	    unsigned u;
60 
61 	    got_uid = 1;
62 	    if ( lutil_atou( &u, user ) != 0 ) {
63 		Debug( LDAP_DEBUG_ANY, "Unble to parse user %s\n",
64 		       user, 0, 0 );
65 
66 		exit( EXIT_FAILURE );
67 	    }
68 	    uid = (uid_t)u;
69 #ifdef HAVE_GETPWUID
70 	    pwd = getpwuid( uid );
71 	    goto did_getpw;
72 #else
73 	    free( user );
74 	    user = NULL;
75 #endif
76 	} else {
77 	    pwd = getpwnam( user );
78 	did_getpw:
79 	    if ( pwd == NULL ) {
80 		Debug( LDAP_DEBUG_ANY, "No passwd entry for user %s\n",
81 		       user, 0, 0 );
82 
83 		exit( EXIT_FAILURE );
84 	    }
85 	    if ( got_uid ) {
86 		free( user );
87 		user = (pwd != NULL ? ch_strdup( pwd->pw_name ) : NULL);
88 	    } else {
89 		got_uid = 1;
90 		uid = pwd->pw_uid;
91 	    }
92 	    got_gid = 1;
93 	    gid = pwd->pw_gid;
94 #ifdef HAVE_ENDPWENT
95 	    endpwent();
96 #endif
97 	}
98     }
99 
100     if ( group ) {
101 	struct group *grp;
102 	if ( isdigit( (unsigned char) *group )) {
103 	    unsigned g;
104 
105 	    if ( lutil_atou( &g, group ) != 0 ) {
106 		Debug( LDAP_DEBUG_ANY, "Unble to parse group %s\n",
107 		       group, 0, 0 );
108 
109 		exit( EXIT_FAILURE );
110 	    }
111 	    gid = (uid_t)g;
112 #ifdef HAVE_GETGRGID
113 	    grp = getgrgid( gid );
114 	    goto did_group;
115 #endif
116 	} else {
117 	    grp = getgrnam( group );
118 	    if ( grp != NULL )
119 		gid = grp->gr_gid;
120 	did_group:
121 	    if ( grp == NULL ) {
122 		Debug( LDAP_DEBUG_ANY, "No group entry for group %s\n",
123 		       group, 0, 0 );
124 
125 		exit( EXIT_FAILURE );
126 	    }
127 	}
128 	free( group );
129 	got_gid = 1;
130     }
131 
132     if ( user ) {
133 	if ( getuid() == 0 && initgroups( user, gid ) != 0 ) {
134 	    Debug( LDAP_DEBUG_ANY,
135 		   "Could not set the group access (gid) list\n", 0, 0, 0 );
136 
137 	    exit( EXIT_FAILURE );
138 	}
139 	free( user );
140     }
141 
142 #ifdef HAVE_ENDGRENT
143     endgrent();
144 #endif
145 
146     if ( got_gid ) {
147 	if ( setgid( gid ) != 0 ) {
148 	    Debug( LDAP_DEBUG_ANY, "Could not set real group id to %d\n",
149 		       (int) gid, 0, 0 );
150 
151 	    exit( EXIT_FAILURE );
152 	}
153 #ifdef HAVE_SETEGID
154 	if ( setegid( gid ) != 0 ) {
155 	    Debug( LDAP_DEBUG_ANY, "Could not set effective group id to %d\n",
156 		       (int) gid, 0, 0 );
157 
158 	    exit( EXIT_FAILURE );
159 	}
160 #endif
161     }
162 
163     if ( got_uid ) {
164 	if ( setuid( uid ) != 0 ) {
165 	    Debug( LDAP_DEBUG_ANY, "Could not set real user id to %d\n",
166 		       (int) uid, 0, 0 );
167 
168 	    exit( EXIT_FAILURE );
169 	}
170 #ifdef HAVE_SETEUID
171 	if ( seteuid( uid ) != 0 ) {
172 	    Debug( LDAP_DEBUG_ANY, "Could not set effective user id to %d\n",
173 		       (int) uid, 0, 0 );
174 
175 	    exit( EXIT_FAILURE );
176 	}
177 #endif
178     }
179 }
180 
181 #endif /* HAVE_PWD_H && HAVE_GRP_H */
182