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
);
45 /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
47 initgroups(pass
->pw_name
, (gid_t
)pass
->pw_gid
);
50 set_sec_ctx(pass
->pw_uid
, pass
->pw_gid
, 0, NULL
, NULL
);
52 current_user
.conn
= NULL
;
53 current_user
.vuid
= UID_FIELD_INVALID
;
58 /*******************************************************************
59 Check if a username is OK.
60 ********************************************************************/
62 static BOOL
check_user_ok(connection_struct
*conn
, user_struct
*vuser
,int snum
)
65 for (i
=0;i
<conn
->uid_cache
.entries
;i
++)
66 if (conn
->uid_cache
.list
[i
] == vuser
->uid
)
69 if (!user_ok(vuser
->user
.unix_name
,snum
))
72 i
= conn
->uid_cache
.entries
% UID_CACHE_SIZE
;
73 conn
->uid_cache
.list
[i
] = vuser
->uid
;
75 if (conn
->uid_cache
.entries
< UID_CACHE_SIZE
)
76 conn
->uid_cache
.entries
++;
81 /****************************************************************************
82 Become the user of a connection number.
83 ****************************************************************************/
85 BOOL
become_user(connection_struct
*conn
, uint16 vuid
)
87 user_struct
*vuser
= get_valid_user_struct(vuid
);
92 BOOL must_free_token
= False
;
93 NT_USER_TOKEN
*token
= NULL
;
96 DEBUG(2,("Connection not open\n"));
101 * We need a separate check in security=share mode due to vuid
102 * always being UID_FIELD_INVALID. If we don't do this then
103 * in share mode security we are *always* changing uid's between
104 * SMB's - this hurts performance - Badly.
107 if((lp_security() == SEC_SHARE
) && (current_user
.conn
== conn
) &&
108 (current_user
.uid
== conn
->uid
)) {
109 DEBUG(4,("Skipping become_user - already user\n"));
111 } else if ((current_user
.conn
== conn
) &&
112 (vuser
!= 0) && (current_user
.vuid
== vuid
) &&
113 (current_user
.uid
== vuser
->uid
)) {
114 DEBUG(4,("Skipping become_user - already user\n"));
120 if((vuser
!= NULL
) && !check_user_ok(conn
, vuser
, snum
))
123 if (conn
->force_user
||
125 lp_security() == SEC_SHARE
||
126 !(vuser
) || (vuser
->guest
)) {
129 current_user
.groups
= conn
->groups
;
130 current_user
.ngroups
= conn
->ngroups
;
131 token
= conn
->nt_user_token
;
134 DEBUG(2,("Invalid vuid used %d\n",vuid
));
139 current_user
.ngroups
= vuser
->n_groups
;
140 current_user
.groups
= vuser
->groups
;
141 token
= vuser
->nt_user_token
;
145 * See if we should force group for this service.
146 * If so this overrides any group set in the force
150 if((group_c
= *lp_force_group(snum
))) {
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 token
= create_nt_token(uid
, gid
, current_user
.ngroups
, current_user
.groups
);
177 must_free_token
= True
;
180 set_sec_ctx(uid
, gid
, current_user
.ngroups
, current_user
.groups
, token
);
183 * Free the new token (as set_sec_ctx copies it).
187 delete_nt_token(&token
);
189 current_user
.conn
= conn
;
190 current_user
.vuid
= vuid
;
192 DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
193 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
198 /****************************************************************************
199 Unbecome the user of a connection number.
200 ****************************************************************************/
202 BOOL
unbecome_user(void )
206 DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
207 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
209 current_user
.conn
= NULL
;
210 current_user
.vuid
= UID_FIELD_INVALID
;
215 /****************************************************************************
216 Become the user of an authenticated connected named pipe.
217 When this is called we are currently running as the connection
219 ****************************************************************************/
221 BOOL
become_authenticated_pipe_user(pipes_struct
*p
)
223 BOOL res
= push_sec_ctx();
229 set_sec_ctx(p
->pipe_user
.uid
, p
->pipe_user
.gid
,
230 p
->pipe_user
.ngroups
, p
->pipe_user
.groups
, p
->pipe_user
.nt_user_token
);
235 /****************************************************************************
236 Unbecome the user of an authenticated connected named pipe.
237 When this is called we are running as the authenticated pipe
238 user and need to go back to being the connection user.
239 ****************************************************************************/
241 BOOL
unbecome_authenticated_pipe_user(pipes_struct
*p
)
243 return pop_sec_ctx();
247 /* Temporarily become a root user. Must match with unbecome_root(). */
248 void become_root(void)
254 /* Unbecome the root user */
256 void unbecome_root(void)
261 /*****************************************************************
262 *THE CANONICAL* convert name to SID function.
263 Tries winbind first - then uses local lookup.
264 *****************************************************************/
266 BOOL
lookup_name(char *name
, DOM_SID
*psid
, enum SID_NAME_USE
*name_type
)
268 extern pstring global_myname
;
271 if (!winbind_lookup_name(name
, psid
, name_type
)) {
274 DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name
));
276 ret
= local_lookup_name(global_myname
, name
, psid
, name_type
);
278 DEBUG(10,("lookup_name : (local) %s -> SID %s (type %u)\n",
279 name
, sid_to_string(sid
,psid
),
280 (unsigned int)*name_type
));
282 DEBUG(10,("lookup name : (local) %s failed.\n",
287 DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n",
288 name
, sid_to_string(sid
,psid
), (unsigned int)*name_type
));
292 /*****************************************************************
293 *THE CANONICAL* convert SID to name function.
294 Tries winbind first - then uses local lookup.
295 *****************************************************************/
297 BOOL
lookup_sid(DOM_SID
*sid
, fstring dom_name
, fstring name
, enum SID_NAME_USE
*name_type
)
302 /* Check if this is our own sid. This should perhaps be done by
303 winbind? For the moment handle it here. */
305 if (sid
->num_auths
== 5) {
309 sid_copy(&tmp_sid
, sid
);
310 sid_split_rid(&tmp_sid
, &rid
);
312 if (sid_equal(&global_sam_sid
, &tmp_sid
)) {
314 return map_domain_sid_to_name(&tmp_sid
, dom_name
) &&
315 local_lookup_rid(rid
, name
, name_type
);
319 if (!winbind_lookup_sid(sid
, dom_name
, name
, name_type
)) {
324 DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str
, sid
) ));
326 sid_copy(&tmp_sid
, sid
);
327 sid_split_rid(&tmp_sid
, &rid
);
328 return map_domain_sid_to_name(&tmp_sid
, dom_name
) &&
329 lookup_known_rid(&tmp_sid
, rid
, name
, name_type
);
334 /*****************************************************************
335 *THE CANONICAL* convert uid_t to SID function.
336 Tries winbind first - then uses local lookup.
338 *****************************************************************/
340 DOM_SID
*uid_to_sid(DOM_SID
*psid
, uid_t uid
)
344 if (!winbind_uid_to_sid(psid
, uid
)) {
345 DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid
));
347 return local_uid_to_sid(psid
, uid
);
350 DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
351 (unsigned int)uid
, sid_to_string(sid
, psid
) ));
356 /*****************************************************************
357 *THE CANONICAL* convert gid_t to SID function.
358 Tries winbind first - then uses local lookup.
360 *****************************************************************/
362 DOM_SID
*gid_to_sid(DOM_SID
*psid
, gid_t gid
)
366 if (!winbind_gid_to_sid(psid
, gid
)) {
367 DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid
));
369 return local_gid_to_sid(psid
, gid
);
372 DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
373 (unsigned int)gid
, sid_to_string(sid
,psid
) ));
378 /*****************************************************************
379 *THE CANONICAL* convert SID to uid function.
380 Tries winbind first - then uses local lookup.
381 Returns True if this name is a user sid and the conversion
382 was done correctly, False if not.
383 *****************************************************************/
385 BOOL
sid_to_uid(DOM_SID
*psid
, uid_t
*puid
, enum SID_NAME_USE
*sidtype
)
387 fstring dom_name
, name
, sid_str
;
388 enum SID_NAME_USE name_type
;
390 *sidtype
= SID_NAME_UNKNOWN
;
393 * First we must look up the name and decide if this is a user sid.
396 if (!winbind_lookup_sid(psid
, dom_name
, name
, &name_type
)) {
397 DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n",
398 sid_to_string(sid_str
, psid
) ));
400 return local_sid_to_uid(puid
, psid
, sidtype
);
404 * Ensure this is a user sid.
407 if (name_type
!= SID_NAME_USER
) {
408 DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n",
409 (unsigned int)name_type
));
413 *sidtype
= SID_NAME_USER
;
416 * Get the uid for this SID.
419 if (!winbind_sid_to_uid(puid
, psid
)) {
420 DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n",
421 sid_to_string(sid_str
, psid
) ));
425 DEBUG(10,("sid_to_uid: winbindd %s -> %u\n",
426 sid_to_string(sid_str
, psid
),
427 (unsigned int)*puid
));
432 /*****************************************************************
433 *THE CANONICAL* convert SID to gid function.
434 Tries winbind first - then uses local lookup.
435 Returns True if this name is a user sid and the conversion
436 was done correctly, False if not.
437 *****************************************************************/
439 BOOL
sid_to_gid(DOM_SID
*psid
, gid_t
*pgid
, enum SID_NAME_USE
*sidtype
)
441 fstring dom_name
, name
, sid_str
;
442 enum SID_NAME_USE name_type
;
444 *sidtype
= SID_NAME_UNKNOWN
;
447 * First we must look up the name and decide if this is a group sid.
450 if (!winbind_lookup_sid(psid
, dom_name
, name
, &name_type
)) {
451 DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n",
452 sid_to_string(sid_str
, psid
) ));
454 return local_sid_to_gid(pgid
, psid
, sidtype
);
458 * Ensure this is a group sid.
461 if ((name_type
!= SID_NAME_DOM_GRP
) && (name_type
!= SID_NAME_ALIAS
) && (name_type
!= SID_NAME_WKN_GRP
)) {
462 DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a know group (%u)\n",
463 (unsigned int)name_type
));
465 return local_sid_to_gid(pgid
, psid
, sidtype
);
468 *sidtype
= name_type
;
471 * Get the gid for this SID.
474 if (!winbind_sid_to_gid(pgid
, psid
)) {
475 DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n",
476 sid_to_string(sid_str
, psid
) ));
480 DEBUG(10,("gid_to_uid: winbindd %s -> %u\n",
481 sid_to_string(sid_str
, psid
),
482 (unsigned int)*pgid
));