s3: add functions to remove entries from idmap memcache
[Samba.git] / source3 / passdb / lookup_sid.c
blob68072f3096373d3cef7580123b42d1309eef7a41
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"
27 #include "../libcli/security/security.h"
29 /*****************************************************************
30 Dissect a user-provided name into domain, name, sid and type.
32 If an explicit domain name was given in the form domain\user, it
33 has to try that. If no explicit domain name was given, we have
34 to do guesswork.
35 *****************************************************************/
37 bool lookup_name(TALLOC_CTX *mem_ctx,
38 const char *full_name, int flags,
39 const char **ret_domain, const char **ret_name,
40 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
42 char *p;
43 const char *tmp;
44 const char *domain = NULL;
45 const char *name = NULL;
46 uint32 rid;
47 struct dom_sid sid;
48 enum lsa_SidType type;
49 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
51 if (tmp_ctx == NULL) {
52 DEBUG(0, ("talloc_new failed\n"));
53 return false;
56 p = strchr_m(full_name, '\\');
58 if (p != NULL) {
59 domain = talloc_strndup(tmp_ctx, full_name,
60 PTR_DIFF(p, full_name));
61 name = talloc_strdup(tmp_ctx, p+1);
62 } else {
63 domain = talloc_strdup(tmp_ctx, "");
64 name = talloc_strdup(tmp_ctx, full_name);
67 if ((domain == NULL) || (name == NULL)) {
68 DEBUG(0, ("talloc failed\n"));
69 TALLOC_FREE(tmp_ctx);
70 return false;
73 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
74 full_name, domain, name));
75 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
77 if ((flags & LOOKUP_NAME_DOMAIN) &&
78 strequal(domain, get_global_sam_name()))
81 /* It's our own domain, lookup the name in passdb */
82 if (lookup_global_sam_name(name, flags, &rid, &type)) {
83 sid_compose(&sid, get_global_sam_sid(), rid);
84 goto ok;
86 TALLOC_FREE(tmp_ctx);
87 return false;
90 if ((flags & LOOKUP_NAME_BUILTIN) &&
91 strequal(domain, builtin_domain_name()))
93 if (strlen(name) == 0) {
94 /* Swap domain and name */
95 tmp = name; name = domain; domain = tmp;
96 sid_copy(&sid, &global_sid_Builtin);
97 type = SID_NAME_DOMAIN;
98 goto ok;
101 /* Explicit request for a name in BUILTIN */
102 if (lookup_builtin_name(name, &rid)) {
103 sid_compose(&sid, &global_sid_Builtin, rid);
104 type = SID_NAME_ALIAS;
105 goto ok;
107 TALLOC_FREE(tmp_ctx);
108 return false;
111 /* Try the explicit winbind lookup first, don't let it guess the
112 * domain yet at this point yet. This comes later. */
114 if ((domain[0] != '\0') &&
115 (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
116 (winbind_lookup_name(domain, name, &sid, &type))) {
117 goto ok;
120 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
121 && strequal(domain, unix_users_domain_name())) {
122 if (lookup_unix_user_name(name, &sid)) {
123 type = SID_NAME_USER;
124 goto ok;
126 TALLOC_FREE(tmp_ctx);
127 return false;
130 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
131 && strequal(domain, unix_groups_domain_name())) {
132 if (lookup_unix_group_name(name, &sid)) {
133 type = SID_NAME_DOM_GRP;
134 goto ok;
136 TALLOC_FREE(tmp_ctx);
137 return false;
140 if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
141 TALLOC_FREE(tmp_ctx);
142 return false;
145 /* Now the guesswork begins, we haven't been given an explicit
146 * domain. Try the sequence as documented on
147 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
148 * November 27, 2005 */
150 /* 1. well-known names */
152 if ((flags & LOOKUP_NAME_WKN) &&
153 lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
155 type = SID_NAME_WKN_GRP;
156 goto ok;
159 /* 2. Builtin domain as such */
161 if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
162 strequal(name, builtin_domain_name()))
164 /* Swap domain and name */
165 tmp = name; name = domain; domain = tmp;
166 sid_copy(&sid, &global_sid_Builtin);
167 type = SID_NAME_DOMAIN;
168 goto ok;
171 /* 3. Account domain */
173 if ((flags & LOOKUP_NAME_DOMAIN) &&
174 strequal(name, get_global_sam_name()))
176 if (!secrets_fetch_domain_sid(name, &sid)) {
177 DEBUG(3, ("Could not fetch my SID\n"));
178 TALLOC_FREE(tmp_ctx);
179 return false;
181 /* Swap domain and name */
182 tmp = name; name = domain; domain = tmp;
183 type = SID_NAME_DOMAIN;
184 goto ok;
187 /* 4. Primary domain */
189 if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
190 strequal(name, lp_workgroup()))
192 if (!secrets_fetch_domain_sid(name, &sid)) {
193 DEBUG(3, ("Could not fetch the domain SID\n"));
194 TALLOC_FREE(tmp_ctx);
195 return false;
197 /* Swap domain and name */
198 tmp = name; name = domain; domain = tmp;
199 type = SID_NAME_DOMAIN;
200 goto ok;
203 /* 5. Trusted domains as such, to me it looks as if members don't do
204 this, tested an XP workstation in a NT domain -- vl */
206 if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
207 (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
209 /* Swap domain and name */
210 tmp = name; name = domain; domain = tmp;
211 type = SID_NAME_DOMAIN;
212 goto ok;
215 /* 6. Builtin aliases */
217 if ((flags & LOOKUP_NAME_BUILTIN) &&
218 lookup_builtin_name(name, &rid))
220 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
221 sid_compose(&sid, &global_sid_Builtin, rid);
222 type = SID_NAME_ALIAS;
223 goto ok;
226 /* 7. Local systems' SAM (DCs don't have a local SAM) */
227 /* 8. Primary SAM (On members, this is the domain) */
229 /* Both cases are done by looking at our passdb */
231 if ((flags & LOOKUP_NAME_DOMAIN) &&
232 lookup_global_sam_name(name, flags, &rid, &type))
234 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
235 sid_compose(&sid, get_global_sam_sid(), rid);
236 goto ok;
239 /* Now our local possibilities are exhausted. */
241 if (!(flags & LOOKUP_NAME_REMOTE)) {
242 TALLOC_FREE(tmp_ctx);
243 return false;
246 /* If we are not a DC, we have to ask in our primary domain. Let
247 * winbind do that. */
249 if (!IS_DC &&
250 (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
251 domain = talloc_strdup(tmp_ctx, lp_workgroup());
252 goto ok;
255 /* 9. Trusted domains */
257 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
258 * that (yet), but give it a chance. */
260 if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
261 struct dom_sid dom_sid;
262 uint32 tmp_rid;
263 enum lsa_SidType domain_type;
265 if (type == SID_NAME_DOMAIN) {
266 /* Swap name and type */
267 tmp = name; name = domain; domain = tmp;
268 goto ok;
271 /* Here we have to cope with a little deficiency in the
272 * winbind API: We have to ask it again for the name of the
273 * domain it figured out itself. Maybe fix that later... */
275 sid_copy(&dom_sid, &sid);
276 sid_split_rid(&dom_sid, &tmp_rid);
278 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
279 &domain_type) ||
280 (domain_type != SID_NAME_DOMAIN)) {
281 DEBUG(2, ("winbind could not find the domain's name "
282 "it just looked up for us\n"));
283 TALLOC_FREE(tmp_ctx);
284 return false;
286 goto ok;
289 /* 10. Don't translate */
291 /* 11. Ok, windows would end here. Samba has two more options:
292 Unmapped users and unmapped groups */
294 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
295 && lookup_unix_user_name(name, &sid)) {
296 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
297 type = SID_NAME_USER;
298 goto ok;
301 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
302 && lookup_unix_group_name(name, &sid)) {
303 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
304 type = SID_NAME_DOM_GRP;
305 goto ok;
309 * Ok, all possibilities tried. Fail.
312 TALLOC_FREE(tmp_ctx);
313 return false;
316 if ((domain == NULL) || (name == NULL)) {
317 DEBUG(0, ("talloc failed\n"));
318 TALLOC_FREE(tmp_ctx);
319 return false;
323 * Hand over the results to the talloc context we've been given.
326 if ((ret_name != NULL) &&
327 !(*ret_name = talloc_strdup(mem_ctx, name))) {
328 DEBUG(0, ("talloc failed\n"));
329 TALLOC_FREE(tmp_ctx);
330 return false;
333 if (ret_domain != NULL) {
334 char *tmp_dom;
335 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
336 DEBUG(0, ("talloc failed\n"));
337 TALLOC_FREE(tmp_ctx);
338 return false;
340 strupper_m(tmp_dom);
341 *ret_domain = tmp_dom;
344 if (ret_sid != NULL) {
345 sid_copy(ret_sid, &sid);
348 if (ret_type != NULL) {
349 *ret_type = type;
352 TALLOC_FREE(tmp_ctx);
353 return true;
356 /************************************************************************
357 Names from smb.conf can be unqualified. eg. valid users = foo
358 These names should never map to a remote name. Try global_sam_name()\foo,
359 and then "Unix Users"\foo (or "Unix Groups"\foo).
360 ************************************************************************/
362 bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
363 const char *full_name, int flags,
364 const char **ret_domain, const char **ret_name,
365 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
367 char *qualified_name;
368 const char *p;
370 /* NB. No winbindd_separator here as lookup_name needs \\' */
371 if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
373 /* The name is already qualified with a domain. */
375 if (*lp_winbind_separator() != '\\') {
376 char *tmp;
378 /* lookup_name() needs '\\' as a separator */
380 tmp = talloc_strdup(mem_ctx, full_name);
381 if (!tmp) {
382 return false;
384 tmp[p - full_name] = '\\';
385 full_name = tmp;
388 return lookup_name(mem_ctx, full_name, flags,
389 ret_domain, ret_name,
390 ret_sid, ret_type);
393 /* Try with our own SAM name. */
394 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
395 get_global_sam_name(),
396 full_name );
397 if (!qualified_name) {
398 return false;
401 if (lookup_name(mem_ctx, qualified_name, flags,
402 ret_domain, ret_name,
403 ret_sid, ret_type)) {
404 return true;
407 /* Finally try with "Unix Users" or "Unix Group" */
408 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
409 flags & LOOKUP_NAME_GROUP ?
410 unix_groups_domain_name() :
411 unix_users_domain_name(),
412 full_name );
413 if (!qualified_name) {
414 return false;
417 return lookup_name(mem_ctx, qualified_name, flags,
418 ret_domain, ret_name,
419 ret_sid, ret_type);
422 static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
423 const struct dom_sid *domain_sid,
424 int num_rids, uint32 *rids,
425 const char **domain_name,
426 const char **names, enum lsa_SidType *types)
428 int i;
429 const char **my_names;
430 enum lsa_SidType *my_types;
431 TALLOC_CTX *tmp_ctx;
433 if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
434 return false;
437 if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
438 domain_name, &my_names, &my_types)) {
439 *domain_name = "";
440 for (i=0; i<num_rids; i++) {
441 names[i] = "";
442 types[i] = SID_NAME_UNKNOWN;
444 TALLOC_FREE(tmp_ctx);
445 return true;
448 if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
449 TALLOC_FREE(tmp_ctx);
450 return false;
454 * winbind_lookup_rids allocates its own array. We've been given the
455 * array, so copy it over
458 for (i=0; i<num_rids; i++) {
459 if (my_names[i] == NULL) {
460 TALLOC_FREE(tmp_ctx);
461 return false;
463 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
464 TALLOC_FREE(tmp_ctx);
465 return false;
467 types[i] = my_types[i];
469 TALLOC_FREE(tmp_ctx);
470 return true;
473 static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
474 int num_rids, uint32_t *rids,
475 const char **domain_name,
476 const char ***names, enum lsa_SidType **types)
478 int i;
480 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
481 sid_string_dbg(domain_sid)));
483 if (num_rids) {
484 *names = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
485 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
487 if ((*names == NULL) || (*types == NULL)) {
488 return false;
491 for (i = 0; i < num_rids; i++)
492 (*types)[i] = SID_NAME_UNKNOWN;
493 } else {
494 *names = NULL;
495 *types = NULL;
498 if (sid_check_is_domain(domain_sid)) {
499 NTSTATUS result;
501 if (*domain_name == NULL) {
502 *domain_name = talloc_strdup(
503 mem_ctx, get_global_sam_name());
506 if (*domain_name == NULL) {
507 return false;
510 become_root();
511 result = pdb_lookup_rids(domain_sid, num_rids, rids,
512 *names, *types);
513 unbecome_root();
515 return (NT_STATUS_IS_OK(result) ||
516 NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
517 NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
520 if (sid_check_is_builtin(domain_sid)) {
522 if (*domain_name == NULL) {
523 *domain_name = talloc_strdup(
524 mem_ctx, builtin_domain_name());
527 if (*domain_name == NULL) {
528 return false;
531 for (i=0; i<num_rids; i++) {
532 if (lookup_builtin_rid(*names, rids[i],
533 &(*names)[i])) {
534 if ((*names)[i] == NULL) {
535 return false;
537 (*types)[i] = SID_NAME_ALIAS;
538 } else {
539 (*types)[i] = SID_NAME_UNKNOWN;
542 return true;
545 if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
546 for (i=0; i<num_rids; i++) {
547 struct dom_sid sid;
548 sid_compose(&sid, domain_sid, rids[i]);
549 if (lookup_wellknown_sid(mem_ctx, &sid,
550 domain_name, &(*names)[i])) {
551 if ((*names)[i] == NULL) {
552 return false;
554 (*types)[i] = SID_NAME_WKN_GRP;
555 } else {
556 (*types)[i] = SID_NAME_UNKNOWN;
559 return true;
562 if (sid_check_is_unix_users(domain_sid)) {
563 if (*domain_name == NULL) {
564 *domain_name = talloc_strdup(
565 mem_ctx, unix_users_domain_name());
566 if (*domain_name == NULL) {
567 return false;
570 for (i=0; i<num_rids; i++) {
571 (*names)[i] = talloc_strdup(
572 (*names), uidtoname(rids[i]));
573 if ((*names)[i] == NULL) {
574 return false;
576 (*types)[i] = SID_NAME_USER;
578 return true;
581 if (sid_check_is_unix_groups(domain_sid)) {
582 if (*domain_name == NULL) {
583 *domain_name = talloc_strdup(
584 mem_ctx, unix_groups_domain_name());
585 if (*domain_name == NULL) {
586 return false;
589 for (i=0; i<num_rids; i++) {
590 (*names)[i] = talloc_strdup(
591 (*names), gidtoname(rids[i]));
592 if ((*names)[i] == NULL) {
593 return false;
595 (*types)[i] = SID_NAME_DOM_GRP;
597 return true;
600 return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
601 domain_name, *names, *types);
605 * Is the SID a domain as such? If yes, lookup its name.
608 static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
609 const char **name)
611 const char *tmp;
612 enum lsa_SidType type;
614 if (sid_check_is_domain(sid)) {
615 *name = talloc_strdup(mem_ctx, get_global_sam_name());
616 return true;
619 if (sid_check_is_builtin(sid)) {
620 *name = talloc_strdup(mem_ctx, builtin_domain_name());
621 return true;
624 if (sid_check_is_wellknown_domain(sid, &tmp)) {
625 *name = talloc_strdup(mem_ctx, tmp);
626 return true;
629 if (sid_check_is_unix_users(sid)) {
630 *name = talloc_strdup(mem_ctx, unix_users_domain_name());
631 return true;
634 if (sid_check_is_unix_groups(sid)) {
635 *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
636 return true;
639 if (sid->num_auths != 4) {
640 /* This can't be a domain */
641 return false;
644 if (IS_DC) {
645 uint32 i, num_domains;
646 struct trustdom_info **domains;
648 /* This is relatively expensive, but it happens only on DCs
649 * and for SIDs that have 4 sub-authorities and thus look like
650 * domains */
652 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
653 &num_domains,
654 &domains))) {
655 return false;
658 for (i=0; i<num_domains; i++) {
659 if (dom_sid_equal(sid, &domains[i]->sid)) {
660 *name = talloc_strdup(mem_ctx,
661 domains[i]->name);
662 return true;
665 return false;
668 if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
669 (type == SID_NAME_DOMAIN)) {
670 *name = tmp;
671 return true;
674 return false;
678 * This tries to implement the rather weird rules for the lsa_lookup level
679 * parameter.
681 * This is as close as we can get to what W2k3 does. With this we survive the
682 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
683 * different, but I assume that's just being too liberal. For example, W2k3
684 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
685 * whereas NT4 does the same as level 1 (I think). I did not fully test that
686 * with NT4, this is what w2k3 does.
688 * Level 1: Ask everywhere
689 * Level 2: Ask domain and trusted domains, no builtin and wkn
690 * Level 3: Only ask domain
691 * Level 4: W2k3ad: Only ask AD trusts
692 * Level 5: Only ask transitive forest trusts
693 * Level 6: Like 4
696 static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
698 int ret = false;
700 switch(level) {
701 case 1:
702 ret = true;
703 break;
704 case 2:
705 ret = (!sid_check_is_builtin(sid) &&
706 !sid_check_is_wellknown_domain(sid, NULL));
707 break;
708 case 3:
709 case 4:
710 case 6:
711 ret = sid_check_is_domain(sid);
712 break;
713 case 5:
714 ret = false;
715 break;
718 DEBUG(10, ("%s SID %s in level %d\n",
719 ret ? "Accepting" : "Rejecting",
720 sid_string_dbg(sid), level));
721 return ret;
725 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
726 * references to domains, it is explicitly made for this.
728 * This attempts to be as efficient as possible: It collects all SIDs
729 * belonging to a domain and hands them in bulk to the appropriate lookup
730 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
731 * *hugely* from this. Winbind is going to be extended with a lookup_rids
732 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
733 * appropriate DC.
736 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
737 const struct dom_sid **sids, int level,
738 struct lsa_dom_info **ret_domains,
739 struct lsa_name_info **ret_names)
741 TALLOC_CTX *tmp_ctx;
742 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
743 struct lsa_name_info *name_infos;
744 struct lsa_dom_info *dom_infos = NULL;
746 int i, j;
748 if (!(tmp_ctx = talloc_new(mem_ctx))) {
749 DEBUG(0, ("talloc_new failed\n"));
750 return NT_STATUS_NO_MEMORY;
753 if (num_sids) {
754 name_infos = TALLOC_ARRAY(mem_ctx, struct lsa_name_info, num_sids);
755 if (name_infos == NULL) {
756 result = NT_STATUS_NO_MEMORY;
757 goto fail;
759 } else {
760 name_infos = NULL;
763 dom_infos = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_dom_info,
764 LSA_REF_DOMAIN_LIST_MULTIPLIER);
765 if (dom_infos == NULL) {
766 result = NT_STATUS_NO_MEMORY;
767 goto fail;
770 /* First build up the data structures:
772 * dom_infos is a list of domains referenced in the list of
773 * SIDs. Later we will walk the list of domains and look up the RIDs
774 * in bulk.
776 * name_infos is a shadow-copy of the SIDs array to collect the real
777 * data.
779 * dom_info->idxs is an index into the name_infos array. The
780 * difficulty we have here is that we need to keep the SIDs the client
781 * asked for in the same order for the reply
784 for (i=0; i<num_sids; i++) {
785 struct dom_sid sid;
786 uint32_t rid = 0;
787 const char *domain_name = NULL;
789 sid_copy(&sid, sids[i]);
790 name_infos[i].type = SID_NAME_USE_NONE;
792 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
793 /* We can't push that through the normal lookup
794 * process, as this would reference illegal
795 * domains.
797 * For example S-1-5-32 would end up referencing
798 * domain S-1-5- with RID 32 which is clearly wrong.
800 if (domain_name == NULL) {
801 result = NT_STATUS_NO_MEMORY;
802 goto fail;
805 name_infos[i].rid = 0;
806 name_infos[i].type = SID_NAME_DOMAIN;
807 name_infos[i].name = NULL;
809 if (sid_check_is_builtin(&sid)) {
810 /* Yes, W2k3 returns "BUILTIN" both as domain
811 * and name here */
812 name_infos[i].name = talloc_strdup(
813 name_infos, builtin_domain_name());
814 if (name_infos[i].name == NULL) {
815 result = NT_STATUS_NO_MEMORY;
816 goto fail;
819 } else {
820 /* This is a normal SID with rid component */
821 if (!sid_split_rid(&sid, &rid)) {
822 result = NT_STATUS_INVALID_SID;
823 goto fail;
827 if (!check_dom_sid_to_level(&sid, level)) {
828 name_infos[i].rid = 0;
829 name_infos[i].type = SID_NAME_UNKNOWN;
830 name_infos[i].name = NULL;
831 continue;
834 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
835 if (!dom_infos[j].valid) {
836 break;
838 if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
839 break;
843 if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
844 /* TODO: What's the right error message here? */
845 result = NT_STATUS_NONE_MAPPED;
846 goto fail;
849 if (!dom_infos[j].valid) {
850 /* We found a domain not yet referenced, create a new
851 * ref. */
852 dom_infos[j].valid = true;
853 sid_copy(&dom_infos[j].sid, &sid);
855 if (domain_name != NULL) {
856 /* This name was being found above in the case
857 * when we found a domain SID */
858 dom_infos[j].name =
859 talloc_strdup(dom_infos, domain_name);
860 if (dom_infos[j].name == NULL) {
861 result = NT_STATUS_NO_MEMORY;
862 goto fail;
864 } else {
865 /* lookup_rids will take care of this */
866 dom_infos[j].name = NULL;
870 name_infos[i].dom_idx = j;
872 if (name_infos[i].type == SID_NAME_USE_NONE) {
873 name_infos[i].rid = rid;
875 ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
876 &dom_infos[j].num_idxs);
878 if (dom_infos[j].idxs == NULL) {
879 result = NT_STATUS_NO_MEMORY;
880 goto fail;
885 /* Iterate over the domains found */
887 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
888 uint32_t *rids;
889 const char *domain_name = NULL;
890 const char **names;
891 enum lsa_SidType *types;
892 struct lsa_dom_info *dom = &dom_infos[i];
894 if (!dom->valid) {
895 /* No domains left, we're done */
896 break;
899 if (dom->num_idxs) {
900 if (!(rids = TALLOC_ARRAY(tmp_ctx, uint32, dom->num_idxs))) {
901 result = NT_STATUS_NO_MEMORY;
902 goto fail;
904 } else {
905 rids = NULL;
908 for (j=0; j<dom->num_idxs; j++) {
909 rids[j] = name_infos[dom->idxs[j]].rid;
912 if (!lookup_rids(tmp_ctx, &dom->sid,
913 dom->num_idxs, rids, &domain_name,
914 &names, &types)) {
915 result = NT_STATUS_NO_MEMORY;
916 goto fail;
919 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
920 result = NT_STATUS_NO_MEMORY;
921 goto fail;
924 for (j=0; j<dom->num_idxs; j++) {
925 int idx = dom->idxs[j];
926 name_infos[idx].type = types[j];
927 if (types[j] != SID_NAME_UNKNOWN) {
928 name_infos[idx].name =
929 talloc_strdup(name_infos, names[j]);
930 if (name_infos[idx].name == NULL) {
931 result = NT_STATUS_NO_MEMORY;
932 goto fail;
934 } else {
935 name_infos[idx].name = NULL;
940 *ret_domains = dom_infos;
941 *ret_names = name_infos;
942 TALLOC_FREE(tmp_ctx);
943 return NT_STATUS_OK;
945 fail:
946 TALLOC_FREE(dom_infos);
947 TALLOC_FREE(name_infos);
948 TALLOC_FREE(tmp_ctx);
949 return result;
952 /*****************************************************************
953 *THE CANONICAL* convert SID to name function.
954 *****************************************************************/
956 bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
957 const char **ret_domain, const char **ret_name,
958 enum lsa_SidType *ret_type)
960 struct lsa_dom_info *domain;
961 struct lsa_name_info *name;
962 TALLOC_CTX *tmp_ctx;
963 bool ret = false;
965 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid)));
967 if (!(tmp_ctx = talloc_new(mem_ctx))) {
968 DEBUG(0, ("talloc_new failed\n"));
969 return false;
972 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
973 &domain, &name))) {
974 goto done;
977 if (name->type == SID_NAME_UNKNOWN) {
978 goto done;
981 if ((ret_domain != NULL) &&
982 !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
983 goto done;
986 if ((ret_name != NULL) &&
987 !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
988 goto done;
991 if (ret_type != NULL) {
992 *ret_type = name->type;
995 ret = true;
997 done:
998 if (ret) {
999 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid),
1000 domain->name, name->name, name->type));
1001 } else {
1002 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid)));
1004 TALLOC_FREE(tmp_ctx);
1005 return ret;
1008 /*****************************************************************
1009 Id mapping cache. This is to avoid Winbind mappings already
1010 seen by smbd to be queried too frequently, keeping winbindd
1011 busy, and blocking smbd while winbindd is busy with other
1012 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1013 modified to use linked lists by jra.
1014 *****************************************************************/
1016 /*****************************************************************
1017 Find a SID given a uid.
1018 *****************************************************************/
1020 static bool fetch_sid_from_uid_cache(struct dom_sid *psid, uid_t uid)
1022 DATA_BLOB cache_value;
1024 if (!memcache_lookup(NULL, UID_SID_CACHE,
1025 data_blob_const(&uid, sizeof(uid)),
1026 &cache_value)) {
1027 return false;
1030 memcpy(psid, cache_value.data, MIN(sizeof(*psid), cache_value.length));
1031 SMB_ASSERT(cache_value.length >= offsetof(struct dom_sid, id_auth));
1032 SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, 0));
1034 return true;
1037 /*****************************************************************
1038 Find a uid given a SID.
1039 *****************************************************************/
1041 static bool fetch_uid_from_cache( uid_t *puid, const struct dom_sid *psid )
1043 DATA_BLOB cache_value;
1045 if (!memcache_lookup(NULL, SID_UID_CACHE,
1046 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1047 &cache_value)) {
1048 return false;
1051 SMB_ASSERT(cache_value.length == sizeof(*puid));
1052 memcpy(puid, cache_value.data, sizeof(*puid));
1054 return true;
1057 /*****************************************************************
1058 Store uid to SID mapping in cache.
1059 *****************************************************************/
1061 void store_uid_sid_cache(const struct dom_sid *psid, uid_t uid)
1063 memcache_add(NULL, SID_UID_CACHE,
1064 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1065 data_blob_const(&uid, sizeof(uid)));
1066 memcache_add(NULL, UID_SID_CACHE,
1067 data_blob_const(&uid, sizeof(uid)),
1068 data_blob_const(psid, ndr_size_dom_sid(psid, 0)));
1071 /*****************************************************************
1072 Find a SID given a gid.
1073 *****************************************************************/
1075 static bool fetch_sid_from_gid_cache(struct dom_sid *psid, gid_t gid)
1077 DATA_BLOB cache_value;
1079 if (!memcache_lookup(NULL, GID_SID_CACHE,
1080 data_blob_const(&gid, sizeof(gid)),
1081 &cache_value)) {
1082 return false;
1085 memcpy(psid, cache_value.data, MIN(sizeof(*psid), cache_value.length));
1086 SMB_ASSERT(cache_value.length >= offsetof(struct dom_sid, id_auth));
1087 SMB_ASSERT(cache_value.length == ndr_size_dom_sid(psid, 0));
1089 return true;
1092 /*****************************************************************
1093 Find a gid given a SID.
1094 *****************************************************************/
1096 static bool fetch_gid_from_cache(gid_t *pgid, const struct dom_sid *psid)
1098 DATA_BLOB cache_value;
1100 if (!memcache_lookup(NULL, SID_GID_CACHE,
1101 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1102 &cache_value)) {
1103 return false;
1106 SMB_ASSERT(cache_value.length == sizeof(*pgid));
1107 memcpy(pgid, cache_value.data, sizeof(*pgid));
1109 return true;
1112 /*****************************************************************
1113 Store gid to SID mapping in cache.
1114 *****************************************************************/
1116 void store_gid_sid_cache(const struct dom_sid *psid, gid_t gid)
1118 memcache_add(NULL, SID_GID_CACHE,
1119 data_blob_const(psid, ndr_size_dom_sid(psid, 0)),
1120 data_blob_const(&gid, sizeof(gid)));
1121 memcache_add(NULL, GID_SID_CACHE,
1122 data_blob_const(&gid, sizeof(gid)),
1123 data_blob_const(psid, ndr_size_dom_sid(psid, 0)));
1126 /*****************************************************************
1127 *THE LEGACY* convert uid_t to SID function.
1128 *****************************************************************/
1130 static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
1132 bool ret;
1134 ZERO_STRUCTP(psid);
1136 become_root();
1137 ret = pdb_uid_to_sid(uid, psid);
1138 unbecome_root();
1140 if (ret) {
1141 /* This is a mapped user */
1142 goto done;
1145 /* This is an unmapped user */
1147 uid_to_unix_users_sid(uid, psid);
1149 done:
1150 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid,
1151 sid_string_dbg(psid)));
1153 store_uid_sid_cache(psid, uid);
1154 return;
1157 /*****************************************************************
1158 *THE LEGACY* convert gid_t to SID function.
1159 *****************************************************************/
1161 static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid)
1163 bool ret;
1165 ZERO_STRUCTP(psid);
1167 become_root();
1168 ret = pdb_gid_to_sid(gid, psid);
1169 unbecome_root();
1171 if (ret) {
1172 /* This is a mapped group */
1173 goto done;
1176 /* This is an unmapped group */
1178 gid_to_unix_groups_sid(gid, psid);
1180 done:
1181 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid,
1182 sid_string_dbg(psid)));
1184 store_gid_sid_cache(psid, gid);
1185 return;
1188 /*****************************************************************
1189 *THE LEGACY* convert SID to uid function.
1190 *****************************************************************/
1192 static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1194 enum lsa_SidType type;
1196 if (sid_check_is_in_our_domain(psid)) {
1197 union unid_t id;
1198 bool ret;
1200 become_root();
1201 ret = pdb_sid_to_id(psid, &id, &type);
1202 unbecome_root();
1204 if (ret) {
1205 if (type != SID_NAME_USER) {
1206 DEBUG(5, ("sid %s is a %s, expected a user\n",
1207 sid_string_dbg(psid),
1208 sid_type_lookup(type)));
1209 return false;
1211 *puid = id.uid;
1212 goto done;
1215 /* This was ours, but it was not mapped. Fail */
1218 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1219 sid_string_dbg(psid)));
1220 return false;
1222 done:
1223 DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_dbg(psid),
1224 (unsigned int)*puid ));
1226 store_uid_sid_cache(psid, *puid);
1227 return true;
1230 /*****************************************************************
1231 *THE LEGACY* convert SID to gid function.
1232 Group mapping is used for gids that maps to Wellknown SIDs
1233 *****************************************************************/
1235 static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1237 GROUP_MAP map;
1238 union unid_t id;
1239 enum lsa_SidType type;
1241 if ((sid_check_is_in_builtin(psid) ||
1242 sid_check_is_in_wellknown_domain(psid))) {
1243 bool ret;
1245 become_root();
1246 ret = pdb_getgrsid(&map, *psid);
1247 unbecome_root();
1249 if (ret) {
1250 *pgid = map.gid;
1251 goto done;
1253 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1254 sid_string_dbg(psid)));
1255 return false;
1258 if (sid_check_is_in_our_domain(psid)) {
1259 bool ret;
1261 become_root();
1262 ret = pdb_sid_to_id(psid, &id, &type);
1263 unbecome_root();
1265 if (ret) {
1266 if ((type != SID_NAME_DOM_GRP) &&
1267 (type != SID_NAME_ALIAS)) {
1268 DEBUG(5, ("LEGACY: sid %s is a %s, expected "
1269 "a group\n", sid_string_dbg(psid),
1270 sid_type_lookup(type)));
1271 return false;
1273 *pgid = id.gid;
1274 goto done;
1277 /* This was ours, but it was not mapped. Fail */
1280 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1281 sid_string_dbg(psid)));
1282 return false;
1284 done:
1285 DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid),
1286 (unsigned int)*pgid ));
1288 store_gid_sid_cache(psid, *pgid);
1290 return true;
1293 /*****************************************************************
1294 *THE CANONICAL* convert uid_t to SID function.
1295 *****************************************************************/
1297 void uid_to_sid(struct dom_sid *psid, uid_t uid)
1299 bool expired = true;
1300 bool ret;
1301 ZERO_STRUCTP(psid);
1303 if (fetch_sid_from_uid_cache(psid, uid))
1304 return;
1306 /* Check the winbindd cache directly. */
1307 ret = idmap_cache_find_uid2sid(uid, psid, &expired);
1309 if (ret && !expired && is_null_sid(psid)) {
1311 * Negative cache entry, we already asked.
1312 * do legacy.
1314 legacy_uid_to_sid(psid, uid);
1315 return;
1318 if (!ret || expired) {
1319 /* Not in cache. Ask winbindd. */
1320 if (!winbind_uid_to_sid(psid, uid)) {
1322 * We shouldn't return the NULL SID
1323 * here if winbind was running and
1324 * couldn't map, as winbind will have
1325 * added a negative entry that will
1326 * cause us to go though the
1327 * legacy_uid_to_sid()
1328 * function anyway in the case above
1329 * the next time we ask.
1331 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1332 "for uid %u\n", (unsigned int)uid));
1334 legacy_uid_to_sid(psid, uid);
1335 return;
1339 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid,
1340 sid_string_dbg(psid)));
1342 store_uid_sid_cache(psid, uid);
1343 return;
1346 /*****************************************************************
1347 *THE CANONICAL* convert gid_t to SID function.
1348 *****************************************************************/
1350 void gid_to_sid(struct dom_sid *psid, gid_t gid)
1352 bool expired = true;
1353 bool ret;
1354 ZERO_STRUCTP(psid);
1356 if (fetch_sid_from_gid_cache(psid, gid))
1357 return;
1359 /* Check the winbindd cache directly. */
1360 ret = idmap_cache_find_gid2sid(gid, psid, &expired);
1362 if (ret && !expired && is_null_sid(psid)) {
1364 * Negative cache entry, we already asked.
1365 * do legacy.
1367 legacy_gid_to_sid(psid, gid);
1368 return;
1371 if (!ret || expired) {
1372 /* Not in cache. Ask winbindd. */
1373 if (!winbind_gid_to_sid(psid, gid)) {
1375 * We shouldn't return the NULL SID
1376 * here if winbind was running and
1377 * couldn't map, as winbind will have
1378 * added a negative entry that will
1379 * cause us to go though the
1380 * legacy_gid_to_sid()
1381 * function anyway in the case above
1382 * the next time we ask.
1384 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1385 "for gid %u\n", (unsigned int)gid));
1387 legacy_gid_to_sid(psid, gid);
1388 return;
1392 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid,
1393 sid_string_dbg(psid)));
1395 store_gid_sid_cache(psid, gid);
1396 return;
1399 /*****************************************************************
1400 *THE CANONICAL* convert SID to uid function.
1401 *****************************************************************/
1403 bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1405 bool expired = true;
1406 bool ret;
1407 uint32 rid;
1408 gid_t gid;
1410 if (fetch_uid_from_cache(puid, psid))
1411 return true;
1413 if (fetch_gid_from_cache(&gid, psid)) {
1414 return false;
1417 /* Optimize for the Unix Users Domain
1418 * as the conversion is straightforward */
1419 if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1420 uid_t uid = rid;
1421 *puid = uid;
1423 /* return here, don't cache */
1424 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1425 (unsigned int)*puid ));
1426 return true;
1429 /* Check the winbindd cache directly. */
1430 ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1432 if (ret && !expired && (*puid == (uid_t)-1)) {
1434 * Negative cache entry, we already asked.
1435 * do legacy.
1437 return legacy_sid_to_uid(psid, puid);
1440 if (!ret || expired) {
1441 /* Not in cache. Ask winbindd. */
1442 if (!winbind_sid_to_uid(puid, psid)) {
1443 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1444 sid_string_dbg(psid)));
1445 /* winbind failed. do legacy */
1446 return legacy_sid_to_uid(psid, puid);
1450 /* TODO: Here would be the place to allocate both a gid and a uid for
1451 * the SID in question */
1453 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1454 (unsigned int)*puid ));
1456 store_uid_sid_cache(psid, *puid);
1457 return true;
1460 /*****************************************************************
1461 *THE CANONICAL* convert SID to gid function.
1462 Group mapping is used for gids that maps to Wellknown SIDs
1463 *****************************************************************/
1465 bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1467 bool expired = true;
1468 bool ret;
1469 uint32 rid;
1470 uid_t uid;
1472 if (fetch_gid_from_cache(pgid, psid))
1473 return true;
1475 if (fetch_uid_from_cache(&uid, psid))
1476 return false;
1478 /* Optimize for the Unix Groups Domain
1479 * as the conversion is straightforward */
1480 if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1481 gid_t gid = rid;
1482 *pgid = gid;
1484 /* return here, don't cache */
1485 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1486 (unsigned int)*pgid ));
1487 return true;
1490 /* Check the winbindd cache directly. */
1491 ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1493 if (ret && !expired && (*pgid == (gid_t)-1)) {
1495 * Negative cache entry, we already asked.
1496 * do legacy.
1498 return legacy_sid_to_gid(psid, pgid);
1501 if (!ret || expired) {
1502 /* Not in cache or negative. Ask winbindd. */
1503 /* Ask winbindd if it can map this sid to a gid.
1504 * (Idmap will check it is a valid SID and of the right type) */
1506 if ( !winbind_sid_to_gid(pgid, psid) ) {
1508 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1509 sid_string_dbg(psid)));
1510 /* winbind failed. do legacy */
1511 return legacy_sid_to_gid(psid, pgid);
1515 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1516 (unsigned int)*pgid ));
1518 store_gid_sid_cache(psid, *pgid);
1519 return true;
1523 * @brief This function gets the primary group SID mapping the primary
1524 * GID of the user as obtained by an actual getpwnam() call.
1525 * This is necessary to avoid issues with arbitrary group SIDs
1526 * stored in passdb. We try as hard as we can to get the SID
1527 * corresponding to the GID, including trying group mapping.
1528 * If nothing else works, we will force "Domain Users" as the
1529 * primary group.
1530 * This is needed because we must always be able to lookup the
1531 * primary group SID, so we cannot settle for an arbitrary SID.
1533 * This call can be expensive. Use with moderation.
1534 * If you have a "samu" struct around use pdb_get_group_sid()
1535 * instead as it does properly cache results.
1537 * @param mem_ctx[in] The memory context iused to allocate the result.
1538 * @param username[in] The user's name
1539 * @param _pwd[in|out] If available, pass in user's passwd struct.
1540 * It will contain a tallocated passwd if NULL was
1541 * passed in.
1542 * @param _group_sid[out] The user's Primary Group SID
1544 * @return NTSTATUS error code.
1546 NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1547 const char *username,
1548 struct passwd **_pwd,
1549 struct dom_sid **_group_sid)
1551 TALLOC_CTX *tmp_ctx;
1552 bool need_lookup_sid = false;
1553 struct dom_sid *group_sid;
1554 struct passwd *pwd = *_pwd;
1556 tmp_ctx = talloc_new(mem_ctx);
1557 if (!tmp_ctx) {
1558 return NT_STATUS_NO_MEMORY;
1561 if (!pwd) {
1562 pwd = Get_Pwnam_alloc(mem_ctx, username);
1563 if (!pwd) {
1564 DEBUG(0, ("Failed to find a Unix account for %s",
1565 username));
1566 TALLOC_FREE(tmp_ctx);
1567 return NT_STATUS_NO_SUCH_USER;
1571 group_sid = talloc_zero(mem_ctx, struct dom_sid);
1572 if (!group_sid) {
1573 TALLOC_FREE(tmp_ctx);
1574 return NT_STATUS_NO_MEMORY;
1577 gid_to_sid(group_sid, pwd->pw_gid);
1578 if (!is_null_sid(group_sid)) {
1579 struct dom_sid domain_sid;
1580 uint32_t rid;
1582 /* We need a sid within our domain */
1583 sid_copy(&domain_sid, group_sid);
1584 sid_split_rid(&domain_sid, &rid);
1585 if (dom_sid_equal(&domain_sid, get_global_sam_sid())) {
1587 * As shortcut for the expensive lookup_sid call
1588 * compare the domain sid part
1590 switch (rid) {
1591 case DOMAIN_RID_ADMINS:
1592 case DOMAIN_RID_USERS:
1593 goto done;
1594 default:
1595 need_lookup_sid = true;
1596 break;
1598 } else {
1599 /* Try group mapping */
1600 ZERO_STRUCTP(group_sid);
1601 if (pdb_gid_to_sid(pwd->pw_gid, group_sid)) {
1602 need_lookup_sid = true;
1607 /* We must verify that this is a valid SID that resolves to a
1608 * group of the correct type */
1609 if (need_lookup_sid) {
1610 enum lsa_SidType type = SID_NAME_UNKNOWN;
1611 bool lookup_ret;
1613 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1614 sid_string_dbg(group_sid), username));
1616 /* Now check that it's actually a domain group and
1617 * not something else */
1618 lookup_ret = lookup_sid(tmp_ctx, group_sid,
1619 NULL, NULL, &type);
1621 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1622 goto done;
1625 DEBUG(3, ("Primary group %s for user %s is"
1626 " a %s and not a domain group\n",
1627 sid_string_dbg(group_sid), username,
1628 sid_type_lookup(type)));
1631 /* Everything else, failed.
1632 * Just set it to the 'Domain Users' RID of 513 which will
1633 always resolve to a name */
1634 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1635 username));
1637 sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1639 done:
1640 *_pwd = talloc_move(mem_ctx, &pwd);
1641 *_group_sid = talloc_move(mem_ctx, &group_sid);
1642 TALLOC_FREE(tmp_ctx);
1643 return NT_STATUS_OK;
1646 bool delete_uid_cache(uid_t puid)
1648 DATA_BLOB uid = data_blob_const(&puid, sizeof(puid));
1649 DATA_BLOB sid;
1651 if (!memcache_lookup(NULL, UID_SID_CACHE, uid, &sid)) {
1652 DEBUG(3, ("UID %d is not memcached!\n", (int)puid));
1653 return false;
1655 DEBUG(3, ("Delete mapping UID %d <-> %s from memcache\n", (int)puid,
1656 sid_string_dbg((struct dom_sid*)sid.data)));
1657 memcache_delete(NULL, SID_UID_CACHE, sid);
1658 memcache_delete(NULL, UID_SID_CACHE, uid);
1659 return true;
1662 bool delete_gid_cache(gid_t pgid)
1664 DATA_BLOB gid = data_blob_const(&pgid, sizeof(pgid));
1665 DATA_BLOB sid;
1666 if (!memcache_lookup(NULL, GID_SID_CACHE, gid, &sid)) {
1667 DEBUG(3, ("GID %d is not memcached!\n", (int)pgid));
1668 return false;
1670 DEBUG(3, ("Delete mapping GID %d <-> %s from memcache\n", (int)pgid,
1671 sid_string_dbg((struct dom_sid*)sid.data)));
1672 memcache_delete(NULL, SID_GID_CACHE, sid);
1673 memcache_delete(NULL, GID_SID_CACHE, gid);
1674 return true;
1677 bool delete_sid_cache(const struct dom_sid* psid)
1679 DATA_BLOB sid = data_blob_const(psid, ndr_size_dom_sid(psid, 0));
1680 DATA_BLOB id;
1681 if (memcache_lookup(NULL, SID_GID_CACHE, sid, &id)) {
1682 DEBUG(3, ("Delete mapping %s <-> GID %d from memcache\n",
1683 sid_string_dbg(psid), *(int*)id.data));
1684 memcache_delete(NULL, SID_GID_CACHE, sid);
1685 memcache_delete(NULL, GID_SID_CACHE, id);
1686 } else if (memcache_lookup(NULL, SID_UID_CACHE, sid, &id)) {
1687 DEBUG(3, ("Delete mapping %s <-> UID %d from memcache\n",
1688 sid_string_dbg(psid), *(int*)id.data));
1689 memcache_delete(NULL, SID_UID_CACHE, sid);
1690 memcache_delete(NULL, UID_SID_CACHE, id);
1691 } else {
1692 DEBUG(3, ("SID %s is not memcached!\n", sid_string_dbg(psid)));
1693 return false;
1695 return true;
1698 void flush_gid_cache(void)
1700 DEBUG(3, ("Flush GID <-> SID memcache\n"));
1701 memcache_flush(NULL, SID_GID_CACHE);
1702 memcache_flush(NULL, GID_SID_CACHE);
1705 void flush_uid_cache(void)
1707 DEBUG(3, ("Flush UID <-> SID memcache\n"));
1708 memcache_flush(NULL, SID_UID_CACHE);
1709 memcache_flush(NULL, UID_SID_CACHE);