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 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/>.
24 #include "../librpc/gen_ndr/ndr_security.h"
26 #include "../lib/util/memcache.h"
27 #include "idmap_cache.h"
28 #include "../libcli/security/security.h"
29 #include "lib/winbind_util.h"
30 #include "../librpc/gen_ndr/idmap.h"
32 /*****************************************************************
33 Dissect a user-provided name into domain, name, sid and type.
35 If an explicit domain name was given in the form domain\user, it
36 has to try that. If no explicit domain name was given, we have
38 *****************************************************************/
40 bool lookup_name(TALLOC_CTX *mem_ctx,
41 const char *full_name, int flags,
42 const char **ret_domain, const char **ret_name,
43 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
47 const char *domain = NULL;
48 const char *name = NULL;
51 enum lsa_SidType type;
52 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
54 if (tmp_ctx == NULL) {
55 DEBUG(0, ("talloc_new failed\n"));
59 p = strchr_m(full_name, '\\');
62 domain = talloc_strndup(tmp_ctx, full_name,
63 PTR_DIFF(p, full_name));
64 name = talloc_strdup(tmp_ctx, p+1);
66 domain = talloc_strdup(tmp_ctx, "");
67 name = talloc_strdup(tmp_ctx, full_name);
70 if ((domain == NULL) || (name == NULL)) {
71 DEBUG(0, ("talloc failed\n"));
76 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
77 full_name, domain, name));
78 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
80 if ((flags & LOOKUP_NAME_DOMAIN) &&
81 strequal(domain, get_global_sam_name()))
84 /* It's our own domain, lookup the name in passdb */
85 if (lookup_global_sam_name(name, flags, &rid, &type)) {
86 sid_compose(&sid, get_global_sam_sid(), rid);
93 if ((flags & LOOKUP_NAME_BUILTIN) &&
94 strequal(domain, builtin_domain_name()))
96 if (strlen(name) == 0) {
97 /* Swap domain and name */
98 tmp = name; name = domain; domain = tmp;
99 sid_copy(&sid, &global_sid_Builtin);
100 type = SID_NAME_DOMAIN;
104 /* Explicit request for a name in BUILTIN */
105 if (lookup_builtin_name(name, &rid)) {
106 sid_compose(&sid, &global_sid_Builtin, rid);
107 type = SID_NAME_ALIAS;
110 TALLOC_FREE(tmp_ctx);
114 /* Try the explicit winbind lookup first, don't let it guess the
115 * domain yet at this point yet. This comes later. */
117 if ((domain[0] != '\0') &&
118 (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
119 (winbind_lookup_name(domain, name, &sid, &type))) {
123 if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
124 && strequal(domain, unix_users_domain_name())) {
125 if (lookup_unix_user_name(name, &sid)) {
126 type = SID_NAME_USER;
129 TALLOC_FREE(tmp_ctx);
133 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
134 && strequal(domain, unix_groups_domain_name())) {
135 if (lookup_unix_group_name(name, &sid)) {
136 type = SID_NAME_DOM_GRP;
139 TALLOC_FREE(tmp_ctx);
144 * Finally check for a well known domain name ("NT Authority"),
145 * this is taken care if in lookup_wellknown_name().
147 if ((domain[0] != '\0') &&
148 (flags & LOOKUP_NAME_WKN) &&
149 lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
151 type = SID_NAME_WKN_GRP;
156 * If we're told not to look up 'isolated' names then we're
159 if (!(flags & LOOKUP_NAME_ISOLATED)) {
160 TALLOC_FREE(tmp_ctx);
165 * No domain names beyond this point
167 if (domain[0] != '\0') {
168 TALLOC_FREE(tmp_ctx);
172 /* Now the guesswork begins, we haven't been given an explicit
173 * domain. Try the sequence as documented on
174 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
175 * November 27, 2005 */
177 /* 1. well-known names */
180 * Check for well known names without a domain name.
181 * e.g. \Creator Owner.
184 if ((flags & LOOKUP_NAME_WKN) &&
185 lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
187 type = SID_NAME_WKN_GRP;
191 /* 2. Builtin domain as such */
193 if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
194 strequal(name, builtin_domain_name()))
196 /* Swap domain and name */
197 tmp = name; name = domain; domain = tmp;
198 sid_copy(&sid, &global_sid_Builtin);
199 type = SID_NAME_DOMAIN;
203 /* 3. Account domain */
205 if ((flags & LOOKUP_NAME_DOMAIN) &&
206 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 ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
222 strequal(name, lp_workgroup()))
224 if (!secrets_fetch_domain_sid(name, &sid)) {
225 DEBUG(3, ("Could not fetch the domain SID\n"));
226 TALLOC_FREE(tmp_ctx);
229 /* Swap domain and name */
230 tmp = name; name = domain; domain = tmp;
231 type = SID_NAME_DOMAIN;
235 /* 5. Trusted domains as such, to me it looks as if members don't do
236 this, tested an XP workstation in a NT domain -- vl */
238 if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
239 (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
241 /* Swap domain and name */
242 tmp = name; name = domain; domain = tmp;
243 type = SID_NAME_DOMAIN;
247 /* 6. Builtin aliases */
249 if ((flags & LOOKUP_NAME_BUILTIN) &&
250 lookup_builtin_name(name, &rid))
252 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
253 sid_compose(&sid, &global_sid_Builtin, rid);
254 type = SID_NAME_ALIAS;
258 /* 7. Local systems' SAM (DCs don't have a local SAM) */
259 /* 8. Primary SAM (On members, this is the domain) */
261 /* Both cases are done by looking at our passdb */
263 if ((flags & LOOKUP_NAME_DOMAIN) &&
264 lookup_global_sam_name(name, flags, &rid, &type))
266 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
267 sid_compose(&sid, get_global_sam_sid(), rid);
271 /* Now our local possibilities are exhausted. */
273 if (!(flags & LOOKUP_NAME_REMOTE)) {
274 TALLOC_FREE(tmp_ctx);
278 /* If we are not a DC, we have to ask in our primary domain. Let
279 * winbind do that. */
282 (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
283 domain = talloc_strdup(tmp_ctx, lp_workgroup());
287 /* 9. Trusted domains */
289 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
290 * that (yet), but give it a chance. */
292 if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
293 struct dom_sid dom_sid;
294 enum lsa_SidType domain_type;
296 if (type == SID_NAME_DOMAIN) {
297 /* Swap name and type */
298 tmp = name; name = domain; domain = tmp;
302 /* Here we have to cope with a little deficiency in the
303 * winbind API: We have to ask it again for the name of the
304 * domain it figured out itself. Maybe fix that later... */
306 sid_copy(&dom_sid, &sid);
307 sid_split_rid(&dom_sid, NULL);
309 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
311 (domain_type != SID_NAME_DOMAIN)) {
312 DEBUG(2, ("winbind could not find the domain's name "
313 "it just looked up for us\n"));
314 TALLOC_FREE(tmp_ctx);
320 /* 10. Don't translate */
322 /* 11. Ok, windows would end here. Samba has two more options:
323 Unmapped users and unmapped groups */
325 if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
326 && lookup_unix_user_name(name, &sid)) {
327 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
328 type = SID_NAME_USER;
332 if (((flags & LOOKUP_NAME_NO_NSS) == 0)
333 && lookup_unix_group_name(name, &sid)) {
334 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
335 type = SID_NAME_DOM_GRP;
340 * Ok, all possibilities tried. Fail.
343 TALLOC_FREE(tmp_ctx);
347 if ((domain == NULL) || (name == NULL)) {
348 DEBUG(0, ("talloc failed\n"));
349 TALLOC_FREE(tmp_ctx);
354 * Hand over the results to the talloc context we've been given.
357 if ((ret_name != NULL) &&
358 !(*ret_name = talloc_strdup(mem_ctx, name))) {
359 DEBUG(0, ("talloc failed\n"));
360 TALLOC_FREE(tmp_ctx);
364 if (ret_domain != NULL) {
366 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
367 DEBUG(0, ("talloc failed\n"));
368 TALLOC_FREE(tmp_ctx);
371 if (!strupper_m(tmp_dom)) {
372 TALLOC_FREE(tmp_ctx);
375 *ret_domain = tmp_dom;
378 if (ret_sid != NULL) {
379 sid_copy(ret_sid, &sid);
382 if (ret_type != NULL) {
386 TALLOC_FREE(tmp_ctx);
390 /************************************************************************
391 Names from smb.conf can be unqualified. eg. valid users = foo
392 These names should never map to a remote name. Try global_sam_name()\foo,
393 and then "Unix Users"\foo (or "Unix Groups"\foo).
394 ************************************************************************/
396 bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
397 const char *full_name, int flags,
398 const char **ret_domain, const char **ret_name,
399 struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
401 char *qualified_name;
404 /* NB. No winbindd_separator here as lookup_name needs \\' */
405 if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
407 /* The name is already qualified with a domain. */
409 if (*lp_winbind_separator() != '\\') {
412 /* lookup_name() needs '\\' as a separator */
414 tmp = talloc_strdup(mem_ctx, full_name);
418 tmp[p - full_name] = '\\';
422 return lookup_name(mem_ctx, full_name, flags,
423 ret_domain, ret_name,
427 /* Try with winbind default domain name. */
428 if (lp_winbind_use_default_domain()) {
431 qualified_name = talloc_asprintf(mem_ctx,
435 if (qualified_name == NULL) {
439 ok = lookup_name(mem_ctx,
451 /* Try with our own SAM name. */
452 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
453 get_global_sam_name(),
455 if (!qualified_name) {
459 if (lookup_name(mem_ctx, qualified_name, flags,
460 ret_domain, ret_name,
461 ret_sid, ret_type)) {
465 /* Finally try with "Unix Users" or "Unix Group" */
466 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
467 flags & LOOKUP_NAME_GROUP ?
468 unix_groups_domain_name() :
469 unix_users_domain_name(),
471 if (!qualified_name) {
475 return lookup_name(mem_ctx, qualified_name, flags,
476 ret_domain, ret_name,
480 static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
481 const struct dom_sid *domain_sid,
482 int num_rids, uint32_t *rids,
483 const char **domain_name,
484 const char **names, enum lsa_SidType *types)
487 const char **my_names;
488 enum lsa_SidType *my_types;
491 if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
495 if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
496 domain_name, &my_names, &my_types)) {
498 for (i=0; i<num_rids; i++) {
500 types[i] = SID_NAME_UNKNOWN;
502 TALLOC_FREE(tmp_ctx);
506 if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
507 TALLOC_FREE(tmp_ctx);
512 * winbind_lookup_rids allocates its own array. We've been given the
513 * array, so copy it over
516 for (i=0; i<num_rids; i++) {
517 if (my_names[i] == NULL) {
518 TALLOC_FREE(tmp_ctx);
521 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
522 TALLOC_FREE(tmp_ctx);
525 types[i] = my_types[i];
527 TALLOC_FREE(tmp_ctx);
531 static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
532 int num_rids, uint32_t *rids,
533 const char **domain_name,
534 const char ***names, enum lsa_SidType **types)
538 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
539 sid_string_dbg(domain_sid)));
542 *names = talloc_zero_array(mem_ctx, const char *, num_rids);
543 *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
545 if ((*names == NULL) || (*types == NULL)) {
549 for (i = 0; i < num_rids; i++)
550 (*types)[i] = SID_NAME_UNKNOWN;
556 if (sid_check_is_our_sam(domain_sid)) {
559 if (*domain_name == NULL) {
560 *domain_name = talloc_strdup(
561 mem_ctx, get_global_sam_name());
564 if (*domain_name == NULL) {
569 result = pdb_lookup_rids(domain_sid, num_rids, rids,
573 return (NT_STATUS_IS_OK(result) ||
574 NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
575 NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
578 if (sid_check_is_builtin(domain_sid)) {
580 if (*domain_name == NULL) {
581 *domain_name = talloc_strdup(
582 mem_ctx, builtin_domain_name());
585 if (*domain_name == NULL) {
589 for (i=0; i<num_rids; i++) {
590 if (lookup_builtin_rid(*names, rids[i],
592 if ((*names)[i] == NULL) {
595 (*types)[i] = SID_NAME_ALIAS;
597 (*types)[i] = SID_NAME_UNKNOWN;
603 if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
604 for (i=0; i<num_rids; i++) {
606 sid_compose(&sid, domain_sid, rids[i]);
607 if (lookup_wellknown_sid(mem_ctx, &sid,
608 domain_name, &(*names)[i])) {
609 if ((*names)[i] == NULL) {
612 (*types)[i] = SID_NAME_WKN_GRP;
614 (*types)[i] = SID_NAME_UNKNOWN;
620 if (sid_check_is_unix_users(domain_sid)) {
621 if (*domain_name == NULL) {
622 *domain_name = talloc_strdup(
623 mem_ctx, unix_users_domain_name());
624 if (*domain_name == NULL) {
628 for (i=0; i<num_rids; i++) {
629 (*names)[i] = talloc_strdup(
630 (*names), uidtoname(rids[i]));
631 if ((*names)[i] == NULL) {
634 (*types)[i] = SID_NAME_USER;
639 if (sid_check_is_unix_groups(domain_sid)) {
640 if (*domain_name == NULL) {
641 *domain_name = talloc_strdup(
642 mem_ctx, unix_groups_domain_name());
643 if (*domain_name == NULL) {
647 for (i=0; i<num_rids; i++) {
648 (*names)[i] = talloc_strdup(
649 (*names), gidtoname(rids[i]));
650 if ((*names)[i] == NULL) {
653 (*types)[i] = SID_NAME_DOM_GRP;
658 return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
659 domain_name, *names, *types);
663 * Is the SID a domain as such? If yes, lookup its name.
666 static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
670 enum lsa_SidType type;
672 if (sid_check_is_our_sam(sid)) {
673 *name = talloc_strdup(mem_ctx, get_global_sam_name());
677 if (sid_check_is_builtin(sid)) {
678 *name = talloc_strdup(mem_ctx, builtin_domain_name());
682 if (sid_check_is_wellknown_domain(sid, &tmp)) {
683 *name = talloc_strdup(mem_ctx, tmp);
687 if (sid_check_is_unix_users(sid)) {
688 *name = talloc_strdup(mem_ctx, unix_users_domain_name());
692 if (sid_check_is_unix_groups(sid)) {
693 *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
697 if (sid->num_auths != 4) {
698 /* This can't be a domain */
703 uint32_t i, num_domains;
704 struct trustdom_info **domains;
706 /* This is relatively expensive, but it happens only on DCs
707 * and for SIDs that have 4 sub-authorities and thus look like
710 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
716 for (i=0; i<num_domains; i++) {
717 if (dom_sid_equal(sid, &domains[i]->sid)) {
718 *name = talloc_strdup(mem_ctx,
726 if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
727 (type == SID_NAME_DOMAIN)) {
736 * This tries to implement the rather weird rules for the lsa_lookup level
739 * This is as close as we can get to what W2k3 does. With this we survive the
740 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
741 * different, but I assume that's just being too liberal. For example, W2k3
742 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
743 * whereas NT4 does the same as level 1 (I think). I did not fully test that
744 * with NT4, this is what w2k3 does.
746 * Level 1: Ask everywhere
747 * Level 2: Ask domain and trusted domains, no builtin and wkn
748 * Level 3: Only ask domain
749 * Level 4: W2k3ad: Only ask AD trusts
750 * Level 5: Only ask transitive forest trusts
754 static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
763 ret = (!sid_check_is_builtin(sid) &&
764 !sid_check_is_wellknown_domain(sid, NULL));
769 ret = sid_check_is_our_sam(sid);
776 DEBUG(10, ("%s SID %s in level %d\n",
777 ret ? "Accepting" : "Rejecting",
778 sid_string_dbg(sid), level));
783 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
784 * references to domains, it is explicitly made for this.
786 * This attempts to be as efficient as possible: It collects all SIDs
787 * belonging to a domain and hands them in bulk to the appropriate lookup
788 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
789 * *hugely* from this.
792 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
793 const struct dom_sid **sids, int level,
794 struct lsa_dom_info **ret_domains,
795 struct lsa_name_info **ret_names)
798 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
799 struct lsa_name_info *name_infos;
800 struct lsa_dom_info *dom_infos = NULL;
804 if (!(tmp_ctx = talloc_new(mem_ctx))) {
805 DEBUG(0, ("talloc_new failed\n"));
806 return NT_STATUS_NO_MEMORY;
810 name_infos = talloc_array(mem_ctx, struct lsa_name_info, num_sids);
811 if (name_infos == NULL) {
812 result = NT_STATUS_NO_MEMORY;
819 dom_infos = talloc_zero_array(mem_ctx, struct lsa_dom_info,
820 LSA_REF_DOMAIN_LIST_MULTIPLIER);
821 if (dom_infos == NULL) {
822 result = NT_STATUS_NO_MEMORY;
826 /* First build up the data structures:
828 * dom_infos is a list of domains referenced in the list of
829 * SIDs. Later we will walk the list of domains and look up the RIDs
832 * name_infos is a shadow-copy of the SIDs array to collect the real
835 * dom_info->idxs is an index into the name_infos array. The
836 * difficulty we have here is that we need to keep the SIDs the client
837 * asked for in the same order for the reply
840 for (i=0; i<num_sids; i++) {
843 const char *domain_name = NULL;
845 sid_copy(&sid, sids[i]);
846 name_infos[i].type = SID_NAME_USE_NONE;
848 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
849 /* We can't push that through the normal lookup
850 * process, as this would reference illegal
853 * For example S-1-5-32 would end up referencing
854 * domain S-1-5- with RID 32 which is clearly wrong.
856 if (domain_name == NULL) {
857 result = NT_STATUS_NO_MEMORY;
861 name_infos[i].rid = 0;
862 name_infos[i].type = SID_NAME_DOMAIN;
863 name_infos[i].name = NULL;
865 if (sid_check_is_builtin(&sid)) {
866 /* Yes, W2k3 returns "BUILTIN" both as domain
868 name_infos[i].name = talloc_strdup(
869 name_infos, builtin_domain_name());
870 if (name_infos[i].name == NULL) {
871 result = NT_STATUS_NO_MEMORY;
876 /* This is a normal SID with rid component */
877 if (!sid_split_rid(&sid, &rid)) {
878 result = NT_STATUS_INVALID_SID;
883 if (!check_dom_sid_to_level(&sid, level)) {
884 name_infos[i].rid = 0;
885 name_infos[i].type = SID_NAME_UNKNOWN;
886 name_infos[i].name = NULL;
890 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
891 if (!dom_infos[j].valid) {
894 if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
899 if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
900 /* TODO: What's the right error message here? */
901 result = NT_STATUS_NONE_MAPPED;
905 if (!dom_infos[j].valid) {
906 /* We found a domain not yet referenced, create a new
908 dom_infos[j].valid = true;
909 sid_copy(&dom_infos[j].sid, &sid);
911 if (domain_name != NULL) {
912 /* This name was being found above in the case
913 * when we found a domain SID */
915 talloc_strdup(dom_infos, domain_name);
916 if (dom_infos[j].name == NULL) {
917 result = NT_STATUS_NO_MEMORY;
921 /* lookup_rids will take care of this */
922 dom_infos[j].name = NULL;
926 name_infos[i].dom_idx = j;
928 if (name_infos[i].type == SID_NAME_USE_NONE) {
929 name_infos[i].rid = rid;
931 ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
932 &dom_infos[j].num_idxs);
934 if (dom_infos[j].idxs == NULL) {
935 result = NT_STATUS_NO_MEMORY;
941 /* Iterate over the domains found */
943 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
945 const char *domain_name = NULL;
947 enum lsa_SidType *types;
948 struct lsa_dom_info *dom = &dom_infos[i];
951 /* No domains left, we're done */
955 if (dom->num_idxs == 0) {
957 * This happens only if the only sid related to
958 * this domain is the domain sid itself, which
959 * is mapped to SID_NAME_DOMAIN above.
964 if (!(rids = talloc_array(tmp_ctx, uint32_t, dom->num_idxs))) {
965 result = NT_STATUS_NO_MEMORY;
969 for (j=0; j<dom->num_idxs; j++) {
970 rids[j] = name_infos[dom->idxs[j]].rid;
973 if (!lookup_rids(tmp_ctx, &dom->sid,
974 dom->num_idxs, rids, &domain_name,
976 result = NT_STATUS_NO_MEMORY;
980 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
981 result = NT_STATUS_NO_MEMORY;
985 for (j=0; j<dom->num_idxs; j++) {
986 int idx = dom->idxs[j];
987 name_infos[idx].type = types[j];
988 if (types[j] != SID_NAME_UNKNOWN) {
989 name_infos[idx].name =
990 talloc_strdup(name_infos, names[j]);
991 if (name_infos[idx].name == NULL) {
992 result = NT_STATUS_NO_MEMORY;
996 name_infos[idx].name = NULL;
1001 *ret_domains = dom_infos;
1002 *ret_names = name_infos;
1003 TALLOC_FREE(tmp_ctx);
1004 return NT_STATUS_OK;
1007 TALLOC_FREE(dom_infos);
1008 TALLOC_FREE(name_infos);
1009 TALLOC_FREE(tmp_ctx);
1013 /*****************************************************************
1014 *THE CANONICAL* convert SID to name function.
1015 *****************************************************************/
1017 bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
1018 const char **ret_domain, const char **ret_name,
1019 enum lsa_SidType *ret_type)
1021 struct lsa_dom_info *domain;
1022 struct lsa_name_info *name;
1023 TALLOC_CTX *tmp_ctx;
1026 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid)));
1028 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1029 DEBUG(0, ("talloc_new failed\n"));
1033 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
1038 if (name->type == SID_NAME_UNKNOWN) {
1042 if ((ret_domain != NULL) &&
1043 !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
1047 if ((ret_name != NULL) &&
1048 !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
1052 if (ret_type != NULL) {
1053 *ret_type = name->type;
1060 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid),
1061 domain->name, name->name, name->type));
1063 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid)));
1065 TALLOC_FREE(tmp_ctx);
1069 /*****************************************************************
1070 Id mapping cache. This is to avoid Winbind mappings already
1071 seen by smbd to be queried too frequently, keeping winbindd
1072 busy, and blocking smbd while winbindd is busy with other
1073 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1074 modified to use linked lists by jra.
1075 *****************************************************************/
1078 /*****************************************************************
1079 *THE LEGACY* convert uid_t to SID function.
1080 *****************************************************************/
1082 static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
1090 id.type = ID_TYPE_UID;
1093 ret = pdb_id_to_sid(&id, psid);
1097 /* This is a mapped user */
1101 /* This is an unmapped user */
1103 uid_to_unix_users_sid(uid, psid);
1106 struct unixid xid = {
1107 .id = uid, .type = ID_TYPE_UID
1109 idmap_cache_set_sid2unixid(psid, &xid);
1113 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid,
1114 sid_string_dbg(psid)));
1119 /*****************************************************************
1120 *THE LEGACY* convert gid_t to SID function.
1121 *****************************************************************/
1123 static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid)
1131 id.type = ID_TYPE_GID;
1134 ret = pdb_id_to_sid(&id, psid);
1138 /* This is a mapped group */
1142 /* This is an unmapped group */
1144 gid_to_unix_groups_sid(gid, psid);
1147 struct unixid xid = {
1148 .id = gid, .type = ID_TYPE_GID
1150 idmap_cache_set_sid2unixid(psid, &xid);
1154 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid,
1155 sid_string_dbg(psid)));
1160 /*****************************************************************
1161 *THE LEGACY* convert SID to id function.
1162 *****************************************************************/
1164 static bool legacy_sid_to_unixid(const struct dom_sid *psid, struct unixid *id)
1169 ret = pdb_sid_to_id(psid, id);
1173 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1174 sid_string_dbg(psid)));
1181 static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1184 if (!legacy_sid_to_unixid(psid, &id)) {
1187 if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) {
1194 static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1197 if (!legacy_sid_to_unixid(psid, &id)) {
1200 if (id.type == ID_TYPE_UID || id.type == ID_TYPE_BOTH) {
1207 /*****************************************************************
1208 *THE CANONICAL* convert uid_t to SID function.
1209 *****************************************************************/
1211 void uid_to_sid(struct dom_sid *psid, uid_t uid)
1213 bool expired = true;
1217 /* Check the winbindd cache directly. */
1218 ret = idmap_cache_find_uid2sid(uid, psid, &expired);
1220 if (ret && !expired && is_null_sid(psid)) {
1222 * Negative cache entry, we already asked.
1225 legacy_uid_to_sid(psid, uid);
1229 if (!ret || expired) {
1230 /* Not in cache. Ask winbindd. */
1231 if (!winbind_uid_to_sid(psid, uid)) {
1233 * We shouldn't return the NULL SID
1234 * here if winbind was running and
1235 * couldn't map, as winbind will have
1236 * added a negative entry that will
1237 * cause us to go though the
1238 * legacy_uid_to_sid()
1239 * function anyway in the case above
1240 * the next time we ask.
1242 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1243 "for uid %u\n", (unsigned int)uid));
1245 legacy_uid_to_sid(psid, uid);
1250 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid,
1251 sid_string_dbg(psid)));
1256 /*****************************************************************
1257 *THE CANONICAL* convert gid_t to SID function.
1258 *****************************************************************/
1260 void gid_to_sid(struct dom_sid *psid, gid_t gid)
1262 bool expired = true;
1266 /* Check the winbindd cache directly. */
1267 ret = idmap_cache_find_gid2sid(gid, psid, &expired);
1269 if (ret && !expired && is_null_sid(psid)) {
1271 * Negative cache entry, we already asked.
1274 legacy_gid_to_sid(psid, gid);
1278 if (!ret || expired) {
1279 /* Not in cache. Ask winbindd. */
1280 if (!winbind_gid_to_sid(psid, gid)) {
1282 * We shouldn't return the NULL SID
1283 * here if winbind was running and
1284 * couldn't map, as winbind will have
1285 * added a negative entry that will
1286 * cause us to go though the
1287 * legacy_gid_to_sid()
1288 * function anyway in the case above
1289 * the next time we ask.
1291 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1292 "for gid %u\n", (unsigned int)gid));
1294 legacy_gid_to_sid(psid, gid);
1299 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid,
1300 sid_string_dbg(psid)));
1305 bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
1308 struct wbcDomainSid *wbc_sids = NULL;
1309 struct wbcUnixId *wbc_ids = NULL;
1310 uint32_t i, num_not_cached;
1314 wbc_sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_sids);
1315 if (wbc_sids == NULL) {
1321 for (i=0; i<num_sids; i++) {
1325 if (sid_peek_check_rid(&global_sid_Unix_Users,
1327 ids[i].type = ID_TYPE_UID;
1331 if (sid_peek_check_rid(&global_sid_Unix_Groups,
1333 ids[i].type = ID_TYPE_GID;
1337 if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
1342 ids[i].type = ID_TYPE_NOT_SPECIFIED;
1343 memcpy(&wbc_sids[num_not_cached], &sids[i],
1344 ndr_size_dom_sid(&sids[i], 0));
1345 num_not_cached += 1;
1347 if (num_not_cached == 0) {
1350 wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, num_not_cached);
1351 if (wbc_ids == NULL) {
1354 for (i=0; i<num_not_cached; i++) {
1355 wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
1357 err = wbcSidsToUnixIds(wbc_sids, num_not_cached, wbc_ids);
1358 if (!WBC_ERROR_IS_OK(err)) {
1359 DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1360 wbcErrorString(err)));
1365 for (i=0; i<num_sids; i++) {
1366 if (ids[i].type == ID_TYPE_NOT_SPECIFIED) {
1367 switch (wbc_ids[num_not_cached].type) {
1368 case WBC_ID_TYPE_UID:
1369 ids[i].type = ID_TYPE_UID;
1370 ids[i].id = wbc_ids[num_not_cached].id.uid;
1372 case WBC_ID_TYPE_GID:
1373 ids[i].type = ID_TYPE_GID;
1374 ids[i].id = wbc_ids[num_not_cached].id.gid;
1377 /* The types match, and wbcUnixId -> id is a union anyway */
1378 ids[i].type = (enum id_type)wbc_ids[num_not_cached].type;
1379 ids[i].id = wbc_ids[num_not_cached].id.gid;
1382 num_not_cached += 1;
1386 for (i=0; i<num_sids; i++) {
1387 if (ids[i].type != ID_TYPE_NOT_SPECIFIED) {
1390 if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
1391 ids[i].type = ID_TYPE_GID;
1394 if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
1395 ids[i].type = ID_TYPE_UID;
1400 for (i=0; i<num_sids; i++) {
1401 switch(ids[i].type) {
1402 case WBC_ID_TYPE_GID:
1403 case WBC_ID_TYPE_UID:
1404 case WBC_ID_TYPE_BOTH:
1405 if (ids[i].id == -1) {
1406 ids[i].type = ID_TYPE_NOT_SPECIFIED;
1409 case WBC_ID_TYPE_NOT_SPECIFIED:
1416 TALLOC_FREE(wbc_ids);
1417 TALLOC_FREE(wbc_sids);
1421 /*****************************************************************
1422 *THE CANONICAL* convert SID to uid function.
1423 *****************************************************************/
1425 bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1427 bool expired = true;
1431 /* Optimize for the Unix Users Domain
1432 * as the conversion is straightforward */
1433 if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1437 /* return here, don't cache */
1438 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1439 (unsigned int)*puid ));
1443 /* Check the winbindd cache directly. */
1444 ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1446 if (ret && !expired && (*puid == (uid_t)-1)) {
1448 * Negative cache entry, we already asked.
1451 return legacy_sid_to_uid(psid, puid);
1454 if (!ret || expired) {
1455 /* Not in cache. Ask winbindd. */
1456 if (!winbind_sid_to_uid(puid, psid)) {
1457 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1458 sid_string_dbg(psid)));
1459 /* winbind failed. do legacy */
1460 return legacy_sid_to_uid(psid, puid);
1464 /* TODO: Here would be the place to allocate both a gid and a uid for
1465 * the SID in question */
1467 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1468 (unsigned int)*puid ));
1473 /*****************************************************************
1474 *THE CANONICAL* convert SID to gid function.
1475 Group mapping is used for gids that maps to Wellknown SIDs
1476 *****************************************************************/
1478 bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1480 bool expired = true;
1484 /* Optimize for the Unix Groups Domain
1485 * as the conversion is straightforward */
1486 if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1490 /* return here, don't cache */
1491 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1492 (unsigned int)*pgid ));
1496 /* Check the winbindd cache directly. */
1497 ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1499 if (ret && !expired && (*pgid == (gid_t)-1)) {
1501 * Negative cache entry, we already asked.
1504 return legacy_sid_to_gid(psid, pgid);
1507 if (!ret || expired) {
1508 /* Not in cache or negative. Ask winbindd. */
1509 /* Ask winbindd if it can map this sid to a gid.
1510 * (Idmap will check it is a valid SID and of the right type) */
1512 if ( !winbind_sid_to_gid(pgid, psid) ) {
1514 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1515 sid_string_dbg(psid)));
1516 /* winbind failed. do legacy */
1517 return legacy_sid_to_gid(psid, pgid);
1521 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1522 (unsigned int)*pgid ));
1528 * @brief This function gets the primary group SID mapping the primary
1529 * GID of the user as obtained by an actual getpwnam() call.
1530 * This is necessary to avoid issues with arbitrary group SIDs
1531 * stored in passdb. We try as hard as we can to get the SID
1532 * corresponding to the GID, including trying group mapping.
1533 * If nothing else works, we will force "Domain Users" as the
1535 * This is needed because we must always be able to lookup the
1536 * primary group SID, so we cannot settle for an arbitrary SID.
1538 * This call can be expensive. Use with moderation.
1539 * If you have a "samu" struct around use pdb_get_group_sid()
1540 * instead as it does properly cache results.
1542 * @param mem_ctx[in] The memory context iused to allocate the result.
1543 * @param username[in] The user's name
1544 * @param _pwd[in|out] If available, pass in user's passwd struct.
1545 * It will contain a tallocated passwd if NULL was
1547 * @param _group_sid[out] The user's Primary Group SID
1549 * @return NTSTATUS error code.
1551 NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1552 const char *username,
1553 struct passwd **_pwd,
1554 struct dom_sid **_group_sid)
1556 TALLOC_CTX *tmp_ctx;
1557 bool need_lookup_sid = false;
1558 struct dom_sid *group_sid;
1559 struct passwd *pwd = *_pwd;
1561 tmp_ctx = talloc_new(mem_ctx);
1563 return NT_STATUS_NO_MEMORY;
1567 pwd = Get_Pwnam_alloc(mem_ctx, username);
1569 DEBUG(0, ("Failed to find a Unix account for %s\n",
1571 TALLOC_FREE(tmp_ctx);
1572 return NT_STATUS_NO_SUCH_USER;
1576 group_sid = talloc_zero(mem_ctx, struct dom_sid);
1578 TALLOC_FREE(tmp_ctx);
1579 return NT_STATUS_NO_MEMORY;
1582 gid_to_sid(group_sid, pwd->pw_gid);
1583 if (!is_null_sid(group_sid)) {
1584 struct dom_sid domain_sid;
1587 /* We need a sid within our domain */
1588 sid_copy(&domain_sid, group_sid);
1589 sid_split_rid(&domain_sid, &rid);
1590 if (dom_sid_equal(&domain_sid, get_global_sam_sid())) {
1592 * As shortcut for the expensive lookup_sid call
1593 * compare the domain sid part
1596 case DOMAIN_RID_ADMINS:
1597 case DOMAIN_RID_USERS:
1600 need_lookup_sid = true;
1604 /* Try group mapping */
1607 id.id = pwd->pw_gid;
1608 id.type = ID_TYPE_GID;
1610 ZERO_STRUCTP(group_sid);
1611 if (pdb_id_to_sid(&id, group_sid)) {
1612 need_lookup_sid = true;
1617 /* We must verify that this is a valid SID that resolves to a
1618 * group of the correct type */
1619 if (need_lookup_sid) {
1620 enum lsa_SidType type = SID_NAME_UNKNOWN;
1623 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1624 sid_string_dbg(group_sid), username));
1626 /* Now check that it's actually a domain group and
1627 * not something else */
1628 lookup_ret = lookup_sid(tmp_ctx, group_sid,
1631 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1635 DEBUG(3, ("Primary group %s for user %s is"
1636 " a %s and not a domain group\n",
1637 sid_string_dbg(group_sid), username,
1638 sid_type_lookup(type)));
1641 /* Everything else, failed.
1642 * Just set it to the 'Domain Users' RID of 513 which will
1643 always resolve to a name */
1644 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1647 sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1650 *_pwd = talloc_move(mem_ctx, &pwd);
1651 *_group_sid = talloc_move(mem_ctx, &group_sid);
1652 TALLOC_FREE(tmp_ctx);
1653 return NT_STATUS_OK;