2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Gerald (Jerry) Carter 2003
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "lib/util_unixsids.h"
25 #include "../librpc/gen_ndr/ndr_security.h"
27 #include "../lib/util/memcache.h"
28 #include "idmap_cache.h"
29 #include "../libcli/security/security.h"
30 #include "lib/winbind_util.h"
31 #include "../librpc/gen_ndr/idmap.h"
32 #include "lib/util/bitmap.h"
34 static bool lookup_unix_user_name(const char *name
, struct dom_sid
*sid
)
39 pwd
= Get_Pwnam_alloc(talloc_tos(), name
);
45 * For 64-bit uid's we have enough space in the whole SID,
46 * should they become necessary
48 ret
= sid_compose(sid
, &global_sid_Unix_Users
, pwd
->pw_uid
);
53 static bool lookup_unix_group_name(const char *name
, struct dom_sid
*sid
)
63 * For 64-bit gid's we have enough space in the whole SID,
64 * should they become necessary
66 return sid_compose(sid
, &global_sid_Unix_Groups
, grp
->gr_gid
);
69 /*****************************************************************
70 Dissect a user-provided name into domain, name, sid and type.
72 If an explicit domain name was given in the form domain\user, it
73 has to try that. If no explicit domain name was given, we have
75 *****************************************************************/
77 bool lookup_name(TALLOC_CTX
*mem_ctx
,
78 const char *full_name
, int flags
,
79 const char **ret_domain
, const char **ret_name
,
80 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
84 const char *domain
= NULL
;
85 const char *name
= NULL
;
88 enum lsa_SidType type
;
89 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
91 if (tmp_ctx
== NULL
) {
92 DEBUG(0, ("talloc_new failed\n"));
96 p
= strchr_m(full_name
, '\\');
99 domain
= talloc_strndup(tmp_ctx
, full_name
,
100 PTR_DIFF(p
, full_name
));
101 name
= talloc_strdup(tmp_ctx
, p
+1);
103 char *q
= strchr_m(full_name
, '@');
105 /* Set the domain for UPNs */
107 name
= talloc_strndup(tmp_ctx
,
109 PTR_DIFF(q
, full_name
));
110 domain
= talloc_strdup(tmp_ctx
, q
+ 1);
112 domain
= talloc_strdup(tmp_ctx
, "");
113 name
= talloc_strdup(tmp_ctx
, full_name
);
117 if ((domain
== NULL
) || (name
== NULL
)) {
118 DEBUG(0, ("talloc failed\n"));
119 TALLOC_FREE(tmp_ctx
);
123 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
124 full_name
, domain
, name
));
125 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags
));
127 if ((flags
& LOOKUP_NAME_DOMAIN
) || (flags
== 0)) {
128 bool check_global_sam
= false;
130 check_global_sam
= strequal(domain
, get_global_sam_name());
132 /* If we are running on a DC that has PASSDB module with domain
133 * information, check if DNS forest name is matching the domain
134 * name. This is the case of IPA domain controller when
135 * trusted AD DC looks up users found in a Global Catalog of
136 * the forest root domain. */
137 if (!check_global_sam
&& (IS_DC
)) {
138 struct pdb_domain_info
*dom_info
= NULL
;
139 dom_info
= pdb_get_domain_info(tmp_ctx
);
141 if ((dom_info
!= NULL
) && (dom_info
->dns_forest
!= NULL
)) {
142 check_global_sam
= strequal(domain
, dom_info
->dns_forest
);
145 TALLOC_FREE(dom_info
);
148 if (check_global_sam
) {
149 /* It's our own domain, lookup the name in passdb */
150 if (lookup_global_sam_name(name
, flags
, &rid
, &type
)) {
151 sid_compose(&sid
, get_global_sam_sid(), rid
);
154 TALLOC_FREE(tmp_ctx
);
159 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
160 strequal(domain
, builtin_domain_name()))
162 if (strlen(name
) == 0) {
163 /* Swap domain and name */
164 tmp
= name
; name
= domain
; domain
= tmp
;
165 sid_copy(&sid
, &global_sid_Builtin
);
166 type
= SID_NAME_DOMAIN
;
170 /* Explicit request for a name in BUILTIN */
171 if (lookup_builtin_name(name
, &rid
)) {
172 sid_compose(&sid
, &global_sid_Builtin
, rid
);
173 type
= SID_NAME_ALIAS
;
176 TALLOC_FREE(tmp_ctx
);
180 /* Try the explicit winbind lookup first, don't let it guess the
181 * domain yet at this point yet. This comes later. */
183 if ((domain
[0] != '\0') &&
184 (flags
& ~(LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
)) &&
185 (winbind_lookup_name(domain
, name
, &sid
, &type
))) {
189 if (((flags
& (LOOKUP_NAME_NO_NSS
|LOOKUP_NAME_GROUP
)) == 0)
190 && strequal(domain
, unix_users_domain_name())) {
191 if (lookup_unix_user_name(name
, &sid
)) {
192 type
= SID_NAME_USER
;
195 TALLOC_FREE(tmp_ctx
);
199 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
200 && strequal(domain
, unix_groups_domain_name())) {
201 if (lookup_unix_group_name(name
, &sid
)) {
202 type
= SID_NAME_DOM_GRP
;
205 TALLOC_FREE(tmp_ctx
);
210 * Finally check for a well known domain name ("NT Authority"),
211 * this is being taken care of in lookup_wellknown_name().
213 if ((domain
[0] != '\0') &&
214 (flags
& LOOKUP_NAME_WKN
) &&
215 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
217 type
= SID_NAME_WKN_GRP
;
222 * If we're told not to look up 'isolated' names then we're
225 if (!(flags
& LOOKUP_NAME_ISOLATED
)) {
226 TALLOC_FREE(tmp_ctx
);
231 * No domain names beyond this point
233 if (domain
[0] != '\0') {
234 TALLOC_FREE(tmp_ctx
);
238 /* Now the guesswork begins, we haven't been given an explicit
239 * domain. Try the sequence as documented on
240 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
241 * November 27, 2005 */
243 /* 1. well-known names */
246 * Check for well known names without a domain name.
247 * e.g. \Creator Owner.
250 if ((flags
& LOOKUP_NAME_WKN
) &&
251 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
253 type
= SID_NAME_WKN_GRP
;
257 /* 2. Builtin domain as such */
259 if ((flags
& (LOOKUP_NAME_BUILTIN
|LOOKUP_NAME_REMOTE
)) &&
260 strequal(name
, builtin_domain_name()))
262 /* Swap domain and name */
263 tmp
= name
; name
= domain
; domain
= tmp
;
264 sid_copy(&sid
, &global_sid_Builtin
);
265 type
= SID_NAME_DOMAIN
;
269 /* 3. Account domain */
271 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
272 strequal(name
, get_global_sam_name()))
274 if (!secrets_fetch_domain_sid(name
, &sid
)) {
275 DEBUG(3, ("Could not fetch my SID\n"));
276 TALLOC_FREE(tmp_ctx
);
279 /* Swap domain and name */
280 tmp
= name
; name
= domain
; domain
= tmp
;
281 type
= SID_NAME_DOMAIN
;
285 /* 4. Primary domain */
287 if ((flags
& LOOKUP_NAME_DOMAIN
) && !IS_DC
&&
288 strequal(name
, lp_workgroup()))
290 if (!secrets_fetch_domain_sid(name
, &sid
)) {
291 DEBUG(3, ("Could not fetch the domain SID\n"));
292 TALLOC_FREE(tmp_ctx
);
295 /* Swap domain and name */
296 tmp
= name
; name
= domain
; domain
= tmp
;
297 type
= SID_NAME_DOMAIN
;
301 /* 5. Trusted domains as such, to me it looks as if members don't do
302 this, tested an XP workstation in a NT domain -- vl */
304 if ((flags
& LOOKUP_NAME_REMOTE
) && IS_DC
&&
305 (pdb_get_trusteddom_pw(name
, NULL
, &sid
, NULL
)))
307 /* Swap domain and name */
308 tmp
= name
; name
= domain
; domain
= tmp
;
309 type
= SID_NAME_DOMAIN
;
313 /* 6. Builtin aliases */
315 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
316 lookup_builtin_name(name
, &rid
))
318 domain
= talloc_strdup(tmp_ctx
, builtin_domain_name());
319 sid_compose(&sid
, &global_sid_Builtin
, rid
);
320 type
= SID_NAME_ALIAS
;
324 /* 7. Local systems' SAM (DCs don't have a local SAM) */
325 /* 8. Primary SAM (On members, this is the domain) */
327 /* Both cases are done by looking at our passdb */
329 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
330 lookup_global_sam_name(name
, flags
, &rid
, &type
))
332 domain
= talloc_strdup(tmp_ctx
, get_global_sam_name());
333 sid_compose(&sid
, get_global_sam_sid(), rid
);
337 /* Now our local possibilities are exhausted. */
339 if (!(flags
& LOOKUP_NAME_REMOTE
)) {
340 TALLOC_FREE(tmp_ctx
);
344 /* If we are not a DC, we have to ask in our primary domain. Let
345 * winbind do that. */
348 (winbind_lookup_name(lp_workgroup(), name
, &sid
, &type
))) {
349 domain
= talloc_strdup(tmp_ctx
, lp_workgroup());
353 /* 9. Trusted domains */
355 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
356 * that (yet), but give it a chance. */
358 if (IS_DC
&& winbind_lookup_name("", name
, &sid
, &type
)) {
359 struct dom_sid dom_sid
;
360 enum lsa_SidType domain_type
;
362 if (type
== SID_NAME_DOMAIN
) {
363 /* Swap name and type */
364 tmp
= name
; name
= domain
; domain
= tmp
;
368 /* Here we have to cope with a little deficiency in the
369 * winbind API: We have to ask it again for the name of the
370 * domain it figured out itself. Maybe fix that later... */
372 sid_copy(&dom_sid
, &sid
);
373 sid_split_rid(&dom_sid
, NULL
);
375 if (!winbind_lookup_sid(tmp_ctx
, &dom_sid
, &domain
, NULL
,
377 (domain_type
!= SID_NAME_DOMAIN
)) {
378 DEBUG(2, ("winbind could not find the domain's name "
379 "it just looked up for us\n"));
380 TALLOC_FREE(tmp_ctx
);
386 /* 10. Don't translate */
388 /* 11. Ok, windows would end here. Samba has two more options:
389 Unmapped users and unmapped groups */
391 if (((flags
& (LOOKUP_NAME_NO_NSS
|LOOKUP_NAME_GROUP
)) == 0)
392 && lookup_unix_user_name(name
, &sid
)) {
393 domain
= talloc_strdup(tmp_ctx
, unix_users_domain_name());
394 type
= SID_NAME_USER
;
398 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
399 && lookup_unix_group_name(name
, &sid
)) {
400 domain
= talloc_strdup(tmp_ctx
, unix_groups_domain_name());
401 type
= SID_NAME_DOM_GRP
;
406 * Ok, all possibilities tried. Fail.
409 TALLOC_FREE(tmp_ctx
);
413 if ((domain
== NULL
) || (name
== NULL
)) {
414 DEBUG(0, ("talloc failed\n"));
415 TALLOC_FREE(tmp_ctx
);
420 * Hand over the results to the talloc context we've been given.
423 if ((ret_name
!= NULL
) &&
424 !(*ret_name
= talloc_strdup(mem_ctx
, name
))) {
425 DEBUG(0, ("talloc failed\n"));
426 TALLOC_FREE(tmp_ctx
);
430 if (ret_domain
!= NULL
) {
432 if (!(tmp_dom
= talloc_strdup(mem_ctx
, domain
))) {
433 DEBUG(0, ("talloc failed\n"));
434 TALLOC_FREE(tmp_ctx
);
437 if (!strupper_m(tmp_dom
)) {
438 TALLOC_FREE(tmp_ctx
);
441 *ret_domain
= tmp_dom
;
444 if (ret_sid
!= NULL
) {
445 sid_copy(ret_sid
, &sid
);
448 if (ret_type
!= NULL
) {
452 TALLOC_FREE(tmp_ctx
);
456 /************************************************************************
457 Names from smb.conf can be unqualified. eg. valid users = foo
458 These names should never map to a remote name. Try global_sam_name()\foo,
459 and then "Unix Users"\foo (or "Unix Groups"\foo).
460 ************************************************************************/
462 bool lookup_name_smbconf(TALLOC_CTX
*mem_ctx
,
463 const char *full_name
, int flags
,
464 const char **ret_domain
, const char **ret_name
,
465 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
467 char *qualified_name
= NULL
;
468 const char *p
= strchr_m(full_name
, *lp_winbind_separator());
469 bool is_qualified
= p
!= NULL
|| strchr_m(full_name
, '@') != NULL
;
471 /* For DOMAIN\user or user@REALM directly call lookup_name(). */
474 /* The name is already qualified with a domain. */
476 if (p
!= NULL
&& *lp_winbind_separator() != '\\') {
477 /* lookup_name() needs '\\' as a separator */
479 qualified_name
= talloc_strdup(mem_ctx
, full_name
);
480 if (qualified_name
== NULL
) {
483 qualified_name
[p
- full_name
] = '\\';
484 full_name
= qualified_name
;
487 return lookup_name(mem_ctx
, full_name
, flags
,
488 ret_domain
, ret_name
,
492 /* Try with winbind default domain name. */
493 if (lp_winbind_use_default_domain()) {
496 qualified_name
= talloc_asprintf(mem_ctx
,
500 if (qualified_name
== NULL
) {
504 ok
= lookup_name(mem_ctx
,
516 /* Try with our own SAM name. */
517 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
518 get_global_sam_name(),
520 if (!qualified_name
) {
524 if (lookup_name(mem_ctx
, qualified_name
, flags
,
525 ret_domain
, ret_name
,
526 ret_sid
, ret_type
)) {
530 /* Finally try with "Unix Users" or "Unix Group" */
531 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
532 flags
& LOOKUP_NAME_GROUP
?
533 unix_groups_domain_name() :
534 unix_users_domain_name(),
536 if (!qualified_name
) {
540 return lookup_name(mem_ctx
, qualified_name
, flags
,
541 ret_domain
, ret_name
,
545 static bool wb_lookup_rids(TALLOC_CTX
*mem_ctx
,
546 const struct dom_sid
*domain_sid
,
547 int num_rids
, uint32_t *rids
,
548 const char **domain_name
,
549 const char **names
, enum lsa_SidType
*types
)
552 const char **my_names
;
553 enum lsa_SidType
*my_types
;
556 if (!(tmp_ctx
= talloc_init("wb_lookup_rids"))) {
560 if (!winbind_lookup_rids(tmp_ctx
, domain_sid
, num_rids
, rids
,
561 domain_name
, &my_names
, &my_types
)) {
563 for (i
=0; i
<num_rids
; i
++) {
565 types
[i
] = SID_NAME_UNKNOWN
;
567 TALLOC_FREE(tmp_ctx
);
571 if (!(*domain_name
= talloc_strdup(mem_ctx
, *domain_name
))) {
572 TALLOC_FREE(tmp_ctx
);
577 * winbind_lookup_rids allocates its own array. We've been given the
578 * array, so copy it over
581 for (i
=0; i
<num_rids
; i
++) {
582 if (my_names
[i
] == NULL
) {
583 TALLOC_FREE(tmp_ctx
);
586 if (!(names
[i
] = talloc_strdup(names
, my_names
[i
]))) {
587 TALLOC_FREE(tmp_ctx
);
590 types
[i
] = my_types
[i
];
592 TALLOC_FREE(tmp_ctx
);
596 static bool lookup_rids(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*domain_sid
,
597 int num_rids
, uint32_t *rids
,
598 const char **domain_name
,
599 const char ***names
, enum lsa_SidType
**types
)
602 struct dom_sid_buf buf
;
604 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
605 dom_sid_str_buf(domain_sid
, &buf
)));
608 *names
= talloc_zero_array(mem_ctx
, const char *, num_rids
);
609 *types
= talloc_array(mem_ctx
, enum lsa_SidType
, num_rids
);
611 if ((*names
== NULL
) || (*types
== NULL
)) {
615 for (i
= 0; i
< num_rids
; i
++)
616 (*types
)[i
] = SID_NAME_UNKNOWN
;
622 if (sid_check_is_our_sam(domain_sid
)) {
625 if (*domain_name
== NULL
) {
626 *domain_name
= talloc_strdup(
627 mem_ctx
, get_global_sam_name());
630 if (*domain_name
== NULL
) {
635 result
= pdb_lookup_rids(domain_sid
, num_rids
, rids
,
639 return (NT_STATUS_IS_OK(result
) ||
640 NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
) ||
641 NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
));
644 if (sid_check_is_builtin(domain_sid
)) {
646 if (*domain_name
== NULL
) {
647 *domain_name
= talloc_strdup(
648 mem_ctx
, builtin_domain_name());
651 if (*domain_name
== NULL
) {
655 for (i
=0; i
<num_rids
; i
++) {
656 if (lookup_builtin_rid(*names
, rids
[i
],
658 if ((*names
)[i
] == NULL
) {
661 (*types
)[i
] = SID_NAME_ALIAS
;
663 (*types
)[i
] = SID_NAME_UNKNOWN
;
669 if (sid_check_is_wellknown_domain(domain_sid
, NULL
)) {
670 for (i
=0; i
<num_rids
; i
++) {
672 sid_compose(&sid
, domain_sid
, rids
[i
]);
673 if (lookup_wellknown_sid(mem_ctx
, &sid
,
674 domain_name
, &(*names
)[i
])) {
675 if ((*names
)[i
] == NULL
) {
678 (*types
)[i
] = SID_NAME_WKN_GRP
;
680 (*types
)[i
] = SID_NAME_UNKNOWN
;
686 if (sid_check_is_unix_users(domain_sid
)) {
687 if (*domain_name
== NULL
) {
688 *domain_name
= talloc_strdup(
689 mem_ctx
, unix_users_domain_name());
690 if (*domain_name
== NULL
) {
694 for (i
=0; i
<num_rids
; i
++) {
695 (*names
)[i
] = talloc_strdup(
696 (*names
), uidtoname(rids
[i
]));
697 if ((*names
)[i
] == NULL
) {
700 (*types
)[i
] = SID_NAME_USER
;
705 if (sid_check_is_unix_groups(domain_sid
)) {
706 if (*domain_name
== NULL
) {
707 *domain_name
= talloc_strdup(
708 mem_ctx
, unix_groups_domain_name());
709 if (*domain_name
== NULL
) {
713 for (i
=0; i
<num_rids
; i
++) {
714 (*names
)[i
] = talloc_strdup(
715 (*names
), gidtoname(rids
[i
]));
716 if ((*names
)[i
] == NULL
) {
719 (*types
)[i
] = SID_NAME_DOM_GRP
;
724 return wb_lookup_rids(mem_ctx
, domain_sid
, num_rids
, rids
,
725 domain_name
, *names
, *types
);
729 * Is the SID a domain as such? If yes, lookup its name.
732 static bool lookup_as_domain(const struct dom_sid
*sid
, TALLOC_CTX
*mem_ctx
,
736 enum lsa_SidType type
;
738 if (sid_check_is_our_sam(sid
)) {
739 *name
= talloc_strdup(mem_ctx
, get_global_sam_name());
743 if (sid_check_is_builtin(sid
)) {
744 *name
= talloc_strdup(mem_ctx
, builtin_domain_name());
748 if (sid_check_is_wellknown_domain(sid
, &tmp
)) {
749 *name
= talloc_strdup(mem_ctx
, tmp
);
753 if (sid_check_is_unix_users(sid
)) {
754 *name
= talloc_strdup(mem_ctx
, unix_users_domain_name());
758 if (sid_check_is_unix_groups(sid
)) {
759 *name
= talloc_strdup(mem_ctx
, unix_groups_domain_name());
763 if (sid
->num_auths
!= 4) {
764 /* This can't be a domain */
769 uint32_t i
, num_domains
;
770 struct trustdom_info
**domains
;
772 /* This is relatively expensive, but it happens only on DCs
773 * and for SIDs that have 4 sub-authorities and thus look like
776 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx
,
782 for (i
=0; i
<num_domains
; i
++) {
783 if (dom_sid_equal(sid
, &domains
[i
]->sid
)) {
784 *name
= talloc_strdup(mem_ctx
,
792 if (winbind_lookup_sid(mem_ctx
, sid
, &tmp
, NULL
, &type
) &&
793 (type
== SID_NAME_DOMAIN
)) {
802 * This tries to implement the rather weird rules for the lsa_lookup level
805 * This is as close as we can get to what W2k3 does. With this we survive the
806 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
807 * different, but I assume that's just being too liberal. For example, W2k3
808 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
809 * whereas NT4 does the same as level 1 (I think). I did not fully test that
810 * with NT4, this is what w2k3 does.
812 * Level 1: Ask everywhere
813 * Level 2: Ask domain and trusted domains, no builtin and wkn
814 * Level 3: Only ask domain
815 * Level 4: W2k3ad: Only ask AD trusts
816 * Level 5: Only ask transitive forest trusts
820 static bool check_dom_sid_to_level(const struct dom_sid
*sid
, int level
)
822 struct dom_sid_buf buf
;
830 ret
= (!sid_check_is_builtin(sid
) &&
831 !sid_check_is_wellknown_domain(sid
, NULL
));
836 ret
= sid_check_is_our_sam(sid
);
843 DEBUG(10, ("%s SID %s in level %d\n",
844 ret
? "Accepting" : "Rejecting",
845 dom_sid_str_buf(sid
, &buf
),
851 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
852 * references to domains, it is explicitly made for this.
854 * This attempts to be as efficient as possible: It collects all SIDs
855 * belonging to a domain and hands them in bulk to the appropriate lookup
856 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
857 * *hugely* from this.
860 NTSTATUS
lookup_sids(TALLOC_CTX
*mem_ctx
, int num_sids
,
861 const struct dom_sid
**sids
, int level
,
862 struct lsa_dom_info
**ret_domains
,
863 struct lsa_name_info
**ret_names
)
867 struct lsa_name_info
*name_infos
;
868 struct lsa_dom_info
*dom_infos
= NULL
;
872 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
873 DEBUG(0, ("talloc_new failed\n"));
874 return NT_STATUS_NO_MEMORY
;
878 name_infos
= talloc_array(mem_ctx
, struct lsa_name_info
, num_sids
);
879 if (name_infos
== NULL
) {
880 result
= NT_STATUS_NO_MEMORY
;
887 dom_infos
= talloc_zero_array(mem_ctx
, struct lsa_dom_info
,
888 LSA_REF_DOMAIN_LIST_MULTIPLIER
);
889 if (dom_infos
== NULL
) {
890 result
= NT_STATUS_NO_MEMORY
;
894 /* First build up the data structures:
896 * dom_infos is a list of domains referenced in the list of
897 * SIDs. Later we will walk the list of domains and look up the RIDs
900 * name_infos is a shadow-copy of the SIDs array to collect the real
903 * dom_info->idxs is an index into the name_infos array. The
904 * difficulty we have here is that we need to keep the SIDs the client
905 * asked for in the same order for the reply
908 for (i
=0; i
<num_sids
; i
++) {
911 const char *domain_name
= NULL
;
913 sid_copy(&sid
, sids
[i
]);
914 name_infos
[i
].type
= SID_NAME_USE_NONE
;
916 if (lookup_as_domain(&sid
, name_infos
, &domain_name
)) {
917 /* We can't push that through the normal lookup
918 * process, as this would reference illegal
921 * For example S-1-5-32 would end up referencing
922 * domain S-1-5- with RID 32 which is clearly wrong.
924 if (domain_name
== NULL
) {
925 result
= NT_STATUS_NO_MEMORY
;
929 name_infos
[i
].rid
= 0;
930 name_infos
[i
].type
= SID_NAME_DOMAIN
;
931 name_infos
[i
].name
= NULL
;
933 if (sid_check_is_builtin(&sid
)) {
934 /* Yes, W2k3 returns "BUILTIN" both as domain
936 name_infos
[i
].name
= talloc_strdup(
937 name_infos
, builtin_domain_name());
938 if (name_infos
[i
].name
== NULL
) {
939 result
= NT_STATUS_NO_MEMORY
;
944 /* This is a normal SID with rid component */
945 if (!sid_split_rid(&sid
, &rid
)) {
946 result
= NT_STATUS_INVALID_SID
;
951 if (!check_dom_sid_to_level(&sid
, level
)) {
952 name_infos
[i
].rid
= 0;
953 name_infos
[i
].type
= SID_NAME_UNKNOWN
;
954 name_infos
[i
].name
= NULL
;
958 for (j
=0; j
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; j
++) {
959 if (!dom_infos
[j
].valid
) {
962 if (dom_sid_equal(&sid
, &dom_infos
[j
].sid
)) {
967 if (j
== LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
968 /* TODO: What's the right error message here? */
969 result
= NT_STATUS_NONE_MAPPED
;
973 if (!dom_infos
[j
].valid
) {
974 /* We found a domain not yet referenced, create a new
976 dom_infos
[j
].valid
= true;
977 sid_copy(&dom_infos
[j
].sid
, &sid
);
979 if (domain_name
!= NULL
) {
980 /* This name was being found above in the case
981 * when we found a domain SID */
983 talloc_strdup(dom_infos
, domain_name
);
984 if (dom_infos
[j
].name
== NULL
) {
985 result
= NT_STATUS_NO_MEMORY
;
989 /* lookup_rids will take care of this */
990 dom_infos
[j
].name
= NULL
;
994 name_infos
[i
].dom_idx
= j
;
996 if (name_infos
[i
].type
== SID_NAME_USE_NONE
) {
997 name_infos
[i
].rid
= rid
;
999 ADD_TO_ARRAY(dom_infos
, int, i
, &dom_infos
[j
].idxs
,
1000 &dom_infos
[j
].num_idxs
);
1002 if (dom_infos
[j
].idxs
== NULL
) {
1003 result
= NT_STATUS_NO_MEMORY
;
1009 /* Iterate over the domains found */
1011 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
1013 const char *domain_name
= NULL
;
1015 enum lsa_SidType
*types
;
1016 struct lsa_dom_info
*dom
= &dom_infos
[i
];
1019 /* No domains left, we're done */
1023 if (dom
->num_idxs
== 0) {
1025 * This happens only if the only sid related to
1026 * this domain is the domain sid itself, which
1027 * is mapped to SID_NAME_DOMAIN above.
1032 if (!(rids
= talloc_array(tmp_ctx
, uint32_t, dom
->num_idxs
))) {
1033 result
= NT_STATUS_NO_MEMORY
;
1037 for (j
=0; j
<dom
->num_idxs
; j
++) {
1038 rids
[j
] = name_infos
[dom
->idxs
[j
]].rid
;
1041 if (!lookup_rids(tmp_ctx
, &dom
->sid
,
1042 dom
->num_idxs
, rids
, &domain_name
,
1044 result
= NT_STATUS_NO_MEMORY
;
1048 if (!(dom
->name
= talloc_strdup(dom_infos
, domain_name
))) {
1049 result
= NT_STATUS_NO_MEMORY
;
1053 for (j
=0; j
<dom
->num_idxs
; j
++) {
1054 int idx
= dom
->idxs
[j
];
1055 name_infos
[idx
].type
= types
[j
];
1056 if (types
[j
] != SID_NAME_UNKNOWN
) {
1057 name_infos
[idx
].name
=
1058 talloc_strdup(name_infos
, names
[j
]);
1059 if (name_infos
[idx
].name
== NULL
) {
1060 result
= NT_STATUS_NO_MEMORY
;
1064 name_infos
[idx
].name
= NULL
;
1069 *ret_domains
= dom_infos
;
1070 *ret_names
= name_infos
;
1071 TALLOC_FREE(tmp_ctx
);
1072 return NT_STATUS_OK
;
1075 TALLOC_FREE(dom_infos
);
1076 TALLOC_FREE(name_infos
);
1077 TALLOC_FREE(tmp_ctx
);
1081 /*****************************************************************
1082 *THE CANONICAL* convert SID to name function.
1083 *****************************************************************/
1085 bool lookup_sid(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*sid
,
1086 const char **ret_domain
, const char **ret_name
,
1087 enum lsa_SidType
*ret_type
)
1089 struct lsa_dom_info
*domain
;
1090 struct lsa_name_info
*name
;
1091 struct dom_sid_buf buf
;
1092 TALLOC_CTX
*tmp_ctx
;
1095 DEBUG(10, ("lookup_sid called for SID '%s'\n",
1096 dom_sid_str_buf(sid
, &buf
)));
1098 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
1099 DEBUG(0, ("talloc_new failed\n"));
1103 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx
, 1, &sid
, 1,
1108 if (name
->type
== SID_NAME_UNKNOWN
) {
1112 if ((ret_domain
!= NULL
) &&
1113 !(*ret_domain
= talloc_strdup(mem_ctx
, domain
->name
))) {
1117 if ((ret_name
!= NULL
) &&
1118 !(*ret_name
= talloc_strdup(mem_ctx
, name
->name
))) {
1122 if (ret_type
!= NULL
) {
1123 *ret_type
= name
->type
;
1130 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n",
1131 dom_sid_str_buf(sid
, &buf
),
1132 domain
->name
, name
->name
, name
->type
));
1134 DEBUG(10, ("failed to lookup sid %s\n",
1135 dom_sid_str_buf(sid
, &buf
)));
1137 TALLOC_FREE(tmp_ctx
);
1141 /*****************************************************************
1142 *THE LEGACY* convert SID to id function.
1143 *****************************************************************/
1145 static bool legacy_sid_to_unixid(const struct dom_sid
*psid
, struct unixid
*id
)
1150 ret
= pdb_sid_to_id(psid
, id
);
1154 struct dom_sid_buf buf
;
1155 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1156 dom_sid_str_buf(psid
, &buf
)));
1163 static bool legacy_sid_to_gid(const struct dom_sid
*psid
, gid_t
*pgid
)
1166 if (!legacy_sid_to_unixid(psid
, &id
)) {
1169 if (id
.type
== ID_TYPE_GID
|| id
.type
== ID_TYPE_BOTH
) {
1176 static bool legacy_sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1179 if (!legacy_sid_to_unixid(psid
, &id
)) {
1182 if (id
.type
== ID_TYPE_UID
|| id
.type
== ID_TYPE_BOTH
) {
1189 void xid_to_sid(struct dom_sid
*psid
, const struct unixid
*xid
)
1191 bool expired
= true;
1193 struct dom_sid_buf buf
;
1195 SMB_ASSERT(xid
->type
== ID_TYPE_UID
|| xid
->type
== ID_TYPE_GID
);
1197 *psid
= (struct dom_sid
) {0};
1199 ret
= idmap_cache_find_xid2sid(xid
, psid
, &expired
);
1200 if (ret
&& !expired
) {
1201 DBG_DEBUG("%cID %"PRIu32
" -> %s from cache\n",
1202 xid
->type
== ID_TYPE_UID
? 'U' : 'G',
1204 dom_sid_str_buf(psid
, &buf
));
1208 ret
= winbind_xid_to_sid(psid
, xid
);
1211 * winbind can return an explicit negative mapping
1212 * here. It's up to winbind to prime the cache either
1213 * positively or negatively, don't mess with the cache
1216 DBG_DEBUG("%cID %"PRIu32
" -> %s from cache\n",
1217 xid
->type
== ID_TYPE_UID
? 'U' : 'G',
1219 dom_sid_str_buf(psid
, &buf
));
1225 * Make a copy, pdb_id_to_sid might want to turn
1226 * xid->type into ID_TYPE_BOTH, which we ignore here.
1228 struct unixid rw_xid
= *xid
;
1231 ret
= pdb_id_to_sid(&rw_xid
, psid
);
1236 DBG_DEBUG("%cID %"PRIu32
" -> %s from passdb\n",
1237 xid
->type
== ID_TYPE_UID
? 'U' : 'G',
1239 dom_sid_str_buf(psid
, &buf
));
1244 if (is_null_sid(psid
)) {
1246 * Nobody found anything: Return S-1-22-xx-yy. Don't
1247 * store that in caches, this is up to the layers
1250 if (xid
->type
== ID_TYPE_UID
) {
1251 uid_to_unix_users_sid(xid
->id
, psid
);
1253 gid_to_unix_groups_sid(xid
->id
, psid
);
1256 DBG_DEBUG("%cID %"PRIu32
" -> %s fallback\n",
1257 xid
->type
== ID_TYPE_UID
? 'U' : 'G',
1259 dom_sid_str_buf(psid
, &buf
));
1263 void uid_to_sid(struct dom_sid
*psid
, uid_t uid
)
1265 struct unixid xid
= { .type
= ID_TYPE_UID
, .id
= uid
};
1266 xid_to_sid(psid
, &xid
);
1269 void gid_to_sid(struct dom_sid
*psid
, gid_t gid
)
1271 struct unixid xid
= { .type
= ID_TYPE_GID
, .id
= gid
};
1272 xid_to_sid(psid
, &xid
);
1275 bool sids_to_unixids(const struct dom_sid
*sids
, uint32_t num_sids
,
1278 struct wbcDomainSid
*wbc_sids
= NULL
;
1279 struct wbcUnixId
*wbc_ids
= NULL
;
1280 struct bitmap
*found
= NULL
;
1281 uint32_t i
, num_not_cached
;
1282 uint32_t wbc_ids_size
= 0;
1286 wbc_sids
= talloc_array(talloc_tos(), struct wbcDomainSid
, num_sids
);
1287 if (wbc_sids
== NULL
) {
1290 found
= bitmap_talloc(wbc_sids
, num_sids
);
1291 if (found
== NULL
) {
1296 * We go through the requested SID array three times.
1297 * First time to look for global_sid_Unix_Users
1298 * and global_sid_Unix_Groups SIDS, and to look
1299 * for mappings cached in the idmap_cache.
1301 * Use bitmap_set() to mark an ids[] array entry as
1307 for (i
=0; i
<num_sids
; i
++) {
1311 if (sid_peek_check_rid(&global_sid_Unix_Users
,
1313 ids
[i
].type
= ID_TYPE_UID
;
1315 bitmap_set(found
, i
);
1318 if (sid_peek_check_rid(&global_sid_Unix_Groups
,
1320 ids
[i
].type
= ID_TYPE_GID
;
1322 bitmap_set(found
, i
);
1325 if (idmap_cache_find_sid2unixid(&sids
[i
], &ids
[i
], &expired
)
1328 bitmap_set(found
, i
);
1331 ids
[i
].type
= ID_TYPE_NOT_SPECIFIED
;
1332 memcpy(&wbc_sids
[num_not_cached
], &sids
[i
],
1333 ndr_size_dom_sid(&sids
[i
], 0));
1334 num_not_cached
+= 1;
1336 if (num_not_cached
== 0) {
1341 * For the ones that we couldn't map in the loop above, query winbindd
1342 * via wbcSidsToUnixIds().
1345 wbc_ids_size
= num_not_cached
;
1346 wbc_ids
= talloc_array(talloc_tos(), struct wbcUnixId
, wbc_ids_size
);
1347 if (wbc_ids
== NULL
) {
1350 for (i
=0; i
<wbc_ids_size
; i
++) {
1351 wbc_ids
[i
].type
= WBC_ID_TYPE_NOT_SPECIFIED
;
1352 wbc_ids
[i
].id
.gid
= (uint32_t)-1;
1354 err
= wbcSidsToUnixIds(wbc_sids
, wbc_ids_size
, wbc_ids
);
1355 if (!WBC_ERROR_IS_OK(err
)) {
1356 DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1357 wbcErrorString(err
)));
1361 * Second time through the SID array, replace
1362 * the ids[] entries that wbcSidsToUnixIds() was able to
1365 * Use bitmap_set() to mark an ids[] array entry as
1371 for (i
=0; i
<num_sids
; i
++) {
1372 if (bitmap_query(found
, i
)) {
1376 SMB_ASSERT(num_not_cached
< wbc_ids_size
);
1378 switch (wbc_ids
[num_not_cached
].type
) {
1379 case WBC_ID_TYPE_UID
:
1380 ids
[i
].type
= ID_TYPE_UID
;
1381 ids
[i
].id
= wbc_ids
[num_not_cached
].id
.uid
;
1382 bitmap_set(found
, i
);
1384 case WBC_ID_TYPE_GID
:
1385 ids
[i
].type
= ID_TYPE_GID
;
1386 ids
[i
].id
= wbc_ids
[num_not_cached
].id
.gid
;
1387 bitmap_set(found
, i
);
1389 case WBC_ID_TYPE_BOTH
:
1390 ids
[i
].type
= ID_TYPE_BOTH
;
1391 ids
[i
].id
= wbc_ids
[num_not_cached
].id
.uid
;
1392 bitmap_set(found
, i
);
1394 case WBC_ID_TYPE_NOT_SPECIFIED
:
1396 * wbcSidsToUnixIds() wasn't able to map this
1397 * so we still need to check legacy_sid_to_XXX()
1398 * below. Don't mark the bitmap entry
1399 * as being found so the final loop knows
1400 * to try and map this entry.
1402 ids
[i
].type
= ID_TYPE_NOT_SPECIFIED
;
1403 ids
[i
].id
= (uint32_t)-1;
1407 * A successful return from wbcSidsToUnixIds()
1408 * cannot return anything other than the values
1409 * checked for above. Ensure this is so.
1411 smb_panic(__location__
);
1414 num_not_cached
+= 1;
1418 * Third and final time through the SID array,
1419 * try legacy_sid_to_gid()/legacy_sid_to_uid()
1420 * for entries we haven't already been able to
1423 * Use bitmap_set() to mark an ids[] array entry as
1427 for (i
=0; i
<num_sids
; i
++) {
1428 if (bitmap_query(found
, i
)) {
1431 if (legacy_sid_to_gid(&sids
[i
], &ids
[i
].id
)) {
1432 ids
[i
].type
= ID_TYPE_GID
;
1433 bitmap_set(found
, i
);
1436 if (legacy_sid_to_uid(&sids
[i
], &ids
[i
].id
)) {
1437 ids
[i
].type
= ID_TYPE_UID
;
1438 bitmap_set(found
, i
);
1444 * Pass through the return array for consistency.
1445 * Any ids[].id mapped to (uint32_t)-1 must be returned
1446 * as ID_TYPE_NOT_SPECIFIED.
1448 for (i
=0; i
<num_sids
; i
++) {
1449 switch(ids
[i
].type
) {
1453 if (ids
[i
].id
== (uint32_t)-1) {
1454 ids
[i
].type
= ID_TYPE_NOT_SPECIFIED
;
1457 case ID_TYPE_NOT_SPECIFIED
:
1459 case ID_TYPE_WB_REQUIRE_TYPE
:
1461 * these are internal between winbindd
1464 smb_panic(__location__
);
1471 TALLOC_FREE(wbc_ids
);
1472 TALLOC_FREE(wbc_sids
);
1476 /*****************************************************************
1477 *THE CANONICAL* convert SID to uid function.
1478 *****************************************************************/
1480 bool sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1482 bool expired
= true;
1485 struct dom_sid_buf buf
;
1487 /* Optimize for the Unix Users Domain
1488 * as the conversion is straightforward */
1489 if (sid_peek_check_rid(&global_sid_Unix_Users
, psid
, &rid
)) {
1493 /* return here, don't cache */
1494 DEBUG(10,("sid %s -> uid %u\n",
1495 dom_sid_str_buf(psid
, &buf
),
1496 (unsigned int)*puid
));
1500 if (sid_check_is_in_unix_groups(psid
)) {
1501 DBG_DEBUG("SID %s is a group, failing\n",
1502 dom_sid_str_buf(psid
, &buf
));
1506 /* Check the winbindd cache directly. */
1507 ret
= idmap_cache_find_sid2uid(psid
, puid
, &expired
);
1509 if (ret
&& !expired
&& (*puid
== (uid_t
)-1)) {
1511 * Negative cache entry, we already asked.
1514 return legacy_sid_to_uid(psid
, puid
);
1517 if (!ret
|| expired
) {
1518 /* Not in cache. Ask winbindd. */
1519 if (!winbind_sid_to_uid(puid
, psid
)) {
1520 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1521 dom_sid_str_buf(psid
, &buf
)));
1522 /* winbind failed. do legacy */
1523 return legacy_sid_to_uid(psid
, puid
);
1527 /* TODO: Here would be the place to allocate both a gid and a uid for
1528 * the SID in question */
1530 DEBUG(10,("sid %s -> uid %u\n",
1531 dom_sid_str_buf(psid
, &buf
),
1532 (unsigned int)*puid
));
1537 /*****************************************************************
1538 *THE CANONICAL* convert SID to gid function.
1539 Group mapping is used for gids that maps to Wellknown SIDs
1540 *****************************************************************/
1542 bool sid_to_gid(const struct dom_sid
*psid
, gid_t
*pgid
)
1544 bool expired
= true;
1547 struct dom_sid_buf buf
;
1549 /* Optimize for the Unix Groups Domain
1550 * as the conversion is straightforward */
1551 if (sid_peek_check_rid(&global_sid_Unix_Groups
, psid
, &rid
)) {
1555 /* return here, don't cache */
1556 DEBUG(10,("sid %s -> gid %u\n",
1557 dom_sid_str_buf(psid
, &buf
),
1558 (unsigned int)*pgid
));
1562 if (sid_check_is_in_unix_users(psid
)) {
1563 DBG_DEBUG("SID %s is a user, failing\n",
1564 dom_sid_str_buf(psid
, &buf
));
1568 /* Check the winbindd cache directly. */
1569 ret
= idmap_cache_find_sid2gid(psid
, pgid
, &expired
);
1571 if (ret
&& !expired
&& (*pgid
== (gid_t
)-1)) {
1573 * Negative cache entry, we already asked.
1576 return legacy_sid_to_gid(psid
, pgid
);
1579 if (!ret
|| expired
) {
1580 /* Not in cache or negative. Ask winbindd. */
1581 /* Ask winbindd if it can map this sid to a gid.
1582 * (Idmap will check it is a valid SID and of the right type) */
1584 if ( !winbind_sid_to_gid(pgid
, psid
) ) {
1586 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1587 dom_sid_str_buf(psid
, &buf
)));
1588 /* winbind failed. do legacy */
1589 return legacy_sid_to_gid(psid
, pgid
);
1593 DEBUG(10,("sid %s -> gid %u\n",
1594 dom_sid_str_buf(psid
, &buf
),
1595 (unsigned int)*pgid
));
1601 * @brief This function gets the primary group SID mapping the primary
1602 * GID of the user as obtained by an actual getpwnam() call.
1603 * This is necessary to avoid issues with arbitrary group SIDs
1604 * stored in passdb. We try as hard as we can to get the SID
1605 * corresponding to the GID, including trying group mapping.
1606 * If nothing else works, we will force "Domain Users" as the
1608 * This is needed because we must always be able to lookup the
1609 * primary group SID, so we cannot settle for an arbitrary SID.
1611 * This call can be expensive. Use with moderation.
1612 * If you have a "samu" struct around use pdb_get_group_sid()
1613 * instead as it does properly cache results.
1615 * @param mem_ctx[in] The memory context iused to allocate the result.
1616 * @param username[in] The user's name
1617 * @param _pwd[in|out] If available, pass in user's passwd struct.
1618 * It will contain a tallocated passwd if NULL was
1620 * @param _group_sid[out] The user's Primary Group SID
1622 * @return NTSTATUS error code.
1624 NTSTATUS
get_primary_group_sid(TALLOC_CTX
*mem_ctx
,
1625 const char *username
,
1626 struct passwd
**_pwd
,
1627 struct dom_sid
**_group_sid
)
1629 TALLOC_CTX
*tmp_ctx
;
1630 bool need_lookup_sid
= false;
1631 struct dom_sid
*group_sid
;
1632 struct passwd
*pwd
= *_pwd
;
1634 tmp_ctx
= talloc_new(mem_ctx
);
1636 return NT_STATUS_NO_MEMORY
;
1640 pwd
= Get_Pwnam_alloc(mem_ctx
, username
);
1642 DEBUG(0, ("Failed to find a Unix account for %s\n",
1644 TALLOC_FREE(tmp_ctx
);
1645 return NT_STATUS_NO_SUCH_USER
;
1649 group_sid
= talloc_zero(mem_ctx
, struct dom_sid
);
1651 TALLOC_FREE(tmp_ctx
);
1652 return NT_STATUS_NO_MEMORY
;
1655 gid_to_sid(group_sid
, pwd
->pw_gid
);
1656 if (!is_null_sid(group_sid
)) {
1657 struct dom_sid domain_sid
;
1660 /* We need a sid within our domain */
1661 sid_copy(&domain_sid
, group_sid
);
1662 sid_split_rid(&domain_sid
, &rid
);
1663 if (dom_sid_equal(&domain_sid
, get_global_sam_sid())) {
1665 * As shortcut for the expensive lookup_sid call
1666 * compare the domain sid part
1669 case DOMAIN_RID_ADMINS
:
1670 case DOMAIN_RID_USERS
:
1673 need_lookup_sid
= true;
1677 /* Try group mapping */
1680 id
.id
= pwd
->pw_gid
;
1681 id
.type
= ID_TYPE_GID
;
1683 ZERO_STRUCTP(group_sid
);
1684 if (pdb_id_to_sid(&id
, group_sid
)) {
1685 need_lookup_sid
= true;
1690 /* We must verify that this is a valid SID that resolves to a
1691 * group of the correct type */
1692 if (need_lookup_sid
) {
1693 enum lsa_SidType type
= SID_NAME_UNKNOWN
;
1695 struct dom_sid_buf buf
;
1697 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1698 dom_sid_str_buf(group_sid
, &buf
),
1701 /* Now check that it's actually a domain group and
1702 * not something else */
1703 lookup_ret
= lookup_sid(tmp_ctx
, group_sid
,
1706 if (lookup_ret
&& (type
== SID_NAME_DOM_GRP
)) {
1710 DEBUG(3, ("Primary group %s for user %s is"
1711 " a %s and not a domain group\n",
1712 dom_sid_str_buf(group_sid
, &buf
),
1714 sid_type_lookup(type
)));
1717 /* Everything else, failed.
1718 * Just set it to the 'Domain Users' RID of 513 which will
1719 always resolve to a name */
1720 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1723 sid_compose(group_sid
, get_global_sam_sid(), DOMAIN_RID_USERS
);
1726 *_pwd
= talloc_move(mem_ctx
, &pwd
);
1727 *_group_sid
= talloc_move(mem_ctx
, &group_sid
);
1728 TALLOC_FREE(tmp_ctx
);
1729 return NT_STATUS_OK
;