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 if ((domain == NULL) || (name == NULL)) {
65 DEBUG(0, ("talloc failed\n"));
70 if (strequal(domain, get_global_sam_name())) {
72 /* It's our own domain, lookup the name in passdb */
73 if (lookup_global_sam_name(name, flags, &rid, &type)) {
74 sid_copy(&sid, get_global_sam_sid());
75 sid_append_rid(&sid, rid);
82 if (strequal(domain, builtin_domain_name())) {
84 /* Explicit request for a name in BUILTIN */
85 if (lookup_builtin_name(name, &rid)) {
86 sid_copy(&sid, &global_sid_Builtin);
87 sid_append_rid(&sid, rid);
88 type = SID_NAME_ALIAS;
95 /* Try the explicit winbind lookup first, don't let it guess the
96 * domain yet at this point yet. This comes later. */
98 if ((domain[0] != '\0') &&
99 (winbind_lookup_name(domain, name, &sid, &type))) {
103 if (strequal(domain, unix_users_domain_name())) {
104 if (lookup_unix_user_name(name, &sid)) {
105 type = SID_NAME_USER;
108 TALLOC_FREE(tmp_ctx);
112 if (strequal(domain, unix_groups_domain_name())) {
113 if (lookup_unix_group_name(name, &sid)) {
114 type = SID_NAME_DOM_GRP;
117 TALLOC_FREE(tmp_ctx);
121 if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
122 TALLOC_FREE(tmp_ctx);
127 * Nasty hack necessary for too common scenarios:
129 * For 'valid users = +users' we know "users" is most probably not
130 * BUILTIN\users but the unix group users. This hack requires the
131 * admin to explicitly qualify BUILTIN if BUILTIN\users is meant.
133 * Please note that LOOKUP_NAME_GROUP can not be requested via for
134 * example lsa_lookupnames, it only comes into this routine via
135 * the expansion of group names coming in from smb.conf
138 if ((flags & LOOKUP_NAME_GROUP) && ((grp = getgrnam(name)) != NULL)) {
142 if (pdb_getgrgid(&map, grp->gr_gid)) {
143 /* The hack gets worse. Handle the case where we have
144 * 'force group = +unixgroup' but "unixgroup" has a
147 if (sid_check_is_in_builtin(&map.sid)) {
148 domain = talloc_strdup(
149 tmp_ctx, builtin_domain_name());
151 domain = talloc_strdup(
152 tmp_ctx, get_global_sam_name());
155 sid_copy(&sid, &map.sid);
156 type = map.sid_name_use;
160 /* If we are using the smbpasswd backend, we need to use the
161 * algorithmic mapping for the unix group we find. This is
162 * necessary because when creating the NT token from the unix
163 * gid list we got from initgroups() we use gid_to_sid() that
164 * uses algorithmic mapping if pdb_rid_algorithm() is true. */
166 if (pdb_rid_algorithm() &&
167 (grp->gr_gid < max_algorithmic_gid())) {
168 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
169 sid_compose(&sid, get_global_sam_sid(),
170 pdb_gid_to_group_rid(grp->gr_gid));
171 type = SID_NAME_DOM_GRP;
175 if (lookup_unix_group_name(name, &sid)) {
176 domain = talloc_strdup(tmp_ctx,
177 unix_groups_domain_name());
178 type = SID_NAME_DOM_GRP;
183 /* Now the guesswork begins, we haven't been given an explicit
184 * domain. Try the sequence as documented on
185 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
186 * November 27, 2005 */
188 /* 1. well-known names */
190 if (lookup_wellknown_name(tmp_ctx, name, &sid, &domain)) {
191 type = SID_NAME_WKN_GRP;
195 /* 2. Builtin domain as such */
197 if (strequal(name, builtin_domain_name())) {
198 /* Swap domain and name */
199 tmp = name; name = domain; domain = tmp;
200 sid_copy(&sid, &global_sid_Builtin);
201 type = SID_NAME_DOMAIN;
205 /* 3. Account domain */
207 if (strequal(name, get_global_sam_name())) {
208 if (!secrets_fetch_domain_sid(name, &sid)) {
209 DEBUG(3, ("Could not fetch my SID\n"));
210 TALLOC_FREE(tmp_ctx);
213 /* Swap domain and name */
214 tmp = name; name = domain; domain = tmp;
215 type = SID_NAME_DOMAIN;
219 /* 4. Primary domain */
221 if (!IS_DC && strequal(name, lp_workgroup())) {
222 if (!secrets_fetch_domain_sid(name, &sid)) {
223 DEBUG(3, ("Could not fetch the domain SID\n"));
224 TALLOC_FREE(tmp_ctx);
227 /* Swap domain and name */
228 tmp = name; name = domain; domain = tmp;
229 type = SID_NAME_DOMAIN;
233 /* 5. Trusted domains as such, to me it looks as if members don't do
234 this, tested an XP workstation in a NT domain -- vl */
236 if (IS_DC && (secrets_fetch_trusted_domain_password(name, NULL,
238 /* Swap domain and name */
239 tmp = name; name = domain; domain = tmp;
240 type = SID_NAME_DOMAIN;
244 /* 6. Builtin aliases */
246 if (lookup_builtin_name(name, &rid)) {
247 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
248 sid_copy(&sid, &global_sid_Builtin);
249 sid_append_rid(&sid, rid);
250 type = SID_NAME_ALIAS;
254 /* 7. Local systems' SAM (DCs don't have a local SAM) */
255 /* 8. Primary SAM (On members, this is the domain) */
257 /* Both cases are done by looking at our passdb */
259 if (lookup_global_sam_name(name, flags, &rid, &type)) {
260 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
261 sid_copy(&sid, get_global_sam_sid());
262 sid_append_rid(&sid, rid);
266 /* Now our local possibilities are exhausted. */
268 if (!(flags & LOOKUP_NAME_REMOTE)) {
269 TALLOC_FREE(tmp_ctx);
273 /* If we are not a DC, we have to ask in our primary domain. Let
274 * winbind do that. */
277 (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
278 domain = talloc_strdup(tmp_ctx, lp_workgroup());
282 /* 9. Trusted domains */
284 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
285 * that (yet), but give it a chance. */
287 if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
290 enum SID_NAME_USE domain_type;
292 if (type == SID_NAME_DOMAIN) {
293 /* Swap name and type */
294 tmp = name; name = domain; domain = tmp;
298 /* Here we have to cope with a little deficiency in the
299 * winbind API: We have to ask it again for the name of the
300 * domain it figured out itself. Maybe fix that later... */
302 sid_copy(&dom_sid, &sid);
303 sid_split_rid(&dom_sid, &tmp_rid);
305 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
307 (domain_type != SID_NAME_DOMAIN)) {
308 DEBUG(2, ("winbind could not find the domain's name "
309 "it just looked up for us\n"));
310 TALLOC_FREE(tmp_ctx);
316 /* 10. Don't translate */
318 /* 11. Ok, windows would end here. Samba has two more options:
319 Unmapped users and unmapped groups */
321 if (lookup_unix_user_name(name, &sid)) {
322 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
323 type = SID_NAME_USER;
327 if (lookup_unix_group_name(name, &sid)) {
328 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
329 type = SID_NAME_DOM_GRP;
334 * Ok, all possibilities tried. Fail.
337 TALLOC_FREE(tmp_ctx);
341 if ((domain == NULL) || (name == NULL)) {
342 DEBUG(0, ("talloc failed\n"));
343 TALLOC_FREE(tmp_ctx);
348 * Hand over the results to the talloc context we've been given.
351 if ((ret_name != NULL) &&
352 !(*ret_name = talloc_strdup(mem_ctx, name))) {
353 DEBUG(0, ("talloc failed\n"));
354 TALLOC_FREE(tmp_ctx);
358 if (ret_domain != NULL) {
360 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
361 DEBUG(0, ("talloc failed\n"));
362 TALLOC_FREE(tmp_ctx);
366 *ret_domain = tmp_dom;
369 if (ret_sid != NULL) {
370 sid_copy(ret_sid, &sid);
373 if (ret_type != NULL) {
377 TALLOC_FREE(tmp_ctx);
381 /************************************************************************
382 Names from smb.conf can be unqualified. eg. valid users = foo
383 These names should never map to a remote name. Try lp_workgroup()\foo,
384 and then "Unix Users"\foo (or "Unix Groups"\foo).
385 ************************************************************************/
387 BOOL lookup_name_smbconf(TALLOC_CTX *mem_ctx,
388 const char *full_name, int flags,
389 const char **ret_domain, const char **ret_name,
390 DOM_SID *ret_sid, enum SID_NAME_USE *ret_type)
392 char *qualified_name;
394 /* NB. No winbindd_separator here as lookup_name needs \\' */
395 if (strchr_m(full_name, '\\')) {
396 /* The name is already qualified with a domain. */
397 return lookup_name(mem_ctx, full_name, flags,
398 ret_domain, ret_name,
402 /* Try with our own domain name. */
403 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
406 if (!qualified_name) {
410 if (lookup_name(mem_ctx, qualified_name, flags,
411 ret_domain, ret_name,
412 ret_sid, ret_type)) {
416 /* Finally try with "Unix Users" or "Unix Group" */
417 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
418 flags & LOOKUP_NAME_GROUP ?
419 unix_groups_domain_name() :
420 unix_users_domain_name(),
422 if (!qualified_name) {
426 return lookup_name(mem_ctx, qualified_name, flags,
427 ret_domain, ret_name,
431 static BOOL wb_lookup_rids(TALLOC_CTX *mem_ctx,
432 const DOM_SID *domain_sid,
433 int num_rids, uint32 *rids,
434 const char **domain_name,
435 const char **names, enum SID_NAME_USE *types)
438 const char **my_names;
439 enum SID_NAME_USE *my_types;
442 if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
446 if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
447 domain_name, &my_names, &my_types)) {
448 for (i=0; i<num_rids; i++) {
449 types[i] = SID_NAME_UNKNOWN;
455 * winbind_lookup_rids allocates its own array. We've been given the
456 * array, so copy it over
459 for (i=0; i<num_rids; i++) {
460 if (my_names[i] == NULL) {
461 TALLOC_FREE(tmp_ctx);
464 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
465 TALLOC_FREE(tmp_ctx);
468 types[i] = my_types[i];
470 TALLOC_FREE(tmp_ctx);
474 static BOOL lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
475 int num_rids, uint32_t *rids,
476 const char **domain_name,
477 const char ***names, enum SID_NAME_USE **types)
481 *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids);
482 *types = TALLOC_ARRAY(mem_ctx, enum SID_NAME_USE, num_rids);
484 if ((*names == NULL) || (*types == NULL)) {
488 if (sid_check_is_domain(domain_sid)) {
491 if (*domain_name == NULL) {
492 *domain_name = talloc_strdup(
493 mem_ctx, get_global_sam_name());
496 if (*domain_name == NULL) {
501 result = pdb_lookup_rids(domain_sid, num_rids, rids,
505 return (NT_STATUS_IS_OK(result) ||
506 NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
507 NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
510 if (sid_check_is_builtin(domain_sid)) {
512 if (*domain_name == NULL) {
513 *domain_name = talloc_strdup(
514 mem_ctx, builtin_domain_name());
517 if (*domain_name == NULL) {
521 for (i=0; i<num_rids; i++) {
522 if (lookup_builtin_rid(*names, rids[i],
524 if ((*names)[i] == NULL) {
527 (*types)[i] = SID_NAME_ALIAS;
529 (*types)[i] = SID_NAME_UNKNOWN;
535 if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
536 for (i=0; i<num_rids; i++) {
538 sid_copy(&sid, domain_sid);
539 sid_append_rid(&sid, rids[i]);
540 if (lookup_wellknown_sid(mem_ctx, &sid,
541 domain_name, &(*names)[i])) {
542 if ((*names)[i] == NULL) {
545 (*types)[i] = SID_NAME_WKN_GRP;
547 (*types)[i] = SID_NAME_UNKNOWN;
553 if (sid_check_is_unix_users(domain_sid)) {
554 if (*domain_name == NULL) {
555 *domain_name = talloc_strdup(
556 mem_ctx, unix_users_domain_name());
558 for (i=0; i<num_rids; i++) {
559 (*names)[i] = talloc_strdup(
560 (*names), uidtoname(rids[i]));
561 (*types)[i] = SID_NAME_USER;
566 if (sid_check_is_unix_groups(domain_sid)) {
567 if (*domain_name == NULL) {
568 *domain_name = talloc_strdup(
569 mem_ctx, unix_groups_domain_name());
571 for (i=0; i<num_rids; i++) {
572 (*names)[i] = talloc_strdup(
573 (*names), gidtoname(rids[i]));
574 (*types)[i] = SID_NAME_DOM_GRP;
579 return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
580 domain_name, *names, *types);
584 * Is the SID a domain as such? If yes, lookup its name.
587 static BOOL lookup_as_domain(const DOM_SID *sid, TALLOC_CTX *mem_ctx,
591 enum SID_NAME_USE type;
593 if (sid_check_is_domain(sid)) {
594 *name = talloc_strdup(mem_ctx, get_global_sam_name());
598 if (sid_check_is_builtin(sid)) {
599 *name = talloc_strdup(mem_ctx, builtin_domain_name());
603 if (sid_check_is_wellknown_domain(sid, &tmp)) {
604 *name = talloc_strdup(mem_ctx, tmp);
608 if (sid->num_auths != 4) {
609 /* This can't be a domain */
614 uint32 i, num_domains;
615 struct trustdom_info **domains;
617 /* This is relatively expensive, but it happens only on DCs
618 * and for SIDs that have 4 sub-authorities and thus look like
621 if (!NT_STATUS_IS_OK(secrets_trusted_domains(mem_ctx,
627 for (i=0; i<num_domains; i++) {
628 if (sid_equal(sid, &domains[i]->sid)) {
629 *name = talloc_strdup(mem_ctx,
637 if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
638 (type == SID_NAME_DOMAIN)) {
647 * This tries to implement the rather weird rules for the lsa_lookup level
650 * This is as close as we can get to what W2k3 does. With this we survive the
651 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
652 * different, but I assume that's just being too liberal. For example, W2k3
653 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
654 * whereas NT4 does the same as level 1 (I think). I did not fully test that
655 * with NT4, this is what w2k3 does.
657 * Level 1: Ask everywhere
658 * Level 2: Ask domain and trusted domains, no builtin and wkn
659 * Level 3: Only ask domain
660 * Level 4: W2k3ad: Only ask AD trusts
661 * Level 5: Don't lookup anything
665 static BOOL check_dom_sid_to_level(const DOM_SID *sid, int level)
674 ret = (!sid_check_is_builtin(sid) &&
675 !sid_check_is_wellknown_domain(sid, NULL));
680 ret = sid_check_is_domain(sid);
687 DEBUG(10, ("%s SID %s in level %d\n",
688 ret ? "Accepting" : "Rejecting",
689 sid_string_static(sid), level));
694 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
695 * references to domains, it is explicitly made for this.
697 * This attempts to be as efficient as possible: It collects all SIDs
698 * belonging to a domain and hands them in bulk to the appropriate lookup
699 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
700 * *hugely* from this. Winbind is going to be extended with a lookup_rids
701 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
705 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
706 const DOM_SID **sids, int level,
707 struct lsa_dom_info **ret_domains,
708 struct lsa_name_info **ret_names)
711 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
712 struct lsa_name_info *name_infos;
713 struct lsa_dom_info *dom_infos;
717 if (!(tmp_ctx = talloc_new(mem_ctx))) {
718 DEBUG(0, ("talloc_new failed\n"));
719 return NT_STATUS_NO_MEMORY;
722 name_infos = TALLOC_ARRAY(mem_ctx, struct lsa_name_info, num_sids);
723 dom_infos = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_dom_info,
725 if ((name_infos == NULL) || (dom_infos == NULL)) {
726 result = NT_STATUS_NO_MEMORY;
730 /* First build up the data structures:
732 * dom_infos is a list of domains referenced in the list of
733 * SIDs. Later we will walk the list of domains and look up the RIDs
736 * name_infos is a shadow-copy of the SIDs array to collect the real
739 * dom_info->idxs is an index into the name_infos array. The
740 * difficulty we have here is that we need to keep the SIDs the client
741 * asked for in the same order for the reply
744 for (i=0; i<num_sids; i++) {
747 const char *domain_name = NULL;
749 sid_copy(&sid, sids[i]);
750 name_infos[i].type = SID_NAME_USE_NONE;
752 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
753 /* We can't push that through the normal lookup
754 * process, as this would reference illegal
757 * For example S-1-5-32 would end up referencing
758 * domain S-1-5- with RID 32 which is clearly wrong.
760 if (domain_name == NULL) {
761 result = NT_STATUS_NO_MEMORY;
765 name_infos[i].rid = 0;
766 name_infos[i].type = SID_NAME_DOMAIN;
767 name_infos[i].name = NULL;
769 if (sid_check_is_builtin(&sid)) {
770 /* Yes, W2k3 returns "BUILTIN" both as domain
772 name_infos[i].name = talloc_strdup(
773 name_infos, builtin_domain_name());
774 if (name_infos[i].name == NULL) {
775 result = NT_STATUS_NO_MEMORY;
780 /* This is a normal SID with rid component */
781 if (!sid_split_rid(&sid, &rid)) {
782 result = NT_STATUS_INVALID_PARAMETER;
787 if (!check_dom_sid_to_level(&sid, level)) {
788 name_infos[i].rid = 0;
789 name_infos[i].type = SID_NAME_UNKNOWN;
790 name_infos[i].name = NULL;
794 for (j=0; j<MAX_REF_DOMAINS; j++) {
795 if (!dom_infos[j].valid) {
798 if (sid_equal(&sid, &dom_infos[j].sid)) {
803 if (j == MAX_REF_DOMAINS) {
804 /* TODO: What's the right error message here? */
805 result = NT_STATUS_NONE_MAPPED;
809 if (!dom_infos[j].valid) {
810 /* We found a domain not yet referenced, create a new
812 dom_infos[j].valid = True;
813 sid_copy(&dom_infos[j].sid, &sid);
815 if (domain_name != NULL) {
816 /* This name was being found above in the case
817 * when we found a domain SID */
819 talloc_strdup(dom_infos, domain_name);
820 if (dom_infos[j].name == NULL) {
821 result = NT_STATUS_NO_MEMORY;
825 /* lookup_rids will take care of this */
826 dom_infos[j].name = NULL;
830 name_infos[i].dom_idx = j;
832 if (name_infos[i].type == SID_NAME_USE_NONE) {
833 name_infos[i].rid = rid;
835 ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
836 &dom_infos[j].num_idxs);
838 if (dom_infos[j].idxs == NULL) {
839 result = NT_STATUS_NO_MEMORY;
845 /* Iterate over the domains found */
847 for (i=0; i<MAX_REF_DOMAINS; i++) {
849 const char *domain_name = NULL;
851 enum SID_NAME_USE *types;
852 struct lsa_dom_info *dom = &dom_infos[i];
855 /* No domains left, we're done */
859 if (!(rids = TALLOC_ARRAY(tmp_ctx, uint32, dom->num_idxs))) {
860 result = NT_STATUS_NO_MEMORY;
864 for (j=0; j<dom->num_idxs; j++) {
865 rids[j] = name_infos[dom->idxs[j]].rid;
868 if (!lookup_rids(tmp_ctx, &dom->sid,
869 dom->num_idxs, rids, &domain_name,
871 result = NT_STATUS_NO_MEMORY;
875 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
876 result = NT_STATUS_NO_MEMORY;
880 for (j=0; j<dom->num_idxs; j++) {
881 int idx = dom->idxs[j];
882 name_infos[idx].type = types[j];
883 if (types[j] != SID_NAME_UNKNOWN) {
884 name_infos[idx].name =
885 talloc_strdup(name_infos, names[j]);
886 if (name_infos[idx].name == NULL) {
887 result = NT_STATUS_NO_MEMORY;
891 name_infos[idx].name = NULL;
896 *ret_domains = dom_infos;
897 *ret_names = name_infos;
901 TALLOC_FREE(dom_infos);
902 TALLOC_FREE(name_infos);
903 TALLOC_FREE(tmp_ctx);
907 /*****************************************************************
908 *THE CANONICAL* convert SID to name function.
909 *****************************************************************/
911 BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
912 const char **ret_domain, const char **ret_name,
913 enum SID_NAME_USE *ret_type)
915 struct lsa_dom_info *domain;
916 struct lsa_name_info *name;
920 if (!(tmp_ctx = talloc_new(mem_ctx))) {
921 DEBUG(0, ("talloc_new failed\n"));
925 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
930 if (name->type == SID_NAME_UNKNOWN) {
934 if ((ret_domain != NULL) &&
935 !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
939 if ((ret_name != NULL) &&
940 !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
944 if (ret_type != NULL) {
945 *ret_type = name->type;
952 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n",
953 sid_string_static(sid), domain->name,
954 name->name, name->type));
956 DEBUG(10, ("failed to lookup sid %s\n",
957 sid_string_static(sid)));
959 TALLOC_FREE(tmp_ctx);
963 /*****************************************************************
964 Id mapping cache. This is to avoid Winbind mappings already
965 seen by smbd to be queried too frequently, keeping winbindd
966 busy, and blocking smbd while winbindd is busy with other
967 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
968 modified to use linked lists by jra.
969 *****************************************************************/
971 #define MAX_UID_SID_CACHE_SIZE 100
972 #define TURNOVER_UID_SID_CACHE_SIZE 10
973 #define MAX_GID_SID_CACHE_SIZE 100
974 #define TURNOVER_GID_SID_CACHE_SIZE 10
976 static size_t n_uid_sid_cache = 0;
977 static size_t n_gid_sid_cache = 0;
979 static struct uid_sid_cache {
980 struct uid_sid_cache *next, *prev;
983 enum SID_NAME_USE sidtype;
984 } *uid_sid_cache_head;
986 static struct gid_sid_cache {
987 struct gid_sid_cache *next, *prev;
990 enum SID_NAME_USE sidtype;
991 } *gid_sid_cache_head;
993 /*****************************************************************
994 Find a SID given a uid.
995 *****************************************************************/
997 static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
999 struct uid_sid_cache *pc;
1001 for (pc = uid_sid_cache_head; pc; pc = pc->next) {
1002 if (pc->uid == uid) {
1004 DEBUG(3,("fetch sid from uid cache %u -> %s\n",
1005 (unsigned int)uid, sid_string_static(psid)));
1006 DLIST_PROMOTE(uid_sid_cache_head, pc);
1013 /*****************************************************************
1014 Find a uid given a SID.
1015 *****************************************************************/
1017 static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
1019 struct uid_sid_cache *pc;
1021 for (pc = uid_sid_cache_head; pc; pc = pc->next) {
1022 if (sid_compare(&pc->sid, psid) == 0) {
1024 DEBUG(3,("fetch uid from cache %u -> %s\n",
1025 (unsigned int)*puid, sid_string_static(psid)));
1026 DLIST_PROMOTE(uid_sid_cache_head, pc);
1033 /*****************************************************************
1034 Store uid to SID mapping in cache.
1035 *****************************************************************/
1037 void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
1039 struct uid_sid_cache *pc;
1041 if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) {
1042 /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */
1043 struct uid_sid_cache *pc_next;
1046 for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next)
1048 for(; pc; pc = pc_next) {
1050 DLIST_REMOVE(uid_sid_cache_head,pc);
1056 pc = SMB_MALLOC_P(struct uid_sid_cache);
1060 sid_copy(&pc->sid, psid);
1061 DLIST_ADD(uid_sid_cache_head, pc);
1065 /*****************************************************************
1066 Find a SID given a gid.
1067 *****************************************************************/
1069 static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
1071 struct gid_sid_cache *pc;
1073 for (pc = gid_sid_cache_head; pc; pc = pc->next) {
1074 if (pc->gid == gid) {
1076 DEBUG(3,("fetch sid from gid cache %u -> %s\n",
1077 (unsigned int)gid, sid_string_static(psid)));
1078 DLIST_PROMOTE(gid_sid_cache_head, pc);
1085 /*****************************************************************
1086 Find a gid given a SID.
1087 *****************************************************************/
1089 static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
1091 struct gid_sid_cache *pc;
1093 for (pc = gid_sid_cache_head; pc; pc = pc->next) {
1094 if (sid_compare(&pc->sid, psid) == 0) {
1096 DEBUG(3,("fetch gid from cache %u -> %s\n",
1097 (unsigned int)*pgid, sid_string_static(psid)));
1098 DLIST_PROMOTE(gid_sid_cache_head, pc);
1105 /*****************************************************************
1106 Store gid to SID mapping in cache.
1107 *****************************************************************/
1109 void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
1111 struct gid_sid_cache *pc;
1113 if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) {
1114 /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */
1115 struct gid_sid_cache *pc_next;
1118 for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next)
1120 for(; pc; pc = pc_next) {
1122 DLIST_REMOVE(gid_sid_cache_head,pc);
1128 pc = SMB_MALLOC_P(struct gid_sid_cache);
1132 sid_copy(&pc->sid, psid);
1133 DLIST_ADD(gid_sid_cache_head, pc);
1135 DEBUG(3,("store_gid_sid_cache: gid %u in cache -> %s\n", (unsigned int)gid,
1136 sid_string_static(psid)));
1141 /*****************************************************************
1142 *THE CANONICAL* convert uid_t to SID function.
1143 *****************************************************************/
1145 void uid_to_sid(DOM_SID *psid, uid_t uid)
1152 if (fetch_sid_from_uid_cache(psid, uid))
1155 if (lp_idmap_uid(&low, &high) && (uid >= low) && (uid <= high) &&
1156 winbind_uid_to_sid(psid, uid)) {
1158 DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
1159 (unsigned int)uid, sid_string_static(psid)));
1163 if (pdb_uid_to_rid(uid, &rid)) {
1164 /* This is a mapped user */
1165 sid_copy(psid, get_global_sam_sid());
1166 sid_append_rid(psid, rid);
1170 if (pdb_rid_algorithm() && (uid < max_algorithmic_uid())) {
1171 sid_copy(psid, get_global_sam_sid());
1172 sid_append_rid(psid, algorithmic_pdb_uid_to_user_rid(uid));
1175 uid_to_unix_users_sid(uid, psid);
1180 DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid,
1181 sid_string_static(psid)));
1183 store_uid_sid_cache(psid, uid);
1187 /*****************************************************************
1188 *THE CANONICAL* convert gid_t to SID function.
1189 *****************************************************************/
1191 void gid_to_sid(DOM_SID *psid, gid_t gid)
1197 if (fetch_sid_from_gid_cache(psid, gid))
1200 if (lp_idmap_gid(&low, &high) && (gid >= low) && (gid <= high) &&
1201 winbind_gid_to_sid(psid, gid)) {
1203 DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
1204 (unsigned int)gid, sid_string_static(psid)));
1208 if (pdb_gid_to_sid(gid, psid)) {
1209 /* This is a mapped group */
1213 if (pdb_rid_algorithm() && (gid < max_algorithmic_gid())) {
1214 sid_copy(psid, get_global_sam_sid());
1215 sid_append_rid(psid, pdb_gid_to_group_rid(gid));
1218 sid_copy(psid, &global_sid_Unix_Groups);
1219 sid_append_rid(psid, gid);
1224 DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid,
1225 sid_string_static(psid)));
1227 store_gid_sid_cache(psid, gid);
1231 /*****************************************************************
1232 *THE CANONICAL* convert SID to uid function.
1233 *****************************************************************/
1235 BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid)
1237 enum SID_NAME_USE type;
1241 if (fetch_uid_from_cache(puid, psid))
1244 if (fetch_gid_from_cache(&gid, psid)) {
1248 if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1254 if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
1257 if (pdb_sid_to_id(psid, &id, &type)) {
1258 if (type != SID_NAME_USER) {
1259 DEBUG(5, ("sid %s is a %s, expected a user\n",
1260 sid_string_static(psid),
1261 sid_type_lookup(type)));
1267 if (pdb_rid_algorithm() &&
1268 algorithmic_pdb_rid_is_user(rid)) {
1269 *puid = algorithmic_pdb_user_rid_to_uid(rid);
1273 /* This was ours, but it was neither mapped nor
1274 * algorithmic. Fail */
1278 if (winbind_lookup_sid(NULL, psid, NULL, NULL, &type)) {
1280 if (type != SID_NAME_USER) {
1281 DEBUG(10, ("sid_to_uid: sid %s is a %s\n",
1282 sid_string_static(psid),
1283 sid_type_lookup(type)));
1287 if (!winbind_sid_to_uid(puid, psid)) {
1288 DEBUG(5, ("sid_to_uid: winbind failed to allocate a "
1289 "new uid for sid %s\n",
1290 sid_string_static(psid)));
1296 /* TODO: Here would be the place to allocate both a gid and a uid for
1297 * the SID in question */
1302 DEBUG(10,("sid_to_uid: %s -> %u\n", sid_string_static(psid),
1303 (unsigned int)*puid ));
1305 store_uid_sid_cache(psid, *puid);
1309 /*****************************************************************
1310 *THE CANONICAL* convert SID to gid function.
1311 Group mapping is used for gids that maps to Wellknown SIDs
1312 *****************************************************************/
1314 BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid)
1319 enum SID_NAME_USE type;
1322 if (fetch_gid_from_cache(pgid, psid))
1325 if (fetch_uid_from_cache(&uid, psid))
1328 if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1334 if ((sid_check_is_in_builtin(psid) ||
1335 sid_check_is_in_wellknown_domain(psid))) {
1336 if (pdb_getgrsid(&map, *psid)) {
1343 if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
1344 if (pdb_sid_to_id(psid, &id, &type)) {
1345 if ((type != SID_NAME_DOM_GRP) &&
1346 (type != SID_NAME_ALIAS)) {
1347 DEBUG(5, ("sid %s is a %s, expected a group\n",
1348 sid_string_static(psid),
1349 sid_type_lookup(type)));
1355 if (pdb_rid_algorithm() &&
1356 !algorithmic_pdb_rid_is_user(rid)) {
1357 /* This must be a group, presented as alias */
1358 *pgid = pdb_group_rid_to_gid(rid);
1361 /* This was ours, but it was neither mapped nor
1362 * algorithmic. Fail. */
1366 if (!winbind_lookup_sid(NULL, psid, NULL, NULL, &type)) {
1367 DEBUG(11,("sid_to_gid: no one knows the SID %s (tried local, "
1368 "then winbind)\n", sid_string_static(psid)));
1373 /* winbindd knows it; Ensure this is a group sid */
1375 if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
1376 (type != SID_NAME_WKN_GRP)) {
1377 DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is "
1378 "a %s\n", sid_type_lookup(type)));
1382 /* winbindd knows it and it is a type of group; sid_to_gid must succeed
1383 or we are dead in the water */
1385 if ( !winbind_sid_to_gid(pgid, psid) ) {
1386 DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid "
1387 "for sid %s\n", sid_string_static(psid)));
1392 DEBUG(10,("sid_to_gid: %s -> %u\n", sid_string_static(psid),
1393 (unsigned int)*pgid ));
1395 store_gid_sid_cache(psid, *pgid);