2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 extern int DEBUGLEVEL;
26 /* what user is current? */
27 extern struct current_user current_user;
29 /****************************************************************************
30 Become the guest user.
31 ****************************************************************************/
33 BOOL become_guest(void)
35 static struct passwd *pass=NULL;
38 pass = Get_Pwnam(lp_guestaccount(-1),True);
43 /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
45 initgroups(pass->pw_name, (gid_t)pass->pw_gid);
48 set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL);
50 current_user.conn = NULL;
51 current_user.vuid = UID_FIELD_INVALID;
56 /*******************************************************************
57 Check if a username is OK.
58 ********************************************************************/
60 static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
63 for (i=0;i<conn->uid_cache.entries;i++)
64 if (conn->uid_cache.list[i] == vuser->uid)
67 if (!user_ok(vuser->user.unix_name,snum))
70 i = conn->uid_cache.entries % UID_CACHE_SIZE;
71 conn->uid_cache.list[i] = vuser->uid;
73 if (conn->uid_cache.entries < UID_CACHE_SIZE)
74 conn->uid_cache.entries++;
79 /****************************************************************************
80 Become the user of a connection number.
81 ****************************************************************************/
83 BOOL become_user(connection_struct *conn, uint16 vuid)
85 user_struct *vuser = get_valid_user_struct(vuid);
90 BOOL must_free_token = False;
91 NT_USER_TOKEN *token = NULL;
94 DEBUG(2,("Connection not open\n"));
99 * We need a separate check in security=share mode due to vuid
100 * always being UID_FIELD_INVALID. If we don't do this then
101 * in share mode security we are *always* changing uid's between
102 * SMB's - this hurts performance - Badly.
105 if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
106 (current_user.uid == conn->uid)) {
107 DEBUG(4,("Skipping become_user - already user\n"));
109 } else if ((current_user.conn == conn) &&
110 (vuser != 0) && (current_user.vuid == vuid) &&
111 (current_user.uid == vuser->uid)) {
112 DEBUG(4,("Skipping become_user - already user\n"));
118 if((vuser != NULL) && !check_user_ok(conn, vuser, snum))
121 if (conn->force_user ||
123 lp_security() == SEC_SHARE ||
124 !(vuser) || (vuser->guest)) {
127 current_user.groups = conn->groups;
128 current_user.ngroups = conn->ngroups;
129 token = conn->nt_user_token;
132 DEBUG(2,("Invalid vuid used %d\n",vuid));
137 current_user.ngroups = vuser->n_groups;
138 current_user.groups = vuser->groups;
139 token = vuser->nt_user_token;
143 * See if we should force group for this service.
144 * If so this overrides any group set in the force
148 if((group_c = *lp_force_group(snum))) {
149 BOOL is_guest = False;
154 * Only force group if the user is a member of
155 * the service group. Check the group memberships for
156 * this user (we already have this) to
157 * see if we should force the group.
161 for (i = 0; i < current_user.ngroups; i++) {
162 if (current_user.groups[i] == conn->gid) {
172 * We've changed the group list in the token - we must
176 if (vuser && vuser->guest)
179 token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest);
180 must_free_token = True;
183 set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token);
186 * Free the new token (as set_sec_ctx copies it).
190 delete_nt_token(&token);
192 current_user.conn = conn;
193 current_user.vuid = vuid;
195 DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
196 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
201 /****************************************************************************
202 Unbecome the user of a connection number.
203 ****************************************************************************/
205 BOOL unbecome_user(void )
209 DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
210 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
212 current_user.conn = NULL;
213 current_user.vuid = UID_FIELD_INVALID;
218 /****************************************************************************
219 Become the user of an authenticated connected named pipe.
220 When this is called we are currently running as the connection
222 ****************************************************************************/
224 BOOL become_authenticated_pipe_user(pipes_struct *p)
226 BOOL res = push_sec_ctx();
232 set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid,
233 p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token);
238 /****************************************************************************
239 Unbecome the user of an authenticated connected named pipe.
240 When this is called we are running as the authenticated pipe
241 user and need to go back to being the connection user.
242 ****************************************************************************/
244 BOOL unbecome_authenticated_pipe_user(pipes_struct *p)
246 return pop_sec_ctx();
249 /* Temporarily become a root user. Must match with unbecome_root(). */
251 void become_root(void)
257 /* Unbecome the root user */
259 void unbecome_root(void)
264 /*****************************************************************
265 *THE CANONICAL* convert name to SID function.
266 Tries winbind first - then uses local lookup.
267 *****************************************************************/
269 BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
271 extern pstring global_myname;
272 extern fstring global_myworkgroup;
274 char *sep = lp_winbind_separator();
276 if (!winbind_lookup_name(name, psid, name_type)) {
279 DEBUG(10, ("lookup_name: winbind lookup for %s failed - trying local\n", name));
281 /* If we are looking up a domain user, make sure it is
282 for the local machine only */
284 if (strchr(name, sep[0]) || strchr(name, '\\')) {
285 fstring domain, username;
287 split_domain_name(name, domain, username);
289 switch (lp_server_role()) {
290 case ROLE_DOMAIN_PDC:
291 case ROLE_DOMAIN_BDC:
292 if (strequal(domain, global_myworkgroup))
293 fstrcpy(domain, global_myname);
294 /* No break is deliberate here. JRA. */
296 if (strcasecmp(global_myname, domain) != 0) {
297 DEBUG(5, ("domain %s is not local\n", domain));
302 ret = local_lookup_name(domain, username, psid,
306 ret = local_lookup_name(global_myname, name, psid,
312 ("lookup_name: (local) %s -> SID %s (type %u)\n",
313 name, sid_to_string(sid,psid),
314 (unsigned int)*name_type ));
316 DEBUG(10,("lookup name: (local) %s failed.\n", name));
322 DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n",
323 name, sid_to_string(sid, psid),
324 (unsigned int)*name_type));
328 /*****************************************************************
329 *THE CANONICAL* convert SID to name function.
330 Tries winbind first - then uses local lookup.
331 *****************************************************************/
333 BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type)
338 /* Check if this is our own sid. This should perhaps be done by
339 winbind? For the moment handle it here. */
341 if (sid->num_auths == 5) {
345 sid_copy(&tmp_sid, sid);
346 sid_split_rid(&tmp_sid, &rid);
348 if (sid_equal(&global_sam_sid, &tmp_sid)) {
350 return map_domain_sid_to_name(&tmp_sid, dom_name) &&
351 local_lookup_rid(rid, name, name_type);
355 if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
360 DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
362 sid_copy(&tmp_sid, sid);
363 sid_split_rid(&tmp_sid, &rid);
364 return map_domain_sid_to_name(&tmp_sid, dom_name) &&
365 lookup_known_rid(&tmp_sid, rid, name, name_type);
370 /*****************************************************************
371 *THE CANONICAL* convert uid_t to SID function.
372 Tries winbind first - then uses local lookup.
374 *****************************************************************/
376 DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
380 if (!winbind_uid_to_sid(psid, uid)) {
381 DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid ));
383 return local_uid_to_sid(psid, uid);
386 DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
387 (unsigned int)uid, sid_to_string(sid, psid) ));
392 /*****************************************************************
393 *THE CANONICAL* convert gid_t to SID function.
394 Tries winbind first - then uses local lookup.
396 *****************************************************************/
398 DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
402 if (!winbind_gid_to_sid(psid, gid)) {
403 DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid ));
405 return local_gid_to_sid(psid, gid);
408 DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
409 (unsigned int)gid, sid_to_string(sid,psid) ));
414 /*****************************************************************
415 *THE CANONICAL* convert SID to uid function.
416 Tries winbind first - then uses local lookup.
417 Returns True if this name is a user sid and the conversion
418 was done correctly, False if not.
419 *****************************************************************/
421 BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
423 fstring dom_name, name, sid_str;
424 enum SID_NAME_USE name_type;
426 *sidtype = SID_NAME_UNKNOWN;
429 * First we must look up the name and decide if this is a user sid.
432 if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
433 DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n",
434 sid_to_string(sid_str, psid) ));
436 return local_sid_to_uid(puid, psid, sidtype);
440 * Ensure this is a user sid.
443 if (name_type != SID_NAME_USER) {
444 DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n",
445 (unsigned int)name_type ));
449 *sidtype = SID_NAME_USER;
452 * Get the uid for this SID.
455 if (!winbind_sid_to_uid(puid, psid)) {
456 DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n",
457 sid_to_string(sid_str, psid) ));
461 DEBUG(10,("sid_to_uid: winbindd %s -> %u\n",
462 sid_to_string(sid_str, psid),
463 (unsigned int)*puid ));
468 /*****************************************************************
469 *THE CANONICAL* convert SID to gid function.
470 Tries winbind first - then uses local lookup.
471 Returns True if this name is a user sid and the conversion
472 was done correctly, False if not.
473 *****************************************************************/
475 BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
477 fstring dom_name, name, sid_str;
478 enum SID_NAME_USE name_type;
480 *sidtype = SID_NAME_UNKNOWN;
483 * First we must look up the name and decide if this is a group sid.
486 if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
487 DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
488 sid_to_string(sid_str, psid) ));
490 return local_sid_to_gid(pgid, psid, sidtype);
494 * Ensure this is a group sid.
497 if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) {
498 DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n",
499 (unsigned int)name_type ));
501 return local_sid_to_gid(pgid, psid, sidtype);
504 *sidtype = name_type;
507 * Get the gid for this SID.
510 if (!winbind_sid_to_gid(pgid, psid)) {
511 DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n",
512 sid_to_string(sid_str, psid) ));
516 DEBUG(10,("gid_to_uid: winbindd %s -> %u\n",
517 sid_to_string(sid_str, psid),
518 (unsigned int)*pgid ));