2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Gerald (Jerry) Carter 2003
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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
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 DOM_SID *ret_sid, enum SID_NAME_USE *ret_type)
40 const char *domain = NULL;
41 const char *name = NULL;
44 enum SID_NAME_USE type;
45 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
48 if (tmp_ctx == NULL) {
49 DEBUG(0, ("talloc_new failed\n"));
53 p = strchr_m(full_name, '\\');
56 domain = talloc_strndup(tmp_ctx, full_name,
57 PTR_DIFF(p, full_name));
58 name = talloc_strdup(tmp_ctx, p+1);
60 domain = talloc_strdup(tmp_ctx, "");
61 name = talloc_strdup(tmp_ctx, full_name);
64 DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n",
65 full_name, domain, name));
67 if ((domain == NULL) || (name == NULL)) {
68 DEBUG(0, ("talloc failed\n"));
73 if (strequal(domain, get_global_sam_name())) {
75 /* It's our own domain, lookup the name in passdb */
76 if (lookup_global_sam_name(name, flags, &rid, &type)) {
77 sid_copy(&sid, get_global_sam_sid());
78 sid_append_rid(&sid, rid);
85 if (strequal(domain, builtin_domain_name())) {
87 /* Explicit request for a name in BUILTIN */
88 if (lookup_builtin_name(name, &rid)) {
89 sid_copy(&sid, &global_sid_Builtin);
90 sid_append_rid(&sid, rid);
91 type = SID_NAME_ALIAS;
98 /* Try the explicit winbind lookup first, don't let it guess the
99 * domain yet at this point yet. This comes later. */
101 if ((domain[0] != '\0') &&
102 (winbind_lookup_name(domain, name, &sid, &type))) {
106 if (strequal(domain, unix_users_domain_name())) {
107 if (lookup_unix_user_name(name, &sid)) {
108 type = SID_NAME_USER;
111 TALLOC_FREE(tmp_ctx);
115 if (strequal(domain, unix_groups_domain_name())) {
116 if (lookup_unix_group_name(name, &sid)) {
117 type = SID_NAME_DOM_GRP;
120 TALLOC_FREE(tmp_ctx);
124 if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
125 TALLOC_FREE(tmp_ctx);
130 * Nasty hack necessary for too common scenarios:
132 * For 'valid users = +users' we know "users" is most probably not
133 * BUILTIN\users but the unix group users. This hack requires the
134 * admin to explicitly qualify BUILTIN if BUILTIN\users is meant.
136 * Please note that LOOKUP_NAME_GROUP can not be requested via for
137 * example lsa_lookupnames, it only comes into this routine via
138 * the expansion of group names coming in from smb.conf
141 if ((flags & LOOKUP_NAME_GROUP) && ((grp = getgrnam(name)) != NULL)) {
145 if (pdb_getgrgid(&map, grp->gr_gid)) {
146 /* The hack gets worse. Handle the case where we have
147 * 'force group = +unixgroup' but "unixgroup" has a
150 if (sid_check_is_in_builtin(&map.sid)) {
151 domain = talloc_strdup(
152 tmp_ctx, builtin_domain_name());
154 domain = talloc_strdup(
155 tmp_ctx, get_global_sam_name());
158 sid_copy(&sid, &map.sid);
159 type = map.sid_name_use;
163 /* If we are using the smbpasswd backend, we need to use the
164 * algorithmic mapping for the unix group we find. This is
165 * necessary because when creating the NT token from the unix
166 * gid list we got from initgroups() we use gid_to_sid() that
167 * uses algorithmic mapping if pdb_rid_algorithm() is true. */
169 if (pdb_rid_algorithm() &&
170 (grp->gr_gid < max_algorithmic_gid())) {
171 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
172 sid_compose(&sid, get_global_sam_sid(),
173 pdb_gid_to_group_rid(grp->gr_gid));
174 type = SID_NAME_DOM_GRP;
178 if (lookup_unix_group_name(name, &sid)) {
179 domain = talloc_strdup(tmp_ctx,
180 unix_groups_domain_name());
181 type = SID_NAME_DOM_GRP;
186 /* Now the guesswork begins, we haven't been given an explicit
187 * domain. Try the sequence as documented on
188 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
189 * November 27, 2005 */
191 /* 1. well-known names */
193 if (lookup_wellknown_name(tmp_ctx, name, &sid, &domain)) {
194 type = SID_NAME_WKN_GRP;
198 /* 2. Builtin domain as such */
200 if (strequal(name, builtin_domain_name())) {
201 /* Swap domain and name */
202 tmp = name; name = domain; domain = tmp;
203 sid_copy(&sid, &global_sid_Builtin);
204 type = SID_NAME_DOMAIN;
208 /* 3. Account domain */
210 if (strequal(name, get_global_sam_name())) {
211 if (!secrets_fetch_domain_sid(name, &sid)) {
212 DEBUG(3, ("Could not fetch my SID\n"));
213 TALLOC_FREE(tmp_ctx);
216 /* Swap domain and name */
217 tmp = name; name = domain; domain = tmp;
218 type = SID_NAME_DOMAIN;
222 /* 4. Primary domain */
224 if (!IS_DC && strequal(name, lp_workgroup())) {
225 if (!secrets_fetch_domain_sid(name, &sid)) {
226 DEBUG(3, ("Could not fetch the domain SID\n"));
227 TALLOC_FREE(tmp_ctx);
230 /* Swap domain and name */
231 tmp = name; name = domain; domain = tmp;
232 type = SID_NAME_DOMAIN;
236 /* 5. Trusted domains as such, to me it looks as if members don't do
237 this, tested an XP workstation in a NT domain -- vl */
239 if (IS_DC && (secrets_fetch_trusted_domain_password(name, NULL,
241 /* Swap domain and name */
242 tmp = name; name = domain; domain = tmp;
243 type = SID_NAME_DOMAIN;
247 /* 6. Builtin aliases */
249 if (lookup_builtin_name(name, &rid)) {
250 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
251 sid_copy(&sid, &global_sid_Builtin);
252 sid_append_rid(&sid, rid);
253 type = SID_NAME_ALIAS;
257 /* 7. Local systems' SAM (DCs don't have a local SAM) */
258 /* 8. Primary SAM (On members, this is the domain) */
260 /* Both cases are done by looking at our passdb */
262 if (lookup_global_sam_name(name, flags, &rid, &type)) {
263 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
264 sid_copy(&sid, get_global_sam_sid());
265 sid_append_rid(&sid, rid);
269 /* Now our local possibilities are exhausted. */
271 if (!(flags & LOOKUP_NAME_REMOTE)) {
272 TALLOC_FREE(tmp_ctx);
276 /* If we are not a DC, we have to ask in our primary domain. Let
277 * winbind do that. */
280 (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
281 domain = talloc_strdup(tmp_ctx, lp_workgroup());
285 /* 9. Trusted domains */
287 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
288 * that (yet), but give it a chance. */
290 if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
293 enum SID_NAME_USE domain_type;
295 if (type == SID_NAME_DOMAIN) {
296 /* Swap name and type */
297 tmp = name; name = domain; domain = tmp;
301 /* Here we have to cope with a little deficiency in the
302 * winbind API: We have to ask it again for the name of the
303 * domain it figured out itself. Maybe fix that later... */
305 sid_copy(&dom_sid, &sid);
306 sid_split_rid(&dom_sid, &tmp_rid);
308 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
310 (domain_type != SID_NAME_DOMAIN)) {
311 DEBUG(2, ("winbind could not find the domain's name "
312 "it just looked up for us\n"));
313 TALLOC_FREE(tmp_ctx);
319 /* 10. Don't translate */
321 /* 11. Ok, windows would end here. Samba has two more options:
322 Unmapped users and unmapped groups */
324 if (lookup_unix_user_name(name, &sid)) {
325 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
326 type = SID_NAME_USER;
330 if (lookup_unix_group_name(name, &sid)) {
331 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
332 type = SID_NAME_DOM_GRP;
337 * Ok, all possibilities tried. Fail.
340 TALLOC_FREE(tmp_ctx);
344 if ((domain == NULL) || (name == NULL)) {
345 DEBUG(0, ("talloc failed\n"));
346 TALLOC_FREE(tmp_ctx);
351 * Hand over the results to the talloc context we've been given.
354 if ((ret_name != NULL) &&
355 !(*ret_name = talloc_strdup(mem_ctx, name))) {
356 DEBUG(0, ("talloc failed\n"));
357 TALLOC_FREE(tmp_ctx);
361 if (ret_domain != NULL) {
363 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
364 DEBUG(0, ("talloc failed\n"));
365 TALLOC_FREE(tmp_ctx);
369 *ret_domain = tmp_dom;
372 if (ret_sid != NULL) {
373 sid_copy(ret_sid, &sid);
376 if (ret_type != NULL) {
380 TALLOC_FREE(tmp_ctx);
384 /************************************************************************
385 Names from smb.conf can be unqualified. eg. valid users = foo
386 These names should never map to a remote name. Try global_sam_name()\foo,
387 and then "Unix Users"\foo (or "Unix Groups"\foo).
388 ************************************************************************/
390 BOOL lookup_name_smbconf(TALLOC_CTX *mem_ctx,
391 const char *full_name, int flags,
392 const char **ret_domain, const char **ret_name,
393 DOM_SID *ret_sid, enum SID_NAME_USE *ret_type)
395 char *qualified_name;
397 /* NB. No winbindd_separator here as lookup_name needs \\' */
398 if (strchr_m(full_name, '\\')) {
399 /* The name is already qualified with a domain. */
400 return lookup_name(mem_ctx, full_name, flags,
401 ret_domain, ret_name,
405 /* Try with our own SAM name. */
406 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
407 get_global_sam_name(),
409 if (!qualified_name) {
413 if (lookup_name(mem_ctx, qualified_name, flags,
414 ret_domain, ret_name,
415 ret_sid, ret_type)) {
419 /* Finally try with "Unix Users" or "Unix Group" */
420 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
421 flags & LOOKUP_NAME_GROUP ?
422 unix_groups_domain_name() :
423 unix_users_domain_name(),
425 if (!qualified_name) {
429 return lookup_name(mem_ctx, qualified_name, flags,
430 ret_domain, ret_name,
434 static BOOL wb_lookup_rids(TALLOC_CTX *mem_ctx,
435 const DOM_SID *domain_sid,
436 int num_rids, uint32 *rids,
437 const char **domain_name,
438 const char **names, enum SID_NAME_USE *types)
441 const char **my_names;
442 enum SID_NAME_USE *my_types;
445 if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
449 if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
450 domain_name, &my_names, &my_types)) {
451 for (i=0; i<num_rids; i++) {
452 types[i] = SID_NAME_UNKNOWN;
458 * winbind_lookup_rids allocates its own array. We've been given the
459 * array, so copy it over
462 for (i=0; i<num_rids; i++) {
463 if (my_names[i] == NULL) {
464 TALLOC_FREE(tmp_ctx);
467 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
468 TALLOC_FREE(tmp_ctx);
471 types[i] = my_types[i];
473 TALLOC_FREE(tmp_ctx);
477 static BOOL lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
478 int num_rids, uint32_t *rids,
479 const char **domain_name,
480 const char ***names, enum SID_NAME_USE **types)
484 *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids);
485 *types = TALLOC_ARRAY(mem_ctx, enum SID_NAME_USE, num_rids);
487 if ((*names == NULL) || (*types == NULL)) {
491 if (sid_check_is_domain(domain_sid)) {
494 if (*domain_name == NULL) {
495 *domain_name = talloc_strdup(
496 mem_ctx, get_global_sam_name());
499 if (*domain_name == NULL) {
504 result = pdb_lookup_rids(domain_sid, num_rids, rids,
508 return (NT_STATUS_IS_OK(result) ||
509 NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
510 NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
513 if (sid_check_is_builtin(domain_sid)) {
515 if (*domain_name == NULL) {
516 *domain_name = talloc_strdup(
517 mem_ctx, builtin_domain_name());
520 if (*domain_name == NULL) {
524 for (i=0; i<num_rids; i++) {
525 if (lookup_builtin_rid(*names, rids[i],
527 if ((*names)[i] == NULL) {
530 (*types)[i] = SID_NAME_ALIAS;
532 (*types)[i] = SID_NAME_UNKNOWN;
538 if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
539 for (i=0; i<num_rids; i++) {
541 sid_copy(&sid, domain_sid);
542 sid_append_rid(&sid, rids[i]);
543 if (lookup_wellknown_sid(mem_ctx, &sid,
544 domain_name, &(*names)[i])) {
545 if ((*names)[i] == NULL) {
548 (*types)[i] = SID_NAME_WKN_GRP;
550 (*types)[i] = SID_NAME_UNKNOWN;
556 if (sid_check_is_unix_users(domain_sid)) {
557 if (*domain_name == NULL) {
558 *domain_name = talloc_strdup(
559 mem_ctx, unix_users_domain_name());
561 for (i=0; i<num_rids; i++) {
562 (*names)[i] = talloc_strdup(
563 (*names), uidtoname(rids[i]));
564 (*types)[i] = SID_NAME_USER;
569 if (sid_check_is_unix_groups(domain_sid)) {
570 if (*domain_name == NULL) {
571 *domain_name = talloc_strdup(
572 mem_ctx, unix_groups_domain_name());
574 for (i=0; i<num_rids; i++) {
575 (*names)[i] = talloc_strdup(
576 (*names), gidtoname(rids[i]));
577 (*types)[i] = SID_NAME_DOM_GRP;
582 return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
583 domain_name, *names, *types);
587 * Is the SID a domain as such? If yes, lookup its name.
590 static BOOL lookup_as_domain(const DOM_SID *sid, TALLOC_CTX *mem_ctx,
594 enum SID_NAME_USE type;
596 if (sid_check_is_domain(sid)) {
597 *name = talloc_strdup(mem_ctx, get_global_sam_name());
601 if (sid_check_is_builtin(sid)) {
602 *name = talloc_strdup(mem_ctx, builtin_domain_name());
606 if (sid_check_is_wellknown_domain(sid, &tmp)) {
607 *name = talloc_strdup(mem_ctx, tmp);
611 if (sid->num_auths != 4) {
612 /* This can't be a domain */
617 uint32 i, num_domains;
618 struct trustdom_info **domains;
620 /* This is relatively expensive, but it happens only on DCs
621 * and for SIDs that have 4 sub-authorities and thus look like
624 if (!NT_STATUS_IS_OK(secrets_trusted_domains(mem_ctx,
630 for (i=0; i<num_domains; i++) {
631 if (sid_equal(sid, &domains[i]->sid)) {
632 *name = talloc_strdup(mem_ctx,
640 if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
641 (type == SID_NAME_DOMAIN)) {
650 * This tries to implement the rather weird rules for the lsa_lookup level
653 * This is as close as we can get to what W2k3 does. With this we survive the
654 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
655 * different, but I assume that's just being too liberal. For example, W2k3
656 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
657 * whereas NT4 does the same as level 1 (I think). I did not fully test that
658 * with NT4, this is what w2k3 does.
660 * Level 1: Ask everywhere
661 * Level 2: Ask domain and trusted domains, no builtin and wkn
662 * Level 3: Only ask domain
663 * Level 4: W2k3ad: Only ask AD trusts
664 * Level 5: Don't lookup anything
668 static BOOL check_dom_sid_to_level(const DOM_SID *sid, int level)
677 ret = (!sid_check_is_builtin(sid) &&
678 !sid_check_is_wellknown_domain(sid, NULL));
683 ret = sid_check_is_domain(sid);
690 DEBUG(10, ("%s SID %s in level %d\n",
691 ret ? "Accepting" : "Rejecting",
692 sid_string_static(sid), level));
697 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
698 * references to domains, it is explicitly made for this.
700 * This attempts to be as efficient as possible: It collects all SIDs
701 * belonging to a domain and hands them in bulk to the appropriate lookup
702 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
703 * *hugely* from this. Winbind is going to be extended with a lookup_rids
704 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
708 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
709 const DOM_SID **sids, int level,
710 struct lsa_dom_info **ret_domains,
711 struct lsa_name_info **ret_names)
714 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
715 struct lsa_name_info *name_infos;
716 struct lsa_dom_info *dom_infos;
720 if (!(tmp_ctx = talloc_new(mem_ctx))) {
721 DEBUG(0, ("talloc_new failed\n"));
722 return NT_STATUS_NO_MEMORY;
725 name_infos = TALLOC_ARRAY(mem_ctx, struct lsa_name_info, num_sids);
726 dom_infos = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_dom_info,
728 if ((name_infos == NULL) || (dom_infos == NULL)) {
729 result = NT_STATUS_NO_MEMORY;
733 /* First build up the data structures:
735 * dom_infos is a list of domains referenced in the list of
736 * SIDs. Later we will walk the list of domains and look up the RIDs
739 * name_infos is a shadow-copy of the SIDs array to collect the real
742 * dom_info->idxs is an index into the name_infos array. The
743 * difficulty we have here is that we need to keep the SIDs the client
744 * asked for in the same order for the reply
747 for (i=0; i<num_sids; i++) {
750 const char *domain_name = NULL;
752 sid_copy(&sid, sids[i]);
753 name_infos[i].type = SID_NAME_USE_NONE;
755 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
756 /* We can't push that through the normal lookup
757 * process, as this would reference illegal
760 * For example S-1-5-32 would end up referencing
761 * domain S-1-5- with RID 32 which is clearly wrong.
763 if (domain_name == NULL) {
764 result = NT_STATUS_NO_MEMORY;
768 name_infos[i].rid = 0;
769 name_infos[i].type = SID_NAME_DOMAIN;
770 name_infos[i].name = NULL;
772 if (sid_check_is_builtin(&sid)) {
773 /* Yes, W2k3 returns "BUILTIN" both as domain
775 name_infos[i].name = talloc_strdup(
776 name_infos, builtin_domain_name());
777 if (name_infos[i].name == NULL) {
778 result = NT_STATUS_NO_MEMORY;
783 /* This is a normal SID with rid component */
784 if (!sid_split_rid(&sid, &rid)) {
785 result = NT_STATUS_INVALID_PARAMETER;
790 if (!check_dom_sid_to_level(&sid, level)) {
791 name_infos[i].rid = 0;
792 name_infos[i].type = SID_NAME_UNKNOWN;
793 name_infos[i].name = NULL;
797 for (j=0; j<MAX_REF_DOMAINS; j++) {
798 if (!dom_infos[j].valid) {
801 if (sid_equal(&sid, &dom_infos[j].sid)) {
806 if (j == MAX_REF_DOMAINS) {
807 /* TODO: What's the right error message here? */
808 result = NT_STATUS_NONE_MAPPED;
812 if (!dom_infos[j].valid) {
813 /* We found a domain not yet referenced, create a new
815 dom_infos[j].valid = True;
816 sid_copy(&dom_infos[j].sid, &sid);
818 if (domain_name != NULL) {
819 /* This name was being found above in the case
820 * when we found a domain SID */
822 talloc_strdup(dom_infos, domain_name);
823 if (dom_infos[j].name == NULL) {
824 result = NT_STATUS_NO_MEMORY;
828 /* lookup_rids will take care of this */
829 dom_infos[j].name = NULL;
833 name_infos[i].dom_idx = j;
835 if (name_infos[i].type == SID_NAME_USE_NONE) {
836 name_infos[i].rid = rid;
838 ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
839 &dom_infos[j].num_idxs);
841 if (dom_infos[j].idxs == NULL) {
842 result = NT_STATUS_NO_MEMORY;
848 /* Iterate over the domains found */
850 for (i=0; i<MAX_REF_DOMAINS; i++) {
852 const char *domain_name = NULL;
854 enum SID_NAME_USE *types;
855 struct lsa_dom_info *dom = &dom_infos[i];
858 /* No domains left, we're done */
862 if (!(rids = TALLOC_ARRAY(tmp_ctx, uint32, dom->num_idxs))) {
863 result = NT_STATUS_NO_MEMORY;
867 for (j=0; j<dom->num_idxs; j++) {
868 rids[j] = name_infos[dom->idxs[j]].rid;
871 if (!lookup_rids(tmp_ctx, &dom->sid,
872 dom->num_idxs, rids, &domain_name,
874 result = NT_STATUS_NO_MEMORY;
878 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
879 result = NT_STATUS_NO_MEMORY;
883 for (j=0; j<dom->num_idxs; j++) {
884 int idx = dom->idxs[j];
885 name_infos[idx].type = types[j];
886 if (types[j] != SID_NAME_UNKNOWN) {
887 name_infos[idx].name =
888 talloc_strdup(name_infos, names[j]);
889 if (name_infos[idx].name == NULL) {
890 result = NT_STATUS_NO_MEMORY;
894 name_infos[idx].name = NULL;
899 *ret_domains = dom_infos;
900 *ret_names = name_infos;
904 TALLOC_FREE(dom_infos);
905 TALLOC_FREE(name_infos);
906 TALLOC_FREE(tmp_ctx);
910 /*****************************************************************
911 *THE CANONICAL* convert SID to name function.
912 *****************************************************************/
914 BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
915 const char **ret_domain, const char **ret_name,
916 enum SID_NAME_USE *ret_type)
918 struct lsa_dom_info *domain;
919 struct lsa_name_info *name;
923 if (!(tmp_ctx = talloc_new(mem_ctx))) {
924 DEBUG(0, ("talloc_new failed\n"));
928 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
933 if (name->type == SID_NAME_UNKNOWN) {
937 if ((ret_domain != NULL) &&
938 !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
942 if ((ret_name != NULL) &&
943 !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
947 if (ret_type != NULL) {
948 *ret_type = name->type;
955 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n",
956 sid_string_static(sid), domain->name,
957 name->name, name->type));
959 DEBUG(10, ("failed to lookup sid %s\n",
960 sid_string_static(sid)));
962 TALLOC_FREE(tmp_ctx);
966 /*****************************************************************
967 Id mapping cache. This is to avoid Winbind mappings already
968 seen by smbd to be queried too frequently, keeping winbindd
969 busy, and blocking smbd while winbindd is busy with other
970 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
971 modified to use linked lists by jra.
972 *****************************************************************/
974 #define MAX_UID_SID_CACHE_SIZE 100
975 #define TURNOVER_UID_SID_CACHE_SIZE 10
976 #define MAX_GID_SID_CACHE_SIZE 100
977 #define TURNOVER_GID_SID_CACHE_SIZE 10
979 static size_t n_uid_sid_cache = 0;
980 static size_t n_gid_sid_cache = 0;
982 static struct uid_sid_cache {
983 struct uid_sid_cache *next, *prev;
986 enum SID_NAME_USE sidtype;
987 } *uid_sid_cache_head;
989 static struct gid_sid_cache {
990 struct gid_sid_cache *next, *prev;
993 enum SID_NAME_USE sidtype;
994 } *gid_sid_cache_head;
996 /*****************************************************************
997 Find a SID given a uid.
998 *****************************************************************/
1000 static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
1002 struct uid_sid_cache *pc;
1004 for (pc = uid_sid_cache_head; pc; pc = pc->next) {
1005 if (pc->uid == uid) {
1007 DEBUG(3,("fetch sid from uid cache %u -> %s\n",
1008 (unsigned int)uid, sid_string_static(psid)));
1009 DLIST_PROMOTE(uid_sid_cache_head, pc);
1016 /*****************************************************************
1017 Find a uid given a SID.
1018 *****************************************************************/
1020 static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
1022 struct uid_sid_cache *pc;
1024 for (pc = uid_sid_cache_head; pc; pc = pc->next) {
1025 if (sid_compare(&pc->sid, psid) == 0) {
1027 DEBUG(3,("fetch uid from cache %u -> %s\n",
1028 (unsigned int)*puid, sid_string_static(psid)));
1029 DLIST_PROMOTE(uid_sid_cache_head, pc);
1036 /*****************************************************************
1037 Store uid to SID mapping in cache.
1038 *****************************************************************/
1040 void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
1042 struct uid_sid_cache *pc;
1044 if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) {
1045 /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */
1046 struct uid_sid_cache *pc_next;
1049 for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next)
1051 for(; pc; pc = pc_next) {
1053 DLIST_REMOVE(uid_sid_cache_head,pc);
1059 pc = SMB_MALLOC_P(struct uid_sid_cache);
1063 sid_copy(&pc->sid, psid);
1064 DLIST_ADD(uid_sid_cache_head, pc);
1068 /*****************************************************************
1069 Find a SID given a gid.
1070 *****************************************************************/
1072 static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
1074 struct gid_sid_cache *pc;
1076 for (pc = gid_sid_cache_head; pc; pc = pc->next) {
1077 if (pc->gid == gid) {
1079 DEBUG(3,("fetch sid from gid cache %u -> %s\n",
1080 (unsigned int)gid, sid_string_static(psid)));
1081 DLIST_PROMOTE(gid_sid_cache_head, pc);
1088 /*****************************************************************
1089 Find a gid given a SID.
1090 *****************************************************************/
1092 static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
1094 struct gid_sid_cache *pc;
1096 for (pc = gid_sid_cache_head; pc; pc = pc->next) {
1097 if (sid_compare(&pc->sid, psid) == 0) {
1099 DEBUG(3,("fetch gid from cache %u -> %s\n",
1100 (unsigned int)*pgid, sid_string_static(psid)));
1101 DLIST_PROMOTE(gid_sid_cache_head, pc);
1108 /*****************************************************************
1109 Store gid to SID mapping in cache.
1110 *****************************************************************/
1112 void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
1114 struct gid_sid_cache *pc;
1116 if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) {
1117 /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */
1118 struct gid_sid_cache *pc_next;
1121 for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next)
1123 for(; pc; pc = pc_next) {
1125 DLIST_REMOVE(gid_sid_cache_head,pc);
1131 pc = SMB_MALLOC_P(struct gid_sid_cache);
1135 sid_copy(&pc->sid, psid);
1136 DLIST_ADD(gid_sid_cache_head, pc);
1138 DEBUG(3,("store_gid_sid_cache: gid %u in cache -> %s\n", (unsigned int)gid,
1139 sid_string_static(psid)));
1144 /*****************************************************************
1145 *THE CANONICAL* convert uid_t to SID function.
1146 *****************************************************************/
1148 void uid_to_sid(DOM_SID *psid, uid_t uid)
1155 if (fetch_sid_from_uid_cache(psid, uid))
1158 if (lp_idmap_uid(&low, &high) && (uid >= low) && (uid <= high) &&
1159 winbind_uid_to_sid(psid, uid)) {
1161 DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
1162 (unsigned int)uid, sid_string_static(psid)));
1166 if (pdb_uid_to_rid(uid, &rid)) {
1167 /* This is a mapped user */
1168 sid_copy(psid, get_global_sam_sid());
1169 sid_append_rid(psid, rid);
1173 if (pdb_rid_algorithm() && (uid < max_algorithmic_uid())) {
1174 sid_copy(psid, get_global_sam_sid());
1175 sid_append_rid(psid, algorithmic_pdb_uid_to_user_rid(uid));
1178 uid_to_unix_users_sid(uid, psid);
1183 DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid,
1184 sid_string_static(psid)));
1186 store_uid_sid_cache(psid, uid);
1190 /*****************************************************************
1191 *THE CANONICAL* convert gid_t to SID function.
1192 *****************************************************************/
1194 void gid_to_sid(DOM_SID *psid, gid_t gid)
1200 if (fetch_sid_from_gid_cache(psid, gid))
1203 if (lp_idmap_gid(&low, &high) && (gid >= low) && (gid <= high) &&
1204 winbind_gid_to_sid(psid, gid)) {
1206 DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
1207 (unsigned int)gid, sid_string_static(psid)));
1211 if (pdb_gid_to_sid(gid, psid)) {
1212 /* This is a mapped group */
1216 if (pdb_rid_algorithm() && (gid < max_algorithmic_gid())) {
1217 sid_copy(psid, get_global_sam_sid());
1218 sid_append_rid(psid, pdb_gid_to_group_rid(gid));
1221 sid_copy(psid, &global_sid_Unix_Groups);
1222 sid_append_rid(psid, gid);
1227 DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid,
1228 sid_string_static(psid)));
1230 store_gid_sid_cache(psid, gid);
1234 /*****************************************************************
1235 *THE CANONICAL* convert SID to uid function.
1236 *****************************************************************/
1238 BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid)
1240 enum SID_NAME_USE type;
1244 if (fetch_uid_from_cache(puid, psid))
1247 if (fetch_gid_from_cache(&gid, psid)) {
1251 if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1257 if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
1260 if (pdb_sid_to_id(psid, &id, &type)) {
1261 if (type != SID_NAME_USER) {
1262 DEBUG(5, ("sid %s is a %s, expected a user\n",
1263 sid_string_static(psid),
1264 sid_type_lookup(type)));
1270 if (pdb_rid_algorithm() &&
1271 algorithmic_pdb_rid_is_user(rid)) {
1272 *puid = algorithmic_pdb_user_rid_to_uid(rid);
1276 /* This was ours, but it was neither mapped nor
1277 * algorithmic. Fail */
1281 if (winbind_lookup_sid(NULL, psid, NULL, NULL, &type)) {
1283 if (type != SID_NAME_USER) {
1284 DEBUG(10, ("sid_to_uid: sid %s is a %s\n",
1285 sid_string_static(psid),
1286 sid_type_lookup(type)));
1290 if (!winbind_sid_to_uid(puid, psid)) {
1291 DEBUG(5, ("sid_to_uid: winbind failed to allocate a "
1292 "new uid for sid %s\n",
1293 sid_string_static(psid)));
1299 /* TODO: Here would be the place to allocate both a gid and a uid for
1300 * the SID in question */
1305 DEBUG(10,("sid_to_uid: %s -> %u\n", sid_string_static(psid),
1306 (unsigned int)*puid ));
1308 store_uid_sid_cache(psid, *puid);
1312 /*****************************************************************
1313 *THE CANONICAL* convert SID to gid function.
1314 Group mapping is used for gids that maps to Wellknown SIDs
1315 *****************************************************************/
1317 BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid)
1322 enum SID_NAME_USE type;
1325 if (fetch_gid_from_cache(pgid, psid))
1328 if (fetch_uid_from_cache(&uid, psid))
1331 if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1337 if ((sid_check_is_in_builtin(psid) ||
1338 sid_check_is_in_wellknown_domain(psid))) {
1339 if (pdb_getgrsid(&map, *psid)) {
1346 if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
1347 if (pdb_sid_to_id(psid, &id, &type)) {
1348 if ((type != SID_NAME_DOM_GRP) &&
1349 (type != SID_NAME_ALIAS)) {
1350 DEBUG(5, ("sid %s is a %s, expected a group\n",
1351 sid_string_static(psid),
1352 sid_type_lookup(type)));
1358 if (pdb_rid_algorithm() &&
1359 !algorithmic_pdb_rid_is_user(rid)) {
1360 /* This must be a group, presented as alias */
1361 *pgid = pdb_group_rid_to_gid(rid);
1364 /* This was ours, but it was neither mapped nor
1365 * algorithmic. Fail. */
1369 if (!winbind_lookup_sid(NULL, psid, NULL, NULL, &type)) {
1370 DEBUG(11,("sid_to_gid: no one knows the SID %s (tried local, "
1371 "then winbind)\n", sid_string_static(psid)));
1376 /* winbindd knows it; Ensure this is a group sid */
1378 if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
1379 (type != SID_NAME_WKN_GRP)) {
1380 DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is "
1381 "a %s\n", sid_type_lookup(type)));
1385 /* winbindd knows it and it is a type of group; sid_to_gid must succeed
1386 or we are dead in the water */
1388 if ( !winbind_sid_to_gid(pgid, psid) ) {
1389 DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid "
1390 "for sid %s\n", sid_string_static(psid)));
1395 DEBUG(10,("sid_to_gid: %s -> %u\n", sid_string_static(psid),
1396 (unsigned int)*pgid ));
1398 store_gid_sid_cache(psid, *pgid);