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