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 "../librpc/gen_ndr/ndr_security.h"
27 #include "idmap_cache.h"
28 #include "../libcli/security/security.h"
29 #include "lib/winbind_util.h"
31 /*****************************************************************
32 Dissect a user-provided name into domain, name, sid and type.
34 If an explicit domain name was given in the form domain\user, it
35 has to try that. If no explicit domain name was given, we have
37 *****************************************************************/
39 bool lookup_name(TALLOC_CTX
*mem_ctx
,
40 const char *full_name
, int flags
,
41 const char **ret_domain
, const char **ret_name
,
42 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
46 const char *domain
= NULL
;
47 const char *name
= NULL
;
50 enum lsa_SidType type
;
51 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
53 if (tmp_ctx
== NULL
) {
54 DEBUG(0, ("talloc_new failed\n"));
58 p
= strchr_m(full_name
, '\\');
61 domain
= talloc_strndup(tmp_ctx
, full_name
,
62 PTR_DIFF(p
, full_name
));
63 name
= talloc_strdup(tmp_ctx
, p
+1);
65 domain
= talloc_strdup(tmp_ctx
, "");
66 name
= talloc_strdup(tmp_ctx
, full_name
);
69 if ((domain
== NULL
) || (name
== NULL
)) {
70 DEBUG(0, ("talloc failed\n"));
75 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
76 full_name
, domain
, name
));
77 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags
));
79 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
80 strequal(domain
, get_global_sam_name()))
83 /* It's our own domain, lookup the name in passdb */
84 if (lookup_global_sam_name(name
, flags
, &rid
, &type
)) {
85 sid_compose(&sid
, get_global_sam_sid(), rid
);
92 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
93 strequal(domain
, builtin_domain_name()))
95 if (strlen(name
) == 0) {
96 /* Swap domain and name */
97 tmp
= name
; name
= domain
; domain
= tmp
;
98 sid_copy(&sid
, &global_sid_Builtin
);
99 type
= SID_NAME_DOMAIN
;
103 /* Explicit request for a name in BUILTIN */
104 if (lookup_builtin_name(name
, &rid
)) {
105 sid_compose(&sid
, &global_sid_Builtin
, rid
);
106 type
= SID_NAME_ALIAS
;
109 TALLOC_FREE(tmp_ctx
);
113 /* Try the explicit winbind lookup first, don't let it guess the
114 * domain yet at this point yet. This comes later. */
116 if ((domain
[0] != '\0') &&
117 (flags
& ~(LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
)) &&
118 (winbind_lookup_name(domain
, name
, &sid
, &type
))) {
122 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
123 && strequal(domain
, unix_users_domain_name())) {
124 if (lookup_unix_user_name(name
, &sid
)) {
125 type
= SID_NAME_USER
;
128 TALLOC_FREE(tmp_ctx
);
132 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
133 && strequal(domain
, unix_groups_domain_name())) {
134 if (lookup_unix_group_name(name
, &sid
)) {
135 type
= SID_NAME_DOM_GRP
;
138 TALLOC_FREE(tmp_ctx
);
142 if ((domain
[0] == '\0') && (!(flags
& LOOKUP_NAME_ISOLATED
))) {
143 TALLOC_FREE(tmp_ctx
);
147 /* Now the guesswork begins, we haven't been given an explicit
148 * domain. Try the sequence as documented on
149 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
150 * November 27, 2005 */
152 /* 1. well-known names */
154 if ((flags
& LOOKUP_NAME_WKN
) &&
155 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
157 type
= SID_NAME_WKN_GRP
;
161 /* 2. Builtin domain as such */
163 if ((flags
& (LOOKUP_NAME_BUILTIN
|LOOKUP_NAME_REMOTE
)) &&
164 strequal(name
, builtin_domain_name()))
166 /* Swap domain and name */
167 tmp
= name
; name
= domain
; domain
= tmp
;
168 sid_copy(&sid
, &global_sid_Builtin
);
169 type
= SID_NAME_DOMAIN
;
173 /* 3. Account domain */
175 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
176 strequal(name
, get_global_sam_name()))
178 if (!secrets_fetch_domain_sid(name
, &sid
)) {
179 DEBUG(3, ("Could not fetch my SID\n"));
180 TALLOC_FREE(tmp_ctx
);
183 /* Swap domain and name */
184 tmp
= name
; name
= domain
; domain
= tmp
;
185 type
= SID_NAME_DOMAIN
;
189 /* 4. Primary domain */
191 if ((flags
& LOOKUP_NAME_DOMAIN
) && !IS_DC
&&
192 strequal(name
, lp_workgroup()))
194 if (!secrets_fetch_domain_sid(name
, &sid
)) {
195 DEBUG(3, ("Could not fetch the domain SID\n"));
196 TALLOC_FREE(tmp_ctx
);
199 /* Swap domain and name */
200 tmp
= name
; name
= domain
; domain
= tmp
;
201 type
= SID_NAME_DOMAIN
;
205 /* 5. Trusted domains as such, to me it looks as if members don't do
206 this, tested an XP workstation in a NT domain -- vl */
208 if ((flags
& LOOKUP_NAME_REMOTE
) && IS_DC
&&
209 (pdb_get_trusteddom_pw(name
, NULL
, &sid
, NULL
)))
211 /* Swap domain and name */
212 tmp
= name
; name
= domain
; domain
= tmp
;
213 type
= SID_NAME_DOMAIN
;
217 /* 6. Builtin aliases */
219 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
220 lookup_builtin_name(name
, &rid
))
222 domain
= talloc_strdup(tmp_ctx
, builtin_domain_name());
223 sid_compose(&sid
, &global_sid_Builtin
, rid
);
224 type
= SID_NAME_ALIAS
;
228 /* 7. Local systems' SAM (DCs don't have a local SAM) */
229 /* 8. Primary SAM (On members, this is the domain) */
231 /* Both cases are done by looking at our passdb */
233 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
234 lookup_global_sam_name(name
, flags
, &rid
, &type
))
236 domain
= talloc_strdup(tmp_ctx
, get_global_sam_name());
237 sid_compose(&sid
, get_global_sam_sid(), rid
);
241 /* Now our local possibilities are exhausted. */
243 if (!(flags
& LOOKUP_NAME_REMOTE
)) {
244 TALLOC_FREE(tmp_ctx
);
248 /* If we are not a DC, we have to ask in our primary domain. Let
249 * winbind do that. */
252 (winbind_lookup_name(lp_workgroup(), name
, &sid
, &type
))) {
253 domain
= talloc_strdup(tmp_ctx
, lp_workgroup());
257 /* 9. Trusted domains */
259 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
260 * that (yet), but give it a chance. */
262 if (IS_DC
&& winbind_lookup_name("", name
, &sid
, &type
)) {
263 struct dom_sid dom_sid
;
264 enum lsa_SidType domain_type
;
266 if (type
== SID_NAME_DOMAIN
) {
267 /* Swap name and type */
268 tmp
= name
; name
= domain
; domain
= tmp
;
272 /* Here we have to cope with a little deficiency in the
273 * winbind API: We have to ask it again for the name of the
274 * domain it figured out itself. Maybe fix that later... */
276 sid_copy(&dom_sid
, &sid
);
277 sid_split_rid(&dom_sid
, NULL
);
279 if (!winbind_lookup_sid(tmp_ctx
, &dom_sid
, &domain
, NULL
,
281 (domain_type
!= SID_NAME_DOMAIN
)) {
282 DEBUG(2, ("winbind could not find the domain's name "
283 "it just looked up for us\n"));
284 TALLOC_FREE(tmp_ctx
);
290 /* 10. Don't translate */
292 /* 11. Ok, windows would end here. Samba has two more options:
293 Unmapped users and unmapped groups */
295 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
296 && lookup_unix_user_name(name
, &sid
)) {
297 domain
= talloc_strdup(tmp_ctx
, unix_users_domain_name());
298 type
= SID_NAME_USER
;
302 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
303 && lookup_unix_group_name(name
, &sid
)) {
304 domain
= talloc_strdup(tmp_ctx
, unix_groups_domain_name());
305 type
= SID_NAME_DOM_GRP
;
310 * Ok, all possibilities tried. Fail.
313 TALLOC_FREE(tmp_ctx
);
317 if ((domain
== NULL
) || (name
== NULL
)) {
318 DEBUG(0, ("talloc failed\n"));
319 TALLOC_FREE(tmp_ctx
);
324 * Hand over the results to the talloc context we've been given.
327 if ((ret_name
!= NULL
) &&
328 !(*ret_name
= talloc_strdup(mem_ctx
, name
))) {
329 DEBUG(0, ("talloc failed\n"));
330 TALLOC_FREE(tmp_ctx
);
334 if (ret_domain
!= NULL
) {
336 if (!(tmp_dom
= talloc_strdup(mem_ctx
, domain
))) {
337 DEBUG(0, ("talloc failed\n"));
338 TALLOC_FREE(tmp_ctx
);
342 *ret_domain
= tmp_dom
;
345 if (ret_sid
!= NULL
) {
346 sid_copy(ret_sid
, &sid
);
349 if (ret_type
!= NULL
) {
353 TALLOC_FREE(tmp_ctx
);
357 /************************************************************************
358 Names from smb.conf can be unqualified. eg. valid users = foo
359 These names should never map to a remote name. Try global_sam_name()\foo,
360 and then "Unix Users"\foo (or "Unix Groups"\foo).
361 ************************************************************************/
363 bool lookup_name_smbconf(TALLOC_CTX
*mem_ctx
,
364 const char *full_name
, int flags
,
365 const char **ret_domain
, const char **ret_name
,
366 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
368 char *qualified_name
;
371 /* NB. No winbindd_separator here as lookup_name needs \\' */
372 if ((p
= strchr_m(full_name
, *lp_winbind_separator())) != NULL
) {
374 /* The name is already qualified with a domain. */
376 if (*lp_winbind_separator() != '\\') {
379 /* lookup_name() needs '\\' as a separator */
381 tmp
= talloc_strdup(mem_ctx
, full_name
);
385 tmp
[p
- full_name
] = '\\';
389 return lookup_name(mem_ctx
, full_name
, flags
,
390 ret_domain
, ret_name
,
394 /* Try with our own SAM name. */
395 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
396 get_global_sam_name(),
398 if (!qualified_name
) {
402 if (lookup_name(mem_ctx
, qualified_name
, flags
,
403 ret_domain
, ret_name
,
404 ret_sid
, ret_type
)) {
408 /* Finally try with "Unix Users" or "Unix Group" */
409 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
410 flags
& LOOKUP_NAME_GROUP
?
411 unix_groups_domain_name() :
412 unix_users_domain_name(),
414 if (!qualified_name
) {
418 return lookup_name(mem_ctx
, qualified_name
, flags
,
419 ret_domain
, ret_name
,
423 static bool wb_lookup_rids(TALLOC_CTX
*mem_ctx
,
424 const struct dom_sid
*domain_sid
,
425 int num_rids
, uint32
*rids
,
426 const char **domain_name
,
427 const char **names
, enum lsa_SidType
*types
)
430 const char **my_names
;
431 enum lsa_SidType
*my_types
;
434 if (!(tmp_ctx
= talloc_init("wb_lookup_rids"))) {
438 if (!winbind_lookup_rids(tmp_ctx
, domain_sid
, num_rids
, rids
,
439 domain_name
, &my_names
, &my_types
)) {
441 for (i
=0; i
<num_rids
; i
++) {
443 types
[i
] = SID_NAME_UNKNOWN
;
445 TALLOC_FREE(tmp_ctx
);
449 if (!(*domain_name
= talloc_strdup(mem_ctx
, *domain_name
))) {
450 TALLOC_FREE(tmp_ctx
);
455 * winbind_lookup_rids allocates its own array. We've been given the
456 * array, so copy it over
459 for (i
=0; i
<num_rids
; i
++) {
460 if (my_names
[i
] == NULL
) {
461 TALLOC_FREE(tmp_ctx
);
464 if (!(names
[i
] = talloc_strdup(names
, my_names
[i
]))) {
465 TALLOC_FREE(tmp_ctx
);
468 types
[i
] = my_types
[i
];
470 TALLOC_FREE(tmp_ctx
);
474 static bool lookup_rids(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*domain_sid
,
475 int num_rids
, uint32_t *rids
,
476 const char **domain_name
,
477 const char ***names
, enum lsa_SidType
**types
)
481 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
482 sid_string_dbg(domain_sid
)));
485 *names
= talloc_zero_array(mem_ctx
, const char *, num_rids
);
486 *types
= talloc_array(mem_ctx
, enum lsa_SidType
, num_rids
);
488 if ((*names
== NULL
) || (*types
== NULL
)) {
492 for (i
= 0; i
< num_rids
; i
++)
493 (*types
)[i
] = SID_NAME_UNKNOWN
;
499 if (sid_check_is_domain(domain_sid
)) {
502 if (*domain_name
== NULL
) {
503 *domain_name
= talloc_strdup(
504 mem_ctx
, get_global_sam_name());
507 if (*domain_name
== NULL
) {
512 result
= pdb_lookup_rids(domain_sid
, num_rids
, rids
,
516 return (NT_STATUS_IS_OK(result
) ||
517 NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
) ||
518 NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
));
521 if (sid_check_is_builtin(domain_sid
)) {
523 if (*domain_name
== NULL
) {
524 *domain_name
= talloc_strdup(
525 mem_ctx
, builtin_domain_name());
528 if (*domain_name
== NULL
) {
532 for (i
=0; i
<num_rids
; i
++) {
533 if (lookup_builtin_rid(*names
, rids
[i
],
535 if ((*names
)[i
] == NULL
) {
538 (*types
)[i
] = SID_NAME_ALIAS
;
540 (*types
)[i
] = SID_NAME_UNKNOWN
;
546 if (sid_check_is_wellknown_domain(domain_sid
, NULL
)) {
547 for (i
=0; i
<num_rids
; i
++) {
549 sid_compose(&sid
, domain_sid
, rids
[i
]);
550 if (lookup_wellknown_sid(mem_ctx
, &sid
,
551 domain_name
, &(*names
)[i
])) {
552 if ((*names
)[i
] == NULL
) {
555 (*types
)[i
] = SID_NAME_WKN_GRP
;
557 (*types
)[i
] = SID_NAME_UNKNOWN
;
563 if (sid_check_is_unix_users(domain_sid
)) {
564 if (*domain_name
== NULL
) {
565 *domain_name
= talloc_strdup(
566 mem_ctx
, unix_users_domain_name());
567 if (*domain_name
== NULL
) {
571 for (i
=0; i
<num_rids
; i
++) {
572 (*names
)[i
] = talloc_strdup(
573 (*names
), uidtoname(rids
[i
]));
574 if ((*names
)[i
] == NULL
) {
577 (*types
)[i
] = SID_NAME_USER
;
582 if (sid_check_is_unix_groups(domain_sid
)) {
583 if (*domain_name
== NULL
) {
584 *domain_name
= talloc_strdup(
585 mem_ctx
, unix_groups_domain_name());
586 if (*domain_name
== NULL
) {
590 for (i
=0; i
<num_rids
; i
++) {
591 (*names
)[i
] = talloc_strdup(
592 (*names
), gidtoname(rids
[i
]));
593 if ((*names
)[i
] == NULL
) {
596 (*types
)[i
] = SID_NAME_DOM_GRP
;
601 return wb_lookup_rids(mem_ctx
, domain_sid
, num_rids
, rids
,
602 domain_name
, *names
, *types
);
606 * Is the SID a domain as such? If yes, lookup its name.
609 static bool lookup_as_domain(const struct dom_sid
*sid
, TALLOC_CTX
*mem_ctx
,
613 enum lsa_SidType type
;
615 if (sid_check_is_domain(sid
)) {
616 *name
= talloc_strdup(mem_ctx
, get_global_sam_name());
620 if (sid_check_is_builtin(sid
)) {
621 *name
= talloc_strdup(mem_ctx
, builtin_domain_name());
625 if (sid_check_is_wellknown_domain(sid
, &tmp
)) {
626 *name
= talloc_strdup(mem_ctx
, tmp
);
630 if (sid_check_is_unix_users(sid
)) {
631 *name
= talloc_strdup(mem_ctx
, unix_users_domain_name());
635 if (sid_check_is_unix_groups(sid
)) {
636 *name
= talloc_strdup(mem_ctx
, unix_groups_domain_name());
640 if (sid
->num_auths
!= 4) {
641 /* This can't be a domain */
646 uint32 i
, num_domains
;
647 struct trustdom_info
**domains
;
649 /* This is relatively expensive, but it happens only on DCs
650 * and for SIDs that have 4 sub-authorities and thus look like
653 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx
,
659 for (i
=0; i
<num_domains
; i
++) {
660 if (dom_sid_equal(sid
, &domains
[i
]->sid
)) {
661 *name
= talloc_strdup(mem_ctx
,
669 if (winbind_lookup_sid(mem_ctx
, sid
, &tmp
, NULL
, &type
) &&
670 (type
== SID_NAME_DOMAIN
)) {
679 * This tries to implement the rather weird rules for the lsa_lookup level
682 * This is as close as we can get to what W2k3 does. With this we survive the
683 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
684 * different, but I assume that's just being too liberal. For example, W2k3
685 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
686 * whereas NT4 does the same as level 1 (I think). I did not fully test that
687 * with NT4, this is what w2k3 does.
689 * Level 1: Ask everywhere
690 * Level 2: Ask domain and trusted domains, no builtin and wkn
691 * Level 3: Only ask domain
692 * Level 4: W2k3ad: Only ask AD trusts
693 * Level 5: Only ask transitive forest trusts
697 static bool check_dom_sid_to_level(const struct dom_sid
*sid
, int level
)
706 ret
= (!sid_check_is_builtin(sid
) &&
707 !sid_check_is_wellknown_domain(sid
, NULL
));
712 ret
= sid_check_is_domain(sid
);
719 DEBUG(10, ("%s SID %s in level %d\n",
720 ret
? "Accepting" : "Rejecting",
721 sid_string_dbg(sid
), level
));
726 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
727 * references to domains, it is explicitly made for this.
729 * This attempts to be as efficient as possible: It collects all SIDs
730 * belonging to a domain and hands them in bulk to the appropriate lookup
731 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
732 * *hugely* from this.
735 NTSTATUS
lookup_sids(TALLOC_CTX
*mem_ctx
, int num_sids
,
736 const struct dom_sid
**sids
, int level
,
737 struct lsa_dom_info
**ret_domains
,
738 struct lsa_name_info
**ret_names
)
741 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
742 struct lsa_name_info
*name_infos
;
743 struct lsa_dom_info
*dom_infos
= NULL
;
747 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
748 DEBUG(0, ("talloc_new failed\n"));
749 return NT_STATUS_NO_MEMORY
;
753 name_infos
= talloc_array(mem_ctx
, struct lsa_name_info
, num_sids
);
754 if (name_infos
== NULL
) {
755 result
= NT_STATUS_NO_MEMORY
;
762 dom_infos
= talloc_zero_array(mem_ctx
, struct lsa_dom_info
,
763 LSA_REF_DOMAIN_LIST_MULTIPLIER
);
764 if (dom_infos
== NULL
) {
765 result
= NT_STATUS_NO_MEMORY
;
769 /* First build up the data structures:
771 * dom_infos is a list of domains referenced in the list of
772 * SIDs. Later we will walk the list of domains and look up the RIDs
775 * name_infos is a shadow-copy of the SIDs array to collect the real
778 * dom_info->idxs is an index into the name_infos array. The
779 * difficulty we have here is that we need to keep the SIDs the client
780 * asked for in the same order for the reply
783 for (i
=0; i
<num_sids
; i
++) {
786 const char *domain_name
= NULL
;
788 sid_copy(&sid
, sids
[i
]);
789 name_infos
[i
].type
= SID_NAME_USE_NONE
;
791 if (lookup_as_domain(&sid
, name_infos
, &domain_name
)) {
792 /* We can't push that through the normal lookup
793 * process, as this would reference illegal
796 * For example S-1-5-32 would end up referencing
797 * domain S-1-5- with RID 32 which is clearly wrong.
799 if (domain_name
== NULL
) {
800 result
= NT_STATUS_NO_MEMORY
;
804 name_infos
[i
].rid
= 0;
805 name_infos
[i
].type
= SID_NAME_DOMAIN
;
806 name_infos
[i
].name
= NULL
;
808 if (sid_check_is_builtin(&sid
)) {
809 /* Yes, W2k3 returns "BUILTIN" both as domain
811 name_infos
[i
].name
= talloc_strdup(
812 name_infos
, builtin_domain_name());
813 if (name_infos
[i
].name
== NULL
) {
814 result
= NT_STATUS_NO_MEMORY
;
819 /* This is a normal SID with rid component */
820 if (!sid_split_rid(&sid
, &rid
)) {
821 result
= NT_STATUS_INVALID_SID
;
826 if (!check_dom_sid_to_level(&sid
, level
)) {
827 name_infos
[i
].rid
= 0;
828 name_infos
[i
].type
= SID_NAME_UNKNOWN
;
829 name_infos
[i
].name
= NULL
;
833 for (j
=0; j
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; j
++) {
834 if (!dom_infos
[j
].valid
) {
837 if (dom_sid_equal(&sid
, &dom_infos
[j
].sid
)) {
842 if (j
== LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
843 /* TODO: What's the right error message here? */
844 result
= NT_STATUS_NONE_MAPPED
;
848 if (!dom_infos
[j
].valid
) {
849 /* We found a domain not yet referenced, create a new
851 dom_infos
[j
].valid
= true;
852 sid_copy(&dom_infos
[j
].sid
, &sid
);
854 if (domain_name
!= NULL
) {
855 /* This name was being found above in the case
856 * when we found a domain SID */
858 talloc_strdup(dom_infos
, domain_name
);
859 if (dom_infos
[j
].name
== NULL
) {
860 result
= NT_STATUS_NO_MEMORY
;
864 /* lookup_rids will take care of this */
865 dom_infos
[j
].name
= NULL
;
869 name_infos
[i
].dom_idx
= j
;
871 if (name_infos
[i
].type
== SID_NAME_USE_NONE
) {
872 name_infos
[i
].rid
= rid
;
874 ADD_TO_ARRAY(dom_infos
, int, i
, &dom_infos
[j
].idxs
,
875 &dom_infos
[j
].num_idxs
);
877 if (dom_infos
[j
].idxs
== NULL
) {
878 result
= NT_STATUS_NO_MEMORY
;
884 /* Iterate over the domains found */
886 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
888 const char *domain_name
= NULL
;
890 enum lsa_SidType
*types
;
891 struct lsa_dom_info
*dom
= &dom_infos
[i
];
894 /* No domains left, we're done */
899 if (!(rids
= talloc_array(tmp_ctx
, uint32
, dom
->num_idxs
))) {
900 result
= NT_STATUS_NO_MEMORY
;
907 for (j
=0; j
<dom
->num_idxs
; j
++) {
908 rids
[j
] = name_infos
[dom
->idxs
[j
]].rid
;
911 if (!lookup_rids(tmp_ctx
, &dom
->sid
,
912 dom
->num_idxs
, rids
, &domain_name
,
914 result
= NT_STATUS_NO_MEMORY
;
918 if (!(dom
->name
= talloc_strdup(dom_infos
, domain_name
))) {
919 result
= NT_STATUS_NO_MEMORY
;
923 for (j
=0; j
<dom
->num_idxs
; j
++) {
924 int idx
= dom
->idxs
[j
];
925 name_infos
[idx
].type
= types
[j
];
926 if (types
[j
] != SID_NAME_UNKNOWN
) {
927 name_infos
[idx
].name
=
928 talloc_strdup(name_infos
, names
[j
]);
929 if (name_infos
[idx
].name
== NULL
) {
930 result
= NT_STATUS_NO_MEMORY
;
934 name_infos
[idx
].name
= NULL
;
939 *ret_domains
= dom_infos
;
940 *ret_names
= name_infos
;
941 TALLOC_FREE(tmp_ctx
);
945 TALLOC_FREE(dom_infos
);
946 TALLOC_FREE(name_infos
);
947 TALLOC_FREE(tmp_ctx
);
951 /*****************************************************************
952 *THE CANONICAL* convert SID to name function.
953 *****************************************************************/
955 bool lookup_sid(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*sid
,
956 const char **ret_domain
, const char **ret_name
,
957 enum lsa_SidType
*ret_type
)
959 struct lsa_dom_info
*domain
;
960 struct lsa_name_info
*name
;
964 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid
)));
966 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
967 DEBUG(0, ("talloc_new failed\n"));
971 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx
, 1, &sid
, 1,
976 if (name
->type
== SID_NAME_UNKNOWN
) {
980 if ((ret_domain
!= NULL
) &&
981 !(*ret_domain
= talloc_strdup(mem_ctx
, domain
->name
))) {
985 if ((ret_name
!= NULL
) &&
986 !(*ret_name
= talloc_strdup(mem_ctx
, name
->name
))) {
990 if (ret_type
!= NULL
) {
991 *ret_type
= name
->type
;
998 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid
),
999 domain
->name
, name
->name
, name
->type
));
1001 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid
)));
1003 TALLOC_FREE(tmp_ctx
);
1007 /*****************************************************************
1008 Id mapping cache. This is to avoid Winbind mappings already
1009 seen by smbd to be queried too frequently, keeping winbindd
1010 busy, and blocking smbd while winbindd is busy with other
1011 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1012 modified to use linked lists by jra.
1013 *****************************************************************/
1015 /*****************************************************************
1016 Find a SID given a uid.
1017 *****************************************************************/
1019 static bool fetch_sid_from_uid_cache(struct dom_sid
*psid
, uid_t uid
)
1021 DATA_BLOB cache_value
;
1023 if (!memcache_lookup(NULL
, UID_SID_CACHE
,
1024 data_blob_const(&uid
, sizeof(uid
)),
1029 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1030 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1031 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, 0));
1036 /*****************************************************************
1037 Find a uid given a SID.
1038 *****************************************************************/
1040 static bool fetch_uid_from_cache( uid_t
*puid
, const struct dom_sid
*psid
)
1042 DATA_BLOB cache_value
;
1044 if (!memcache_lookup(NULL
, SID_UID_CACHE
,
1045 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1050 SMB_ASSERT(cache_value
.length
== sizeof(*puid
));
1051 memcpy(puid
, cache_value
.data
, sizeof(*puid
));
1056 /*****************************************************************
1057 Store uid to SID mapping in cache.
1058 *****************************************************************/
1060 void store_uid_sid_cache(const struct dom_sid
*psid
, uid_t uid
)
1062 memcache_add(NULL
, SID_UID_CACHE
,
1063 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1064 data_blob_const(&uid
, sizeof(uid
)));
1065 memcache_add(NULL
, UID_SID_CACHE
,
1066 data_blob_const(&uid
, sizeof(uid
)),
1067 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)));
1070 /*****************************************************************
1071 Find a SID given a gid.
1072 *****************************************************************/
1074 static bool fetch_sid_from_gid_cache(struct dom_sid
*psid
, gid_t gid
)
1076 DATA_BLOB cache_value
;
1078 if (!memcache_lookup(NULL
, GID_SID_CACHE
,
1079 data_blob_const(&gid
, sizeof(gid
)),
1084 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1085 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1086 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, 0));
1091 /*****************************************************************
1092 Find a gid given a SID.
1093 *****************************************************************/
1095 static bool fetch_gid_from_cache(gid_t
*pgid
, const struct dom_sid
*psid
)
1097 DATA_BLOB cache_value
;
1099 if (!memcache_lookup(NULL
, SID_GID_CACHE
,
1100 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1105 SMB_ASSERT(cache_value
.length
== sizeof(*pgid
));
1106 memcpy(pgid
, cache_value
.data
, sizeof(*pgid
));
1111 /*****************************************************************
1112 Store gid to SID mapping in cache.
1113 *****************************************************************/
1115 void store_gid_sid_cache(const struct dom_sid
*psid
, gid_t gid
)
1117 memcache_add(NULL
, SID_GID_CACHE
,
1118 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1119 data_blob_const(&gid
, sizeof(gid
)));
1120 memcache_add(NULL
, GID_SID_CACHE
,
1121 data_blob_const(&gid
, sizeof(gid
)),
1122 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)));
1125 /*****************************************************************
1126 *THE LEGACY* convert uid_t to SID function.
1127 *****************************************************************/
1129 static void legacy_uid_to_sid(struct dom_sid
*psid
, uid_t uid
)
1136 ret
= pdb_uid_to_sid(uid
, psid
);
1140 /* This is a mapped user */
1144 /* This is an unmapped user */
1146 uid_to_unix_users_sid(uid
, psid
);
1149 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid
,
1150 sid_string_dbg(psid
)));
1152 store_uid_sid_cache(psid
, uid
);
1156 /*****************************************************************
1157 *THE LEGACY* convert gid_t to SID function.
1158 *****************************************************************/
1160 static void legacy_gid_to_sid(struct dom_sid
*psid
, gid_t gid
)
1167 ret
= pdb_gid_to_sid(gid
, psid
);
1171 /* This is a mapped group */
1175 /* This is an unmapped group */
1177 gid_to_unix_groups_sid(gid
, psid
);
1180 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid
,
1181 sid_string_dbg(psid
)));
1183 store_gid_sid_cache(psid
, gid
);
1187 /*****************************************************************
1188 *THE LEGACY* convert SID to uid function.
1189 *****************************************************************/
1191 static bool legacy_sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1193 enum lsa_SidType type
;
1195 if (sid_check_is_in_our_domain(psid
)) {
1200 ret
= pdb_sid_to_id(psid
, &id
, &type
);
1204 if (type
!= SID_NAME_USER
) {
1205 DEBUG(5, ("sid %s is a %s, expected a user\n",
1206 sid_string_dbg(psid
),
1207 sid_type_lookup(type
)));
1214 /* This was ours, but it was not mapped. Fail */
1217 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1218 sid_string_dbg(psid
)));
1222 DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_dbg(psid
),
1223 (unsigned int)*puid
));
1225 store_uid_sid_cache(psid
, *puid
);
1229 /*****************************************************************
1230 *THE LEGACY* convert SID to gid function.
1231 Group mapping is used for gids that maps to Wellknown SIDs
1232 *****************************************************************/
1234 static bool legacy_sid_to_gid(const struct dom_sid
*psid
, gid_t
*pgid
)
1238 enum lsa_SidType type
;
1240 if ((sid_check_is_in_builtin(psid
) ||
1241 sid_check_is_in_wellknown_domain(psid
))) {
1245 ret
= pdb_getgrsid(&map
, *psid
);
1252 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1253 sid_string_dbg(psid
)));
1257 if (sid_check_is_in_our_domain(psid
)) {
1261 ret
= pdb_sid_to_id(psid
, &id
, &type
);
1265 if ((type
!= SID_NAME_DOM_GRP
) &&
1266 (type
!= SID_NAME_ALIAS
)) {
1267 DEBUG(5, ("LEGACY: sid %s is a %s, expected "
1268 "a group\n", sid_string_dbg(psid
),
1269 sid_type_lookup(type
)));
1276 /* This was ours, but it was not mapped. Fail */
1279 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1280 sid_string_dbg(psid
)));
1284 DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid
),
1285 (unsigned int)*pgid
));
1287 store_gid_sid_cache(psid
, *pgid
);
1292 /*****************************************************************
1293 *THE CANONICAL* convert uid_t to SID function.
1294 *****************************************************************/
1296 void uid_to_sid(struct dom_sid
*psid
, uid_t uid
)
1298 bool expired
= true;
1302 if (fetch_sid_from_uid_cache(psid
, uid
))
1305 /* Check the winbindd cache directly. */
1306 ret
= idmap_cache_find_uid2sid(uid
, psid
, &expired
);
1308 if (ret
&& !expired
&& is_null_sid(psid
)) {
1310 * Negative cache entry, we already asked.
1313 legacy_uid_to_sid(psid
, uid
);
1317 if (!ret
|| expired
) {
1318 /* Not in cache. Ask winbindd. */
1319 if (!winbind_uid_to_sid(psid
, uid
)) {
1321 * We shouldn't return the NULL SID
1322 * here if winbind was running and
1323 * couldn't map, as winbind will have
1324 * added a negative entry that will
1325 * cause us to go though the
1326 * legacy_uid_to_sid()
1327 * function anyway in the case above
1328 * the next time we ask.
1330 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1331 "for uid %u\n", (unsigned int)uid
));
1333 legacy_uid_to_sid(psid
, uid
);
1338 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid
,
1339 sid_string_dbg(psid
)));
1341 store_uid_sid_cache(psid
, uid
);
1345 /*****************************************************************
1346 *THE CANONICAL* convert gid_t to SID function.
1347 *****************************************************************/
1349 void gid_to_sid(struct dom_sid
*psid
, gid_t gid
)
1351 bool expired
= true;
1355 if (fetch_sid_from_gid_cache(psid
, gid
))
1358 /* Check the winbindd cache directly. */
1359 ret
= idmap_cache_find_gid2sid(gid
, psid
, &expired
);
1361 if (ret
&& !expired
&& is_null_sid(psid
)) {
1363 * Negative cache entry, we already asked.
1366 legacy_gid_to_sid(psid
, gid
);
1370 if (!ret
|| expired
) {
1371 /* Not in cache. Ask winbindd. */
1372 if (!winbind_gid_to_sid(psid
, gid
)) {
1374 * We shouldn't return the NULL SID
1375 * here if winbind was running and
1376 * couldn't map, as winbind will have
1377 * added a negative entry that will
1378 * cause us to go though the
1379 * legacy_gid_to_sid()
1380 * function anyway in the case above
1381 * the next time we ask.
1383 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1384 "for gid %u\n", (unsigned int)gid
));
1386 legacy_gid_to_sid(psid
, gid
);
1391 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid
,
1392 sid_string_dbg(psid
)));
1394 store_gid_sid_cache(psid
, gid
);
1398 bool sids_to_unix_ids(const struct dom_sid
*sids
, uint32_t num_sids
,
1399 struct wbcUnixId
*ids
)
1401 struct wbcDomainSid
*wbc_sids
= NULL
;
1402 struct wbcUnixId
*wbc_ids
= NULL
;
1403 uint32_t i
, num_not_cached
;
1407 wbc_sids
= talloc_array(talloc_tos(), struct wbcDomainSid
, num_sids
);
1408 if (wbc_sids
== NULL
) {
1414 for (i
=0; i
<num_sids
; i
++) {
1418 if (fetch_uid_from_cache(&ids
[i
].id
.uid
, &sids
[i
])) {
1419 ids
[i
].type
= WBC_ID_TYPE_UID
;
1422 if (fetch_gid_from_cache(&ids
[i
].id
.gid
, &sids
[i
])) {
1423 ids
[i
].type
= WBC_ID_TYPE_GID
;
1426 if (sid_peek_check_rid(&global_sid_Unix_Users
,
1428 ids
[i
].type
= WBC_ID_TYPE_UID
;
1429 ids
[i
].id
.uid
= rid
;
1432 if (sid_peek_check_rid(&global_sid_Unix_Groups
,
1434 ids
[i
].type
= WBC_ID_TYPE_GID
;
1435 ids
[i
].id
.gid
= rid
;
1438 if (idmap_cache_find_sid2uid(&sids
[i
], &ids
[i
].id
.uid
,
1441 ids
[i
].type
= WBC_ID_TYPE_UID
;
1444 if (idmap_cache_find_sid2gid(&sids
[i
], &ids
[i
].id
.gid
,
1447 ids
[i
].type
= WBC_ID_TYPE_GID
;
1450 ids
[i
].type
= WBC_ID_TYPE_NOT_SPECIFIED
;
1451 memcpy(&wbc_sids
[num_not_cached
], &sids
[i
],
1452 ndr_size_dom_sid(&sids
[i
], 0));
1453 num_not_cached
+= 1;
1455 if (num_not_cached
== 0) {
1458 wbc_ids
= talloc_array(talloc_tos(), struct wbcUnixId
, num_not_cached
);
1459 if (wbc_ids
== NULL
) {
1462 for (i
=0; i
<num_not_cached
; i
++) {
1463 wbc_ids
[i
].type
= WBC_ID_TYPE_NOT_SPECIFIED
;
1465 err
= wbcSidsToUnixIds(wbc_sids
, num_not_cached
, wbc_ids
);
1466 if (!WBC_ERROR_IS_OK(err
)) {
1467 DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1468 wbcErrorString(err
)));
1473 for (i
=0; i
<num_sids
; i
++) {
1474 if (ids
[i
].type
== WBC_ID_TYPE_NOT_SPECIFIED
) {
1475 ids
[i
] = wbc_ids
[num_not_cached
];
1476 num_not_cached
+= 1;
1480 for (i
=0; i
<num_sids
; i
++) {
1481 if (ids
[i
].type
!= WBC_ID_TYPE_NOT_SPECIFIED
) {
1484 if (legacy_sid_to_gid(&sids
[i
], &ids
[i
].id
.gid
)) {
1485 ids
[i
].type
= WBC_ID_TYPE_GID
;
1488 if (legacy_sid_to_uid(&sids
[i
], &ids
[i
].id
.uid
)) {
1489 ids
[i
].type
= WBC_ID_TYPE_UID
;
1496 TALLOC_FREE(wbc_ids
);
1497 TALLOC_FREE(wbc_sids
);
1501 /*****************************************************************
1502 *THE CANONICAL* convert SID to uid function.
1503 *****************************************************************/
1505 bool sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1507 bool expired
= true;
1512 if (fetch_uid_from_cache(puid
, psid
))
1515 if (fetch_gid_from_cache(&gid
, psid
)) {
1519 /* Optimize for the Unix Users Domain
1520 * as the conversion is straightforward */
1521 if (sid_peek_check_rid(&global_sid_Unix_Users
, psid
, &rid
)) {
1525 /* return here, don't cache */
1526 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1527 (unsigned int)*puid
));
1531 /* Check the winbindd cache directly. */
1532 ret
= idmap_cache_find_sid2uid(psid
, puid
, &expired
);
1534 if (ret
&& !expired
&& (*puid
== (uid_t
)-1)) {
1536 * Negative cache entry, we already asked.
1539 return legacy_sid_to_uid(psid
, puid
);
1542 if (!ret
|| expired
) {
1543 /* Not in cache. Ask winbindd. */
1544 if (!winbind_sid_to_uid(puid
, psid
)) {
1545 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1546 sid_string_dbg(psid
)));
1547 /* winbind failed. do legacy */
1548 return legacy_sid_to_uid(psid
, puid
);
1552 /* TODO: Here would be the place to allocate both a gid and a uid for
1553 * the SID in question */
1555 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1556 (unsigned int)*puid
));
1558 store_uid_sid_cache(psid
, *puid
);
1562 /*****************************************************************
1563 *THE CANONICAL* convert SID to gid function.
1564 Group mapping is used for gids that maps to Wellknown SIDs
1565 *****************************************************************/
1567 bool sid_to_gid(const struct dom_sid
*psid
, gid_t
*pgid
)
1569 bool expired
= true;
1574 if (fetch_gid_from_cache(pgid
, psid
))
1577 if (fetch_uid_from_cache(&uid
, psid
))
1580 /* Optimize for the Unix Groups Domain
1581 * as the conversion is straightforward */
1582 if (sid_peek_check_rid(&global_sid_Unix_Groups
, psid
, &rid
)) {
1586 /* return here, don't cache */
1587 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1588 (unsigned int)*pgid
));
1592 /* Check the winbindd cache directly. */
1593 ret
= idmap_cache_find_sid2gid(psid
, pgid
, &expired
);
1595 if (ret
&& !expired
&& (*pgid
== (gid_t
)-1)) {
1597 * Negative cache entry, we already asked.
1600 return legacy_sid_to_gid(psid
, pgid
);
1603 if (!ret
|| expired
) {
1604 /* Not in cache or negative. Ask winbindd. */
1605 /* Ask winbindd if it can map this sid to a gid.
1606 * (Idmap will check it is a valid SID and of the right type) */
1608 if ( !winbind_sid_to_gid(pgid
, psid
) ) {
1610 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1611 sid_string_dbg(psid
)));
1612 /* winbind failed. do legacy */
1613 return legacy_sid_to_gid(psid
, pgid
);
1617 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1618 (unsigned int)*pgid
));
1620 store_gid_sid_cache(psid
, *pgid
);
1625 * @brief This function gets the primary group SID mapping the primary
1626 * GID of the user as obtained by an actual getpwnam() call.
1627 * This is necessary to avoid issues with arbitrary group SIDs
1628 * stored in passdb. We try as hard as we can to get the SID
1629 * corresponding to the GID, including trying group mapping.
1630 * If nothing else works, we will force "Domain Users" as the
1632 * This is needed because we must always be able to lookup the
1633 * primary group SID, so we cannot settle for an arbitrary SID.
1635 * This call can be expensive. Use with moderation.
1636 * If you have a "samu" struct around use pdb_get_group_sid()
1637 * instead as it does properly cache results.
1639 * @param mem_ctx[in] The memory context iused to allocate the result.
1640 * @param username[in] The user's name
1641 * @param _pwd[in|out] If available, pass in user's passwd struct.
1642 * It will contain a tallocated passwd if NULL was
1644 * @param _group_sid[out] The user's Primary Group SID
1646 * @return NTSTATUS error code.
1648 NTSTATUS
get_primary_group_sid(TALLOC_CTX
*mem_ctx
,
1649 const char *username
,
1650 struct passwd
**_pwd
,
1651 struct dom_sid
**_group_sid
)
1653 TALLOC_CTX
*tmp_ctx
;
1654 bool need_lookup_sid
= false;
1655 struct dom_sid
*group_sid
;
1656 struct passwd
*pwd
= *_pwd
;
1658 tmp_ctx
= talloc_new(mem_ctx
);
1660 return NT_STATUS_NO_MEMORY
;
1664 pwd
= Get_Pwnam_alloc(mem_ctx
, username
);
1666 DEBUG(0, ("Failed to find a Unix account for %s",
1668 TALLOC_FREE(tmp_ctx
);
1669 return NT_STATUS_NO_SUCH_USER
;
1673 group_sid
= talloc_zero(mem_ctx
, struct dom_sid
);
1675 TALLOC_FREE(tmp_ctx
);
1676 return NT_STATUS_NO_MEMORY
;
1679 gid_to_sid(group_sid
, pwd
->pw_gid
);
1680 if (!is_null_sid(group_sid
)) {
1681 struct dom_sid domain_sid
;
1684 /* We need a sid within our domain */
1685 sid_copy(&domain_sid
, group_sid
);
1686 sid_split_rid(&domain_sid
, &rid
);
1687 if (dom_sid_equal(&domain_sid
, get_global_sam_sid())) {
1689 * As shortcut for the expensive lookup_sid call
1690 * compare the domain sid part
1693 case DOMAIN_RID_ADMINS
:
1694 case DOMAIN_RID_USERS
:
1697 need_lookup_sid
= true;
1701 /* Try group mapping */
1702 ZERO_STRUCTP(group_sid
);
1703 if (pdb_gid_to_sid(pwd
->pw_gid
, group_sid
)) {
1704 need_lookup_sid
= true;
1709 /* We must verify that this is a valid SID that resolves to a
1710 * group of the correct type */
1711 if (need_lookup_sid
) {
1712 enum lsa_SidType type
= SID_NAME_UNKNOWN
;
1715 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1716 sid_string_dbg(group_sid
), username
));
1718 /* Now check that it's actually a domain group and
1719 * not something else */
1720 lookup_ret
= lookup_sid(tmp_ctx
, group_sid
,
1723 if (lookup_ret
&& (type
== SID_NAME_DOM_GRP
)) {
1727 DEBUG(3, ("Primary group %s for user %s is"
1728 " a %s and not a domain group\n",
1729 sid_string_dbg(group_sid
), username
,
1730 sid_type_lookup(type
)));
1733 /* Everything else, failed.
1734 * Just set it to the 'Domain Users' RID of 513 which will
1735 always resolve to a name */
1736 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1739 sid_compose(group_sid
, get_global_sam_sid(), DOMAIN_RID_USERS
);
1742 *_pwd
= talloc_move(mem_ctx
, &pwd
);
1743 *_group_sid
= talloc_move(mem_ctx
, &group_sid
);
1744 TALLOC_FREE(tmp_ctx
);
1745 return NT_STATUS_OK
;