s3: Lift the server_messaging_context from notify_job_status
[Samba/gbeck.git] / source3 / passdb / lookup_sid.c
blob0ec1f420f92c94e1ee6cd8767545ee722177fb91
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"
26 /*****************************************************************
27 Dissect a user-provided name into domain, name, sid and type.
29 If an explicit domain name was given in the form domain\user, it
30 has to try that. If no explicit domain name was given, we have
31 to do guesswork.
32 *****************************************************************/
34 bool lookup_name(TALLOC_CTX *mem_ctx,
35 const char *full_name, int flags,
36 const char **ret_domain, const char **ret_name,
37 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
39 char *p;
40 const char *tmp;
41 const char *domain = NULL;
42 const char *name = NULL;
43 uint32 rid;
44 struct dom_sid sid;
45 enum lsa_SidType type;
46 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
48 if (tmp_ctx == NULL) {
49 DEBUG(0, ("talloc_new failed\n"));
50 return false;
53 p = strchr_m(full_name, '\\');
55 if (p != NULL) {
56 domain = talloc_strndup(tmp_ctx, full_name,
57 PTR_DIFF(p, full_name));
58 name = talloc_strdup(tmp_ctx, p+1);
59 } else {
60 domain = talloc_strdup(tmp_ctx, "");
61 name = talloc_strdup(tmp_ctx, full_name);
64 if ((domain == NULL) || (name == NULL)) {
65 DEBUG(0, ("talloc failed\n"));
66 TALLOC_FREE(tmp_ctx);
67 return false;
70 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
71 full_name, domain, name));
72 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
74 if ((flags & LOOKUP_NAME_DOMAIN) &&
75 strequal(domain, get_global_sam_name()))
78 /* It's our own domain, lookup the name in passdb */
79 if (lookup_global_sam_name(name, flags, &rid, &type)) {
80 sid_compose(&sid, get_global_sam_sid(), rid);
81 goto ok;
83 TALLOC_FREE(tmp_ctx);
84 return false;
87 if ((flags & LOOKUP_NAME_BUILTIN) &&
88 strequal(domain, builtin_domain_name()))
90 if (strlen(name) == 0) {
91 /* Swap domain and name */
92 tmp = name; name = domain; domain = tmp;
93 sid_copy(&sid, &global_sid_Builtin);
94 type = SID_NAME_DOMAIN;
95 goto ok;
98 /* Explicit request for a name in BUILTIN */
99 if (lookup_builtin_name(name, &rid)) {
100 sid_compose(&sid, &global_sid_Builtin, rid);
101 type = SID_NAME_ALIAS;
102 goto ok;
104 TALLOC_FREE(tmp_ctx);
105 return false;
108 /* Try the explicit winbind lookup first, don't let it guess the
109 * domain yet at this point yet. This comes later. */
111 if ((domain[0] != '\0') &&
112 (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
113 (winbind_lookup_name(domain, name, &sid, &type))) {
114 goto ok;
117 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
118 && strequal(domain, unix_users_domain_name())) {
119 if (lookup_unix_user_name(name, &sid)) {
120 type = SID_NAME_USER;
121 goto ok;
123 TALLOC_FREE(tmp_ctx);
124 return false;
127 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
128 && strequal(domain, unix_groups_domain_name())) {
129 if (lookup_unix_group_name(name, &sid)) {
130 type = SID_NAME_DOM_GRP;
131 goto ok;
133 TALLOC_FREE(tmp_ctx);
134 return false;
137 if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
138 TALLOC_FREE(tmp_ctx);
139 return false;
142 /* Now the guesswork begins, we haven't been given an explicit
143 * domain. Try the sequence as documented on
144 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
145 * November 27, 2005 */
147 /* 1. well-known names */
149 if ((flags & LOOKUP_NAME_WKN) &&
150 lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
152 type = SID_NAME_WKN_GRP;
153 goto ok;
156 /* 2. Builtin domain as such */
158 if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
159 strequal(name, builtin_domain_name()))
161 /* Swap domain and name */
162 tmp = name; name = domain; domain = tmp;
163 sid_copy(&sid, &global_sid_Builtin);
164 type = SID_NAME_DOMAIN;
165 goto ok;
168 /* 3. Account domain */
170 if ((flags & LOOKUP_NAME_DOMAIN) &&
171 strequal(name, get_global_sam_name()))
173 if (!secrets_fetch_domain_sid(name, &sid)) {
174 DEBUG(3, ("Could not fetch my SID\n"));
175 TALLOC_FREE(tmp_ctx);
176 return false;
178 /* Swap domain and name */
179 tmp = name; name = domain; domain = tmp;
180 type = SID_NAME_DOMAIN;
181 goto ok;
184 /* 4. Primary domain */
186 if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
187 strequal(name, lp_workgroup()))
189 if (!secrets_fetch_domain_sid(name, &sid)) {
190 DEBUG(3, ("Could not fetch the domain SID\n"));
191 TALLOC_FREE(tmp_ctx);
192 return false;
194 /* Swap domain and name */
195 tmp = name; name = domain; domain = tmp;
196 type = SID_NAME_DOMAIN;
197 goto ok;
200 /* 5. Trusted domains as such, to me it looks as if members don't do
201 this, tested an XP workstation in a NT domain -- vl */
203 if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
204 (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
206 /* Swap domain and name */
207 tmp = name; name = domain; domain = tmp;
208 type = SID_NAME_DOMAIN;
209 goto ok;
212 /* 6. Builtin aliases */
214 if ((flags & LOOKUP_NAME_BUILTIN) &&
215 lookup_builtin_name(name, &rid))
217 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
218 sid_compose(&sid, &global_sid_Builtin, rid);
219 type = SID_NAME_ALIAS;
220 goto ok;
223 /* 7. Local systems' SAM (DCs don't have a local SAM) */
224 /* 8. Primary SAM (On members, this is the domain) */
226 /* Both cases are done by looking at our passdb */
228 if ((flags & LOOKUP_NAME_DOMAIN) &&
229 lookup_global_sam_name(name, flags, &rid, &type))
231 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
232 sid_compose(&sid, get_global_sam_sid(), rid);
233 goto ok;
236 /* Now our local possibilities are exhausted. */
238 if (!(flags & LOOKUP_NAME_REMOTE)) {
239 TALLOC_FREE(tmp_ctx);
240 return false;
243 /* If we are not a DC, we have to ask in our primary domain. Let
244 * winbind do that. */
246 if (!IS_DC &&
247 (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
248 domain = talloc_strdup(tmp_ctx, lp_workgroup());
249 goto ok;
252 /* 9. Trusted domains */
254 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
255 * that (yet), but give it a chance. */
257 if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
258 struct dom_sid dom_sid;
259 uint32 tmp_rid;
260 enum lsa_SidType domain_type;
262 if (type == SID_NAME_DOMAIN) {
263 /* Swap name and type */
264 tmp = name; name = domain; domain = tmp;
265 goto ok;
268 /* Here we have to cope with a little deficiency in the
269 * winbind API: We have to ask it again for the name of the
270 * domain it figured out itself. Maybe fix that later... */
272 sid_copy(&dom_sid, &sid);
273 sid_split_rid(&dom_sid, &tmp_rid);
275 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
276 &domain_type) ||
277 (domain_type != SID_NAME_DOMAIN)) {
278 DEBUG(2, ("winbind could not find the domain's name "
279 "it just looked up for us\n"));
280 TALLOC_FREE(tmp_ctx);
281 return false;
283 goto ok;
286 /* 10. Don't translate */
288 /* 11. Ok, windows would end here. Samba has two more options:
289 Unmapped users and unmapped groups */
291 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
292 && lookup_unix_user_name(name, &sid)) {
293 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
294 type = SID_NAME_USER;
295 goto ok;
298 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
299 && lookup_unix_group_name(name, &sid)) {
300 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
301 type = SID_NAME_DOM_GRP;
302 goto ok;
306 * Ok, all possibilities tried. Fail.
309 TALLOC_FREE(tmp_ctx);
310 return false;
313 if ((domain == NULL) || (name == NULL)) {
314 DEBUG(0, ("talloc failed\n"));
315 TALLOC_FREE(tmp_ctx);
316 return false;
320 * Hand over the results to the talloc context we've been given.
323 if ((ret_name != NULL) &&
324 !(*ret_name = talloc_strdup(mem_ctx, name))) {
325 DEBUG(0, ("talloc failed\n"));
326 TALLOC_FREE(tmp_ctx);
327 return false;
330 if (ret_domain != NULL) {
331 char *tmp_dom;
332 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
333 DEBUG(0, ("talloc failed\n"));
334 TALLOC_FREE(tmp_ctx);
335 return false;
337 strupper_m(tmp_dom);
338 *ret_domain = tmp_dom;
341 if (ret_sid != NULL) {
342 sid_copy(ret_sid, &sid);
345 if (ret_type != NULL) {
346 *ret_type = type;
349 TALLOC_FREE(tmp_ctx);
350 return true;
353 /************************************************************************
354 Names from smb.conf can be unqualified. eg. valid users = foo
355 These names should never map to a remote name. Try global_sam_name()\foo,
356 and then "Unix Users"\foo (or "Unix Groups"\foo).
357 ************************************************************************/
359 bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
360 const char *full_name, int flags,
361 const char **ret_domain, const char **ret_name,
362 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
364 char *qualified_name;
365 const char *p;
367 /* NB. No winbindd_separator here as lookup_name needs \\' */
368 if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
370 /* The name is already qualified with a domain. */
372 if (*lp_winbind_separator() != '\\') {
373 char *tmp;
375 /* lookup_name() needs '\\' as a separator */
377 tmp = talloc_strdup(mem_ctx, full_name);
378 if (!tmp) {
379 return false;
381 tmp[p - full_name] = '\\';
382 full_name = tmp;
385 return lookup_name(mem_ctx, full_name, flags,
386 ret_domain, ret_name,
387 ret_sid, ret_type);
390 /* Try with our own SAM name. */
391 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
392 get_global_sam_name(),
393 full_name );
394 if (!qualified_name) {
395 return false;
398 if (lookup_name(mem_ctx, qualified_name, flags,
399 ret_domain, ret_name,
400 ret_sid, ret_type)) {
401 return true;
404 /* Finally try with "Unix Users" or "Unix Group" */
405 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
406 flags & LOOKUP_NAME_GROUP ?
407 unix_groups_domain_name() :
408 unix_users_domain_name(),
409 full_name );
410 if (!qualified_name) {
411 return false;
414 return lookup_name(mem_ctx, qualified_name, flags,
415 ret_domain, ret_name,
416 ret_sid, ret_type);
419 static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
420 const struct dom_sid *domain_sid,
421 int num_rids, uint32 *rids,
422 const char **domain_name,
423 const char **names, enum lsa_SidType *types)
425 int i;
426 const char **my_names;
427 enum lsa_SidType *my_types;
428 TALLOC_CTX *tmp_ctx;
430 if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
431 return false;
434 if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
435 domain_name, &my_names, &my_types)) {
436 *domain_name = "";
437 for (i=0; i<num_rids; i++) {
438 names[i] = "";
439 types[i] = SID_NAME_UNKNOWN;
441 TALLOC_FREE(tmp_ctx);
442 return true;
445 if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
446 TALLOC_FREE(tmp_ctx);
447 return false;
451 * winbind_lookup_rids allocates its own array. We've been given the
452 * array, so copy it over
455 for (i=0; i<num_rids; i++) {
456 if (my_names[i] == NULL) {
457 TALLOC_FREE(tmp_ctx);
458 return false;
460 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
461 TALLOC_FREE(tmp_ctx);
462 return false;
464 types[i] = my_types[i];
466 TALLOC_FREE(tmp_ctx);
467 return true;
470 static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
471 int num_rids, uint32_t *rids,
472 const char **domain_name,
473 const char ***names, enum lsa_SidType **types)
475 int i;
477 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
478 sid_string_dbg(domain_sid)));
480 if (num_rids) {
481 *names = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
482 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
484 if ((*names == NULL) || (*types == NULL)) {
485 return false;
488 for (i = 0; i < num_rids; i++)
489 (*types)[i] = SID_NAME_UNKNOWN;
490 } else {
491 *names = NULL;
492 *types = NULL;
495 if (sid_check_is_domain(domain_sid)) {
496 NTSTATUS result;
498 if (*domain_name == NULL) {
499 *domain_name = talloc_strdup(
500 mem_ctx, get_global_sam_name());
503 if (*domain_name == NULL) {
504 return false;
507 become_root();
508 result = pdb_lookup_rids(domain_sid, num_rids, rids,
509 *names, *types);
510 unbecome_root();
512 return (NT_STATUS_IS_OK(result) ||
513 NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
514 NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
517 if (sid_check_is_builtin(domain_sid)) {
519 if (*domain_name == NULL) {
520 *domain_name = talloc_strdup(
521 mem_ctx, builtin_domain_name());
524 if (*domain_name == NULL) {
525 return false;
528 for (i=0; i<num_rids; i++) {
529 if (lookup_builtin_rid(*names, rids[i],
530 &(*names)[i])) {
531 if ((*names)[i] == NULL) {
532 return false;
534 (*types)[i] = SID_NAME_ALIAS;
535 } else {
536 (*types)[i] = SID_NAME_UNKNOWN;
539 return true;
542 if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
543 for (i=0; i<num_rids; i++) {
544 struct dom_sid sid;
545 sid_compose(&sid, domain_sid, rids[i]);
546 if (lookup_wellknown_sid(mem_ctx, &sid,
547 domain_name, &(*names)[i])) {
548 if ((*names)[i] == NULL) {
549 return false;
551 (*types)[i] = SID_NAME_WKN_GRP;
552 } else {
553 (*types)[i] = SID_NAME_UNKNOWN;
556 return true;
559 if (sid_check_is_unix_users(domain_sid)) {
560 if (*domain_name == NULL) {
561 *domain_name = talloc_strdup(
562 mem_ctx, unix_users_domain_name());
563 if (*domain_name == NULL) {
564 return false;
567 for (i=0; i<num_rids; i++) {
568 (*names)[i] = talloc_strdup(
569 (*names), uidtoname(rids[i]));
570 if ((*names)[i] == NULL) {
571 return false;
573 (*types)[i] = SID_NAME_USER;
575 return true;
578 if (sid_check_is_unix_groups(domain_sid)) {
579 if (*domain_name == NULL) {
580 *domain_name = talloc_strdup(
581 mem_ctx, unix_groups_domain_name());
582 if (*domain_name == NULL) {
583 return false;
586 for (i=0; i<num_rids; i++) {
587 (*names)[i] = talloc_strdup(
588 (*names), gidtoname(rids[i]));
589 if ((*names)[i] == NULL) {
590 return false;
592 (*types)[i] = SID_NAME_DOM_GRP;
594 return true;
597 return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
598 domain_name, *names, *types);
602 * Is the SID a domain as such? If yes, lookup its name.
605 static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
606 const char **name)
608 const char *tmp;
609 enum lsa_SidType type;
611 if (sid_check_is_domain(sid)) {
612 *name = talloc_strdup(mem_ctx, get_global_sam_name());
613 return true;
616 if (sid_check_is_builtin(sid)) {
617 *name = talloc_strdup(mem_ctx, builtin_domain_name());
618 return true;
621 if (sid_check_is_wellknown_domain(sid, &tmp)) {
622 *name = talloc_strdup(mem_ctx, tmp);
623 return true;
626 if (sid_check_is_unix_users(sid)) {
627 *name = talloc_strdup(mem_ctx, unix_users_domain_name());
628 return true;
631 if (sid_check_is_unix_groups(sid)) {
632 *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
633 return true;
636 if (sid->num_auths != 4) {
637 /* This can't be a domain */
638 return false;
641 if (IS_DC) {
642 uint32 i, num_domains;
643 struct trustdom_info **domains;
645 /* This is relatively expensive, but it happens only on DCs
646 * and for SIDs that have 4 sub-authorities and thus look like
647 * domains */
649 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
650 &num_domains,
651 &domains))) {
652 return false;
655 for (i=0; i<num_domains; i++) {
656 if (sid_equal(sid, &domains[i]->sid)) {
657 *name = talloc_strdup(mem_ctx,
658 domains[i]->name);
659 return true;
662 return false;
665 if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
666 (type == SID_NAME_DOMAIN)) {
667 *name = tmp;
668 return true;
671 return false;
675 * This tries to implement the rather weird rules for the lsa_lookup level
676 * parameter.
678 * This is as close as we can get to what W2k3 does. With this we survive the
679 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
680 * different, but I assume that's just being too liberal. For example, W2k3
681 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
682 * whereas NT4 does the same as level 1 (I think). I did not fully test that
683 * with NT4, this is what w2k3 does.
685 * Level 1: Ask everywhere
686 * Level 2: Ask domain and trusted domains, no builtin and wkn
687 * Level 3: Only ask domain
688 * Level 4: W2k3ad: Only ask AD trusts
689 * Level 5: Only ask transitive forest trusts
690 * Level 6: Like 4
693 static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
695 int ret = false;
697 switch(level) {
698 case 1:
699 ret = true;
700 break;
701 case 2:
702 ret = (!sid_check_is_builtin(sid) &&
703 !sid_check_is_wellknown_domain(sid, NULL));
704 break;
705 case 3:
706 case 4:
707 case 6:
708 ret = sid_check_is_domain(sid);
709 break;
710 case 5:
711 ret = false;
712 break;
715 DEBUG(10, ("%s SID %s in level %d\n",
716 ret ? "Accepting" : "Rejecting",
717 sid_string_dbg(sid), level));
718 return ret;
722 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
723 * references to domains, it is explicitly made for this.
725 * This attempts to be as efficient as possible: It collects all SIDs
726 * belonging to a domain and hands them in bulk to the appropriate lookup
727 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
728 * *hugely* from this. Winbind is going to be extended with a lookup_rids
729 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
730 * appropriate DC.
733 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
734 const struct dom_sid **sids, int level,
735 struct lsa_dom_info **ret_domains,
736 struct lsa_name_info **ret_names)
738 TALLOC_CTX *tmp_ctx;
739 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
740 struct lsa_name_info *name_infos;
741 struct lsa_dom_info *dom_infos = NULL;
743 int i, j;
745 if (!(tmp_ctx = talloc_new(mem_ctx))) {
746 DEBUG(0, ("talloc_new failed\n"));
747 return NT_STATUS_NO_MEMORY;
750 if (num_sids) {
751 name_infos = TALLOC_ARRAY(mem_ctx, struct lsa_name_info, num_sids);
752 if (name_infos == NULL) {
753 result = NT_STATUS_NO_MEMORY;
754 goto fail;
756 } else {
757 name_infos = NULL;
760 dom_infos = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_dom_info,
761 LSA_REF_DOMAIN_LIST_MULTIPLIER);
762 if (dom_infos == NULL) {
763 result = NT_STATUS_NO_MEMORY;
764 goto fail;
767 /* First build up the data structures:
769 * dom_infos is a list of domains referenced in the list of
770 * SIDs. Later we will walk the list of domains and look up the RIDs
771 * in bulk.
773 * name_infos is a shadow-copy of the SIDs array to collect the real
774 * data.
776 * dom_info->idxs is an index into the name_infos array. The
777 * difficulty we have here is that we need to keep the SIDs the client
778 * asked for in the same order for the reply
781 for (i=0; i<num_sids; i++) {
782 struct dom_sid sid;
783 uint32_t rid = 0;
784 const char *domain_name = NULL;
786 sid_copy(&sid, sids[i]);
787 name_infos[i].type = SID_NAME_USE_NONE;
789 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
790 /* We can't push that through the normal lookup
791 * process, as this would reference illegal
792 * domains.
794 * For example S-1-5-32 would end up referencing
795 * domain S-1-5- with RID 32 which is clearly wrong.
797 if (domain_name == NULL) {
798 result = NT_STATUS_NO_MEMORY;
799 goto fail;
802 name_infos[i].rid = 0;
803 name_infos[i].type = SID_NAME_DOMAIN;
804 name_infos[i].name = NULL;
806 if (sid_check_is_builtin(&sid)) {
807 /* Yes, W2k3 returns "BUILTIN" both as domain
808 * and name here */
809 name_infos[i].name = talloc_strdup(
810 name_infos, builtin_domain_name());
811 if (name_infos[i].name == NULL) {
812 result = NT_STATUS_NO_MEMORY;
813 goto fail;
816 } else {
817 /* This is a normal SID with rid component */
818 if (!sid_split_rid(&sid, &rid)) {
819 result = NT_STATUS_INVALID_SID;
820 goto fail;
824 if (!check_dom_sid_to_level(&sid, level)) {
825 name_infos[i].rid = 0;
826 name_infos[i].type = SID_NAME_UNKNOWN;
827 name_infos[i].name = NULL;
828 continue;
831 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
832 if (!dom_infos[j].valid) {
833 break;
835 if (sid_equal(&sid, &dom_infos[j].sid)) {
836 break;
840 if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
841 /* TODO: What's the right error message here? */
842 result = NT_STATUS_NONE_MAPPED;
843 goto fail;
846 if (!dom_infos[j].valid) {
847 /* We found a domain not yet referenced, create a new
848 * ref. */
849 dom_infos[j].valid = true;
850 sid_copy(&dom_infos[j].sid, &sid);
852 if (domain_name != NULL) {
853 /* This name was being found above in the case
854 * when we found a domain SID */
855 dom_infos[j].name =
856 talloc_strdup(dom_infos, domain_name);
857 if (dom_infos[j].name == NULL) {
858 result = NT_STATUS_NO_MEMORY;
859 goto fail;
861 } else {
862 /* lookup_rids will take care of this */
863 dom_infos[j].name = NULL;
867 name_infos[i].dom_idx = j;
869 if (name_infos[i].type == SID_NAME_USE_NONE) {
870 name_infos[i].rid = rid;
872 ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
873 &dom_infos[j].num_idxs);
875 if (dom_infos[j].idxs == NULL) {
876 result = NT_STATUS_NO_MEMORY;
877 goto fail;
882 /* Iterate over the domains found */
884 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
885 uint32_t *rids;
886 const char *domain_name = NULL;
887 const char **names;
888 enum lsa_SidType *types;
889 struct lsa_dom_info *dom = &dom_infos[i];
891 if (!dom->valid) {
892 /* No domains left, we're done */
893 break;
896 if (dom->num_idxs) {
897 if (!(rids = TALLOC_ARRAY(tmp_ctx, uint32, dom->num_idxs))) {
898 result = NT_STATUS_NO_MEMORY;
899 goto fail;
901 } else {
902 rids = NULL;
905 for (j=0; j<dom->num_idxs; j++) {
906 rids[j] = name_infos[dom->idxs[j]].rid;
909 if (!lookup_rids(tmp_ctx, &dom->sid,
910 dom->num_idxs, rids, &domain_name,
911 &names, &types)) {
912 result = NT_STATUS_NO_MEMORY;
913 goto fail;
916 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
917 result = NT_STATUS_NO_MEMORY;
918 goto fail;
921 for (j=0; j<dom->num_idxs; j++) {
922 int idx = dom->idxs[j];
923 name_infos[idx].type = types[j];
924 if (types[j] != SID_NAME_UNKNOWN) {
925 name_infos[idx].name =
926 talloc_strdup(name_infos, names[j]);
927 if (name_infos[idx].name == NULL) {
928 result = NT_STATUS_NO_MEMORY;
929 goto fail;
931 } else {
932 name_infos[idx].name = NULL;
937 *ret_domains = dom_infos;
938 *ret_names = name_infos;
939 TALLOC_FREE(tmp_ctx);
940 return NT_STATUS_OK;
942 fail:
943 TALLOC_FREE(dom_infos);
944 TALLOC_FREE(name_infos);
945 TALLOC_FREE(tmp_ctx);
946 return result;
949 /*****************************************************************
950 *THE CANONICAL* convert SID to name function.
951 *****************************************************************/
953 bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
954 const char **ret_domain, const char **ret_name,
955 enum lsa_SidType *ret_type)
957 struct lsa_dom_info *domain;
958 struct lsa_name_info *name;
959 TALLOC_CTX *tmp_ctx;
960 bool ret = false;
962 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid)));
964 if (!(tmp_ctx = talloc_new(mem_ctx))) {
965 DEBUG(0, ("talloc_new failed\n"));
966 return false;
969 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
970 &domain, &name))) {
971 goto done;
974 if (name->type == SID_NAME_UNKNOWN) {
975 goto done;
978 if ((ret_domain != NULL) &&
979 !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
980 goto done;
983 if ((ret_name != NULL) &&
984 !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
985 goto done;
988 if (ret_type != NULL) {
989 *ret_type = name->type;
992 ret = true;
994 done:
995 if (ret) {
996 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid),
997 domain->name, name->name, name->type));
998 } else {
999 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid)));
1001 TALLOC_FREE(tmp_ctx);
1002 return ret;
1005 /*****************************************************************
1006 Id mapping cache. This is to avoid Winbind mappings already
1007 seen by smbd to be queried too frequently, keeping winbindd
1008 busy, and blocking smbd while winbindd is busy with other
1009 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1010 modified to use linked lists by jra.
1011 *****************************************************************/
1013 /*****************************************************************
1014 Find a SID given a uid.
1015 *****************************************************************/
1017 static bool fetch_sid_from_uid_cache(struct dom_sid *psid, uid_t uid)
1019 DATA_BLOB cache_value;
1021 if (!memcache_lookup(NULL, UID_SID_CACHE,
1022 data_blob_const(&uid, sizeof(uid)),
1023 &cache_value)) {
1024 return false;
1027 memcpy(psid, cache_value.data, MIN(sizeof(*psid), cache_value.length));
1028 SMB_ASSERT(cache_value.length >= offsetof(struct dom_sid, id_auth));
1029 SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, 0));
1031 return true;
1034 /*****************************************************************
1035 Find a uid given a SID.
1036 *****************************************************************/
1038 static bool fetch_uid_from_cache( uid_t *puid, const struct dom_sid *psid )
1040 DATA_BLOB cache_value;
1042 if (!memcache_lookup(NULL, SID_UID_CACHE,
1043 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1044 &cache_value)) {
1045 return false;
1048 SMB_ASSERT(cache_value.length == sizeof(*puid));
1049 memcpy(puid, cache_value.data, sizeof(*puid));
1051 return true;
1054 /*****************************************************************
1055 Store uid to SID mapping in cache.
1056 *****************************************************************/
1058 void store_uid_sid_cache(const struct dom_sid *psid, uid_t uid)
1060 memcache_add(NULL, SID_UID_CACHE,
1061 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1062 data_blob_const(&uid, sizeof(uid)));
1063 memcache_add(NULL, UID_SID_CACHE,
1064 data_blob_const(&uid, sizeof(uid)),
1065 data_blob_const(psid, ndr_size_dom_sid(psid, 0)));
1068 /*****************************************************************
1069 Find a SID given a gid.
1070 *****************************************************************/
1072 static bool fetch_sid_from_gid_cache(struct dom_sid *psid, gid_t gid)
1074 DATA_BLOB cache_value;
1076 if (!memcache_lookup(NULL, GID_SID_CACHE,
1077 data_blob_const(&gid, sizeof(gid)),
1078 &cache_value)) {
1079 return false;
1082 memcpy(psid, cache_value.data, MIN(sizeof(*psid), cache_value.length));
1083 SMB_ASSERT(cache_value.length >= offsetof(struct dom_sid, id_auth));
1084 SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, 0));
1086 return true;
1089 /*****************************************************************
1090 Find a gid given a SID.
1091 *****************************************************************/
1093 static bool fetch_gid_from_cache(gid_t *pgid, const struct dom_sid *psid)
1095 DATA_BLOB cache_value;
1097 if (!memcache_lookup(NULL, SID_GID_CACHE,
1098 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1099 &cache_value)) {
1100 return false;
1103 SMB_ASSERT(cache_value.length == sizeof(*pgid));
1104 memcpy(pgid, cache_value.data, sizeof(*pgid));
1106 return true;
1109 /*****************************************************************
1110 Store gid to SID mapping in cache.
1111 *****************************************************************/
1113 void store_gid_sid_cache(const struct dom_sid *psid, gid_t gid)
1115 memcache_add(NULL, SID_GID_CACHE,
1116 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1117 data_blob_const(&gid, sizeof(gid)));
1118 memcache_add(NULL, GID_SID_CACHE,
1119 data_blob_const(&gid, sizeof(gid)),
1120 data_blob_const(psid, ndr_size_dom_sid(psid, 0)));
1123 /*****************************************************************
1124 *THE LEGACY* convert uid_t to SID function.
1125 *****************************************************************/
1127 static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
1129 bool ret;
1131 ZERO_STRUCTP(psid);
1133 become_root();
1134 ret = pdb_uid_to_sid(uid, psid);
1135 unbecome_root();
1137 if (ret) {
1138 /* This is a mapped user */
1139 goto done;
1142 /* This is an unmapped user */
1144 uid_to_unix_users_sid(uid, psid);
1146 done:
1147 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid,
1148 sid_string_dbg(psid)));
1150 store_uid_sid_cache(psid, uid);
1151 return;
1154 /*****************************************************************
1155 *THE LEGACY* convert gid_t to SID function.
1156 *****************************************************************/
1158 static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid)
1160 bool ret;
1162 ZERO_STRUCTP(psid);
1164 become_root();
1165 ret = pdb_gid_to_sid(gid, psid);
1166 unbecome_root();
1168 if (ret) {
1169 /* This is a mapped group */
1170 goto done;
1173 /* This is an unmapped group */
1175 gid_to_unix_groups_sid(gid, psid);
1177 done:
1178 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid,
1179 sid_string_dbg(psid)));
1181 store_gid_sid_cache(psid, gid);
1182 return;
1185 /*****************************************************************
1186 *THE LEGACY* convert SID to uid function.
1187 *****************************************************************/
1189 static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1191 enum lsa_SidType type;
1193 if (sid_check_is_in_our_domain(psid)) {
1194 union unid_t id;
1195 bool ret;
1197 become_root();
1198 ret = pdb_sid_to_id(psid, &id, &type);
1199 unbecome_root();
1201 if (ret) {
1202 if (type != SID_NAME_USER) {
1203 DEBUG(5, ("sid %s is a %s, expected a user\n",
1204 sid_string_dbg(psid),
1205 sid_type_lookup(type)));
1206 return false;
1208 *puid = id.uid;
1209 goto done;
1212 /* This was ours, but it was not mapped. Fail */
1215 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1216 sid_string_dbg(psid)));
1217 return false;
1219 done:
1220 DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_dbg(psid),
1221 (unsigned int)*puid ));
1223 store_uid_sid_cache(psid, *puid);
1224 return true;
1227 /*****************************************************************
1228 *THE LEGACY* convert SID to gid function.
1229 Group mapping is used for gids that maps to Wellknown SIDs
1230 *****************************************************************/
1232 static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1234 GROUP_MAP map;
1235 union unid_t id;
1236 enum lsa_SidType type;
1238 if ((sid_check_is_in_builtin(psid) ||
1239 sid_check_is_in_wellknown_domain(psid))) {
1240 bool ret;
1242 become_root();
1243 ret = pdb_getgrsid(&map, *psid);
1244 unbecome_root();
1246 if (ret) {
1247 *pgid = map.gid;
1248 goto done;
1250 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1251 sid_string_dbg(psid)));
1252 return false;
1255 if (sid_check_is_in_our_domain(psid)) {
1256 bool ret;
1258 become_root();
1259 ret = pdb_sid_to_id(psid, &id, &type);
1260 unbecome_root();
1262 if (ret) {
1263 if ((type != SID_NAME_DOM_GRP) &&
1264 (type != SID_NAME_ALIAS)) {
1265 DEBUG(5, ("LEGACY: sid %s is a %s, expected "
1266 "a group\n", sid_string_dbg(psid),
1267 sid_type_lookup(type)));
1268 return false;
1270 *pgid = id.gid;
1271 goto done;
1274 /* This was ours, but it was not mapped. Fail */
1277 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1278 sid_string_dbg(psid)));
1279 return false;
1281 done:
1282 DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid),
1283 (unsigned int)*pgid ));
1285 store_gid_sid_cache(psid, *pgid);
1287 return true;
1290 /*****************************************************************
1291 *THE CANONICAL* convert uid_t to SID function.
1292 *****************************************************************/
1294 void uid_to_sid(struct dom_sid *psid, uid_t uid)
1296 bool expired = true;
1297 bool ret;
1298 ZERO_STRUCTP(psid);
1300 if (fetch_sid_from_uid_cache(psid, uid))
1301 return;
1303 /* Check the winbindd cache directly. */
1304 ret = idmap_cache_find_uid2sid(uid, psid, &expired);
1306 if (ret && !expired && is_null_sid(psid)) {
1308 * Negative cache entry, we already asked.
1309 * do legacy.
1311 legacy_uid_to_sid(psid, uid);
1312 return;
1315 if (!ret || expired) {
1316 /* Not in cache. Ask winbindd. */
1317 if (!winbind_uid_to_sid(psid, uid)) {
1319 * We shouldn't return the NULL SID
1320 * here if winbind was running and
1321 * couldn't map, as winbind will have
1322 * added a negative entry that will
1323 * cause us to go though the
1324 * legacy_uid_to_sid()
1325 * function anyway in the case above
1326 * the next time we ask.
1328 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1329 "for uid %u\n", (unsigned int)uid));
1331 legacy_uid_to_sid(psid, uid);
1332 return;
1336 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid,
1337 sid_string_dbg(psid)));
1339 store_uid_sid_cache(psid, uid);
1340 return;
1343 /*****************************************************************
1344 *THE CANONICAL* convert gid_t to SID function.
1345 *****************************************************************/
1347 void gid_to_sid(struct dom_sid *psid, gid_t gid)
1349 bool expired = true;
1350 bool ret;
1351 ZERO_STRUCTP(psid);
1353 if (fetch_sid_from_gid_cache(psid, gid))
1354 return;
1356 /* Check the winbindd cache directly. */
1357 ret = idmap_cache_find_gid2sid(gid, psid, &expired);
1359 if (ret && !expired && is_null_sid(psid)) {
1361 * Negative cache entry, we already asked.
1362 * do legacy.
1364 legacy_gid_to_sid(psid, gid);
1365 return;
1368 if (!ret || expired) {
1369 /* Not in cache. Ask winbindd. */
1370 if (!winbind_gid_to_sid(psid, gid)) {
1372 * We shouldn't return the NULL SID
1373 * here if winbind was running and
1374 * couldn't map, as winbind will have
1375 * added a negative entry that will
1376 * cause us to go though the
1377 * legacy_gid_to_sid()
1378 * function anyway in the case above
1379 * the next time we ask.
1381 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1382 "for gid %u\n", (unsigned int)gid));
1384 legacy_gid_to_sid(psid, gid);
1385 return;
1389 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid,
1390 sid_string_dbg(psid)));
1392 store_gid_sid_cache(psid, gid);
1393 return;
1396 /*****************************************************************
1397 *THE CANONICAL* convert SID to uid function.
1398 *****************************************************************/
1400 bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1402 bool expired = true;
1403 bool ret;
1404 uint32 rid;
1405 gid_t gid;
1407 if (fetch_uid_from_cache(puid, psid))
1408 return true;
1410 if (fetch_gid_from_cache(&gid, psid)) {
1411 return false;
1414 /* Optimize for the Unix Users Domain
1415 * as the conversion is straightforward */
1416 if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1417 uid_t uid = rid;
1418 *puid = uid;
1420 /* return here, don't cache */
1421 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1422 (unsigned int)*puid ));
1423 return true;
1426 /* Check the winbindd cache directly. */
1427 ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1429 if (ret && !expired && (*puid == (uid_t)-1)) {
1431 * Negative cache entry, we already asked.
1432 * do legacy.
1434 return legacy_sid_to_uid(psid, puid);
1437 if (!ret || expired) {
1438 /* Not in cache. Ask winbindd. */
1439 if (!winbind_sid_to_uid(puid, psid)) {
1440 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1441 sid_string_dbg(psid)));
1442 /* winbind failed. do legacy */
1443 return legacy_sid_to_uid(psid, puid);
1447 /* TODO: Here would be the place to allocate both a gid and a uid for
1448 * the SID in question */
1450 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1451 (unsigned int)*puid ));
1453 store_uid_sid_cache(psid, *puid);
1454 return true;
1457 /*****************************************************************
1458 *THE CANONICAL* convert SID to gid function.
1459 Group mapping is used for gids that maps to Wellknown SIDs
1460 *****************************************************************/
1462 bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1464 bool expired = true;
1465 bool ret;
1466 uint32 rid;
1467 uid_t uid;
1469 if (fetch_gid_from_cache(pgid, psid))
1470 return true;
1472 if (fetch_uid_from_cache(&uid, psid))
1473 return false;
1475 /* Optimize for the Unix Groups Domain
1476 * as the conversion is straightforward */
1477 if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1478 gid_t gid = rid;
1479 *pgid = gid;
1481 /* return here, don't cache */
1482 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1483 (unsigned int)*pgid ));
1484 return true;
1487 /* Check the winbindd cache directly. */
1488 ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1490 if (ret && !expired && (*pgid == (gid_t)-1)) {
1492 * Negative cache entry, we already asked.
1493 * do legacy.
1495 return legacy_sid_to_gid(psid, pgid);
1498 if (!ret || expired) {
1499 /* Not in cache or negative. Ask winbindd. */
1500 /* Ask winbindd if it can map this sid to a gid.
1501 * (Idmap will check it is a valid SID and of the right type) */
1503 if ( !winbind_sid_to_gid(pgid, psid) ) {
1505 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1506 sid_string_dbg(psid)));
1507 /* winbind failed. do legacy */
1508 return legacy_sid_to_gid(psid, pgid);
1512 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1513 (unsigned int)*pgid ));
1515 store_gid_sid_cache(psid, *pgid);
1516 return true;
1520 * @brief This function gets the primary group SID mapping the primary
1521 * GID of the user as obtained by an actual getpwnam() call.
1522 * This is necessary to avoid issues with arbitrary group SIDs
1523 * stored in passdb. We try as hard as we can to get the SID
1524 * corresponding to the GID, including trying group mapping.
1525 * If nothing else works, we will force "Domain Users" as the
1526 * primary group.
1527 * This is needed because we must always be able to lookup the
1528 * primary group SID, so we cannot settle for an arbitrary SID.
1530 * This call can be expensive. Use with moderation.
1531 * If you have a "samu" struct around use pdb_get_group_sid()
1532 * instead as it does properly cache results.
1534 * @param mem_ctx[in] The memory context iused to allocate the result.
1535 * @param username[in] The user's name
1536 * @param _pwd[in|out] If available, pass in user's passwd struct.
1537 * It will contain a tallocated passwd if NULL was
1538 * passed in.
1539 * @param _group_sid[out] The user's Primary Group SID
1541 * @return NTSTATUS error code.
1543 NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1544 const char *username,
1545 struct passwd **_pwd,
1546 struct dom_sid **_group_sid)
1548 TALLOC_CTX *tmp_ctx;
1549 bool need_lookup_sid = false;
1550 struct dom_sid *group_sid;
1551 struct passwd *pwd = *_pwd;
1553 tmp_ctx = talloc_new(mem_ctx);
1554 if (!tmp_ctx) {
1555 return NT_STATUS_NO_MEMORY;
1558 if (!pwd) {
1559 pwd = Get_Pwnam_alloc(mem_ctx, username);
1560 if (!pwd) {
1561 DEBUG(0, ("Failed to find a Unix account for %s",
1562 username));
1563 TALLOC_FREE(tmp_ctx);
1564 return NT_STATUS_NO_SUCH_USER;
1568 group_sid = talloc_zero(mem_ctx, struct dom_sid);
1569 if (!group_sid) {
1570 TALLOC_FREE(tmp_ctx);
1571 return NT_STATUS_NO_MEMORY;
1574 gid_to_sid(group_sid, pwd->pw_gid);
1575 if (!is_null_sid(group_sid)) {
1576 struct dom_sid domain_sid;
1577 uint32_t rid;
1579 /* We need a sid within our domain */
1580 sid_copy(&domain_sid, group_sid);
1581 sid_split_rid(&domain_sid, &rid);
1582 if (sid_equal(&domain_sid, get_global_sam_sid())) {
1584 * As shortcut for the expensive lookup_sid call
1585 * compare the domain sid part
1587 switch (rid) {
1588 case DOMAIN_RID_ADMINS:
1589 case DOMAIN_RID_USERS:
1590 goto done;
1591 default:
1592 need_lookup_sid = true;
1593 break;
1595 } else {
1596 /* Try group mapping */
1597 ZERO_STRUCTP(group_sid);
1598 if (pdb_gid_to_sid(pwd->pw_gid, group_sid)) {
1599 need_lookup_sid = true;
1604 /* We must verify that this is a valid SID that resolves to a
1605 * group of the correct type */
1606 if (need_lookup_sid) {
1607 enum lsa_SidType type = SID_NAME_UNKNOWN;
1608 bool lookup_ret;
1610 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1611 sid_string_dbg(group_sid), username));
1613 /* Now check that it's actually a domain group and
1614 * not something else */
1615 lookup_ret = lookup_sid(tmp_ctx, group_sid,
1616 NULL, NULL, &type);
1618 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1619 goto done;
1622 DEBUG(3, ("Primary group %s for user %s is"
1623 " a %s and not a domain group\n",
1624 sid_string_dbg(group_sid), username,
1625 sid_type_lookup(type)));
1628 /* Everything else, failed.
1629 * Just set it to the 'Domain Users' RID of 513 which will
1630 always resolve to a name */
1631 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1632 username));
1634 sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1636 done:
1637 *_pwd = talloc_move(mem_ctx, &pwd);
1638 *_group_sid = talloc_move(mem_ctx, &group_sid);
1639 TALLOC_FREE(tmp_ctx);
1640 return NT_STATUS_OK;