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
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.
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.
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/>.
25 /* functions moved from auth/auth_util.c to minimize linker deps */
30 #include "../librpc/gen_ndr/netlogon.h"
31 #include "../libcli/security/security.h"
33 /****************************************************************************
34 Check for a SID in an struct security_token
35 ****************************************************************************/
37 bool nt_token_check_sid ( const struct dom_sid
*sid
, const struct security_token
*token
)
42 return security_token_has_sid(token
, sid
);
45 bool nt_token_check_domain_rid( struct security_token
*token
, uint32 rid
)
47 struct dom_sid domain_sid
;
49 /* if we are a domain member, the get the domain SID, else for
50 a DC or standalone server, use our own SID */
52 if ( lp_server_role() == ROLE_DOMAIN_MEMBER
) {
53 if ( !secrets_fetch_domain_sid( lp_workgroup(),
55 DEBUG(1,("nt_token_check_domain_rid: Cannot lookup "
56 "SID for domain [%s]\n", lp_workgroup()));
61 sid_copy( &domain_sid
, get_global_sam_sid() );
63 sid_append_rid( &domain_sid
, rid
);
65 return nt_token_check_sid( &domain_sid
, token
);\
68 /******************************************************************************
69 Create a token for the root user to be used internally by smbd.
70 This is similar to running under the context of the LOCAL_SYSTEM account
71 in Windows. This is a read-only token. Do not modify it or free() it.
72 Create a copy if you need to change it.
73 ******************************************************************************/
75 struct security_token
*get_root_nt_token( void )
77 struct security_token
*token
, *for_cache
;
78 struct dom_sid u_sid
, g_sid
;
82 cache_data
= memcache_lookup_talloc(
83 NULL
, SINGLETON_CACHE_TALLOC
,
84 data_blob_string_const_null("root_nt_token"));
86 if (cache_data
!= NULL
) {
87 return talloc_get_type_abort(
88 cache_data
, struct security_token
);
91 if ( !(pw
= sys_getpwuid(0)) ) {
92 if ( !(pw
= sys_getpwnam("root")) ) {
93 DEBUG(0,("get_root_nt_token: both sys_getpwuid(0) "
94 "and sys_getpwnam(\"root\") failed!\n"));
99 /* get the user and primary group SIDs; although the
100 BUILTIN\Administrators SId is really the one that matters here */
102 uid_to_sid(&u_sid
, pw
->pw_uid
);
103 gid_to_sid(&g_sid
, pw
->pw_gid
);
105 token
= create_local_nt_token(talloc_tos(), &u_sid
, False
,
106 1, &global_sid_Builtin_Administrators
);
108 security_token_set_privilege(token
, SEC_PRIV_DISK_OPERATOR
);
113 NULL
, SINGLETON_CACHE_TALLOC
,
114 data_blob_string_const_null("root_nt_token"), &for_cache
);
121 * Add alias SIDs from memberships within the partially created token SID list
124 NTSTATUS
add_aliases(const struct dom_sid
*domain_sid
,
125 struct security_token
*token
)
128 size_t i
, num_aliases
;
132 if (!(tmp_ctx
= talloc_init("add_aliases"))) {
133 return NT_STATUS_NO_MEMORY
;
139 status
= pdb_enum_alias_memberships(tmp_ctx
, domain_sid
,
142 &aliases
, &num_aliases
);
144 if (!NT_STATUS_IS_OK(status
)) {
145 DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
150 for (i
=0; i
<num_aliases
; i
++) {
151 struct dom_sid alias_sid
;
152 sid_compose(&alias_sid
, domain_sid
, aliases
[i
]);
153 status
= add_sid_to_array_unique(token
, &alias_sid
,
156 if (!NT_STATUS_IS_OK(status
)) {
157 DEBUG(0, ("add_sid_to_array failed\n"));
163 TALLOC_FREE(tmp_ctx
);
167 /*******************************************************************
168 *******************************************************************/
170 static NTSTATUS
add_builtin_administrators(struct security_token
*token
,
171 const struct dom_sid
*dom_sid
)
173 struct dom_sid domadm
;
176 /* nothing to do if we aren't in a domain */
178 if ( !(IS_DC
|| lp_server_role()==ROLE_DOMAIN_MEMBER
) ) {
182 /* Find the Domain Admins SID */
185 sid_copy( &domadm
, get_global_sam_sid() );
187 sid_copy(&domadm
, dom_sid
);
189 sid_append_rid( &domadm
, DOMAIN_RID_ADMINS
);
191 /* Add Administrators if the user beloongs to Domain Admins */
193 if ( nt_token_check_sid( &domadm
, token
) ) {
194 status
= add_sid_to_array(token
,
195 &global_sid_Builtin_Administrators
,
196 &token
->sids
, &token
->num_sids
);
197 if (!NT_STATUS_IS_OK(status
)) {
206 * Create the requested BUILTIN if it doesn't already exist. This requires
207 * winbindd to be running.
209 * @param[in] rid BUILTIN rid to create
210 * @return Normal NTSTATUS return.
212 static NTSTATUS
create_builtin(uint32 rid
)
214 NTSTATUS status
= NT_STATUS_OK
;
218 if (!sid_compose(&sid
, &global_sid_Builtin
, rid
)) {
219 return NT_STATUS_NO_SUCH_ALIAS
;
222 if (!sid_to_gid(&sid
, &gid
)) {
223 if (!lp_winbind_nested_groups() || !winbind_ping()) {
224 return NT_STATUS_PROTOCOL_UNREACHABLE
;
226 status
= pdb_create_builtin_alias(rid
);
232 * Add sid as a member of builtin_sid.
234 * @param[in] builtin_sid An existing builtin group.
235 * @param[in] dom_sid sid to add as a member of builtin_sid.
236 * @return Normal NTSTATUS return
238 static NTSTATUS
add_sid_to_builtin(const struct dom_sid
*builtin_sid
,
239 const struct dom_sid
*dom_sid
)
241 NTSTATUS status
= NT_STATUS_OK
;
243 if (!dom_sid
|| !builtin_sid
) {
244 return NT_STATUS_INVALID_PARAMETER
;
247 status
= pdb_add_aliasmem(builtin_sid
, dom_sid
);
249 if (NT_STATUS_EQUAL(status
, NT_STATUS_MEMBER_IN_ALIAS
)) {
250 DEBUG(5, ("add_sid_to_builtin %s is already a member of %s\n",
251 sid_string_dbg(dom_sid
),
252 sid_string_dbg(builtin_sid
)));
256 if (!NT_STATUS_IS_OK(status
)) {
257 DEBUG(4, ("add_sid_to_builtin %s could not be added to %s: "
258 "%s\n", sid_string_dbg(dom_sid
),
259 sid_string_dbg(builtin_sid
), nt_errstr(status
)));
264 /*******************************************************************
265 *******************************************************************/
267 NTSTATUS
create_builtin_users(const struct dom_sid
*dom_sid
)
270 struct dom_sid dom_users
;
272 status
= create_builtin(BUILTIN_RID_USERS
);
273 if ( !NT_STATUS_IS_OK(status
) ) {
274 DEBUG(5,("create_builtin_users: Failed to create Users\n"));
278 /* add domain users */
279 if ((IS_DC
|| (lp_server_role() == ROLE_DOMAIN_MEMBER
))
280 && sid_compose(&dom_users
, dom_sid
, DOMAIN_RID_USERS
))
282 status
= add_sid_to_builtin(&global_sid_Builtin_Users
,
289 /*******************************************************************
290 *******************************************************************/
292 NTSTATUS
create_builtin_administrators(const struct dom_sid
*dom_sid
)
295 struct dom_sid dom_admins
, root_sid
;
297 enum lsa_SidType type
;
301 status
= create_builtin(BUILTIN_RID_ADMINISTRATORS
);
302 if ( !NT_STATUS_IS_OK(status
) ) {
303 DEBUG(5,("create_builtin_administrators: Failed to create Administrators\n"));
307 /* add domain admins */
308 if ((IS_DC
|| (lp_server_role() == ROLE_DOMAIN_MEMBER
))
309 && sid_compose(&dom_admins
, dom_sid
, DOMAIN_RID_ADMINS
))
311 status
= add_sid_to_builtin(&global_sid_Builtin_Administrators
,
313 if (!NT_STATUS_IS_OK(status
)) {
319 if ( (ctx
= talloc_init("create_builtin_administrators")) == NULL
) {
320 return NT_STATUS_NO_MEMORY
;
322 fstr_sprintf( root_name
, "%s\\root", get_global_sam_name() );
323 ret
= lookup_name(ctx
, root_name
, LOOKUP_NAME_DOMAIN
, NULL
, NULL
,
328 status
= add_sid_to_builtin(&global_sid_Builtin_Administrators
,
335 static NTSTATUS
finalize_local_nt_token(struct security_token
*result
,
338 NTSTATUS
create_local_nt_token_from_info3(TALLOC_CTX
*mem_ctx
,
340 struct netr_SamInfo3
*info3
,
341 struct extra_auth_info
*extra
,
342 struct security_token
**ntok
)
344 struct security_token
*usrtok
= NULL
;
348 DEBUG(10, ("Create local NT token for %s\n",
349 info3
->base
.account_name
.string
));
351 usrtok
= talloc_zero(mem_ctx
, struct security_token
);
353 DEBUG(0, ("talloc failed\n"));
354 return NT_STATUS_NO_MEMORY
;
357 /* Add the user and primary group sid FIRST */
358 /* check if the user rid is the special "Domain Guests" rid.
359 * If so pick the first sid for the extra sids instead as it
360 * is a local fake account */
361 usrtok
->sids
= talloc_array(usrtok
, struct dom_sid
, 2);
364 return NT_STATUS_NO_MEMORY
;
366 usrtok
->num_sids
= 2;
369 if (info3
->base
.rid
== (uint32_t)(-1)) {
370 /* this is a signal the user was fake and generated,
371 * the actual SID we want to use is stored in the extra
373 if (is_null_sid(&extra
->user_sid
)) {
374 /* we couldn't find the user sid, bail out */
375 DEBUG(3, ("Invalid user SID\n"));
377 return NT_STATUS_UNSUCCESSFUL
;
379 sid_copy(&usrtok
->sids
[0], &extra
->user_sid
);
381 sid_copy(&usrtok
->sids
[0], info3
->base
.domain_sid
);
382 sid_append_rid(&usrtok
->sids
[0], info3
->base
.rid
);
386 if (info3
->base
.primary_gid
== (uint32_t)(-1)) {
387 /* this is a signal the user was fake and generated,
388 * the actual SID we want to use is stored in the extra
390 if (is_null_sid(&extra
->pgid_sid
)) {
391 /* we couldn't find the user sid, bail out */
392 DEBUG(3, ("Invalid group SID\n"));
394 return NT_STATUS_UNSUCCESSFUL
;
396 sid_copy(&usrtok
->sids
[1], &extra
->pgid_sid
);
398 sid_copy(&usrtok
->sids
[1], info3
->base
.domain_sid
);
399 sid_append_rid(&usrtok
->sids
[1],
400 info3
->base
.primary_gid
);
403 /* Now the SIDs we got from authentication. These are the ones from
404 * the info3 struct or from the pdb_enum_group_memberships, depending
405 * on who authenticated the user.
406 * Note that we start the for loop at "1" here, we already added the
407 * first group sid as primary above. */
409 for (i
= 0; i
< info3
->base
.groups
.count
; i
++) {
410 struct dom_sid tmp_sid
;
412 sid_copy(&tmp_sid
, info3
->base
.domain_sid
);
413 sid_append_rid(&tmp_sid
, info3
->base
.groups
.rids
[i
].rid
);
415 status
= add_sid_to_array_unique(usrtok
, &tmp_sid
,
418 if (!NT_STATUS_IS_OK(status
)) {
419 DEBUG(3, ("Failed to add SID to nt token\n"));
425 /* now also add extra sids if they are not the special user/group
427 for (i
= 0; i
< info3
->sidcount
; i
++) {
428 status
= add_sid_to_array_unique(usrtok
,
432 if (!NT_STATUS_IS_OK(status
)) {
433 DEBUG(3, ("Failed to add SID to nt token\n"));
439 status
= finalize_local_nt_token(usrtok
, is_guest
);
440 if (!NT_STATUS_IS_OK(status
)) {
441 DEBUG(3, ("Failed to finalize nt token\n"));
450 /*******************************************************************
451 Create a NT token for the user, expanding local aliases
452 *******************************************************************/
454 struct security_token
*create_local_nt_token(TALLOC_CTX
*mem_ctx
,
455 const struct dom_sid
*user_sid
,
458 const struct dom_sid
*groupsids
)
460 struct security_token
*result
= NULL
;
464 DEBUG(10, ("Create local NT token for %s\n",
465 sid_string_dbg(user_sid
)));
467 if (!(result
= TALLOC_ZERO_P(mem_ctx
, struct security_token
))) {
468 DEBUG(0, ("talloc failed\n"));
472 /* Add the user and primary group sid */
474 status
= add_sid_to_array(result
, user_sid
,
475 &result
->sids
, &result
->num_sids
);
476 if (!NT_STATUS_IS_OK(status
)) {
481 /* For guest, num_groupsids may be zero. */
483 status
= add_sid_to_array(result
, &groupsids
[0],
486 if (!NT_STATUS_IS_OK(status
)) {
492 /* Now the SIDs we got from authentication. These are the ones from
493 * the info3 struct or from the pdb_enum_group_memberships, depending
494 * on who authenticated the user.
495 * Note that we start the for loop at "1" here, we already added the
496 * first group sid as primary above. */
498 for (i
=1; i
<num_groupsids
; i
++) {
499 status
= add_sid_to_array_unique(result
, &groupsids
[i
],
502 if (!NT_STATUS_IS_OK(status
)) {
508 status
= finalize_local_nt_token(result
, is_guest
);
509 if (!NT_STATUS_IS_OK(status
)) {
517 static NTSTATUS
finalize_local_nt_token(struct security_token
*result
,
520 struct dom_sid dom_sid
;
524 /* Add in BUILTIN sids */
526 status
= add_sid_to_array(result
, &global_sid_World
,
527 &result
->sids
, &result
->num_sids
);
528 if (!NT_STATUS_IS_OK(status
)) {
531 status
= add_sid_to_array(result
, &global_sid_Network
,
532 &result
->sids
, &result
->num_sids
);
533 if (!NT_STATUS_IS_OK(status
)) {
538 status
= add_sid_to_array(result
, &global_sid_Builtin_Guests
,
541 if (!NT_STATUS_IS_OK(status
)) {
545 status
= add_sid_to_array(result
,
546 &global_sid_Authenticated_Users
,
549 if (!NT_STATUS_IS_OK(status
)) {
554 /* Deal with the BUILTIN\Administrators group. If the SID can
555 be resolved then assume that the add_aliasmem( S-1-5-32 )
558 if (!sid_to_gid(&global_sid_Builtin_Administrators
, &gid
)) {
561 if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid
)) {
562 status
= NT_STATUS_OK
;
563 DEBUG(3, ("Failed to fetch domain sid for %s\n",
566 status
= create_builtin_administrators(&dom_sid
);
570 if (NT_STATUS_EQUAL(status
, NT_STATUS_PROTOCOL_UNREACHABLE
)) {
571 /* Add BUILTIN\Administrators directly to token. */
572 status
= add_builtin_administrators(result
, &dom_sid
);
573 if ( !NT_STATUS_IS_OK(status
) ) {
574 DEBUG(3, ("Failed to check for local "
575 "Administrators membership (%s)\n",
578 } else if (!NT_STATUS_IS_OK(status
)) {
579 DEBUG(2, ("WARNING: Failed to create "
580 "BUILTIN\\Administrators group! Can "
581 "Winbind allocate gids?\n"));
585 /* Deal with the BUILTIN\Users group. If the SID can
586 be resolved then assume that the add_aliasmem( S-1-5-32 )
589 if (!sid_to_gid(&global_sid_Builtin_Users
, &gid
)) {
592 if (!secrets_fetch_domain_sid(lp_workgroup(), &dom_sid
)) {
593 status
= NT_STATUS_OK
;
594 DEBUG(3, ("Failed to fetch domain sid for %s\n",
597 status
= create_builtin_users(&dom_sid
);
601 if (!NT_STATUS_EQUAL(status
, NT_STATUS_PROTOCOL_UNREACHABLE
) &&
602 !NT_STATUS_IS_OK(status
))
604 DEBUG(2, ("WARNING: Failed to create BUILTIN\\Users group! "
605 "Can Winbind allocate gids?\n"));
609 /* Deal with local groups */
611 if (lp_winbind_nested_groups()) {
615 /* Now add the aliases. First the one from our local SAM */
617 status
= add_aliases(get_global_sam_sid(), result
);
619 if (!NT_STATUS_IS_OK(status
)) {
624 /* Finally the builtin ones */
626 status
= add_aliases(&global_sid_Builtin
, result
);
628 if (!NT_STATUS_IS_OK(status
)) {
636 /* Add privileges based on current user sids */
638 get_privileges_for_sids(&result
->privilege_mask
, result
->sids
,
644 /****************************************************************************
645 prints a UNIX 'token' to debug output.
646 ****************************************************************************/
648 void debug_unix_user_token(int dbg_class
, int dbg_lev
, uid_t uid
, gid_t gid
,
649 int n_groups
, gid_t
*groups
)
652 DEBUGC(dbg_class
, dbg_lev
,
653 ("UNIX token of user %ld\n", (long int)uid
));
655 DEBUGADDC(dbg_class
, dbg_lev
,
656 ("Primary group is %ld and contains %i supplementary "
657 "groups\n", (long int)gid
, n_groups
));
658 for (i
= 0; i
< n_groups
; i
++)
659 DEBUGADDC(dbg_class
, dbg_lev
, ("Group[%3i]: %ld\n", i
,
660 (long int)groups
[i
]));
664 * Create an artificial NT token given just a username. (Initially intended
667 * We go through lookup_name() to avoid problems we had with 'winbind use
672 * unmapped unix users: Go directly to nss to find the user's group.
674 * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
676 * If the user is provided by winbind, the primary gid is set to "domain
677 * users" of the user's domain. For an explanation why this is necessary, see
678 * the thread starting at
679 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
682 NTSTATUS
create_token_from_username(TALLOC_CTX
*mem_ctx
, const char *username
,
684 uid_t
*uid
, gid_t
*gid
,
685 char **found_username
,
686 struct security_token
**token
)
688 NTSTATUS result
= NT_STATUS_NO_SUCH_USER
;
689 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
690 struct dom_sid user_sid
;
691 enum lsa_SidType type
;
693 struct dom_sid
*group_sids
;
694 struct dom_sid unix_group_sid
;
695 uint32_t num_group_sids
;
699 if (!lookup_name_smbconf(tmp_ctx
, username
, LOOKUP_NAME_ALL
,
700 NULL
, NULL
, &user_sid
, &type
)) {
701 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username
));
705 if (type
!= SID_NAME_USER
) {
706 DEBUG(1, ("%s is a %s, not a user\n", username
,
707 sid_type_lookup(type
)));
711 if (sid_check_is_in_our_domain(&user_sid
)) {
713 size_t pdb_num_group_sids
;
714 /* This is a passdb user, so ask passdb */
716 struct samu
*sam_acct
= NULL
;
718 if ( !(sam_acct
= samu_new( tmp_ctx
)) ) {
719 result
= NT_STATUS_NO_MEMORY
;
724 ret
= pdb_getsampwsid(sam_acct
, &user_sid
);
728 DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
729 sid_string_dbg(&user_sid
), username
));
730 DEBUGADD(1, ("Fall back to unix user %s\n", username
));
734 result
= pdb_enum_group_memberships(tmp_ctx
, sam_acct
,
736 &pdb_num_group_sids
);
737 if (!NT_STATUS_IS_OK(result
)) {
738 DEBUG(1, ("enum_group_memberships failed for %s (%s): "
739 "%s\n", username
, sid_string_dbg(&user_sid
),
741 DEBUGADD(1, ("Fall back to unix user %s\n", username
));
744 num_group_sids
= pdb_num_group_sids
;
746 /* see the smb_panic() in pdb_default_enum_group_memberships */
747 SMB_ASSERT(num_group_sids
> 0);
751 /* Ensure we're returning the found_username on the right context. */
752 *found_username
= talloc_strdup(mem_ctx
,
753 pdb_get_username(sam_acct
));
756 * If the SID from lookup_name() was the guest sid, passdb knows
757 * about the mapping of guest sid to lp_guestaccount()
758 * username and will return the unix_pw info for a guest
759 * user. Use it if it's there, else lookup the *uid details
760 * using Get_Pwnam_alloc(). See bug #6291 for details. JRA.
763 /* We must always assign the *uid. */
764 if (sam_acct
->unix_pw
== NULL
) {
765 struct passwd
*pwd
= Get_Pwnam_alloc(sam_acct
, *found_username
);
767 DEBUG(10, ("Get_Pwnam_alloc failed for %s\n",
769 result
= NT_STATUS_NO_SUCH_USER
;
772 result
= samu_set_unix(sam_acct
, pwd
);
773 if (!NT_STATUS_IS_OK(result
)) {
774 DEBUG(10, ("samu_set_unix failed for %s\n",
776 result
= NT_STATUS_NO_SUCH_USER
;
780 *uid
= sam_acct
->unix_pw
->pw_uid
;
782 } else if (sid_check_is_in_unix_users(&user_sid
)) {
783 size_t getgroups_num_group_sids
;
784 /* This is a unix user not in passdb. We need to ask nss
785 * directly, without consulting passdb */
790 * This goto target is used as a fallback for the passdb
791 * case. The concrete bug report is when passdb gave us an
797 if (!sid_to_uid(&user_sid
, uid
)) {
798 DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",
799 username
, sid_string_dbg(&user_sid
)));
800 result
= NT_STATUS_NO_SUCH_USER
;
804 uid_to_unix_users_sid(*uid
, &user_sid
);
806 pass
= getpwuid_alloc(tmp_ctx
, *uid
);
808 DEBUG(1, ("getpwuid(%u) for user %s failed\n",
809 (unsigned int)*uid
, username
));
813 if (!getgroups_unix_user(tmp_ctx
, username
, pass
->pw_gid
,
814 &gids
, &getgroups_num_group_sids
)) {
815 DEBUG(1, ("getgroups_unix_user for user %s failed\n",
819 num_group_sids
= getgroups_num_group_sids
;
821 if (num_group_sids
) {
822 group_sids
= TALLOC_ARRAY(tmp_ctx
, struct dom_sid
, num_group_sids
);
823 if (group_sids
== NULL
) {
824 DEBUG(1, ("TALLOC_ARRAY failed\n"));
825 result
= NT_STATUS_NO_MEMORY
;
832 for (i
=0; i
<num_group_sids
; i
++) {
833 gid_to_sid(&group_sids
[i
], gids
[i
]);
836 /* In getgroups_unix_user we always set the primary gid */
837 SMB_ASSERT(num_group_sids
> 0);
841 /* Ensure we're returning the found_username on the right context. */
842 *found_username
= talloc_strdup(mem_ctx
, pass
->pw_name
);
845 /* This user is from winbind, force the primary gid to the
846 * user's "domain users" group. Under certain circumstances
847 * (user comes from NT4), this might be a loss of
848 * information. But we can not rely on winbind getting the
849 * correct info. AD might prohibit winbind looking up that
854 /* We must always assign the *uid. */
855 if (!sid_to_uid(&user_sid
, uid
)) {
856 DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",
857 username
, sid_string_dbg(&user_sid
)));
858 result
= NT_STATUS_NO_SUCH_USER
;
863 group_sids
= TALLOC_ARRAY(tmp_ctx
, struct dom_sid
, num_group_sids
);
864 if (group_sids
== NULL
) {
865 DEBUG(1, ("TALLOC_ARRAY failed\n"));
866 result
= NT_STATUS_NO_MEMORY
;
870 sid_copy(&group_sids
[0], &user_sid
);
871 sid_split_rid(&group_sids
[0], &dummy
);
872 sid_append_rid(&group_sids
[0], DOMAIN_RID_USERS
);
874 if (!sid_to_gid(&group_sids
[0], gid
)) {
875 DEBUG(1, ("sid_to_gid(%s) failed\n",
876 sid_string_dbg(&group_sids
[0])));
882 /* Ensure we're returning the found_username on the right context. */
883 *found_username
= talloc_strdup(mem_ctx
, username
);
886 /* Add the "Unix Group" SID for each gid to catch mapped groups
887 and their Unix equivalent. This is to solve the backwards
888 compatibility problem of 'valid users = +ntadmin' where
889 ntadmin has been paired with "Domain Admins" in the group
890 mapping table. Otherwise smb.conf would need to be changed
891 to 'valid user = "Domain Admins"'. --jerry */
893 num_gids
= num_group_sids
;
894 for ( i
=0; i
<num_gids
; i
++ ) {
897 /* don't pickup anything managed by Winbind */
899 if ( lp_idmap_gid(&low
, &high
) && (gids
[i
] >= low
) && (gids
[i
] <= high
) )
902 gid_to_unix_groups_sid(gids
[i
], &unix_group_sid
);
904 result
= add_sid_to_array_unique(tmp_ctx
, &unix_group_sid
,
905 &group_sids
, &num_group_sids
);
906 if (!NT_STATUS_IS_OK(result
)) {
911 /* Ensure we're creating the nt_token on the right context. */
912 *token
= create_local_nt_token(mem_ctx
, &user_sid
,
913 is_guest
, num_group_sids
, group_sids
);
915 if ((*token
== NULL
) || (*found_username
== NULL
)) {
916 result
= NT_STATUS_NO_MEMORY
;
920 result
= NT_STATUS_OK
;
922 TALLOC_FREE(tmp_ctx
);
926 /***************************************************************************
927 Build upon create_token_from_username:
929 Expensive helper function to figure out whether a user given its name is
930 member of a particular group.
931 ***************************************************************************/
933 bool user_in_group_sid(const char *username
, const struct dom_sid
*group_sid
)
938 char *found_username
;
939 struct security_token
*token
;
941 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
943 status
= create_token_from_username(mem_ctx
, username
, False
,
944 &uid
, &gid
, &found_username
,
947 if (!NT_STATUS_IS_OK(status
)) {
948 DEBUG(10, ("could not create token for %s\n", username
));
949 TALLOC_FREE(mem_ctx
);
953 result
= security_token_has_sid(token
, group_sid
);
955 TALLOC_FREE(mem_ctx
);
959 bool user_in_group(const char *username
, const char *groupname
)
961 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
962 struct dom_sid group_sid
;
965 ret
= lookup_name(mem_ctx
, groupname
, LOOKUP_NAME_ALL
,
966 NULL
, NULL
, &group_sid
, NULL
);
967 TALLOC_FREE(mem_ctx
);
970 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname
));
974 return user_in_group_sid(username
, &group_sid
);