4 Unix SMB/Netbios implementation.
7 Copyright (C) Andrew Tridgell 1992-1998
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 extern int DEBUGLEVEL;
28 /* what user is current? */
29 extern struct current_user current_user;
31 /****************************************************************************
32 Become the guest user.
33 ****************************************************************************/
35 BOOL become_guest(void)
37 static struct passwd *pass=NULL;
40 pass = Get_Pwnam(lp_guestaccount(-1),True);
41 if (!pass) return(False);
44 /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
46 initgroups(pass->pw_name, (gid_t)pass->pw_gid);
49 set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL);
51 current_user.conn = NULL;
52 current_user.vuid = UID_FIELD_INVALID;
57 /*******************************************************************
58 Check if a username is OK.
59 ********************************************************************/
61 static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
64 for (i=0;i<conn->uid_cache.entries;i++)
65 if (conn->uid_cache.list[i] == vuser->uid) return(True);
67 if (!user_ok(vuser->user.unix_name,snum)) return(False);
69 i = conn->uid_cache.entries % UID_CACHE_SIZE;
70 conn->uid_cache.list[i] = vuser->uid;
72 if (conn->uid_cache.entries < UID_CACHE_SIZE)
73 conn->uid_cache.entries++;
78 /****************************************************************************
79 Become the user of a connection number.
80 ****************************************************************************/
82 BOOL become_user(connection_struct *conn, uint16 vuid)
84 user_struct *vuser = get_valid_user_struct(vuid);
91 DEBUG(2,("Connection not open\n"));
96 * We need a separate check in security=share mode due to vuid
97 * always being UID_FIELD_INVALID. If we don't do this then
98 * in share mode security we are *always* changing uid's between
99 * SMB's - this hurts performance - Badly.
102 if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
103 (current_user.uid == conn->uid)) {
104 DEBUG(4,("Skipping become_user - already user\n"));
106 } else if ((current_user.conn == conn) &&
107 (vuser != 0) && (current_user.vuid == vuid) &&
108 (current_user.uid == vuser->uid)) {
109 DEBUG(4,("Skipping become_user - already user\n"));
115 if((vuser != NULL) && !check_user_ok(conn, vuser, snum))
118 if (conn->force_user ||
119 lp_security() == SEC_SHARE ||
120 !(vuser) || (vuser->guest)) {
123 current_user.groups = conn->groups;
124 current_user.ngroups = conn->ngroups;
127 DEBUG(2,("Invalid vuid used %d\n",vuid));
132 current_user.ngroups = vuser->n_groups;
133 current_user.groups = vuser->groups;
137 * See if we should force group for this service.
138 * If so this overrides any group set in the force
142 if((group_c = *lp_force_group(snum))) {
146 * Only force group if the user is a member of
147 * the service group. Check the group memberships for
148 * this user (we already have this) to
149 * see if we should force the group.
153 for (i = 0; i < current_user.ngroups; i++) {
154 if (current_user.groups[i] == conn->gid) {
164 set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups);
166 current_user.conn = conn;
167 current_user.vuid = vuid;
169 DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
170 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
175 /****************************************************************************
176 Unbecome the user of a connection number.
177 ****************************************************************************/
179 BOOL unbecome_user(void )
183 DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
184 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
186 current_user.conn = NULL;
187 current_user.vuid = UID_FIELD_INVALID;
192 /****************************************************************************
193 Become the user of an authenticated connected named pipe.
194 When this is called we are currently running as the connection
196 ****************************************************************************/
198 BOOL become_authenticated_pipe_user(pipes_struct *p)
200 BOOL res = push_sec_ctx();
206 set_sec_ctx(p->uid, p->gid, 0, NULL); /* fix group stuff */
209 /****************************************************************************
210 Unbecome the user of an authenticated connected named pipe.
211 When this is called we are running as the authenticated pipe
212 user and need to go back to being the connection user.
213 ****************************************************************************/
215 BOOL unbecome_authenticated_pipe_user(pipes_struct *p)
217 return pop_sec_ctx();
220 /* Temporarily become a root user. Must match with unbecome_root(). */
222 void become_root(void)
228 /* Unbecome the root user */
230 void unbecome_root(void)