1 /*
2  *  Unix SMB/CIFS implementation.
3  *  Authentication utility functions
4  *  Copyright (C) Andrew Tridgell 1992-1998
5  *  Copyright (C) Andrew Bartlett 2001
6  *  Copyright (C) Jeremy Allison 2000-2001
7  *  Copyright (C) Rafal Szczesniak 2002
8  *  Copyright (C) Volker Lendecke 2006
9  *  Copyright (C) Michael Adam 2007
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 3 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
23  */
24 
25 /* functions moved from auth/auth_util.c to minimize linker deps */
26 
27 #include "includes.h"
28 #include "lib/util_unixsids.h"
29 #include "system/passwd.h"
30 #include "auth.h"
31 #include "secrets.h"
32 #include "../lib/util/memcache.h"
33 #include "../librpc/gen_ndr/netlogon.h"
34 #include "../libcli/security/security.h"
35 #include "../lib/util/util_pw.h"
36 #include "passdb.h"
37 #include "lib/privileges.h"
38 
39 /****************************************************************************
40  Check for a SID in an struct security_token
41 ****************************************************************************/
42 
nt_token_check_sid(const struct dom_sid * sid,const struct security_token * token)43 bool nt_token_check_sid ( const struct dom_sid *sid, const struct security_token *token )
44 {
45 	if ( !sid || !token )
46 		return False;
47 
48 	return security_token_has_sid(token, sid);
49 }
50 
nt_token_check_domain_rid(struct security_token * token,uint32_t rid)51 bool nt_token_check_domain_rid( struct security_token *token, uint32_t rid )
52 {
53 	struct dom_sid domain_sid;
54 
55 	/* if we are a domain member, the get the domain SID, else for
56 	   a DC or standalone server, use our own SID */
57 
58 	if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
59 		if ( !secrets_fetch_domain_sid( lp_workgroup(),
60 						&domain_sid ) ) {
61 			DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
62 				 "SID for domain [%s]\n", lp_workgroup()));
63 			return False;
64 		}
65 	}
66 	else
67 		sid_copy( &domain_sid, get_global_sam_sid() );
68 
69 	sid_append_rid( &domain_sid, rid );
70 
71 	return nt_token_check_sid( &domain_sid, token );\
72 }
73 
74 /******************************************************************************
75  Create a token for the root user to be used internally by smbd.
76  This is similar to running under the context of the LOCAL_SYSTEM account
77  in Windows.  This is a read-only token.  Do not modify it or free() it.
78  Create a copy if you need to change it.
79 ******************************************************************************/
80 
get_root_nt_token(struct security_token ** token)81 NTSTATUS get_root_nt_token( struct security_token **token )
82 {
83 	struct security_token *for_cache;
84 	struct dom_sid u_sid, g_sid;
85 	struct passwd *pw;
86 	void *cache_data;
87 	NTSTATUS status = NT_STATUS_OK;
88 
89 	cache_data = memcache_lookup_talloc(
90 		NULL, SINGLETON_CACHE_TALLOC,
91 		data_blob_string_const_null("root_nt_token"));
92 
93 	if (cache_data != NULL) {
94 		*token = talloc_get_type_abort(
95 			cache_data, struct security_token);
96 		return NT_STATUS_OK;
97 	}
98 
99 	if ( !(pw = getpwuid(0)) ) {
100 		if ( !(pw = getpwnam("root")) ) {
101 			DBG_ERR("get_root_nt_token: both getpwuid(0) "
102 				"and getpwnam(\"root\") failed!\n");
103 			return NT_STATUS_NO_SUCH_USER;
104 		}
105 	}
106 
107 	/* get the user and primary group SIDs; although the
108 	   BUILTIN\Administrators SId is really the one that matters here */
109 
110 	uid_to_sid(&u_sid, pw->pw_uid);
111 	gid_to_sid(&g_sid, pw->pw_gid);
112 
113 	status = create_local_nt_token(talloc_tos(), &u_sid, False,
114 				      1, &global_sid_Builtin_Administrators, token);
115 	if (!NT_STATUS_IS_OK(status)) {
116 		return status;
117 	}
118 
119 	security_token_set_privilege(*token, SEC_PRIV_DISK_OPERATOR);
120 
121 	for_cache = *token;
122 
123 	memcache_add_talloc(
124 		NULL, SINGLETON_CACHE_TALLOC,
125 		data_blob_string_const_null("root_nt_token"), &for_cache);
126 
127 	return status;
128 }
129 
130 
131 /*
132  * Add alias SIDs from memberships within the partially created token SID list
133  */
134 
add_aliases(const struct dom_sid * domain_sid,struct security_token * token)135 NTSTATUS add_aliases(const struct dom_sid *domain_sid,
136 		     struct security_token *token)
137 {
138 	uint32_t *aliases;
139 	size_t i, num_aliases;
140 	NTSTATUS status;
141 	TALLOC_CTX *tmp_ctx;
142 
143 	if (!(tmp_ctx = talloc_init("add_aliases"))) {
144 		return NT_STATUS_NO_MEMORY;
145 	}
146 
147 	aliases = NULL;
148 	num_aliases = 0;
149 
150 	status = pdb_enum_alias_memberships(tmp_ctx, domain_sid,
151 					    token->sids,
152 					    token->num_sids,
153 					    &aliases, &num_aliases);
154 
155 	if (!NT_STATUS_IS_OK(status)) {
156 		DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
157 			   nt_errstr(status)));
158 		goto done;
159 	}
160 
161 	for (i=0; i<num_aliases; i++) {
162 		struct dom_sid alias_sid;
163 		sid_compose(&alias_sid, domain_sid, aliases[i]);
164 		status = add_sid_to_array_unique(token, &alias_sid,
165 						 &token->sids,
166 						 &token->num_sids);
167 		if (!NT_STATUS_IS_OK(status)) {
168 			DEBUG(0, ("add_sid_to_array failed\n"));
169 			goto done;
170 		}
171 	}
172 
173 done:
174 	TALLOC_FREE(tmp_ctx);
175 	return NT_STATUS_OK;
176 }
177 
178 /*******************************************************************
179 *******************************************************************/
180 
add_builtin_administrators(struct security_token * token,const struct dom_sid * dom_sid)181 static NTSTATUS add_builtin_administrators(struct security_token *token,
182 					   const struct dom_sid *dom_sid)
183 {
184 	struct dom_sid domadm;
185 	NTSTATUS status;
186 
187 	/* nothing to do if we aren't in a domain */
188 
189 	if ( !(IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER) ) {
190 		return NT_STATUS_OK;
191 	}
192 
193 	/* Find the Domain Admins SID */
194 
195 	if ( IS_DC ) {
196 		sid_copy( &domadm, get_global_sam_sid() );
197 	} else {
198 		if (dom_sid == NULL) {
199 			return NT_STATUS_INVALID_PARAMETER_MIX;
200 		}
201 		sid_copy(&domadm, dom_sid);
202 	}
203 	sid_append_rid( &domadm, DOMAIN_RID_ADMINS );
204 
205 	/* Add Administrators if the user beloongs to Domain Admins */
206 
207 	if ( nt_token_check_sid( &domadm, token ) ) {
208 		status = add_sid_to_array(token,
209 					  &global_sid_Builtin_Administrators,
210 					  &token->sids, &token->num_sids);
211 	if (!NT_STATUS_IS_OK(status)) {
212 			return status;
213 		}
214 	}
215 
216 	return NT_STATUS_OK;
217 }
218 
add_builtin_guests(struct security_token * token,const struct dom_sid * dom_sid)219 static NTSTATUS add_builtin_guests(struct security_token *token,
220 				   const struct dom_sid *dom_sid)
221 {
222 	struct dom_sid tmp_sid;
223 	NTSTATUS status;
224 
225 	/*
226 	 * First check the local GUEST account.
227 	 */
228 	sid_compose(&tmp_sid, get_global_sam_sid(), DOMAIN_RID_GUEST);
229 
230 	if (nt_token_check_sid(&tmp_sid, token)) {
231 		status = add_sid_to_array_unique(token,
232 					&global_sid_Builtin_Guests,
233 					&token->sids, &token->num_sids);
234 		if (!NT_STATUS_IS_OK(status)) {
235 			return status;
236 		}
237 
238 		return NT_STATUS_OK;
239 	}
240 
241 	/*
242 	 * First check the local GUESTS group.
243 	 */
244 	sid_compose(&tmp_sid, get_global_sam_sid(), DOMAIN_RID_GUESTS);
245 
246 	if (nt_token_check_sid(&tmp_sid, token)) {
247 		status = add_sid_to_array_unique(token,
248 					&global_sid_Builtin_Guests,
249 					&token->sids, &token->num_sids);
250 		if (!NT_STATUS_IS_OK(status)) {
251 			return status;
252 		}
253 
254 		return NT_STATUS_OK;
255 	}
256 
257 	if (lp_server_role() != ROLE_DOMAIN_MEMBER) {
258 		return NT_STATUS_OK;
259 	}
260 
261 	if (dom_sid == NULL) {
262 		return NT_STATUS_INVALID_PARAMETER_MIX;
263 	}
264 
265 	/*
266 	 * First check the domain GUESTS group.
267 	 */
268 	sid_copy(&tmp_sid, dom_sid);
269 	sid_append_rid(&tmp_sid, DOMAIN_RID_GUESTS);
270 
271 	if (nt_token_check_sid(&tmp_sid, token)) {
272 		status = add_sid_to_array_unique(token,
273 					&global_sid_Builtin_Guests,
274 					&token->sids, &token->num_sids);
275 		if (!NT_STATUS_IS_OK(status)) {
276 			return status;
277 		}
278 
279 		return NT_STATUS_OK;
280 	}
281 
282 	return NT_STATUS_OK;
283 }
284 
285 static NTSTATUS add_local_groups(struct security_token *result,
286 				 bool is_guest);
287 
get_user_sid_info3_and_extra(const struct netr_SamInfo3 * info3,const struct extra_auth_info * extra,struct dom_sid * sid)288 NTSTATUS get_user_sid_info3_and_extra(const struct netr_SamInfo3 *info3,
289 				      const struct extra_auth_info *extra,
290 				      struct dom_sid *sid)
291 {
292 	/* USER SID */
293 	if (info3->base.rid == (uint32_t)(-1)) {
294 		/* this is a signal the user was fake and generated,
295 		 * the actual SID we want to use is stored in the extra
296 		 * sids */
297 		if (is_null_sid(&extra->user_sid)) {
298 			/* we couldn't find the user sid, bail out */
299 			DEBUG(3, ("Invalid user SID\n"));
300 			return NT_STATUS_UNSUCCESSFUL;
301 		}
302 		sid_copy(sid, &extra->user_sid);
303 	} else {
304 		sid_copy(sid, info3->base.domain_sid);
305 		sid_append_rid(sid, info3->base.rid);
306 	}
307 	return NT_STATUS_OK;
308 }
309 
create_local_nt_token_from_info3(TALLOC_CTX * mem_ctx,bool is_guest,const struct netr_SamInfo3 * info3,const struct extra_auth_info * extra,struct security_token ** ntok)310 NTSTATUS create_local_nt_token_from_info3(TALLOC_CTX *mem_ctx,
311 					  bool is_guest,
312 					  const struct netr_SamInfo3 *info3,
313 					  const struct extra_auth_info *extra,
314 					  struct security_token **ntok)
315 {
316 	struct security_token *usrtok = NULL;
317 	uint32_t session_info_flags = 0;
318 	NTSTATUS status;
319 	int i;
320 
321 	DEBUG(10, ("Create local NT token for %s\n",
322 		   info3->base.account_name.string));
323 
324 	usrtok = talloc_zero(mem_ctx, struct security_token);
325 	if (!usrtok) {
326 		DEBUG(0, ("talloc failed\n"));
327 		return NT_STATUS_NO_MEMORY;
328 	}
329 
330 	/* Add the user and primary group sid FIRST */
331 	/* check if the user rid is the special "Domain Guests" rid.
332 	 * If so pick the first sid for the extra sids instead as it
333 	 * is a local fake account */
334 	usrtok->sids = talloc_array(usrtok, struct dom_sid, 2);
335 	if (!usrtok->sids) {
336 		TALLOC_FREE(usrtok);
337 		return NT_STATUS_NO_MEMORY;
338 	}
339 	usrtok->num_sids = 2;
340 
341 	status = get_user_sid_info3_and_extra(info3, extra, &usrtok->sids[0]);
342 	if (!NT_STATUS_IS_OK(status)) {
343 		TALLOC_FREE(usrtok);
344 		return status;
345 	}
346 
347 	/* GROUP SID */
348 	if (info3->base.primary_gid == (uint32_t)(-1)) {
349 		/* this is a signal the user was fake and generated,
350 		 * the actual SID we want to use is stored in the extra
351 		 * sids */
352 		if (is_null_sid(&extra->pgid_sid)) {
353 			/* we couldn't find the user sid, bail out */
354 			DEBUG(3, ("Invalid group SID\n"));
355 			TALLOC_FREE(usrtok);
356 			return NT_STATUS_UNSUCCESSFUL;
357 		}
358 		sid_copy(&usrtok->sids[1], &extra->pgid_sid);
359 	} else {
360 		sid_copy(&usrtok->sids[1], info3->base.domain_sid);
361 		sid_append_rid(&usrtok->sids[1],
362 				info3->base.primary_gid);
363 	}
364 
365 	/* Now the SIDs we got from authentication. These are the ones from
366 	 * the info3 struct or from the pdb_enum_group_memberships, depending
367 	 * on who authenticated the user.
368 	 * Note that we start the for loop at "1" here, we already added the
369 	 * first group sid as primary above. */
370 
371 	for (i = 0; i < info3->base.groups.count; i++) {
372 		struct dom_sid tmp_sid;
373 
374 		sid_copy(&tmp_sid, info3->base.domain_sid);
375 		sid_append_rid(&tmp_sid, info3->base.groups.rids[i].rid);
376 
377 		status = add_sid_to_array_unique(usrtok, &tmp_sid,
378 						 &usrtok->sids,
379 						 &usrtok->num_sids);
380 		if (!NT_STATUS_IS_OK(status)) {
381 			DEBUG(3, ("Failed to add SID to nt token\n"));
382 			TALLOC_FREE(usrtok);
383 			return status;
384 		}
385 	}
386 
387 	/* now also add extra sids if they are not the special user/group
388 	 * sids */
389 	for (i = 0; i < info3->sidcount; i++) {
390 		status = add_sid_to_array_unique(usrtok,
391 						 info3->sids[i].sid,
392 						 &usrtok->sids,
393 						 &usrtok->num_sids);
394 		if (!NT_STATUS_IS_OK(status)) {
395 			DEBUG(3, ("Failed to add SID to nt token\n"));
396 			TALLOC_FREE(usrtok);
397 			return status;
398 		}
399 	}
400 
401 	status = add_local_groups(usrtok, is_guest);
402 	if (!NT_STATUS_IS_OK(status)) {
403 		DEBUG(3, ("Failed to add local groups\n"));
404 		TALLOC_FREE(usrtok);
405 		return status;
406 	}
407 
408 	session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
409 	if (!is_guest) {
410 		session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
411 	}
412 
413 	status = finalize_local_nt_token(usrtok, session_info_flags);
414 	if (!NT_STATUS_IS_OK(status)) {
415 		DEBUG(3, ("Failed to finalize nt token\n"));
416 		TALLOC_FREE(usrtok);
417 		return status;
418 	}
419 
420 	*ntok = usrtok;
421 	return NT_STATUS_OK;
422 }
423 
424 /*******************************************************************
425  Create a NT token for the user, expanding local aliases
426 *******************************************************************/
427 
create_local_nt_token(TALLOC_CTX * mem_ctx,const struct dom_sid * user_sid,bool is_guest,int num_groupsids,const struct dom_sid * groupsids,struct security_token ** token)428 NTSTATUS create_local_nt_token(TALLOC_CTX *mem_ctx,
429 					    const struct dom_sid *user_sid,
430 					    bool is_guest,
431 					    int num_groupsids,
432 					    const struct dom_sid *groupsids,
433 					    struct security_token **token)
434 {
435 	struct security_token *result = NULL;
436 	int i;
437 	NTSTATUS status;
438 	uint32_t session_info_flags = 0;
439 	struct dom_sid_buf buf;
440 
441 	DEBUG(10, ("Create local NT token for %s\n",
442 		   dom_sid_str_buf(user_sid, &buf)));
443 
444 	if (!(result = talloc_zero(mem_ctx, struct security_token))) {
445 		DEBUG(0, ("talloc failed\n"));
446 		status = NT_STATUS_NO_MEMORY;
447 		goto err;
448 	}
449 
450 	/* Add the user and primary group sid */
451 
452 	status = add_sid_to_array(result, user_sid,
453 				  &result->sids, &result->num_sids);
454 	if (!NT_STATUS_IS_OK(status)) {
455 		goto err;
456 	}
457 
458 	/* For guest, num_groupsids may be zero. */
459 	if (num_groupsids) {
460 		status = add_sid_to_array(result, &groupsids[0],
461 					  &result->sids,
462 					  &result->num_sids);
463 		if (!NT_STATUS_IS_OK(status)) {
464 			goto err;
465 		}
466 	}
467 
468 	/* Now the SIDs we got from authentication. These are the ones from
469 	 * the info3 struct or from the pdb_enum_group_memberships, depending
470 	 * on who authenticated the user.
471 	 * Note that we start the for loop at "1" here, we already added the
472 	 * first group sid as primary above. */
473 
474 	for (i=1; i<num_groupsids; i++) {
475 		status = add_sid_to_array_unique(result, &groupsids[i],
476 						 &result->sids,
477 						 &result->num_sids);
478 		if (!NT_STATUS_IS_OK(status)) {
479 			goto err;
480 		}
481 	}
482 
483 	status = add_local_groups(result, is_guest);
484 	if (!NT_STATUS_IS_OK(status)) {
485 		goto err;
486 	}
487 
488 	session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
489 	if (!is_guest) {
490 		session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
491 	}
492 
493 	status = finalize_local_nt_token(result, session_info_flags);
494 	if (!NT_STATUS_IS_OK(status)) {
495 		goto err;
496 	}
497 
498 	if (is_guest) {
499 		/*
500 		 * It's ugly, but for now it's
501 		 * needed to add Builtin_Guests
502 		 * here, the "local" token only
503 		 * consist of S-1-22-* SIDs
504 		 * and finalize_local_nt_token()
505 		 * doesn't have the chance to
506 		 * to detect it need to
507 		 * add Builtin_Guests via
508 		 * add_builtin_guests().
509 		 */
510 		status = add_sid_to_array_unique(result,
511 						 &global_sid_Builtin_Guests,
512 						 &result->sids,
513 						 &result->num_sids);
514 		if (!NT_STATUS_IS_OK(status)) {
515 			DEBUG(3, ("Failed to add SID to nt token\n"));
516 			goto err;
517 		}
518 	}
519 
520 	*token = result;
521 	return NT_STATUS_SUCCESS;
522 
523 err:
524 	TALLOC_FREE(result);
525 	return status;
526 }
527 
528 /***************************************************
529  Merge in any groups from /etc/group.
530 ***************************************************/
531 
add_local_groups(struct security_token * result,bool is_guest)532 static NTSTATUS add_local_groups(struct security_token *result,
533 				 bool is_guest)
534 {
535 	gid_t *gids = NULL;
536 	uint32_t getgroups_num_group_sids = 0;
537 	struct passwd *pass = NULL;
538 	TALLOC_CTX *tmp_ctx = talloc_stackframe();
539 	int i;
540 
541 	if (is_guest) {
542 		/*
543 		 * Guest is a special case. It's always
544 		 * a user that can be looked up, but
545 		 * result->sids[0] is set to DOMAIN\Guest.
546 		 * Lookup by account name instead.
547 		 */
548 		pass = Get_Pwnam_alloc(tmp_ctx, lp_guest_account());
549 	} else {
550 		uid_t uid;
551 
552 		/* For non-guest result->sids[0] is always the user sid. */
553 		if (!sid_to_uid(&result->sids[0], &uid)) {
554 			/*
555 			 * Non-mappable SID like SYSTEM.
556 			 * Can't be in any /etc/group groups.
557 			 */
558 			TALLOC_FREE(tmp_ctx);
559 			return NT_STATUS_OK;
560 		}
561 
562 		pass = getpwuid_alloc(tmp_ctx, uid);
563 		if (pass == NULL) {
564 			struct dom_sid_buf buf;
565 			DBG_ERR("SID %s -> getpwuid(%u) failed, is nsswitch configured?\n",
566 				dom_sid_str_buf(&result->sids[0], &buf),
567 				(unsigned int)uid);
568 			TALLOC_FREE(tmp_ctx);
569 			return NT_STATUS_NO_SUCH_USER;
570 		}
571 	}
572 
573 	if (!pass) {
574 		TALLOC_FREE(tmp_ctx);
575 		return NT_STATUS_UNSUCCESSFUL;
576 	}
577 
578 	/*
579 	 * Now we must get any groups this user has been
580 	 * added to in /etc/group and merge them in.
581 	 * This has to be done in every code path
582 	 * that creates an NT token, as remote users
583 	 * may have been added to the local /etc/group
584 	 * database. Tokens created merely from the
585 	 * info3 structs (via the DC or via the krb5 PAC)
586 	 * won't have these local groups. Note the
587 	 * groups added here will only be UNIX groups
588 	 * (S-1-22-2-XXXX groups) as getgroups_unix_user()
589 	 * turns off winbindd before calling getgroups().
590 	 *
591 	 * NB. This is duplicating work already
592 	 * done in the 'unix_user:' case of
593 	 * create_token_from_sid() but won't
594 	 * do anything other than be inefficient
595 	 * in that case.
596 	 */
597 
598 	if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
599 			&gids, &getgroups_num_group_sids)) {
600 		DEBUG(1, ("getgroups_unix_user for user %s failed\n",
601 			pass->pw_name));
602 		TALLOC_FREE(tmp_ctx);
603 		return NT_STATUS_UNSUCCESSFUL;
604 	}
605 
606 	for (i=0; i<getgroups_num_group_sids; i++) {
607 		NTSTATUS status;
608 		struct dom_sid grp_sid;
609 		gid_to_sid(&grp_sid, gids[i]);
610 
611 		status = add_sid_to_array_unique(result,
612 					 &grp_sid,
613 					 &result->sids,
614 					 &result->num_sids);
615 		if (!NT_STATUS_IS_OK(status)) {
616 			DEBUG(3, ("Failed to add UNIX SID to nt token\n"));
617 			TALLOC_FREE(tmp_ctx);
618 			return status;
619 		}
620 	}
621 	TALLOC_FREE(tmp_ctx);
622 	return NT_STATUS_OK;
623 }
624 
finalize_local_nt_token(struct security_token * result,uint32_t session_info_flags)625 NTSTATUS finalize_local_nt_token(struct security_token *result,
626 				 uint32_t session_info_flags)
627 {
628 	struct dom_sid _dom_sid = { 0, };
629 	struct dom_sid *domain_sid = NULL;
630 	NTSTATUS status;
631 	struct acct_info *info;
632 	bool ok;
633 
634 	result->privilege_mask = 0;
635 	result->rights_mask = 0;
636 
637 	if (result->num_sids == 0) {
638 		return NT_STATUS_INVALID_TOKEN;
639 	}
640 
641 	if (session_info_flags & AUTH_SESSION_INFO_DEFAULT_GROUPS) {
642 		status = add_sid_to_array(result, &global_sid_World,
643 					  &result->sids, &result->num_sids);
644 		if (!NT_STATUS_IS_OK(status)) {
645 			return status;
646 		}
647 		status = add_sid_to_array(result, &global_sid_Network,
648 					  &result->sids, &result->num_sids);
649 		if (!NT_STATUS_IS_OK(status)) {
650 			return status;
651 		}
652 	}
653 
654 	/*
655 	 * Don't expand nested groups of system, anonymous etc
656 	 *
657 	 * Note that they still get SID_WORLD and SID_NETWORK
658 	 * for now in order let existing tests pass.
659 	 *
660 	 * But SYSTEM doesn't get AUTHENTICATED_USERS
661 	 * and ANONYMOUS doesn't get BUILTIN GUESTS anymore.
662 	 */
663 	if (security_token_is_anonymous(result)) {
664 		return NT_STATUS_OK;
665 	}
666 	if (security_token_is_system(result)) {
667 		result->privilege_mask = ~0;
668 		return NT_STATUS_OK;
669 	}
670 
671 	if (session_info_flags & AUTH_SESSION_INFO_AUTHENTICATED) {
672 		status = add_sid_to_array(result,
673 					  &global_sid_Authenticated_Users,
674 					  &result->sids,
675 					  &result->num_sids);
676 		if (!NT_STATUS_IS_OK(status)) {
677 			return status;
678 		}
679 	}
680 
681 	/* Add in BUILTIN sids */
682 
683 	become_root();
684 	ok = secrets_fetch_domain_sid(lp_workgroup(), &_dom_sid);
685 	if (ok) {
686 		domain_sid = &_dom_sid;
687 	} else {
688 		DEBUG(3, ("Failed to fetch domain sid for %s\n",
689 			  lp_workgroup()));
690 	}
691 	unbecome_root();
692 
693 	info = talloc_zero(talloc_tos(), struct acct_info);
694 	if (info == NULL) {
695 		DEBUG(0, ("talloc failed!\n"));
696 		return NT_STATUS_NO_MEMORY;
697 	}
698 
699 	/* Deal with the BUILTIN\Administrators group.  If the SID can
700 	   be resolved then assume that the add_aliasmem( S-1-5-32 )
701 	   handled it. */
702 
703 	status = pdb_get_aliasinfo(&global_sid_Builtin_Administrators, info);
704 	if (!NT_STATUS_IS_OK(status)) {
705 
706 		become_root();
707 		status = create_builtin_administrators(domain_sid);
708 		unbecome_root();
709 
710 		if (NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE)) {
711 			/* Add BUILTIN\Administrators directly to token. */
712 			status = add_builtin_administrators(result, domain_sid);
713 			if ( !NT_STATUS_IS_OK(status) ) {
714 				DEBUG(3, ("Failed to check for local "
715 					  "Administrators membership (%s)\n",
716 					  nt_errstr(status)));
717 			}
718 		} else if (!NT_STATUS_IS_OK(status)) {
719 			DEBUG(2, ("WARNING: Failed to create "
720 				  "BUILTIN\\Administrators group!  Can "
721 				  "Winbind allocate gids?\n"));
722 		}
723 	}
724 
725 	/* Deal with the BUILTIN\Users group.  If the SID can
726 	   be resolved then assume that the add_aliasmem( S-1-5-32 )
727 	   handled it. */
728 
729 	status = pdb_get_aliasinfo(&global_sid_Builtin_Users, info);
730 	if (!NT_STATUS_IS_OK(status)) {
731 
732 		become_root();
733 		status = create_builtin_users(domain_sid);
734 		unbecome_root();
735 
736 		if (!NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE) &&
737 		    !NT_STATUS_IS_OK(status))
738 		{
739 			DEBUG(2, ("WARNING: Failed to create BUILTIN\\Users group! "
740 				  "Can Winbind allocate gids?\n"));
741 		}
742 	}
743 
744 	/*
745 	 * Deal with the BUILTIN\Guests group.  If the SID can
746 	 * be resolved then assume that the add_aliasmem( S-1-5-32 )
747 	 * handled it.
748 	 */
749 	status = pdb_get_aliasinfo(&global_sid_Builtin_Guests, info);
750 	if (!NT_STATUS_IS_OK(status)) {
751 
752 		become_root();
753 		status = create_builtin_guests(domain_sid);
754 		unbecome_root();
755 
756 		/*
757 		 * NT_STATUS_PROTOCOL_UNREACHABLE:
758 		 * => winbindd is not running.
759 		 *
760 		 * NT_STATUS_ACCESS_DENIED:
761 		 * => no idmap config at all
762 		 * and wbint_AllocateGid()/winbind_allocate_gid()
763 		 * failed.
764 		 *
765 		 * NT_STATUS_NO_SUCH_GROUP:
766 		 * => no idmap config at all and
767 		 * "tdbsam:map builtin = no" means
768 		 * wbint_Sids2UnixIDs() fails.
769 		 */
770 		if (NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE) ||
771 		    NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
772 		    NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_GROUP)) {
773 			/*
774 			 * Add BUILTIN\Guests directly to token.
775 			 * But only if the token already indicates
776 			 * real guest access by:
777 			 * - local GUEST account
778 			 * - local GUESTS group
779 			 * - domain GUESTS group
780 			 *
781 			 * Even if a user was authenticated, it
782 			 * can be member of a guest related group.
783 			 */
784 			status = add_builtin_guests(result, domain_sid);
785 			if (!NT_STATUS_IS_OK(status)) {
786 				DEBUG(3, ("Failed to check for local "
787 					  "Guests membership (%s)\n",
788 					  nt_errstr(status)));
789 				/*
790 				 * This is a hard error.
791 				 */
792 				return status;
793 			}
794 		} else if (!NT_STATUS_IS_OK(status)) {
795 			DEBUG(2, ("Failed to create "
796 				  "BUILTIN\\Guests group %s!  Can "
797 				  "Winbind allocate gids?\n",
798 				  nt_errstr(status)));
799 			/*
800 			 * This is a hard error.
801 			 */
802 			return status;
803 		}
804 	}
805 
806 	TALLOC_FREE(info);
807 
808 	/* Deal with local groups */
809 
810 	if (lp_winbind_nested_groups()) {
811 
812 		become_root();
813 
814 		/* Now add the aliases. First the one from our local SAM */
815 
816 		status = add_aliases(get_global_sam_sid(), result);
817 
818 		if (!NT_STATUS_IS_OK(status)) {
819 			unbecome_root();
820 			return status;
821 		}
822 
823 		/* Finally the builtin ones */
824 
825 		status = add_aliases(&global_sid_Builtin, result);
826 
827 		if (!NT_STATUS_IS_OK(status)) {
828 			unbecome_root();
829 			return status;
830 		}
831 
832 		unbecome_root();
833 	}
834 
835 	if (session_info_flags & AUTH_SESSION_INFO_NTLM) {
836 		struct dom_sid tmp_sid = { 0, };
837 
838 		ok = dom_sid_parse(SID_NT_NTLM_AUTHENTICATION, &tmp_sid);
839 		if (!ok) {
840 			return NT_STATUS_NO_MEMORY;
841 		}
842 
843 		status = add_sid_to_array(result,
844 					  &tmp_sid,
845 					  &result->sids,
846 					  &result->num_sids);
847 		if (!NT_STATUS_IS_OK(status)) {
848 			return status;
849 		}
850 	}
851 
852 	if (session_info_flags & AUTH_SESSION_INFO_SIMPLE_PRIVILEGES) {
853 		if (security_token_has_builtin_administrators(result)) {
854 			result->privilege_mask = ~0;
855 		}
856 	} else {
857 		/* Add privileges based on current user sids */
858 		get_privileges_for_sids(&result->privilege_mask, result->sids,
859 					result->num_sids);
860 	}
861 
862 	return NT_STATUS_OK;
863 }
864 
865 /****************************************************************************
866  prints a UNIX 'token' to debug output.
867 ****************************************************************************/
868 
debug_unix_user_token(int dbg_class,int dbg_lev,uid_t uid,gid_t gid,int n_groups,gid_t * groups)869 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
870 			   int n_groups, gid_t *groups)
871 {
872 	int     i;
873 	DEBUGC(dbg_class, dbg_lev,
874 	       ("UNIX token of user %ld\n", (long int)uid));
875 
876 	DEBUGADDC(dbg_class, dbg_lev,
877 		  ("Primary group is %ld and contains %i supplementary "
878 		   "groups\n", (long int)gid, n_groups));
879 	for (i = 0; i < n_groups; i++)
880 		DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i,
881 			(long int)groups[i]));
882 }
883 
884 /*
885  * Create an artificial NT token given just a domain SID.
886  *
887  * We have 3 cases:
888  *
889  * unmapped unix users: Go directly to nss to find the user's group.
890  *
891  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
892  *
893  * If the user is provided by winbind, the primary gid is set to "domain
894  * users" of the user's domain. For an explanation why this is necessary, see
895  * the thread starting at
896  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
897  */
898 
create_token_from_sid(TALLOC_CTX * mem_ctx,const struct dom_sid * user_sid,bool is_guest,uid_t * uid,gid_t * gid,char ** found_username,struct security_token ** token)899 static NTSTATUS create_token_from_sid(TALLOC_CTX *mem_ctx,
900 				      const struct dom_sid *user_sid,
901 				      bool is_guest,
902 				      uid_t *uid, gid_t *gid,
903 				      char **found_username,
904 				      struct security_token **token)
905 {
906 	NTSTATUS result = NT_STATUS_NO_SUCH_USER;
907 	TALLOC_CTX *tmp_ctx = talloc_stackframe();
908 	gid_t *gids;
909 	struct dom_sid *group_sids;
910 	struct dom_sid tmp_sid;
911 	uint32_t num_group_sids;
912 	uint32_t num_gids;
913 	uint32_t i;
914 	uint32_t high, low;
915 	bool range_ok;
916 	struct dom_sid_buf buf;
917 
918 	if (sid_check_is_in_our_sam(user_sid)) {
919 		bool ret;
920 		uint32_t pdb_num_group_sids;
921 		/* This is a passdb user, so ask passdb */
922 
923 		struct samu *sam_acct = NULL;
924 
925 		if ( !(sam_acct = samu_new( tmp_ctx )) ) {
926 			result = NT_STATUS_NO_MEMORY;
927 			goto done;
928 		}
929 
930 		become_root();
931 		ret = pdb_getsampwsid(sam_acct, user_sid);
932 		unbecome_root();
933 
934 		if (!ret) {
935 			DEBUG(1, ("pdb_getsampwsid(%s) failed\n",
936 				  dom_sid_str_buf(user_sid, &buf)));
937 			DEBUGADD(1, ("Fall back to unix user\n"));
938 			goto unix_user;
939 		}
940 
941 		result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
942 						    &group_sids, &gids,
943 						    &pdb_num_group_sids);
944 		if (!NT_STATUS_IS_OK(result)) {
945 			DEBUG(1, ("enum_group_memberships failed for %s: "
946 				  "%s\n",
947 				  dom_sid_str_buf(user_sid, &buf),
948 				  nt_errstr(result)));
949 			DEBUGADD(1, ("Fall back to unix uid lookup\n"));
950 			goto unix_user;
951 		}
952 		num_group_sids = pdb_num_group_sids;
953 
954 		/* see the smb_panic() in pdb_default_enum_group_memberships */
955 		SMB_ASSERT(num_group_sids > 0);
956 
957 		/* Ensure we're returning the found_username on the right context. */
958 		*found_username = talloc_strdup(mem_ctx,
959 						pdb_get_username(sam_acct));
960 
961 		if (*found_username == NULL) {
962 			result = NT_STATUS_NO_MEMORY;
963 			goto done;
964 		}
965 
966 		/*
967 		 * If the SID from lookup_name() was the guest sid, passdb knows
968 		 * about the mapping of guest sid to lp_guest_account()
969 		 * username and will return the unix_pw info for a guest
970 		 * user. Use it if it's there, else lookup the *uid details
971 		 * using Get_Pwnam_alloc(). See bug #6291 for details. JRA.
972 		 */
973 
974 		/* We must always assign the *uid. */
975 		if (sam_acct->unix_pw == NULL) {
976 			struct passwd *pwd = Get_Pwnam_alloc(sam_acct, *found_username );
977 			if (!pwd) {
978 				DEBUG(10, ("Get_Pwnam_alloc failed for %s\n",
979 					*found_username));
980 				result = NT_STATUS_NO_SUCH_USER;
981 				goto done;
982 			}
983 			result = samu_set_unix(sam_acct, pwd );
984 			if (!NT_STATUS_IS_OK(result)) {
985 				DEBUG(10, ("samu_set_unix failed for %s\n",
986 					*found_username));
987 				result = NT_STATUS_NO_SUCH_USER;
988 				goto done;
989 			}
990 		}
991 		*uid = sam_acct->unix_pw->pw_uid;
992 
993 	} else 	if (sid_check_is_in_unix_users(user_sid)) {
994 		uint32_t getgroups_num_group_sids;
995 		/* This is a unix user not in passdb. We need to ask nss
996 		 * directly, without consulting passdb */
997 
998 		struct passwd *pass;
999 
1000 		/*
1001 		 * This goto target is used as a fallback for the passdb
1002 		 * case. The concrete bug report is when passdb gave us an
1003 		 * unmapped gid.
1004 		 */
1005 
1006 	unix_user:
1007 
1008 		if (!sid_to_uid(user_sid, uid)) {
1009 			DEBUG(1, ("unix_user case, sid_to_uid for %s failed\n",
1010 				  dom_sid_str_buf(user_sid, &buf)));
1011 			result = NT_STATUS_NO_SUCH_USER;
1012 			goto done;
1013 		}
1014 
1015 		uid_to_unix_users_sid(*uid, &tmp_sid);
1016 		user_sid = &tmp_sid;
1017 
1018 		pass = getpwuid_alloc(tmp_ctx, *uid);
1019 		if (pass == NULL) {
1020 			DEBUG(1, ("getpwuid(%u) failed\n",
1021 				  (unsigned int)*uid));
1022 			goto done;
1023 		}
1024 
1025 		if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
1026 					 &gids, &getgroups_num_group_sids)) {
1027 			DEBUG(1, ("getgroups_unix_user for user %s failed\n",
1028 				  pass->pw_name));
1029 			goto done;
1030 		}
1031 		num_group_sids = getgroups_num_group_sids;
1032 
1033 		group_sids = talloc_array(tmp_ctx, struct dom_sid, num_group_sids);
1034 		if (group_sids == NULL) {
1035 			DEBUG(1, ("talloc_array failed\n"));
1036 			result = NT_STATUS_NO_MEMORY;
1037 			goto done;
1038 		}
1039 
1040 		for (i=0; i<num_group_sids; i++) {
1041 			gid_to_sid(&group_sids[i], gids[i]);
1042 		}
1043 
1044 		/* In getgroups_unix_user we always set the primary gid */
1045 		SMB_ASSERT(num_group_sids > 0);
1046 
1047 		/* Ensure we're returning the found_username on the right context. */
1048 		*found_username = talloc_strdup(mem_ctx, pass->pw_name);
1049 		if (*found_username == NULL) {
1050 			result = NT_STATUS_NO_MEMORY;
1051 			goto done;
1052 		}
1053 	} else {
1054 
1055 		/* This user is from winbind, force the primary gid to the
1056 		 * user's "domain users" group. Under certain circumstances
1057 		 * (user comes from NT4), this might be a loss of
1058 		 * information. But we can not rely on winbind getting the
1059 		 * correct info. AD might prohibit winbind looking up that
1060 		 * information. */
1061 
1062 		/* We must always assign the *uid. */
1063 		if (!sid_to_uid(user_sid, uid)) {
1064 			DEBUG(1, ("winbindd case, sid_to_uid for %s failed\n",
1065 				  dom_sid_str_buf(user_sid, &buf)));
1066 			result = NT_STATUS_NO_SUCH_USER;
1067 			goto done;
1068 		}
1069 
1070 		num_group_sids = 1;
1071 		group_sids = talloc_array(tmp_ctx, struct dom_sid, num_group_sids);
1072 		if (group_sids == NULL) {
1073 			DEBUG(1, ("talloc_array failed\n"));
1074 			result = NT_STATUS_NO_MEMORY;
1075 			goto done;
1076 		}
1077 
1078 		gids = talloc_array(tmp_ctx, gid_t, num_group_sids);
1079 		if (gids == NULL) {
1080 			result = NT_STATUS_NO_MEMORY;
1081 			goto done;
1082 		}
1083 
1084 		sid_copy(&group_sids[0], user_sid);
1085 		sid_split_rid(&group_sids[0], NULL);
1086 		sid_append_rid(&group_sids[0], DOMAIN_RID_USERS);
1087 
1088 		if (!sid_to_gid(&group_sids[0], &gids[0])) {
1089 			DEBUG(1, ("sid_to_gid(%s) failed\n",
1090 				  dom_sid_str_buf(&group_sids[0], &buf)));
1091 			goto done;
1092 		}
1093 
1094 		*found_username = NULL;
1095 	}
1096 
1097 	*gid = gids[0];
1098 
1099 	/* Add the "Unix Group" SID for each gid to catch mapped groups
1100 	   and their Unix equivalent.  This is to solve the backwards
1101 	   compatibility problem of 'valid users = +ntadmin' where
1102 	   ntadmin has been paired with "Domain Admins" in the group
1103 	   mapping table.  Otherwise smb.conf would need to be changed
1104 	   to 'valid user = "Domain Admins"'.  --jerry */
1105 
1106 	num_gids = num_group_sids;
1107 	range_ok = lp_idmap_default_range(&low, &high);
1108 	for ( i=0; i<num_gids; i++ ) {
1109 		struct dom_sid unix_group_sid;
1110 
1111 		/* don't pickup anything managed by Winbind */
1112 		if (range_ok && (gids[i] >= low) && (gids[i] <= high)) {
1113 			continue;
1114 		}
1115 
1116 		gid_to_unix_groups_sid(gids[i], &unix_group_sid);
1117 
1118 		result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
1119 						 &group_sids, &num_group_sids);
1120 		if (!NT_STATUS_IS_OK(result)) {
1121 			goto done;
1122 		}
1123 	}
1124 
1125 	/* Ensure we're creating the nt_token on the right context. */
1126 	result = create_local_nt_token(mem_ctx, user_sid,
1127 				       is_guest, num_group_sids, group_sids, token);
1128 
1129 	if (!NT_STATUS_IS_OK(result)) {
1130 		goto done;
1131 	}
1132 
1133 	result = NT_STATUS_OK;
1134  done:
1135 	TALLOC_FREE(tmp_ctx);
1136 	return result;
1137 }
1138 
1139 /*
1140  * Create an artificial NT token given just a username. (Initially intended
1141  * for force user)
1142  *
1143  * We go through lookup_name() to avoid problems we had with 'winbind use
1144  * default domain'.
1145  *
1146  * We have 3 cases:
1147  *
1148  * unmapped unix users: Go directly to nss to find the user's group.
1149  *
1150  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
1151  *
1152  * If the user is provided by winbind, the primary gid is set to "domain
1153  * users" of the user's domain. For an explanation why this is necessary, see
1154  * the thread starting at
1155  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
1156  */
1157 
create_token_from_username(TALLOC_CTX * mem_ctx,const char * username,bool is_guest,uid_t * uid,gid_t * gid,char ** found_username,struct security_token ** token)1158 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
1159 				    bool is_guest,
1160 				    uid_t *uid, gid_t *gid,
1161 				    char **found_username,
1162 				    struct security_token **token)
1163 {
1164 	NTSTATUS result = NT_STATUS_NO_SUCH_USER;
1165 	TALLOC_CTX *tmp_ctx = talloc_stackframe();
1166 	struct dom_sid user_sid;
1167 	enum lsa_SidType type;
1168 
1169 	if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
1170 			 NULL, NULL, &user_sid, &type)) {
1171 		DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
1172 		goto done;
1173 	}
1174 
1175 	if (type != SID_NAME_USER) {
1176 		DEBUG(1, ("%s is a %s, not a user\n", username,
1177 			  sid_type_lookup(type)));
1178 		goto done;
1179 	}
1180 
1181 	result = create_token_from_sid(mem_ctx, &user_sid, is_guest, uid, gid, found_username, token);
1182 
1183 	if (!NT_STATUS_IS_OK(result)) {
1184 		goto done;
1185 	}
1186 
1187 	/*
1188 	 * If result == NT_STATUS_OK then
1189 	 * we know we have a valid token. Ensure
1190 	 * we also have a valid username to match.
1191 	 */
1192 
1193 	if (*found_username == NULL) {
1194 		*found_username = talloc_strdup(mem_ctx, username);
1195 		if (*found_username == NULL) {
1196 			result = NT_STATUS_NO_MEMORY;
1197 		}
1198 	}
1199 
1200 done:
1201 	TALLOC_FREE(tmp_ctx);
1202 	return result;
1203 }
1204 
1205 /***************************************************************************
1206  Build upon create_token_from_sid:
1207 
1208  Expensive helper function to figure out whether a user given its sid is
1209  member of a particular group.
1210 ***************************************************************************/
1211 
user_sid_in_group_sid(const struct dom_sid * sid,const struct dom_sid * group_sid)1212 bool user_sid_in_group_sid(const struct dom_sid *sid, const struct dom_sid *group_sid)
1213 {
1214 	NTSTATUS status;
1215 	uid_t uid;
1216 	gid_t gid;
1217 	char *found_username;
1218 	struct security_token *token;
1219 	bool result = false;
1220 	enum lsa_SidType type;
1221 	TALLOC_CTX *mem_ctx = talloc_stackframe();
1222 	struct dom_sid_buf buf;
1223 
1224 	if (!lookup_sid(mem_ctx, sid,
1225 			 NULL, NULL, &type)) {
1226 		DEBUG(1, ("lookup_sid for %s failed\n",
1227 			  dom_sid_str_buf(sid, &buf)));
1228 		goto done;
1229 	}
1230 
1231 	if (type != SID_NAME_USER) {
1232 		DEBUG(5, ("%s is a %s, not a user\n",
1233 			  dom_sid_str_buf(sid, &buf),
1234 			  sid_type_lookup(type)));
1235 		goto done;
1236 	}
1237 
1238 	status = create_token_from_sid(mem_ctx, sid, False,
1239 				       &uid, &gid, &found_username,
1240 				       &token);
1241 
1242 	if (!NT_STATUS_IS_OK(status)) {
1243 		DEBUG(10, ("could not create token for %s\n",
1244 			   dom_sid_str_buf(sid, &buf)));
1245 		goto done;
1246 	}
1247 
1248 	result = security_token_has_sid(token, group_sid);
1249 
1250 done:
1251 	TALLOC_FREE(mem_ctx);
1252 	return result;
1253 }
1254 
1255 /***************************************************************************
1256  Build upon create_token_from_username:
1257 
1258  Expensive helper function to figure out whether a user given its name is
1259  member of a particular group.
1260 ***************************************************************************/
1261 
user_in_group_sid(const char * username,const struct dom_sid * group_sid)1262 bool user_in_group_sid(const char *username, const struct dom_sid *group_sid)
1263 {
1264 	NTSTATUS status;
1265 	uid_t uid;
1266 	gid_t gid;
1267 	char *found_username;
1268 	struct security_token *token;
1269 	bool result;
1270 	TALLOC_CTX *mem_ctx = talloc_stackframe();
1271 
1272 	status = create_token_from_username(mem_ctx, username, False,
1273 					    &uid, &gid, &found_username,
1274 					    &token);
1275 
1276 	if (!NT_STATUS_IS_OK(status)) {
1277 		DEBUG(10, ("could not create token for %s\n", username));
1278 		TALLOC_FREE(mem_ctx);
1279 		return False;
1280 	}
1281 
1282 	result = security_token_has_sid(token, group_sid);
1283 
1284 	TALLOC_FREE(mem_ctx);
1285 	return result;
1286 }
1287 
user_in_group(const char * username,const char * groupname)1288 bool user_in_group(const char *username, const char *groupname)
1289 {
1290 	TALLOC_CTX *mem_ctx = talloc_stackframe();
1291 	struct dom_sid group_sid;
1292 	bool ret;
1293 
1294 	ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1295 			  NULL, NULL, &group_sid, NULL);
1296 	TALLOC_FREE(mem_ctx);
1297 
1298 	if (!ret) {
1299 		DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1300 		return False;
1301 	}
1302 
1303 	return user_in_group_sid(username, &group_sid);
1304 }
1305 
1306 /* END */
1307