s3:passdb Export function to calculate the proper primary group sid
[Samba/bjacke.git] / source3 / passdb / lookup_sid.c
blobd523055b9dd3dd3fb07583fbec0b88deaf8c78b5
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"
25 /*****************************************************************
26 Dissect a user-provided name into domain, name, sid and type.
28 If an explicit domain name was given in the form domain\user, it
29 has to try that. If no explicit domain name was given, we have
30 to do guesswork.
31 *****************************************************************/
33 bool lookup_name(TALLOC_CTX *mem_ctx,
34 const char *full_name, int flags,
35 const char **ret_domain, const char **ret_name,
36 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
38 char *p;
39 const char *tmp;
40 const char *domain = NULL;
41 const char *name = NULL;
42 uint32 rid;
43 struct dom_sid sid;
44 enum lsa_SidType type;
45 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
47 if (tmp_ctx == NULL) {
48 DEBUG(0, ("talloc_new failed\n"));
49 return false;
52 p = strchr_m(full_name, '\\');
54 if (p != NULL) {
55 domain = talloc_strndup(tmp_ctx, full_name,
56 PTR_DIFF(p, full_name));
57 name = talloc_strdup(tmp_ctx, p+1);
58 } else {
59 domain = talloc_strdup(tmp_ctx, "");
60 name = talloc_strdup(tmp_ctx, full_name);
63 if ((domain == NULL) || (name == NULL)) {
64 DEBUG(0, ("talloc failed\n"));
65 TALLOC_FREE(tmp_ctx);
66 return false;
69 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
70 full_name, domain, name));
71 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
73 if ((flags & LOOKUP_NAME_DOMAIN) &&
74 strequal(domain, get_global_sam_name()))
77 /* It's our own domain, lookup the name in passdb */
78 if (lookup_global_sam_name(name, flags, &rid, &type)) {
79 sid_compose(&sid, get_global_sam_sid(), rid);
80 goto ok;
82 TALLOC_FREE(tmp_ctx);
83 return false;
86 if ((flags & LOOKUP_NAME_BUILTIN) &&
87 strequal(domain, builtin_domain_name()))
89 if (strlen(name) == 0) {
90 /* Swap domain and name */
91 tmp = name; name = domain; domain = tmp;
92 sid_copy(&sid, &global_sid_Builtin);
93 type = SID_NAME_DOMAIN;
94 goto ok;
97 /* Explicit request for a name in BUILTIN */
98 if (lookup_builtin_name(name, &rid)) {
99 sid_compose(&sid, &global_sid_Builtin, rid);
100 type = SID_NAME_ALIAS;
101 goto ok;
103 TALLOC_FREE(tmp_ctx);
104 return false;
107 /* Try the explicit winbind lookup first, don't let it guess the
108 * domain yet at this point yet. This comes later. */
110 if ((domain[0] != '\0') &&
111 (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
112 (winbind_lookup_name(domain, name, &sid, &type))) {
113 goto ok;
116 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
117 && strequal(domain, unix_users_domain_name())) {
118 if (lookup_unix_user_name(name, &sid)) {
119 type = SID_NAME_USER;
120 goto ok;
122 TALLOC_FREE(tmp_ctx);
123 return false;
126 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
127 && strequal(domain, unix_groups_domain_name())) {
128 if (lookup_unix_group_name(name, &sid)) {
129 type = SID_NAME_DOM_GRP;
130 goto ok;
132 TALLOC_FREE(tmp_ctx);
133 return false;
136 if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
137 TALLOC_FREE(tmp_ctx);
138 return false;
141 /* Now the guesswork begins, we haven't been given an explicit
142 * domain. Try the sequence as documented on
143 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
144 * November 27, 2005 */
146 /* 1. well-known names */
148 if ((flags & LOOKUP_NAME_WKN) &&
149 lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
151 type = SID_NAME_WKN_GRP;
152 goto ok;
155 /* 2. Builtin domain as such */
157 if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
158 strequal(name, builtin_domain_name()))
160 /* Swap domain and name */
161 tmp = name; name = domain; domain = tmp;
162 sid_copy(&sid, &global_sid_Builtin);
163 type = SID_NAME_DOMAIN;
164 goto ok;
167 /* 3. Account domain */
169 if ((flags & LOOKUP_NAME_DOMAIN) &&
170 strequal(name, get_global_sam_name()))
172 if (!secrets_fetch_domain_sid(name, &sid)) {
173 DEBUG(3, ("Could not fetch my SID\n"));
174 TALLOC_FREE(tmp_ctx);
175 return false;
177 /* Swap domain and name */
178 tmp = name; name = domain; domain = tmp;
179 type = SID_NAME_DOMAIN;
180 goto ok;
183 /* 4. Primary domain */
185 if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
186 strequal(name, lp_workgroup()))
188 if (!secrets_fetch_domain_sid(name, &sid)) {
189 DEBUG(3, ("Could not fetch the domain SID\n"));
190 TALLOC_FREE(tmp_ctx);
191 return false;
193 /* Swap domain and name */
194 tmp = name; name = domain; domain = tmp;
195 type = SID_NAME_DOMAIN;
196 goto ok;
199 /* 5. Trusted domains as such, to me it looks as if members don't do
200 this, tested an XP workstation in a NT domain -- vl */
202 if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
203 (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
205 /* Swap domain and name */
206 tmp = name; name = domain; domain = tmp;
207 type = SID_NAME_DOMAIN;
208 goto ok;
211 /* 6. Builtin aliases */
213 if ((flags & LOOKUP_NAME_BUILTIN) &&
214 lookup_builtin_name(name, &rid))
216 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
217 sid_compose(&sid, &global_sid_Builtin, rid);
218 type = SID_NAME_ALIAS;
219 goto ok;
222 /* 7. Local systems' SAM (DCs don't have a local SAM) */
223 /* 8. Primary SAM (On members, this is the domain) */
225 /* Both cases are done by looking at our passdb */
227 if ((flags & LOOKUP_NAME_DOMAIN) &&
228 lookup_global_sam_name(name, flags, &rid, &type))
230 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
231 sid_compose(&sid, get_global_sam_sid(), rid);
232 goto ok;
235 /* Now our local possibilities are exhausted. */
237 if (!(flags & LOOKUP_NAME_REMOTE)) {
238 TALLOC_FREE(tmp_ctx);
239 return false;
242 /* If we are not a DC, we have to ask in our primary domain. Let
243 * winbind do that. */
245 if (!IS_DC &&
246 (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
247 domain = talloc_strdup(tmp_ctx, lp_workgroup());
248 goto ok;
251 /* 9. Trusted domains */
253 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
254 * that (yet), but give it a chance. */
256 if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
257 struct dom_sid dom_sid;
258 uint32 tmp_rid;
259 enum lsa_SidType domain_type;
261 if (type == SID_NAME_DOMAIN) {
262 /* Swap name and type */
263 tmp = name; name = domain; domain = tmp;
264 goto ok;
267 /* Here we have to cope with a little deficiency in the
268 * winbind API: We have to ask it again for the name of the
269 * domain it figured out itself. Maybe fix that later... */
271 sid_copy(&dom_sid, &sid);
272 sid_split_rid(&dom_sid, &tmp_rid);
274 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
275 &domain_type) ||
276 (domain_type != SID_NAME_DOMAIN)) {
277 DEBUG(2, ("winbind could not find the domain's name "
278 "it just looked up for us\n"));
279 TALLOC_FREE(tmp_ctx);
280 return false;
282 goto ok;
285 /* 10. Don't translate */
287 /* 11. Ok, windows would end here. Samba has two more options:
288 Unmapped users and unmapped groups */
290 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
291 && lookup_unix_user_name(name, &sid)) {
292 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
293 type = SID_NAME_USER;
294 goto ok;
297 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
298 && lookup_unix_group_name(name, &sid)) {
299 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
300 type = SID_NAME_DOM_GRP;
301 goto ok;
305 * Ok, all possibilities tried. Fail.
308 TALLOC_FREE(tmp_ctx);
309 return false;
312 if ((domain == NULL) || (name == NULL)) {
313 DEBUG(0, ("talloc failed\n"));
314 TALLOC_FREE(tmp_ctx);
315 return false;
319 * Hand over the results to the talloc context we've been given.
322 if ((ret_name != NULL) &&
323 !(*ret_name = talloc_strdup(mem_ctx, name))) {
324 DEBUG(0, ("talloc failed\n"));
325 TALLOC_FREE(tmp_ctx);
326 return false;
329 if (ret_domain != NULL) {
330 char *tmp_dom;
331 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
332 DEBUG(0, ("talloc failed\n"));
333 TALLOC_FREE(tmp_ctx);
334 return false;
336 strupper_m(tmp_dom);
337 *ret_domain = tmp_dom;
340 if (ret_sid != NULL) {
341 sid_copy(ret_sid, &sid);
344 if (ret_type != NULL) {
345 *ret_type = type;
348 TALLOC_FREE(tmp_ctx);
349 return true;
352 /************************************************************************
353 Names from smb.conf can be unqualified. eg. valid users = foo
354 These names should never map to a remote name. Try global_sam_name()\foo,
355 and then "Unix Users"\foo (or "Unix Groups"\foo).
356 ************************************************************************/
358 bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
359 const char *full_name, int flags,
360 const char **ret_domain, const char **ret_name,
361 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
363 char *qualified_name;
364 const char *p;
366 /* NB. No winbindd_separator here as lookup_name needs \\' */
367 if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
369 /* The name is already qualified with a domain. */
371 if (*lp_winbind_separator() != '\\') {
372 char *tmp;
374 /* lookup_name() needs '\\' as a separator */
376 tmp = talloc_strdup(mem_ctx, full_name);
377 if (!tmp) {
378 return false;
380 tmp[p - full_name] = '\\';
381 full_name = tmp;
384 return lookup_name(mem_ctx, full_name, flags,
385 ret_domain, ret_name,
386 ret_sid, ret_type);
389 /* Try with our own SAM name. */
390 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
391 get_global_sam_name(),
392 full_name );
393 if (!qualified_name) {
394 return false;
397 if (lookup_name(mem_ctx, qualified_name, flags,
398 ret_domain, ret_name,
399 ret_sid, ret_type)) {
400 return true;
403 /* Finally try with "Unix Users" or "Unix Group" */
404 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
405 flags & LOOKUP_NAME_GROUP ?
406 unix_groups_domain_name() :
407 unix_users_domain_name(),
408 full_name );
409 if (!qualified_name) {
410 return false;
413 return lookup_name(mem_ctx, qualified_name, flags,
414 ret_domain, ret_name,
415 ret_sid, ret_type);
418 static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
419 const struct dom_sid *domain_sid,
420 int num_rids, uint32 *rids,
421 const char **domain_name,
422 const char **names, enum lsa_SidType *types)
424 int i;
425 const char **my_names;
426 enum lsa_SidType *my_types;
427 TALLOC_CTX *tmp_ctx;
429 if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
430 return false;
433 if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
434 domain_name, &my_names, &my_types)) {
435 *domain_name = "";
436 for (i=0; i<num_rids; i++) {
437 names[i] = "";
438 types[i] = SID_NAME_UNKNOWN;
440 TALLOC_FREE(tmp_ctx);
441 return true;
444 if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
445 TALLOC_FREE(tmp_ctx);
446 return false;
450 * winbind_lookup_rids allocates its own array. We've been given the
451 * array, so copy it over
454 for (i=0; i<num_rids; i++) {
455 if (my_names[i] == NULL) {
456 TALLOC_FREE(tmp_ctx);
457 return false;
459 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
460 TALLOC_FREE(tmp_ctx);
461 return false;
463 types[i] = my_types[i];
465 TALLOC_FREE(tmp_ctx);
466 return true;
469 static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
470 int num_rids, uint32_t *rids,
471 const char **domain_name,
472 const char ***names, enum lsa_SidType **types)
474 int i;
476 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
477 sid_string_dbg(domain_sid)));
479 if (num_rids) {
480 *names = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
481 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
483 if ((*names == NULL) || (*types == NULL)) {
484 return false;
487 for (i = 0; i < num_rids; i++)
488 (*types)[i] = SID_NAME_UNKNOWN;
489 } else {
490 *names = NULL;
491 *types = NULL;
494 if (sid_check_is_domain(domain_sid)) {
495 NTSTATUS result;
497 if (*domain_name == NULL) {
498 *domain_name = talloc_strdup(
499 mem_ctx, get_global_sam_name());
502 if (*domain_name == NULL) {
503 return false;
506 become_root();
507 result = pdb_lookup_rids(domain_sid, num_rids, rids,
508 *names, *types);
509 unbecome_root();
511 return (NT_STATUS_IS_OK(result) ||
512 NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
513 NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
516 if (sid_check_is_builtin(domain_sid)) {
518 if (*domain_name == NULL) {
519 *domain_name = talloc_strdup(
520 mem_ctx, builtin_domain_name());
523 if (*domain_name == NULL) {
524 return false;
527 for (i=0; i<num_rids; i++) {
528 if (lookup_builtin_rid(*names, rids[i],
529 &(*names)[i])) {
530 if ((*names)[i] == NULL) {
531 return false;
533 (*types)[i] = SID_NAME_ALIAS;
534 } else {
535 (*types)[i] = SID_NAME_UNKNOWN;
538 return true;
541 if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
542 for (i=0; i<num_rids; i++) {
543 struct dom_sid sid;
544 sid_compose(&sid, domain_sid, rids[i]);
545 if (lookup_wellknown_sid(mem_ctx, &sid,
546 domain_name, &(*names)[i])) {
547 if ((*names)[i] == NULL) {
548 return false;
550 (*types)[i] = SID_NAME_WKN_GRP;
551 } else {
552 (*types)[i] = SID_NAME_UNKNOWN;
555 return true;
558 if (sid_check_is_unix_users(domain_sid)) {
559 if (*domain_name == NULL) {
560 *domain_name = talloc_strdup(
561 mem_ctx, unix_users_domain_name());
562 if (*domain_name == NULL) {
563 return false;
566 for (i=0; i<num_rids; i++) {
567 (*names)[i] = talloc_strdup(
568 (*names), uidtoname(rids[i]));
569 if ((*names)[i] == NULL) {
570 return false;
572 (*types)[i] = SID_NAME_USER;
574 return true;
577 if (sid_check_is_unix_groups(domain_sid)) {
578 if (*domain_name == NULL) {
579 *domain_name = talloc_strdup(
580 mem_ctx, unix_groups_domain_name());
581 if (*domain_name == NULL) {
582 return false;
585 for (i=0; i<num_rids; i++) {
586 (*names)[i] = talloc_strdup(
587 (*names), gidtoname(rids[i]));
588 if ((*names)[i] == NULL) {
589 return false;
591 (*types)[i] = SID_NAME_DOM_GRP;
593 return true;
596 return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
597 domain_name, *names, *types);
601 * Is the SID a domain as such? If yes, lookup its name.
604 static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
605 const char **name)
607 const char *tmp;
608 enum lsa_SidType type;
610 if (sid_check_is_domain(sid)) {
611 *name = talloc_strdup(mem_ctx, get_global_sam_name());
612 return true;
615 if (sid_check_is_builtin(sid)) {
616 *name = talloc_strdup(mem_ctx, builtin_domain_name());
617 return true;
620 if (sid_check_is_wellknown_domain(sid, &tmp)) {
621 *name = talloc_strdup(mem_ctx, tmp);
622 return true;
625 if (sid_check_is_unix_users(sid)) {
626 *name = talloc_strdup(mem_ctx, unix_users_domain_name());
627 return true;
630 if (sid_check_is_unix_groups(sid)) {
631 *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
632 return true;
635 if (sid->num_auths != 4) {
636 /* This can't be a domain */
637 return false;
640 if (IS_DC) {
641 uint32 i, num_domains;
642 struct trustdom_info **domains;
644 /* This is relatively expensive, but it happens only on DCs
645 * and for SIDs that have 4 sub-authorities and thus look like
646 * domains */
648 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
649 &num_domains,
650 &domains))) {
651 return false;
654 for (i=0; i<num_domains; i++) {
655 if (sid_equal(sid, &domains[i]->sid)) {
656 *name = talloc_strdup(mem_ctx,
657 domains[i]->name);
658 return true;
661 return false;
664 if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
665 (type == SID_NAME_DOMAIN)) {
666 *name = tmp;
667 return true;
670 return false;
674 * This tries to implement the rather weird rules for the lsa_lookup level
675 * parameter.
677 * This is as close as we can get to what W2k3 does. With this we survive the
678 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
679 * different, but I assume that's just being too liberal. For example, W2k3
680 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
681 * whereas NT4 does the same as level 1 (I think). I did not fully test that
682 * with NT4, this is what w2k3 does.
684 * Level 1: Ask everywhere
685 * Level 2: Ask domain and trusted domains, no builtin and wkn
686 * Level 3: Only ask domain
687 * Level 4: W2k3ad: Only ask AD trusts
688 * Level 5: Only ask transitive forest trusts
689 * Level 6: Like 4
692 static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
694 int ret = false;
696 switch(level) {
697 case 1:
698 ret = true;
699 break;
700 case 2:
701 ret = (!sid_check_is_builtin(sid) &&
702 !sid_check_is_wellknown_domain(sid, NULL));
703 break;
704 case 3:
705 case 4:
706 case 6:
707 ret = sid_check_is_domain(sid);
708 break;
709 case 5:
710 ret = false;
711 break;
714 DEBUG(10, ("%s SID %s in level %d\n",
715 ret ? "Accepting" : "Rejecting",
716 sid_string_dbg(sid), level));
717 return ret;
721 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
722 * references to domains, it is explicitly made for this.
724 * This attempts to be as efficient as possible: It collects all SIDs
725 * belonging to a domain and hands them in bulk to the appropriate lookup
726 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
727 * *hugely* from this. Winbind is going to be extended with a lookup_rids
728 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
729 * appropriate DC.
732 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
733 const struct dom_sid **sids, int level,
734 struct lsa_dom_info **ret_domains,
735 struct lsa_name_info **ret_names)
737 TALLOC_CTX *tmp_ctx;
738 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
739 struct lsa_name_info *name_infos;
740 struct lsa_dom_info *dom_infos = NULL;
742 int i, j;
744 if (!(tmp_ctx = talloc_new(mem_ctx))) {
745 DEBUG(0, ("talloc_new failed\n"));
746 return NT_STATUS_NO_MEMORY;
749 if (num_sids) {
750 name_infos = TALLOC_ARRAY(mem_ctx, struct lsa_name_info, num_sids);
751 if (name_infos == NULL) {
752 result = NT_STATUS_NO_MEMORY;
753 goto fail;
755 } else {
756 name_infos = NULL;
759 dom_infos = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_dom_info,
760 LSA_REF_DOMAIN_LIST_MULTIPLIER);
761 if (dom_infos == NULL) {
762 result = NT_STATUS_NO_MEMORY;
763 goto fail;
766 /* First build up the data structures:
768 * dom_infos is a list of domains referenced in the list of
769 * SIDs. Later we will walk the list of domains and look up the RIDs
770 * in bulk.
772 * name_infos is a shadow-copy of the SIDs array to collect the real
773 * data.
775 * dom_info->idxs is an index into the name_infos array. The
776 * difficulty we have here is that we need to keep the SIDs the client
777 * asked for in the same order for the reply
780 for (i=0; i<num_sids; i++) {
781 struct dom_sid sid;
782 uint32 rid;
783 const char *domain_name = NULL;
785 sid_copy(&sid, sids[i]);
786 name_infos[i].type = SID_NAME_USE_NONE;
788 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
789 /* We can't push that through the normal lookup
790 * process, as this would reference illegal
791 * domains.
793 * For example S-1-5-32 would end up referencing
794 * domain S-1-5- with RID 32 which is clearly wrong.
796 if (domain_name == NULL) {
797 result = NT_STATUS_NO_MEMORY;
798 goto fail;
801 name_infos[i].rid = 0;
802 name_infos[i].type = SID_NAME_DOMAIN;
803 name_infos[i].name = NULL;
805 if (sid_check_is_builtin(&sid)) {
806 /* Yes, W2k3 returns "BUILTIN" both as domain
807 * and name here */
808 name_infos[i].name = talloc_strdup(
809 name_infos, builtin_domain_name());
810 if (name_infos[i].name == NULL) {
811 result = NT_STATUS_NO_MEMORY;
812 goto fail;
815 } else {
816 /* This is a normal SID with rid component */
817 if (!sid_split_rid(&sid, &rid)) {
818 result = NT_STATUS_INVALID_SID;
819 goto fail;
823 if (!check_dom_sid_to_level(&sid, level)) {
824 name_infos[i].rid = 0;
825 name_infos[i].type = SID_NAME_UNKNOWN;
826 name_infos[i].name = NULL;
827 continue;
830 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
831 if (!dom_infos[j].valid) {
832 break;
834 if (sid_equal(&sid, &dom_infos[j].sid)) {
835 break;
839 if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
840 /* TODO: What's the right error message here? */
841 result = NT_STATUS_NONE_MAPPED;
842 goto fail;
845 if (!dom_infos[j].valid) {
846 /* We found a domain not yet referenced, create a new
847 * ref. */
848 dom_infos[j].valid = true;
849 sid_copy(&dom_infos[j].sid, &sid);
851 if (domain_name != NULL) {
852 /* This name was being found above in the case
853 * when we found a domain SID */
854 dom_infos[j].name =
855 talloc_strdup(dom_infos, domain_name);
856 if (dom_infos[j].name == NULL) {
857 result = NT_STATUS_NO_MEMORY;
858 goto fail;
860 } else {
861 /* lookup_rids will take care of this */
862 dom_infos[j].name = NULL;
866 name_infos[i].dom_idx = j;
868 if (name_infos[i].type == SID_NAME_USE_NONE) {
869 name_infos[i].rid = rid;
871 ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
872 &dom_infos[j].num_idxs);
874 if (dom_infos[j].idxs == NULL) {
875 result = NT_STATUS_NO_MEMORY;
876 goto fail;
881 /* Iterate over the domains found */
883 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
884 uint32_t *rids;
885 const char *domain_name = NULL;
886 const char **names;
887 enum lsa_SidType *types;
888 struct lsa_dom_info *dom = &dom_infos[i];
890 if (!dom->valid) {
891 /* No domains left, we're done */
892 break;
895 if (dom->num_idxs) {
896 if (!(rids = TALLOC_ARRAY(tmp_ctx, uint32, dom->num_idxs))) {
897 result = NT_STATUS_NO_MEMORY;
898 goto fail;
900 } else {
901 rids = NULL;
904 for (j=0; j<dom->num_idxs; j++) {
905 rids[j] = name_infos[dom->idxs[j]].rid;
908 if (!lookup_rids(tmp_ctx, &dom->sid,
909 dom->num_idxs, rids, &domain_name,
910 &names, &types)) {
911 result = NT_STATUS_NO_MEMORY;
912 goto fail;
915 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
916 result = NT_STATUS_NO_MEMORY;
917 goto fail;
920 for (j=0; j<dom->num_idxs; j++) {
921 int idx = dom->idxs[j];
922 name_infos[idx].type = types[j];
923 if (types[j] != SID_NAME_UNKNOWN) {
924 name_infos[idx].name =
925 talloc_strdup(name_infos, names[j]);
926 if (name_infos[idx].name == NULL) {
927 result = NT_STATUS_NO_MEMORY;
928 goto fail;
930 } else {
931 name_infos[idx].name = NULL;
936 *ret_domains = dom_infos;
937 *ret_names = name_infos;
938 TALLOC_FREE(tmp_ctx);
939 return NT_STATUS_OK;
941 fail:
942 TALLOC_FREE(dom_infos);
943 TALLOC_FREE(name_infos);
944 TALLOC_FREE(tmp_ctx);
945 return result;
948 /*****************************************************************
949 *THE CANONICAL* convert SID to name function.
950 *****************************************************************/
952 bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
953 const char **ret_domain, const char **ret_name,
954 enum lsa_SidType *ret_type)
956 struct lsa_dom_info *domain;
957 struct lsa_name_info *name;
958 TALLOC_CTX *tmp_ctx;
959 bool ret = false;
961 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid)));
963 if (!(tmp_ctx = talloc_new(mem_ctx))) {
964 DEBUG(0, ("talloc_new failed\n"));
965 return false;
968 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
969 &domain, &name))) {
970 goto done;
973 if (name->type == SID_NAME_UNKNOWN) {
974 goto done;
977 if ((ret_domain != NULL) &&
978 !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
979 goto done;
982 if ((ret_name != NULL) &&
983 !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
984 goto done;
987 if (ret_type != NULL) {
988 *ret_type = name->type;
991 ret = true;
993 done:
994 if (ret) {
995 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid),
996 domain->name, name->name, name->type));
997 } else {
998 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid)));
1000 TALLOC_FREE(tmp_ctx);
1001 return ret;
1004 /*****************************************************************
1005 Id mapping cache. This is to avoid Winbind mappings already
1006 seen by smbd to be queried too frequently, keeping winbindd
1007 busy, and blocking smbd while winbindd is busy with other
1008 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1009 modified to use linked lists by jra.
1010 *****************************************************************/
1012 /*****************************************************************
1013 Find a SID given a uid.
1014 *****************************************************************/
1016 static bool fetch_sid_from_uid_cache(struct dom_sid *psid, uid_t uid)
1018 DATA_BLOB cache_value;
1020 if (!memcache_lookup(NULL, UID_SID_CACHE,
1021 data_blob_const(&uid, sizeof(uid)),
1022 &cache_value)) {
1023 return false;
1026 memcpy(psid, cache_value.data, MIN(sizeof(*psid), cache_value.length));
1027 SMB_ASSERT(cache_value.length >= offsetof(struct dom_sid, id_auth));
1028 SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, 0));
1030 return true;
1033 /*****************************************************************
1034 Find a uid given a SID.
1035 *****************************************************************/
1037 static bool fetch_uid_from_cache( uid_t *puid, const struct dom_sid *psid )
1039 DATA_BLOB cache_value;
1041 if (!memcache_lookup(NULL, SID_UID_CACHE,
1042 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1043 &cache_value)) {
1044 return false;
1047 SMB_ASSERT(cache_value.length == sizeof(*puid));
1048 memcpy(puid, cache_value.data, sizeof(*puid));
1050 return true;
1053 /*****************************************************************
1054 Store uid to SID mapping in cache.
1055 *****************************************************************/
1057 void store_uid_sid_cache(const struct dom_sid *psid, uid_t uid)
1059 memcache_add(NULL, SID_UID_CACHE,
1060 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1061 data_blob_const(&uid, sizeof(uid)));
1062 memcache_add(NULL, UID_SID_CACHE,
1063 data_blob_const(&uid, sizeof(uid)),
1064 data_blob_const(psid, ndr_size_dom_sid(psid, 0)));
1067 /*****************************************************************
1068 Find a SID given a gid.
1069 *****************************************************************/
1071 static bool fetch_sid_from_gid_cache(struct dom_sid *psid, gid_t gid)
1073 DATA_BLOB cache_value;
1075 if (!memcache_lookup(NULL, GID_SID_CACHE,
1076 data_blob_const(&gid, sizeof(gid)),
1077 &cache_value)) {
1078 return false;
1081 memcpy(psid, cache_value.data, MIN(sizeof(*psid), cache_value.length));
1082 SMB_ASSERT(cache_value.length >= offsetof(struct dom_sid, id_auth));
1083 SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, 0));
1085 return true;
1088 /*****************************************************************
1089 Find a gid given a SID.
1090 *****************************************************************/
1092 static bool fetch_gid_from_cache(gid_t *pgid, const struct dom_sid *psid)
1094 DATA_BLOB cache_value;
1096 if (!memcache_lookup(NULL, SID_GID_CACHE,
1097 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1098 &cache_value)) {
1099 return false;
1102 SMB_ASSERT(cache_value.length == sizeof(*pgid));
1103 memcpy(pgid, cache_value.data, sizeof(*pgid));
1105 return true;
1108 /*****************************************************************
1109 Store gid to SID mapping in cache.
1110 *****************************************************************/
1112 void store_gid_sid_cache(const struct dom_sid *psid, gid_t gid)
1114 memcache_add(NULL, SID_GID_CACHE,
1115 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1116 data_blob_const(&gid, sizeof(gid)));
1117 memcache_add(NULL, GID_SID_CACHE,
1118 data_blob_const(&gid, sizeof(gid)),
1119 data_blob_const(psid, ndr_size_dom_sid(psid, 0)));
1122 /*****************************************************************
1123 *THE LEGACY* convert uid_t to SID function.
1124 *****************************************************************/
1126 static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
1128 bool ret;
1130 ZERO_STRUCTP(psid);
1132 become_root();
1133 ret = pdb_uid_to_sid(uid, psid);
1134 unbecome_root();
1136 if (ret) {
1137 /* This is a mapped user */
1138 goto done;
1141 /* This is an unmapped user */
1143 uid_to_unix_users_sid(uid, psid);
1145 done:
1146 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid,
1147 sid_string_dbg(psid)));
1149 store_uid_sid_cache(psid, uid);
1150 return;
1153 /*****************************************************************
1154 *THE LEGACY* convert gid_t to SID function.
1155 *****************************************************************/
1157 static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid)
1159 bool ret;
1161 ZERO_STRUCTP(psid);
1163 become_root();
1164 ret = pdb_gid_to_sid(gid, psid);
1165 unbecome_root();
1167 if (ret) {
1168 /* This is a mapped group */
1169 goto done;
1172 /* This is an unmapped group */
1174 gid_to_unix_groups_sid(gid, psid);
1176 done:
1177 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid,
1178 sid_string_dbg(psid)));
1180 store_gid_sid_cache(psid, gid);
1181 return;
1184 /*****************************************************************
1185 *THE LEGACY* convert SID to uid function.
1186 *****************************************************************/
1188 static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1190 enum lsa_SidType type;
1192 if (sid_check_is_in_our_domain(psid)) {
1193 union unid_t id;
1194 bool ret;
1196 become_root();
1197 ret = pdb_sid_to_id(psid, &id, &type);
1198 unbecome_root();
1200 if (ret) {
1201 if (type != SID_NAME_USER) {
1202 DEBUG(5, ("sid %s is a %s, expected a user\n",
1203 sid_string_dbg(psid),
1204 sid_type_lookup(type)));
1205 return false;
1207 *puid = id.uid;
1208 goto done;
1211 /* This was ours, but it was not mapped. Fail */
1214 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1215 sid_string_dbg(psid)));
1216 return false;
1218 done:
1219 DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_dbg(psid),
1220 (unsigned int)*puid ));
1222 store_uid_sid_cache(psid, *puid);
1223 return true;
1226 /*****************************************************************
1227 *THE LEGACY* convert SID to gid function.
1228 Group mapping is used for gids that maps to Wellknown SIDs
1229 *****************************************************************/
1231 static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1233 GROUP_MAP map;
1234 union unid_t id;
1235 enum lsa_SidType type;
1237 if ((sid_check_is_in_builtin(psid) ||
1238 sid_check_is_in_wellknown_domain(psid))) {
1239 bool ret;
1241 become_root();
1242 ret = pdb_getgrsid(&map, *psid);
1243 unbecome_root();
1245 if (ret) {
1246 *pgid = map.gid;
1247 goto done;
1249 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1250 sid_string_dbg(psid)));
1251 return false;
1254 if (sid_check_is_in_our_domain(psid)) {
1255 bool ret;
1257 become_root();
1258 ret = pdb_sid_to_id(psid, &id, &type);
1259 unbecome_root();
1261 if (ret) {
1262 if ((type != SID_NAME_DOM_GRP) &&
1263 (type != SID_NAME_ALIAS)) {
1264 DEBUG(5, ("LEGACY: sid %s is a %s, expected "
1265 "a group\n", sid_string_dbg(psid),
1266 sid_type_lookup(type)));
1267 return false;
1269 *pgid = id.gid;
1270 goto done;
1273 /* This was ours, but it was not mapped. Fail */
1276 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1277 sid_string_dbg(psid)));
1278 return false;
1280 done:
1281 DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid),
1282 (unsigned int)*pgid ));
1284 store_gid_sid_cache(psid, *pgid);
1286 return true;
1289 /*****************************************************************
1290 *THE CANONICAL* convert uid_t to SID function.
1291 *****************************************************************/
1293 void uid_to_sid(struct dom_sid *psid, uid_t uid)
1295 bool expired = true;
1296 bool ret;
1297 ZERO_STRUCTP(psid);
1299 if (fetch_sid_from_uid_cache(psid, uid))
1300 return;
1302 /* Check the winbindd cache directly. */
1303 ret = idmap_cache_find_uid2sid(uid, psid, &expired);
1305 if (ret && !expired && is_null_sid(psid)) {
1307 * Negative cache entry, we already asked.
1308 * do legacy.
1310 legacy_uid_to_sid(psid, uid);
1311 return;
1314 if (!ret || expired) {
1315 /* Not in cache. Ask winbindd. */
1316 if (!winbind_uid_to_sid(psid, uid)) {
1318 * We shouldn't return the NULL SID
1319 * here if winbind was running and
1320 * couldn't map, as winbind will have
1321 * added a negative entry that will
1322 * cause us to go though the
1323 * legacy_uid_to_sid()
1324 * function anyway in the case above
1325 * the next time we ask.
1327 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1328 "for uid %u\n", (unsigned int)uid));
1330 legacy_uid_to_sid(psid, uid);
1331 return;
1335 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid,
1336 sid_string_dbg(psid)));
1338 store_uid_sid_cache(psid, uid);
1339 return;
1342 /*****************************************************************
1343 *THE CANONICAL* convert gid_t to SID function.
1344 *****************************************************************/
1346 void gid_to_sid(struct dom_sid *psid, gid_t gid)
1348 bool expired = true;
1349 bool ret;
1350 ZERO_STRUCTP(psid);
1352 if (fetch_sid_from_gid_cache(psid, gid))
1353 return;
1355 /* Check the winbindd cache directly. */
1356 ret = idmap_cache_find_gid2sid(gid, psid, &expired);
1358 if (ret && !expired && is_null_sid(psid)) {
1360 * Negative cache entry, we already asked.
1361 * do legacy.
1363 legacy_gid_to_sid(psid, gid);
1364 return;
1367 if (!ret || expired) {
1368 /* Not in cache. Ask winbindd. */
1369 if (!winbind_gid_to_sid(psid, gid)) {
1371 * We shouldn't return the NULL SID
1372 * here if winbind was running and
1373 * couldn't map, as winbind will have
1374 * added a negative entry that will
1375 * cause us to go though the
1376 * legacy_gid_to_sid()
1377 * function anyway in the case above
1378 * the next time we ask.
1380 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1381 "for gid %u\n", (unsigned int)gid));
1383 legacy_gid_to_sid(psid, gid);
1384 return;
1388 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid,
1389 sid_string_dbg(psid)));
1391 store_gid_sid_cache(psid, gid);
1392 return;
1395 /*****************************************************************
1396 *THE CANONICAL* convert SID to uid function.
1397 *****************************************************************/
1399 bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1401 bool expired = true;
1402 bool ret;
1403 uint32 rid;
1404 gid_t gid;
1406 if (fetch_uid_from_cache(puid, psid))
1407 return true;
1409 if (fetch_gid_from_cache(&gid, psid)) {
1410 return false;
1413 /* Optimize for the Unix Users Domain
1414 * as the conversion is straightforward */
1415 if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1416 uid_t uid = rid;
1417 *puid = uid;
1419 /* return here, don't cache */
1420 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1421 (unsigned int)*puid ));
1422 return true;
1425 /* Check the winbindd cache directly. */
1426 ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1428 if (ret && !expired && (*puid == (uid_t)-1)) {
1430 * Negative cache entry, we already asked.
1431 * do legacy.
1433 return legacy_sid_to_uid(psid, puid);
1436 if (!ret || expired) {
1437 /* Not in cache. Ask winbindd. */
1438 if (!winbind_sid_to_uid(puid, psid)) {
1439 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1440 sid_string_dbg(psid)));
1441 /* winbind failed. do legacy */
1442 return legacy_sid_to_uid(psid, puid);
1446 /* TODO: Here would be the place to allocate both a gid and a uid for
1447 * the SID in question */
1449 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1450 (unsigned int)*puid ));
1452 store_uid_sid_cache(psid, *puid);
1453 return true;
1456 /*****************************************************************
1457 *THE CANONICAL* convert SID to gid function.
1458 Group mapping is used for gids that maps to Wellknown SIDs
1459 *****************************************************************/
1461 bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1463 bool expired = true;
1464 bool ret;
1465 uint32 rid;
1466 uid_t uid;
1468 if (fetch_gid_from_cache(pgid, psid))
1469 return true;
1471 if (fetch_uid_from_cache(&uid, psid))
1472 return false;
1474 /* Optimize for the Unix Groups Domain
1475 * as the conversion is straightforward */
1476 if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1477 gid_t gid = rid;
1478 *pgid = gid;
1480 /* return here, don't cache */
1481 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1482 (unsigned int)*pgid ));
1483 return true;
1486 /* Check the winbindd cache directly. */
1487 ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1489 if (ret && !expired && (*pgid == (gid_t)-1)) {
1491 * Negative cache entry, we already asked.
1492 * do legacy.
1494 return legacy_sid_to_gid(psid, pgid);
1497 if (!ret || expired) {
1498 /* Not in cache or negative. Ask winbindd. */
1499 /* Ask winbindd if it can map this sid to a gid.
1500 * (Idmap will check it is a valid SID and of the right type) */
1502 if ( !winbind_sid_to_gid(pgid, psid) ) {
1504 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1505 sid_string_dbg(psid)));
1506 /* winbind failed. do legacy */
1507 return legacy_sid_to_gid(psid, pgid);
1511 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1512 (unsigned int)*pgid ));
1514 store_gid_sid_cache(psid, *pgid);
1515 return true;
1519 * @brief This function gets the primary group SID mapping the primary
1520 * GID of the user as obtained by an actual getpwnam() call.
1521 * This is necessary to avoid issues with arbitrary group SIDs
1522 * stored in passdb. We try as hard as we can to get the SID
1523 * corresponding to the GID, including trying group mapping.
1524 * If nothing else works, we will force "Domain Users" as the
1525 * primary group.
1526 * This is needed because we must always be able to lookup the
1527 * primary group SID, so we cannot settle for an arbitrary SID.
1529 * This call can be expensive. Use with moderation.
1530 * If you have a "samu" struct around use pdb_get_group_sid()
1531 * instead as it does properly cache results.
1533 * @param mem_ctx[in] The memory context iused to allocate the result.
1534 * @param username[in] The user's name
1535 * @param _pwd[in|out] If available, pass in user's passwd struct.
1536 * It will contain a tallocated passwd if NULL was
1537 * passed in.
1538 * @param _group_sid[out] The user's Primary Group SID
1540 * @return NTSTATUS error code.
1542 NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1543 const char *username,
1544 struct passwd **_pwd,
1545 struct dom_sid **_group_sid)
1547 TALLOC_CTX *tmp_ctx;
1548 bool need_lookup_sid = false;
1549 struct dom_sid *group_sid;
1550 struct passwd *pwd = *_pwd;
1552 tmp_ctx = talloc_new(mem_ctx);
1553 if (!tmp_ctx) {
1554 return NT_STATUS_NO_MEMORY;
1557 if (!pwd) {
1558 pwd = Get_Pwnam_alloc(mem_ctx, username);
1559 if (!pwd) {
1560 DEBUG(0, ("Failed to find a Unix account for %s",
1561 username));
1562 TALLOC_FREE(tmp_ctx);
1563 return NT_STATUS_NO_SUCH_USER;
1567 group_sid = talloc_zero(mem_ctx, struct dom_sid);
1568 if (!group_sid) {
1569 TALLOC_FREE(tmp_ctx);
1570 return NT_STATUS_NO_MEMORY;
1573 gid_to_sid(group_sid, pwd->pw_gid);
1574 if (!is_null_sid(group_sid)) {
1575 struct dom_sid domain_sid;
1576 uint32_t rid;
1578 /* We need a sid within our domain */
1579 sid_copy(&domain_sid, group_sid);
1580 sid_split_rid(&domain_sid, &rid);
1581 if (sid_equal(&domain_sid, get_global_sam_sid())) {
1583 * As shortcut for the expensive lookup_sid call
1584 * compare the domain sid part
1586 switch (rid) {
1587 case DOMAIN_RID_ADMINS:
1588 case DOMAIN_RID_USERS:
1589 goto done;
1590 default:
1591 need_lookup_sid = true;
1592 break;
1594 } else {
1595 /* Try group mapping */
1596 ZERO_STRUCTP(group_sid);
1597 if (pdb_gid_to_sid(pwd->pw_gid, group_sid)) {
1598 need_lookup_sid = true;
1603 /* We must verify that this is a valid SID that resolves to a
1604 * group of the correct type */
1605 if (need_lookup_sid) {
1606 enum lsa_SidType type = SID_NAME_UNKNOWN;
1607 bool lookup_ret;
1609 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1610 sid_string_dbg(group_sid), username));
1612 /* Now check that it's actually a domain group and
1613 * not something else */
1614 lookup_ret = lookup_sid(tmp_ctx, group_sid,
1615 NULL, NULL, &type);
1617 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1618 goto done;
1621 DEBUG(3, ("Primary group %s for user %s is"
1622 " a %s and not a domain group\n",
1623 sid_string_dbg(group_sid), username,
1624 sid_type_lookup(type)));
1627 /* Everything else, failed.
1628 * Just set it to the 'Domain Users' RID of 513 which will
1629 always resolve to a name */
1630 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1631 username));
1633 sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1635 done:
1636 *_pwd = talloc_move(mem_ctx, &pwd);
1637 *_group_sid = talloc_move(mem_ctx, &group_sid);
1638 TALLOC_FREE(tmp_ctx);
1639 return NT_STATUS_OK;