s3-rpc_server: Added debug to see how much data has been read out.
[Samba.git] / source3 / passdb / lookup_sid.c
blob0e2385f43fdb492a6eb1ea79dce4fd7e0f35d5ef
1 /*
2 Unix SMB/CIFS implementation.
3 uid/user handling
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/>.
22 #include "includes.h"
23 #include "../librpc/gen_ndr/ndr_security.h"
24 #include "secrets.h"
25 #include "memcache.h"
26 #include "idmap_cache.h"
28 /*****************************************************************
29 Dissect a user-provided name into domain, name, sid and type.
31 If an explicit domain name was given in the form domain\user, it
32 has to try that. If no explicit domain name was given, we have
33 to do guesswork.
34 *****************************************************************/
36 bool lookup_name(TALLOC_CTX *mem_ctx,
37 const char *full_name, int flags,
38 const char **ret_domain, const char **ret_name,
39 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
41 char *p;
42 const char *tmp;
43 const char *domain = NULL;
44 const char *name = NULL;
45 uint32 rid;
46 struct dom_sid sid;
47 enum lsa_SidType type;
48 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
50 if (tmp_ctx == NULL) {
51 DEBUG(0, ("talloc_new failed\n"));
52 return false;
55 p = strchr_m(full_name, '\\');
57 if (p != NULL) {
58 domain = talloc_strndup(tmp_ctx, full_name,
59 PTR_DIFF(p, full_name));
60 name = talloc_strdup(tmp_ctx, p+1);
61 } else {
62 domain = talloc_strdup(tmp_ctx, "");
63 name = talloc_strdup(tmp_ctx, full_name);
66 if ((domain == NULL) || (name == NULL)) {
67 DEBUG(0, ("talloc failed\n"));
68 TALLOC_FREE(tmp_ctx);
69 return false;
72 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
73 full_name, domain, name));
74 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
76 if ((flags & LOOKUP_NAME_DOMAIN) &&
77 strequal(domain, get_global_sam_name()))
80 /* It's our own domain, lookup the name in passdb */
81 if (lookup_global_sam_name(name, flags, &rid, &type)) {
82 sid_compose(&sid, get_global_sam_sid(), rid);
83 goto ok;
85 TALLOC_FREE(tmp_ctx);
86 return false;
89 if ((flags & LOOKUP_NAME_BUILTIN) &&
90 strequal(domain, builtin_domain_name()))
92 if (strlen(name) == 0) {
93 /* Swap domain and name */
94 tmp = name; name = domain; domain = tmp;
95 sid_copy(&sid, &global_sid_Builtin);
96 type = SID_NAME_DOMAIN;
97 goto ok;
100 /* Explicit request for a name in BUILTIN */
101 if (lookup_builtin_name(name, &rid)) {
102 sid_compose(&sid, &global_sid_Builtin, rid);
103 type = SID_NAME_ALIAS;
104 goto ok;
106 TALLOC_FREE(tmp_ctx);
107 return false;
110 /* Try the explicit winbind lookup first, don't let it guess the
111 * domain yet at this point yet. This comes later. */
113 if ((domain[0] != '\0') &&
114 (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
115 (winbind_lookup_name(domain, name, &sid, &type))) {
116 goto ok;
119 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
120 && strequal(domain, unix_users_domain_name())) {
121 if (lookup_unix_user_name(name, &sid)) {
122 type = SID_NAME_USER;
123 goto ok;
125 TALLOC_FREE(tmp_ctx);
126 return false;
129 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
130 && strequal(domain, unix_groups_domain_name())) {
131 if (lookup_unix_group_name(name, &sid)) {
132 type = SID_NAME_DOM_GRP;
133 goto ok;
135 TALLOC_FREE(tmp_ctx);
136 return false;
139 if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
140 TALLOC_FREE(tmp_ctx);
141 return false;
144 /* Now the guesswork begins, we haven't been given an explicit
145 * domain. Try the sequence as documented on
146 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
147 * November 27, 2005 */
149 /* 1. well-known names */
151 if ((flags & LOOKUP_NAME_WKN) &&
152 lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
154 type = SID_NAME_WKN_GRP;
155 goto ok;
158 /* 2. Builtin domain as such */
160 if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
161 strequal(name, builtin_domain_name()))
163 /* Swap domain and name */
164 tmp = name; name = domain; domain = tmp;
165 sid_copy(&sid, &global_sid_Builtin);
166 type = SID_NAME_DOMAIN;
167 goto ok;
170 /* 3. Account domain */
172 if ((flags & LOOKUP_NAME_DOMAIN) &&
173 strequal(name, get_global_sam_name()))
175 if (!secrets_fetch_domain_sid(name, &sid)) {
176 DEBUG(3, ("Could not fetch my SID\n"));
177 TALLOC_FREE(tmp_ctx);
178 return false;
180 /* Swap domain and name */
181 tmp = name; name = domain; domain = tmp;
182 type = SID_NAME_DOMAIN;
183 goto ok;
186 /* 4. Primary domain */
188 if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
189 strequal(name, lp_workgroup()))
191 if (!secrets_fetch_domain_sid(name, &sid)) {
192 DEBUG(3, ("Could not fetch the domain SID\n"));
193 TALLOC_FREE(tmp_ctx);
194 return false;
196 /* Swap domain and name */
197 tmp = name; name = domain; domain = tmp;
198 type = SID_NAME_DOMAIN;
199 goto ok;
202 /* 5. Trusted domains as such, to me it looks as if members don't do
203 this, tested an XP workstation in a NT domain -- vl */
205 if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
206 (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
208 /* Swap domain and name */
209 tmp = name; name = domain; domain = tmp;
210 type = SID_NAME_DOMAIN;
211 goto ok;
214 /* 6. Builtin aliases */
216 if ((flags & LOOKUP_NAME_BUILTIN) &&
217 lookup_builtin_name(name, &rid))
219 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
220 sid_compose(&sid, &global_sid_Builtin, rid);
221 type = SID_NAME_ALIAS;
222 goto ok;
225 /* 7. Local systems' SAM (DCs don't have a local SAM) */
226 /* 8. Primary SAM (On members, this is the domain) */
228 /* Both cases are done by looking at our passdb */
230 if ((flags & LOOKUP_NAME_DOMAIN) &&
231 lookup_global_sam_name(name, flags, &rid, &type))
233 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
234 sid_compose(&sid, get_global_sam_sid(), rid);
235 goto ok;
238 /* Now our local possibilities are exhausted. */
240 if (!(flags & LOOKUP_NAME_REMOTE)) {
241 TALLOC_FREE(tmp_ctx);
242 return false;
245 /* If we are not a DC, we have to ask in our primary domain. Let
246 * winbind do that. */
248 if (!IS_DC &&
249 (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
250 domain = talloc_strdup(tmp_ctx, lp_workgroup());
251 goto ok;
254 /* 9. Trusted domains */
256 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
257 * that (yet), but give it a chance. */
259 if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
260 struct dom_sid dom_sid;
261 uint32 tmp_rid;
262 enum lsa_SidType domain_type;
264 if (type == SID_NAME_DOMAIN) {
265 /* Swap name and type */
266 tmp = name; name = domain; domain = tmp;
267 goto ok;
270 /* Here we have to cope with a little deficiency in the
271 * winbind API: We have to ask it again for the name of the
272 * domain it figured out itself. Maybe fix that later... */
274 sid_copy(&dom_sid, &sid);
275 sid_split_rid(&dom_sid, &tmp_rid);
277 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
278 &domain_type) ||
279 (domain_type != SID_NAME_DOMAIN)) {
280 DEBUG(2, ("winbind could not find the domain's name "
281 "it just looked up for us\n"));
282 TALLOC_FREE(tmp_ctx);
283 return false;
285 goto ok;
288 /* 10. Don't translate */
290 /* 11. Ok, windows would end here. Samba has two more options:
291 Unmapped users and unmapped groups */
293 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
294 && lookup_unix_user_name(name, &sid)) {
295 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
296 type = SID_NAME_USER;
297 goto ok;
300 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
301 && lookup_unix_group_name(name, &sid)) {
302 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
303 type = SID_NAME_DOM_GRP;
304 goto ok;
308 * Ok, all possibilities tried. Fail.
311 TALLOC_FREE(tmp_ctx);
312 return false;
315 if ((domain == NULL) || (name == NULL)) {
316 DEBUG(0, ("talloc failed\n"));
317 TALLOC_FREE(tmp_ctx);
318 return false;
322 * Hand over the results to the talloc context we've been given.
325 if ((ret_name != NULL) &&
326 !(*ret_name = talloc_strdup(mem_ctx, name))) {
327 DEBUG(0, ("talloc failed\n"));
328 TALLOC_FREE(tmp_ctx);
329 return false;
332 if (ret_domain != NULL) {
333 char *tmp_dom;
334 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
335 DEBUG(0, ("talloc failed\n"));
336 TALLOC_FREE(tmp_ctx);
337 return false;
339 strupper_m(tmp_dom);
340 *ret_domain = tmp_dom;
343 if (ret_sid != NULL) {
344 sid_copy(ret_sid, &sid);
347 if (ret_type != NULL) {
348 *ret_type = type;
351 TALLOC_FREE(tmp_ctx);
352 return true;
355 /************************************************************************
356 Names from smb.conf can be unqualified. eg. valid users = foo
357 These names should never map to a remote name. Try global_sam_name()\foo,
358 and then "Unix Users"\foo (or "Unix Groups"\foo).
359 ************************************************************************/
361 bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
362 const char *full_name, int flags,
363 const char **ret_domain, const char **ret_name,
364 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
366 char *qualified_name;
367 const char *p;
369 /* NB. No winbindd_separator here as lookup_name needs \\' */
370 if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
372 /* The name is already qualified with a domain. */
374 if (*lp_winbind_separator() != '\\') {
375 char *tmp;
377 /* lookup_name() needs '\\' as a separator */
379 tmp = talloc_strdup(mem_ctx, full_name);
380 if (!tmp) {
381 return false;
383 tmp[p - full_name] = '\\';
384 full_name = tmp;
387 return lookup_name(mem_ctx, full_name, flags,
388 ret_domain, ret_name,
389 ret_sid, ret_type);
392 /* Try with our own SAM name. */
393 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
394 get_global_sam_name(),
395 full_name );
396 if (!qualified_name) {
397 return false;
400 if (lookup_name(mem_ctx, qualified_name, flags,
401 ret_domain, ret_name,
402 ret_sid, ret_type)) {
403 return true;
406 /* Finally try with "Unix Users" or "Unix Group" */
407 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
408 flags & LOOKUP_NAME_GROUP ?
409 unix_groups_domain_name() :
410 unix_users_domain_name(),
411 full_name );
412 if (!qualified_name) {
413 return false;
416 return lookup_name(mem_ctx, qualified_name, flags,
417 ret_domain, ret_name,
418 ret_sid, ret_type);
421 static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
422 const struct dom_sid *domain_sid,
423 int num_rids, uint32 *rids,
424 const char **domain_name,
425 const char **names, enum lsa_SidType *types)
427 int i;
428 const char **my_names;
429 enum lsa_SidType *my_types;
430 TALLOC_CTX *tmp_ctx;
432 if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
433 return false;
436 if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
437 domain_name, &my_names, &my_types)) {
438 *domain_name = "";
439 for (i=0; i<num_rids; i++) {
440 names[i] = "";
441 types[i] = SID_NAME_UNKNOWN;
443 TALLOC_FREE(tmp_ctx);
444 return true;
447 if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
448 TALLOC_FREE(tmp_ctx);
449 return false;
453 * winbind_lookup_rids allocates its own array. We've been given the
454 * array, so copy it over
457 for (i=0; i<num_rids; i++) {
458 if (my_names[i] == NULL) {
459 TALLOC_FREE(tmp_ctx);
460 return false;
462 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
463 TALLOC_FREE(tmp_ctx);
464 return false;
466 types[i] = my_types[i];
468 TALLOC_FREE(tmp_ctx);
469 return true;
472 static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
473 int num_rids, uint32_t *rids,
474 const char **domain_name,
475 const char ***names, enum lsa_SidType **types)
477 int i;
479 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
480 sid_string_dbg(domain_sid)));
482 if (num_rids) {
483 *names = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
484 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
486 if ((*names == NULL) || (*types == NULL)) {
487 return false;
490 for (i = 0; i < num_rids; i++)
491 (*types)[i] = SID_NAME_UNKNOWN;
492 } else {
493 *names = NULL;
494 *types = NULL;
497 if (sid_check_is_domain(domain_sid)) {
498 NTSTATUS result;
500 if (*domain_name == NULL) {
501 *domain_name = talloc_strdup(
502 mem_ctx, get_global_sam_name());
505 if (*domain_name == NULL) {
506 return false;
509 become_root();
510 result = pdb_lookup_rids(domain_sid, num_rids, rids,
511 *names, *types);
512 unbecome_root();
514 return (NT_STATUS_IS_OK(result) ||
515 NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
516 NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
519 if (sid_check_is_builtin(domain_sid)) {
521 if (*domain_name == NULL) {
522 *domain_name = talloc_strdup(
523 mem_ctx, builtin_domain_name());
526 if (*domain_name == NULL) {
527 return false;
530 for (i=0; i<num_rids; i++) {
531 if (lookup_builtin_rid(*names, rids[i],
532 &(*names)[i])) {
533 if ((*names)[i] == NULL) {
534 return false;
536 (*types)[i] = SID_NAME_ALIAS;
537 } else {
538 (*types)[i] = SID_NAME_UNKNOWN;
541 return true;
544 if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
545 for (i=0; i<num_rids; i++) {
546 struct dom_sid sid;
547 sid_compose(&sid, domain_sid, rids[i]);
548 if (lookup_wellknown_sid(mem_ctx, &sid,
549 domain_name, &(*names)[i])) {
550 if ((*names)[i] == NULL) {
551 return false;
553 (*types)[i] = SID_NAME_WKN_GRP;
554 } else {
555 (*types)[i] = SID_NAME_UNKNOWN;
558 return true;
561 if (sid_check_is_unix_users(domain_sid)) {
562 if (*domain_name == NULL) {
563 *domain_name = talloc_strdup(
564 mem_ctx, unix_users_domain_name());
565 if (*domain_name == NULL) {
566 return false;
569 for (i=0; i<num_rids; i++) {
570 (*names)[i] = talloc_strdup(
571 (*names), uidtoname(rids[i]));
572 if ((*names)[i] == NULL) {
573 return false;
575 (*types)[i] = SID_NAME_USER;
577 return true;
580 if (sid_check_is_unix_groups(domain_sid)) {
581 if (*domain_name == NULL) {
582 *domain_name = talloc_strdup(
583 mem_ctx, unix_groups_domain_name());
584 if (*domain_name == NULL) {
585 return false;
588 for (i=0; i<num_rids; i++) {
589 (*names)[i] = talloc_strdup(
590 (*names), gidtoname(rids[i]));
591 if ((*names)[i] == NULL) {
592 return false;
594 (*types)[i] = SID_NAME_DOM_GRP;
596 return true;
599 return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
600 domain_name, *names, *types);
604 * Is the SID a domain as such? If yes, lookup its name.
607 static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
608 const char **name)
610 const char *tmp;
611 enum lsa_SidType type;
613 if (sid_check_is_domain(sid)) {
614 *name = talloc_strdup(mem_ctx, get_global_sam_name());
615 return true;
618 if (sid_check_is_builtin(sid)) {
619 *name = talloc_strdup(mem_ctx, builtin_domain_name());
620 return true;
623 if (sid_check_is_wellknown_domain(sid, &tmp)) {
624 *name = talloc_strdup(mem_ctx, tmp);
625 return true;
628 if (sid_check_is_unix_users(sid)) {
629 *name = talloc_strdup(mem_ctx, unix_users_domain_name());
630 return true;
633 if (sid_check_is_unix_groups(sid)) {
634 *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
635 return true;
638 if (sid->num_auths != 4) {
639 /* This can't be a domain */
640 return false;
643 if (IS_DC) {
644 uint32 i, num_domains;
645 struct trustdom_info **domains;
647 /* This is relatively expensive, but it happens only on DCs
648 * and for SIDs that have 4 sub-authorities and thus look like
649 * domains */
651 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
652 &num_domains,
653 &domains))) {
654 return false;
657 for (i=0; i<num_domains; i++) {
658 if (sid_equal(sid, &domains[i]->sid)) {
659 *name = talloc_strdup(mem_ctx,
660 domains[i]->name);
661 return true;
664 return false;
667 if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
668 (type == SID_NAME_DOMAIN)) {
669 *name = tmp;
670 return true;
673 return false;
677 * This tries to implement the rather weird rules for the lsa_lookup level
678 * parameter.
680 * This is as close as we can get to what W2k3 does. With this we survive the
681 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
682 * different, but I assume that's just being too liberal. For example, W2k3
683 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
684 * whereas NT4 does the same as level 1 (I think). I did not fully test that
685 * with NT4, this is what w2k3 does.
687 * Level 1: Ask everywhere
688 * Level 2: Ask domain and trusted domains, no builtin and wkn
689 * Level 3: Only ask domain
690 * Level 4: W2k3ad: Only ask AD trusts
691 * Level 5: Only ask transitive forest trusts
692 * Level 6: Like 4
695 static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
697 int ret = false;
699 switch(level) {
700 case 1:
701 ret = true;
702 break;
703 case 2:
704 ret = (!sid_check_is_builtin(sid) &&
705 !sid_check_is_wellknown_domain(sid, NULL));
706 break;
707 case 3:
708 case 4:
709 case 6:
710 ret = sid_check_is_domain(sid);
711 break;
712 case 5:
713 ret = false;
714 break;
717 DEBUG(10, ("%s SID %s in level %d\n",
718 ret ? "Accepting" : "Rejecting",
719 sid_string_dbg(sid), level));
720 return ret;
724 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
725 * references to domains, it is explicitly made for this.
727 * This attempts to be as efficient as possible: It collects all SIDs
728 * belonging to a domain and hands them in bulk to the appropriate lookup
729 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
730 * *hugely* from this. Winbind is going to be extended with a lookup_rids
731 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
732 * appropriate DC.
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)
740 TALLOC_CTX *tmp_ctx;
741 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
742 struct lsa_name_info *name_infos;
743 struct lsa_dom_info *dom_infos = NULL;
745 int i, j;
747 if (!(tmp_ctx = talloc_new(mem_ctx))) {
748 DEBUG(0, ("talloc_new failed\n"));
749 return NT_STATUS_NO_MEMORY;
752 if (num_sids) {
753 name_infos = TALLOC_ARRAY(mem_ctx, struct lsa_name_info, num_sids);
754 if (name_infos == NULL) {
755 result = NT_STATUS_NO_MEMORY;
756 goto fail;
758 } else {
759 name_infos = NULL;
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;
766 goto fail;
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
773 * in bulk.
775 * name_infos is a shadow-copy of the SIDs array to collect the real
776 * data.
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++) {
784 struct dom_sid sid;
785 uint32_t rid = 0;
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
794 * domains.
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;
801 goto fail;
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
810 * and name here */
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;
815 goto fail;
818 } else {
819 /* This is a normal SID with rid component */
820 if (!sid_split_rid(&sid, &rid)) {
821 result = NT_STATUS_INVALID_SID;
822 goto fail;
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;
830 continue;
833 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
834 if (!dom_infos[j].valid) {
835 break;
837 if (sid_equal(&sid, &dom_infos[j].sid)) {
838 break;
842 if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
843 /* TODO: What's the right error message here? */
844 result = NT_STATUS_NONE_MAPPED;
845 goto fail;
848 if (!dom_infos[j].valid) {
849 /* We found a domain not yet referenced, create a new
850 * ref. */
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 */
857 dom_infos[j].name =
858 talloc_strdup(dom_infos, domain_name);
859 if (dom_infos[j].name == NULL) {
860 result = NT_STATUS_NO_MEMORY;
861 goto fail;
863 } else {
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;
879 goto fail;
884 /* Iterate over the domains found */
886 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
887 uint32_t *rids;
888 const char *domain_name = NULL;
889 const char **names;
890 enum lsa_SidType *types;
891 struct lsa_dom_info *dom = &dom_infos[i];
893 if (!dom->valid) {
894 /* No domains left, we're done */
895 break;
898 if (dom->num_idxs) {
899 if (!(rids = TALLOC_ARRAY(tmp_ctx, uint32, dom->num_idxs))) {
900 result = NT_STATUS_NO_MEMORY;
901 goto fail;
903 } else {
904 rids = NULL;
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,
913 &names, &types)) {
914 result = NT_STATUS_NO_MEMORY;
915 goto fail;
918 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
919 result = NT_STATUS_NO_MEMORY;
920 goto fail;
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;
931 goto fail;
933 } else {
934 name_infos[idx].name = NULL;
939 *ret_domains = dom_infos;
940 *ret_names = name_infos;
941 TALLOC_FREE(tmp_ctx);
942 return NT_STATUS_OK;
944 fail:
945 TALLOC_FREE(dom_infos);
946 TALLOC_FREE(name_infos);
947 TALLOC_FREE(tmp_ctx);
948 return result;
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;
961 TALLOC_CTX *tmp_ctx;
962 bool ret = false;
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"));
968 return false;
971 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
972 &domain, &name))) {
973 goto done;
976 if (name->type == SID_NAME_UNKNOWN) {
977 goto done;
980 if ((ret_domain != NULL) &&
981 !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
982 goto done;
985 if ((ret_name != NULL) &&
986 !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
987 goto done;
990 if (ret_type != NULL) {
991 *ret_type = name->type;
994 ret = true;
996 done:
997 if (ret) {
998 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid),
999 domain->name, name->name, name->type));
1000 } else {
1001 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid)));
1003 TALLOC_FREE(tmp_ctx);
1004 return ret;
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)),
1025 &cache_value)) {
1026 return false;
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));
1033 return true;
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)),
1046 &cache_value)) {
1047 return false;
1050 SMB_ASSERT(cache_value.length == sizeof(*puid));
1051 memcpy(puid, cache_value.data, sizeof(*puid));
1053 return true;
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)),
1080 &cache_value)) {
1081 return false;
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));
1088 return true;
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)),
1101 &cache_value)) {
1102 return false;
1105 SMB_ASSERT(cache_value.length == sizeof(*pgid));
1106 memcpy(pgid, cache_value.data, sizeof(*pgid));
1108 return true;
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)
1131 bool ret;
1133 ZERO_STRUCTP(psid);
1135 become_root();
1136 ret = pdb_uid_to_sid(uid, psid);
1137 unbecome_root();
1139 if (ret) {
1140 /* This is a mapped user */
1141 goto done;
1144 /* This is an unmapped user */
1146 uid_to_unix_users_sid(uid, psid);
1148 done:
1149 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid,
1150 sid_string_dbg(psid)));
1152 store_uid_sid_cache(psid, uid);
1153 return;
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)
1162 bool ret;
1164 ZERO_STRUCTP(psid);
1166 become_root();
1167 ret = pdb_gid_to_sid(gid, psid);
1168 unbecome_root();
1170 if (ret) {
1171 /* This is a mapped group */
1172 goto done;
1175 /* This is an unmapped group */
1177 gid_to_unix_groups_sid(gid, psid);
1179 done:
1180 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid,
1181 sid_string_dbg(psid)));
1183 store_gid_sid_cache(psid, gid);
1184 return;
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)) {
1196 union unid_t id;
1197 bool ret;
1199 become_root();
1200 ret = pdb_sid_to_id(psid, &id, &type);
1201 unbecome_root();
1203 if (ret) {
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)));
1208 return false;
1210 *puid = id.uid;
1211 goto done;
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)));
1219 return false;
1221 done:
1222 DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_dbg(psid),
1223 (unsigned int)*puid ));
1225 store_uid_sid_cache(psid, *puid);
1226 return true;
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)
1236 GROUP_MAP map;
1237 union unid_t id;
1238 enum lsa_SidType type;
1240 if ((sid_check_is_in_builtin(psid) ||
1241 sid_check_is_in_wellknown_domain(psid))) {
1242 bool ret;
1244 become_root();
1245 ret = pdb_getgrsid(&map, *psid);
1246 unbecome_root();
1248 if (ret) {
1249 *pgid = map.gid;
1250 goto done;
1252 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1253 sid_string_dbg(psid)));
1254 return false;
1257 if (sid_check_is_in_our_domain(psid)) {
1258 bool ret;
1260 become_root();
1261 ret = pdb_sid_to_id(psid, &id, &type);
1262 unbecome_root();
1264 if (ret) {
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)));
1270 return false;
1272 *pgid = id.gid;
1273 goto done;
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)));
1281 return false;
1283 done:
1284 DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid),
1285 (unsigned int)*pgid ));
1287 store_gid_sid_cache(psid, *pgid);
1289 return true;
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;
1299 bool ret;
1300 ZERO_STRUCTP(psid);
1302 if (fetch_sid_from_uid_cache(psid, uid))
1303 return;
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.
1311 * do legacy.
1313 legacy_uid_to_sid(psid, uid);
1314 return;
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);
1334 return;
1338 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid,
1339 sid_string_dbg(psid)));
1341 store_uid_sid_cache(psid, uid);
1342 return;
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;
1352 bool ret;
1353 ZERO_STRUCTP(psid);
1355 if (fetch_sid_from_gid_cache(psid, gid))
1356 return;
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.
1364 * do legacy.
1366 legacy_gid_to_sid(psid, gid);
1367 return;
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);
1387 return;
1391 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid,
1392 sid_string_dbg(psid)));
1394 store_gid_sid_cache(psid, gid);
1395 return;
1398 /*****************************************************************
1399 *THE CANONICAL* convert SID to uid function.
1400 *****************************************************************/
1402 bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1404 bool expired = true;
1405 bool ret;
1406 uint32 rid;
1407 gid_t gid;
1409 if (fetch_uid_from_cache(puid, psid))
1410 return true;
1412 if (fetch_gid_from_cache(&gid, psid)) {
1413 return false;
1416 /* Optimize for the Unix Users Domain
1417 * as the conversion is straightforward */
1418 if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1419 uid_t uid = rid;
1420 *puid = uid;
1422 /* return here, don't cache */
1423 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1424 (unsigned int)*puid ));
1425 return true;
1428 /* Check the winbindd cache directly. */
1429 ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1431 if (ret && !expired && (*puid == (uid_t)-1)) {
1433 * Negative cache entry, we already asked.
1434 * do legacy.
1436 return legacy_sid_to_uid(psid, puid);
1439 if (!ret || expired) {
1440 /* Not in cache. Ask winbindd. */
1441 if (!winbind_sid_to_uid(puid, psid)) {
1442 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1443 sid_string_dbg(psid)));
1444 /* winbind failed. do legacy */
1445 return legacy_sid_to_uid(psid, puid);
1449 /* TODO: Here would be the place to allocate both a gid and a uid for
1450 * the SID in question */
1452 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1453 (unsigned int)*puid ));
1455 store_uid_sid_cache(psid, *puid);
1456 return true;
1459 /*****************************************************************
1460 *THE CANONICAL* convert SID to gid function.
1461 Group mapping is used for gids that maps to Wellknown SIDs
1462 *****************************************************************/
1464 bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1466 bool expired = true;
1467 bool ret;
1468 uint32 rid;
1469 uid_t uid;
1471 if (fetch_gid_from_cache(pgid, psid))
1472 return true;
1474 if (fetch_uid_from_cache(&uid, psid))
1475 return false;
1477 /* Optimize for the Unix Groups Domain
1478 * as the conversion is straightforward */
1479 if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1480 gid_t gid = rid;
1481 *pgid = gid;
1483 /* return here, don't cache */
1484 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1485 (unsigned int)*pgid ));
1486 return true;
1489 /* Check the winbindd cache directly. */
1490 ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1492 if (ret && !expired && (*pgid == (gid_t)-1)) {
1494 * Negative cache entry, we already asked.
1495 * do legacy.
1497 return legacy_sid_to_gid(psid, pgid);
1500 if (!ret || expired) {
1501 /* Not in cache or negative. Ask winbindd. */
1502 /* Ask winbindd if it can map this sid to a gid.
1503 * (Idmap will check it is a valid SID and of the right type) */
1505 if ( !winbind_sid_to_gid(pgid, psid) ) {
1507 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1508 sid_string_dbg(psid)));
1509 /* winbind failed. do legacy */
1510 return legacy_sid_to_gid(psid, pgid);
1514 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1515 (unsigned int)*pgid ));
1517 store_gid_sid_cache(psid, *pgid);
1518 return true;
1522 * @brief This function gets the primary group SID mapping the primary
1523 * GID of the user as obtained by an actual getpwnam() call.
1524 * This is necessary to avoid issues with arbitrary group SIDs
1525 * stored in passdb. We try as hard as we can to get the SID
1526 * corresponding to the GID, including trying group mapping.
1527 * If nothing else works, we will force "Domain Users" as the
1528 * primary group.
1529 * This is needed because we must always be able to lookup the
1530 * primary group SID, so we cannot settle for an arbitrary SID.
1532 * This call can be expensive. Use with moderation.
1533 * If you have a "samu" struct around use pdb_get_group_sid()
1534 * instead as it does properly cache results.
1536 * @param mem_ctx[in] The memory context iused to allocate the result.
1537 * @param username[in] The user's name
1538 * @param _pwd[in|out] If available, pass in user's passwd struct.
1539 * It will contain a tallocated passwd if NULL was
1540 * passed in.
1541 * @param _group_sid[out] The user's Primary Group SID
1543 * @return NTSTATUS error code.
1545 NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1546 const char *username,
1547 struct passwd **_pwd,
1548 struct dom_sid **_group_sid)
1550 TALLOC_CTX *tmp_ctx;
1551 bool need_lookup_sid = false;
1552 struct dom_sid *group_sid;
1553 struct passwd *pwd = *_pwd;
1555 tmp_ctx = talloc_new(mem_ctx);
1556 if (!tmp_ctx) {
1557 return NT_STATUS_NO_MEMORY;
1560 if (!pwd) {
1561 pwd = Get_Pwnam_alloc(mem_ctx, username);
1562 if (!pwd) {
1563 DEBUG(0, ("Failed to find a Unix account for %s",
1564 username));
1565 TALLOC_FREE(tmp_ctx);
1566 return NT_STATUS_NO_SUCH_USER;
1570 group_sid = talloc_zero(mem_ctx, struct dom_sid);
1571 if (!group_sid) {
1572 TALLOC_FREE(tmp_ctx);
1573 return NT_STATUS_NO_MEMORY;
1576 gid_to_sid(group_sid, pwd->pw_gid);
1577 if (!is_null_sid(group_sid)) {
1578 struct dom_sid domain_sid;
1579 uint32_t rid;
1581 /* We need a sid within our domain */
1582 sid_copy(&domain_sid, group_sid);
1583 sid_split_rid(&domain_sid, &rid);
1584 if (sid_equal(&domain_sid, get_global_sam_sid())) {
1586 * As shortcut for the expensive lookup_sid call
1587 * compare the domain sid part
1589 switch (rid) {
1590 case DOMAIN_RID_ADMINS:
1591 case DOMAIN_RID_USERS:
1592 goto done;
1593 default:
1594 need_lookup_sid = true;
1595 break;
1597 } else {
1598 /* Try group mapping */
1599 ZERO_STRUCTP(group_sid);
1600 if (pdb_gid_to_sid(pwd->pw_gid, group_sid)) {
1601 need_lookup_sid = true;
1606 /* We must verify that this is a valid SID that resolves to a
1607 * group of the correct type */
1608 if (need_lookup_sid) {
1609 enum lsa_SidType type = SID_NAME_UNKNOWN;
1610 bool lookup_ret;
1612 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1613 sid_string_dbg(group_sid), username));
1615 /* Now check that it's actually a domain group and
1616 * not something else */
1617 lookup_ret = lookup_sid(tmp_ctx, group_sid,
1618 NULL, NULL, &type);
1620 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1621 goto done;
1624 DEBUG(3, ("Primary group %s for user %s is"
1625 " a %s and not a domain group\n",
1626 sid_string_dbg(group_sid), username,
1627 sid_type_lookup(type)));
1630 /* Everything else, failed.
1631 * Just set it to the 'Domain Users' RID of 513 which will
1632 always resolve to a name */
1633 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1634 username));
1636 sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1638 done:
1639 *_pwd = talloc_move(mem_ctx, &pwd);
1640 *_group_sid = talloc_move(mem_ctx, &group_sid);
1641 TALLOC_FREE(tmp_ctx);
1642 return NT_STATUS_OK;