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 if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
406 /* The name is already qualified with a domain. */
408 if (*lp_winbind_separator() != '\\') {
411 /* lookup_name() needs '\\' as a separator */
413 tmp = talloc_strdup(mem_ctx, full_name);
417 tmp[p - full_name] = '\\';
421 return lookup_name(mem_ctx, full_name, flags,
422 ret_domain, ret_name,
426 /* Try with winbind default domain name. */
427 if (lp_winbind_use_default_domain()) {
430 qualified_name = talloc_asprintf(mem_ctx,
434 if (qualified_name == NULL) {
438 ok = lookup_name(mem_ctx,
450 /* Try with our own SAM name. */
451 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
452 get_global_sam_name(),
454 if (!qualified_name) {
458 if (lookup_name(mem_ctx, qualified_name, flags,
459 ret_domain, ret_name,
460 ret_sid, ret_type)) {
464 /* Finally try with "Unix Users" or "Unix Group" */
465 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
466 flags & LOOKUP_NAME_GROUP ?
467 unix_groups_domain_name() :
468 unix_users_domain_name(),
470 if (!qualified_name) {
474 return lookup_name(mem_ctx, qualified_name, flags,
475 ret_domain, ret_name,
479 static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
480 const struct dom_sid *domain_sid,
481 int num_rids, uint32_t *rids,
482 const char **domain_name,
483 const char **names, enum lsa_SidType *types)
486 const char **my_names;
487 enum lsa_SidType *my_types;
490 if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
494 if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
495 domain_name, &my_names, &my_types)) {
497 for (i=0; i<num_rids; i++) {
499 types[i] = SID_NAME_UNKNOWN;
501 TALLOC_FREE(tmp_ctx);
505 if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
506 TALLOC_FREE(tmp_ctx);
511 * winbind_lookup_rids allocates its own array. We've been given the
512 * array, so copy it over
515 for (i=0; i<num_rids; i++) {
516 if (my_names[i] == NULL) {
517 TALLOC_FREE(tmp_ctx);
520 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
521 TALLOC_FREE(tmp_ctx);
524 types[i] = my_types[i];
526 TALLOC_FREE(tmp_ctx);
530 static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
531 int num_rids, uint32_t *rids,
532 const char **domain_name,
533 const char ***names, enum lsa_SidType **types)
537 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
538 sid_string_dbg(domain_sid)));
541 *names = talloc_zero_array(mem_ctx, const char *, num_rids);
542 *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
544 if ((*names == NULL) || (*types == NULL)) {
548 for (i = 0; i < num_rids; i++)
549 (*types)[i] = SID_NAME_UNKNOWN;
555 if (sid_check_is_our_sam(domain_sid)) {
558 if (*domain_name == NULL) {
559 *domain_name = talloc_strdup(
560 mem_ctx, get_global_sam_name());
563 if (*domain_name == NULL) {
568 result = pdb_lookup_rids(domain_sid, num_rids, rids,
572 return (NT_STATUS_IS_OK(result) ||
573 NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
574 NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
577 if (sid_check_is_builtin(domain_sid)) {
579 if (*domain_name == NULL) {
580 *domain_name = talloc_strdup(
581 mem_ctx, builtin_domain_name());
584 if (*domain_name == NULL) {
588 for (i=0; i<num_rids; i++) {
589 if (lookup_builtin_rid(*names, rids[i],
591 if ((*names)[i] == NULL) {
594 (*types)[i] = SID_NAME_ALIAS;
596 (*types)[i] = SID_NAME_UNKNOWN;
602 if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
603 for (i=0; i<num_rids; i++) {
605 sid_compose(&sid, domain_sid, rids[i]);
606 if (lookup_wellknown_sid(mem_ctx, &sid,
607 domain_name, &(*names)[i])) {
608 if ((*names)[i] == NULL) {
611 (*types)[i] = SID_NAME_WKN_GRP;
613 (*types)[i] = SID_NAME_UNKNOWN;
619 if (sid_check_is_unix_users(domain_sid)) {
620 if (*domain_name == NULL) {
621 *domain_name = talloc_strdup(
622 mem_ctx, unix_users_domain_name());
623 if (*domain_name == NULL) {
627 for (i=0; i<num_rids; i++) {
628 (*names)[i] = talloc_strdup(
629 (*names), uidtoname(rids[i]));
630 if ((*names)[i] == NULL) {
633 (*types)[i] = SID_NAME_USER;
638 if (sid_check_is_unix_groups(domain_sid)) {
639 if (*domain_name == NULL) {
640 *domain_name = talloc_strdup(
641 mem_ctx, unix_groups_domain_name());
642 if (*domain_name == NULL) {
646 for (i=0; i<num_rids; i++) {
647 (*names)[i] = talloc_strdup(
648 (*names), gidtoname(rids[i]));
649 if ((*names)[i] == NULL) {
652 (*types)[i] = SID_NAME_DOM_GRP;
657 return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
658 domain_name, *names, *types);
662 * Is the SID a domain as such? If yes, lookup its name.
665 static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
669 enum lsa_SidType type;
671 if (sid_check_is_our_sam(sid)) {
672 *name = talloc_strdup(mem_ctx, get_global_sam_name());
676 if (sid_check_is_builtin(sid)) {
677 *name = talloc_strdup(mem_ctx, builtin_domain_name());
681 if (sid_check_is_wellknown_domain(sid, &tmp)) {
682 *name = talloc_strdup(mem_ctx, tmp);
686 if (sid_check_is_unix_users(sid)) {
687 *name = talloc_strdup(mem_ctx, unix_users_domain_name());
691 if (sid_check_is_unix_groups(sid)) {
692 *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
696 if (sid->num_auths != 4) {
697 /* This can't be a domain */
702 uint32_t i, num_domains;
703 struct trustdom_info **domains;
705 /* This is relatively expensive, but it happens only on DCs
706 * and for SIDs that have 4 sub-authorities and thus look like
709 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
715 for (i=0; i<num_domains; i++) {
716 if (dom_sid_equal(sid, &domains[i]->sid)) {
717 *name = talloc_strdup(mem_ctx,
725 if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
726 (type == SID_NAME_DOMAIN)) {
735 * This tries to implement the rather weird rules for the lsa_lookup level
738 * This is as close as we can get to what W2k3 does. With this we survive the
739 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
740 * different, but I assume that's just being too liberal. For example, W2k3
741 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
742 * whereas NT4 does the same as level 1 (I think). I did not fully test that
743 * with NT4, this is what w2k3 does.
745 * Level 1: Ask everywhere
746 * Level 2: Ask domain and trusted domains, no builtin and wkn
747 * Level 3: Only ask domain
748 * Level 4: W2k3ad: Only ask AD trusts
749 * Level 5: Only ask transitive forest trusts
753 static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
762 ret = (!sid_check_is_builtin(sid) &&
763 !sid_check_is_wellknown_domain(sid, NULL));
768 ret = sid_check_is_our_sam(sid);
775 DEBUG(10, ("%s SID %s in level %d\n",
776 ret ? "Accepting" : "Rejecting",
777 sid_string_dbg(sid), level));
782 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
783 * references to domains, it is explicitly made for this.
785 * This attempts to be as efficient as possible: It collects all SIDs
786 * belonging to a domain and hands them in bulk to the appropriate lookup
787 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
788 * *hugely* from this.
791 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
792 const struct dom_sid **sids, int level,
793 struct lsa_dom_info **ret_domains,
794 struct lsa_name_info **ret_names)
797 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
798 struct lsa_name_info *name_infos;
799 struct lsa_dom_info *dom_infos = NULL;
803 if (!(tmp_ctx = talloc_new(mem_ctx))) {
804 DEBUG(0, ("talloc_new failed\n"));
805 return NT_STATUS_NO_MEMORY;
809 name_infos = talloc_array(mem_ctx, struct lsa_name_info, num_sids);
810 if (name_infos == NULL) {
811 result = NT_STATUS_NO_MEMORY;
818 dom_infos = talloc_zero_array(mem_ctx, struct lsa_dom_info,
819 LSA_REF_DOMAIN_LIST_MULTIPLIER);
820 if (dom_infos == NULL) {
821 result = NT_STATUS_NO_MEMORY;
825 /* First build up the data structures:
827 * dom_infos is a list of domains referenced in the list of
828 * SIDs. Later we will walk the list of domains and look up the RIDs
831 * name_infos is a shadow-copy of the SIDs array to collect the real
834 * dom_info->idxs is an index into the name_infos array. The
835 * difficulty we have here is that we need to keep the SIDs the client
836 * asked for in the same order for the reply
839 for (i=0; i<num_sids; i++) {
842 const char *domain_name = NULL;
844 sid_copy(&sid, sids[i]);
845 name_infos[i].type = SID_NAME_USE_NONE;
847 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
848 /* We can't push that through the normal lookup
849 * process, as this would reference illegal
852 * For example S-1-5-32 would end up referencing
853 * domain S-1-5- with RID 32 which is clearly wrong.
855 if (domain_name == NULL) {
856 result = NT_STATUS_NO_MEMORY;
860 name_infos[i].rid = 0;
861 name_infos[i].type = SID_NAME_DOMAIN;
862 name_infos[i].name = NULL;
864 if (sid_check_is_builtin(&sid)) {
865 /* Yes, W2k3 returns "BUILTIN" both as domain
867 name_infos[i].name = talloc_strdup(
868 name_infos, builtin_domain_name());
869 if (name_infos[i].name == NULL) {
870 result = NT_STATUS_NO_MEMORY;
875 /* This is a normal SID with rid component */
876 if (!sid_split_rid(&sid, &rid)) {
877 result = NT_STATUS_INVALID_SID;
882 if (!check_dom_sid_to_level(&sid, level)) {
883 name_infos[i].rid = 0;
884 name_infos[i].type = SID_NAME_UNKNOWN;
885 name_infos[i].name = NULL;
889 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
890 if (!dom_infos[j].valid) {
893 if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
898 if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
899 /* TODO: What's the right error message here? */
900 result = NT_STATUS_NONE_MAPPED;
904 if (!dom_infos[j].valid) {
905 /* We found a domain not yet referenced, create a new
907 dom_infos[j].valid = true;
908 sid_copy(&dom_infos[j].sid, &sid);
910 if (domain_name != NULL) {
911 /* This name was being found above in the case
912 * when we found a domain SID */
914 talloc_strdup(dom_infos, domain_name);
915 if (dom_infos[j].name == NULL) {
916 result = NT_STATUS_NO_MEMORY;
920 /* lookup_rids will take care of this */
921 dom_infos[j].name = NULL;
925 name_infos[i].dom_idx = j;
927 if (name_infos[i].type == SID_NAME_USE_NONE) {
928 name_infos[i].rid = rid;
930 ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
931 &dom_infos[j].num_idxs);
933 if (dom_infos[j].idxs == NULL) {
934 result = NT_STATUS_NO_MEMORY;
940 /* Iterate over the domains found */
942 for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
944 const char *domain_name = NULL;
946 enum lsa_SidType *types;
947 struct lsa_dom_info *dom = &dom_infos[i];
950 /* No domains left, we're done */
954 if (dom->num_idxs == 0) {
956 * This happens only if the only sid related to
957 * this domain is the domain sid itself, which
958 * is mapped to SID_NAME_DOMAIN above.
963 if (!(rids = talloc_array(tmp_ctx, uint32_t, dom->num_idxs))) {
964 result = NT_STATUS_NO_MEMORY;
968 for (j=0; j<dom->num_idxs; j++) {
969 rids[j] = name_infos[dom->idxs[j]].rid;
972 if (!lookup_rids(tmp_ctx, &dom->sid,
973 dom->num_idxs, rids, &domain_name,
975 result = NT_STATUS_NO_MEMORY;
979 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
980 result = NT_STATUS_NO_MEMORY;
984 for (j=0; j<dom->num_idxs; j++) {
985 int idx = dom->idxs[j];
986 name_infos[idx].type = types[j];
987 if (types[j] != SID_NAME_UNKNOWN) {
988 name_infos[idx].name =
989 talloc_strdup(name_infos, names[j]);
990 if (name_infos[idx].name == NULL) {
991 result = NT_STATUS_NO_MEMORY;
995 name_infos[idx].name = NULL;
1000 *ret_domains = dom_infos;
1001 *ret_names = name_infos;
1002 TALLOC_FREE(tmp_ctx);
1003 return NT_STATUS_OK;
1006 TALLOC_FREE(dom_infos);
1007 TALLOC_FREE(name_infos);
1008 TALLOC_FREE(tmp_ctx);
1012 /*****************************************************************
1013 *THE CANONICAL* convert SID to name function.
1014 *****************************************************************/
1016 bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
1017 const char **ret_domain, const char **ret_name,
1018 enum lsa_SidType *ret_type)
1020 struct lsa_dom_info *domain;
1021 struct lsa_name_info *name;
1022 TALLOC_CTX *tmp_ctx;
1025 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid)));
1027 if (!(tmp_ctx = talloc_new(mem_ctx))) {
1028 DEBUG(0, ("talloc_new failed\n"));
1032 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
1037 if (name->type == SID_NAME_UNKNOWN) {
1041 if ((ret_domain != NULL) &&
1042 !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
1046 if ((ret_name != NULL) &&
1047 !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
1051 if (ret_type != NULL) {
1052 *ret_type = name->type;
1059 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid),
1060 domain->name, name->name, name->type));
1062 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid)));
1064 TALLOC_FREE(tmp_ctx);
1068 /*****************************************************************
1069 Id mapping cache. This is to avoid Winbind mappings already
1070 seen by smbd to be queried too frequently, keeping winbindd
1071 busy, and blocking smbd while winbindd is busy with other
1072 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1073 modified to use linked lists by jra.
1074 *****************************************************************/
1077 /*****************************************************************
1078 *THE LEGACY* convert uid_t to SID function.
1079 *****************************************************************/
1081 static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
1089 id.type = ID_TYPE_UID;
1092 ret = pdb_id_to_sid(&id, psid);
1096 /* This is a mapped user */
1100 /* This is an unmapped user */
1102 uid_to_unix_users_sid(uid, psid);
1105 struct unixid xid = {
1106 .id = uid, .type = ID_TYPE_UID
1108 idmap_cache_set_sid2unixid(psid, &xid);
1112 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid,
1113 sid_string_dbg(psid)));
1118 /*****************************************************************
1119 *THE LEGACY* convert gid_t to SID function.
1120 *****************************************************************/
1122 static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid)
1130 id.type = ID_TYPE_GID;
1133 ret = pdb_id_to_sid(&id, psid);
1137 /* This is a mapped group */
1141 /* This is an unmapped group */
1143 gid_to_unix_groups_sid(gid, psid);
1146 struct unixid xid = {
1147 .id = gid, .type = ID_TYPE_GID
1149 idmap_cache_set_sid2unixid(psid, &xid);
1153 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid,
1154 sid_string_dbg(psid)));
1159 /*****************************************************************
1160 *THE LEGACY* convert SID to id function.
1161 *****************************************************************/
1163 static bool legacy_sid_to_unixid(const struct dom_sid *psid, struct unixid *id)
1168 ret = pdb_sid_to_id(psid, id);
1172 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1173 sid_string_dbg(psid)));
1180 static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1183 if (!legacy_sid_to_unixid(psid, &id)) {
1186 if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) {
1193 static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1196 if (!legacy_sid_to_unixid(psid, &id)) {
1199 if (id.type == ID_TYPE_UID || id.type == ID_TYPE_BOTH) {
1206 /*****************************************************************
1207 *THE CANONICAL* convert uid_t to SID function.
1208 *****************************************************************/
1210 void uid_to_sid(struct dom_sid *psid, uid_t uid)
1212 bool expired = true;
1216 /* Check the winbindd cache directly. */
1217 ret = idmap_cache_find_uid2sid(uid, psid, &expired);
1219 if (ret && !expired && is_null_sid(psid)) {
1221 * Negative cache entry, we already asked.
1224 legacy_uid_to_sid(psid, uid);
1228 if (!ret || expired) {
1229 /* Not in cache. Ask winbindd. */
1230 if (!winbind_uid_to_sid(psid, uid)) {
1232 * We shouldn't return the NULL SID
1233 * here if winbind was running and
1234 * couldn't map, as winbind will have
1235 * added a negative entry that will
1236 * cause us to go though the
1237 * legacy_uid_to_sid()
1238 * function anyway in the case above
1239 * the next time we ask.
1241 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1242 "for uid %u\n", (unsigned int)uid));
1244 legacy_uid_to_sid(psid, uid);
1249 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid,
1250 sid_string_dbg(psid)));
1255 /*****************************************************************
1256 *THE CANONICAL* convert gid_t to SID function.
1257 *****************************************************************/
1259 void gid_to_sid(struct dom_sid *psid, gid_t gid)
1261 bool expired = true;
1265 /* Check the winbindd cache directly. */
1266 ret = idmap_cache_find_gid2sid(gid, psid, &expired);
1268 if (ret && !expired && is_null_sid(psid)) {
1270 * Negative cache entry, we already asked.
1273 legacy_gid_to_sid(psid, gid);
1277 if (!ret || expired) {
1278 /* Not in cache. Ask winbindd. */
1279 if (!winbind_gid_to_sid(psid, gid)) {
1281 * We shouldn't return the NULL SID
1282 * here if winbind was running and
1283 * couldn't map, as winbind will have
1284 * added a negative entry that will
1285 * cause us to go though the
1286 * legacy_gid_to_sid()
1287 * function anyway in the case above
1288 * the next time we ask.
1290 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1291 "for gid %u\n", (unsigned int)gid));
1293 legacy_gid_to_sid(psid, gid);
1298 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid,
1299 sid_string_dbg(psid)));
1304 bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
1307 struct wbcDomainSid *wbc_sids = NULL;
1308 struct wbcUnixId *wbc_ids = NULL;
1309 uint32_t i, num_not_cached;
1313 wbc_sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_sids);
1314 if (wbc_sids == NULL) {
1320 for (i=0; i<num_sids; i++) {
1324 if (sid_peek_check_rid(&global_sid_Unix_Users,
1326 ids[i].type = ID_TYPE_UID;
1330 if (sid_peek_check_rid(&global_sid_Unix_Groups,
1332 ids[i].type = ID_TYPE_GID;
1336 if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
1341 ids[i].type = ID_TYPE_NOT_SPECIFIED;
1342 memcpy(&wbc_sids[num_not_cached], &sids[i],
1343 ndr_size_dom_sid(&sids[i], 0));
1344 num_not_cached += 1;
1346 if (num_not_cached == 0) {
1349 wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, num_not_cached);
1350 if (wbc_ids == NULL) {
1353 for (i=0; i<num_not_cached; i++) {
1354 wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
1356 err = wbcSidsToUnixIds(wbc_sids, num_not_cached, wbc_ids);
1357 if (!WBC_ERROR_IS_OK(err)) {
1358 DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1359 wbcErrorString(err)));
1364 for (i=0; i<num_sids; i++) {
1365 if (ids[i].type == ID_TYPE_NOT_SPECIFIED) {
1366 switch (wbc_ids[num_not_cached].type) {
1367 case WBC_ID_TYPE_UID:
1368 ids[i].type = ID_TYPE_UID;
1369 ids[i].id = wbc_ids[num_not_cached].id.uid;
1371 case WBC_ID_TYPE_GID:
1372 ids[i].type = ID_TYPE_GID;
1373 ids[i].id = wbc_ids[num_not_cached].id.gid;
1376 /* The types match, and wbcUnixId -> id is a union anyway */
1377 ids[i].type = (enum id_type)wbc_ids[num_not_cached].type;
1378 ids[i].id = wbc_ids[num_not_cached].id.gid;
1381 num_not_cached += 1;
1385 for (i=0; i<num_sids; i++) {
1386 if (ids[i].type != ID_TYPE_NOT_SPECIFIED) {
1389 if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
1390 ids[i].type = ID_TYPE_GID;
1393 if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
1394 ids[i].type = ID_TYPE_UID;
1399 for (i=0; i<num_sids; i++) {
1400 switch(ids[i].type) {
1401 case WBC_ID_TYPE_GID:
1402 case WBC_ID_TYPE_UID:
1403 case WBC_ID_TYPE_BOTH:
1404 if (ids[i].id == -1) {
1405 ids[i].type = ID_TYPE_NOT_SPECIFIED;
1408 case WBC_ID_TYPE_NOT_SPECIFIED:
1415 TALLOC_FREE(wbc_ids);
1416 TALLOC_FREE(wbc_sids);
1420 /*****************************************************************
1421 *THE CANONICAL* convert SID to uid function.
1422 *****************************************************************/
1424 bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1426 bool expired = true;
1430 /* Optimize for the Unix Users Domain
1431 * as the conversion is straightforward */
1432 if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1436 /* return here, don't cache */
1437 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1438 (unsigned int)*puid ));
1442 /* Check the winbindd cache directly. */
1443 ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1445 if (ret && !expired && (*puid == (uid_t)-1)) {
1447 * Negative cache entry, we already asked.
1450 return legacy_sid_to_uid(psid, puid);
1453 if (!ret || expired) {
1454 /* Not in cache. Ask winbindd. */
1455 if (!winbind_sid_to_uid(puid, psid)) {
1456 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1457 sid_string_dbg(psid)));
1458 /* winbind failed. do legacy */
1459 return legacy_sid_to_uid(psid, puid);
1463 /* TODO: Here would be the place to allocate both a gid and a uid for
1464 * the SID in question */
1466 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1467 (unsigned int)*puid ));
1472 /*****************************************************************
1473 *THE CANONICAL* convert SID to gid function.
1474 Group mapping is used for gids that maps to Wellknown SIDs
1475 *****************************************************************/
1477 bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1479 bool expired = true;
1483 /* Optimize for the Unix Groups Domain
1484 * as the conversion is straightforward */
1485 if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1489 /* return here, don't cache */
1490 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1491 (unsigned int)*pgid ));
1495 /* Check the winbindd cache directly. */
1496 ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1498 if (ret && !expired && (*pgid == (gid_t)-1)) {
1500 * Negative cache entry, we already asked.
1503 return legacy_sid_to_gid(psid, pgid);
1506 if (!ret || expired) {
1507 /* Not in cache or negative. Ask winbindd. */
1508 /* Ask winbindd if it can map this sid to a gid.
1509 * (Idmap will check it is a valid SID and of the right type) */
1511 if ( !winbind_sid_to_gid(pgid, psid) ) {
1513 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1514 sid_string_dbg(psid)));
1515 /* winbind failed. do legacy */
1516 return legacy_sid_to_gid(psid, pgid);
1520 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1521 (unsigned int)*pgid ));
1527 * @brief This function gets the primary group SID mapping the primary
1528 * GID of the user as obtained by an actual getpwnam() call.
1529 * This is necessary to avoid issues with arbitrary group SIDs
1530 * stored in passdb. We try as hard as we can to get the SID
1531 * corresponding to the GID, including trying group mapping.
1532 * If nothing else works, we will force "Domain Users" as the
1534 * This is needed because we must always be able to lookup the
1535 * primary group SID, so we cannot settle for an arbitrary SID.
1537 * This call can be expensive. Use with moderation.
1538 * If you have a "samu" struct around use pdb_get_group_sid()
1539 * instead as it does properly cache results.
1541 * @param mem_ctx[in] The memory context iused to allocate the result.
1542 * @param username[in] The user's name
1543 * @param _pwd[in|out] If available, pass in user's passwd struct.
1544 * It will contain a tallocated passwd if NULL was
1546 * @param _group_sid[out] The user's Primary Group SID
1548 * @return NTSTATUS error code.
1550 NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1551 const char *username,
1552 struct passwd **_pwd,
1553 struct dom_sid **_group_sid)
1555 TALLOC_CTX *tmp_ctx;
1556 bool need_lookup_sid = false;
1557 struct dom_sid *group_sid;
1558 struct passwd *pwd = *_pwd;
1560 tmp_ctx = talloc_new(mem_ctx);
1562 return NT_STATUS_NO_MEMORY;
1566 pwd = Get_Pwnam_alloc(mem_ctx, username);
1568 DEBUG(0, ("Failed to find a Unix account for %s\n",
1570 TALLOC_FREE(tmp_ctx);
1571 return NT_STATUS_NO_SUCH_USER;
1575 group_sid = talloc_zero(mem_ctx, struct dom_sid);
1577 TALLOC_FREE(tmp_ctx);
1578 return NT_STATUS_NO_MEMORY;
1581 gid_to_sid(group_sid, pwd->pw_gid);
1582 if (!is_null_sid(group_sid)) {
1583 struct dom_sid domain_sid;
1586 /* We need a sid within our domain */
1587 sid_copy(&domain_sid, group_sid);
1588 sid_split_rid(&domain_sid, &rid);
1589 if (dom_sid_equal(&domain_sid, get_global_sam_sid())) {
1591 * As shortcut for the expensive lookup_sid call
1592 * compare the domain sid part
1595 case DOMAIN_RID_ADMINS:
1596 case DOMAIN_RID_USERS:
1599 need_lookup_sid = true;
1603 /* Try group mapping */
1606 id.id = pwd->pw_gid;
1607 id.type = ID_TYPE_GID;
1609 ZERO_STRUCTP(group_sid);
1610 if (pdb_id_to_sid(&id, group_sid)) {
1611 need_lookup_sid = true;
1616 /* We must verify that this is a valid SID that resolves to a
1617 * group of the correct type */
1618 if (need_lookup_sid) {
1619 enum lsa_SidType type = SID_NAME_UNKNOWN;
1622 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1623 sid_string_dbg(group_sid), username));
1625 /* Now check that it's actually a domain group and
1626 * not something else */
1627 lookup_ret = lookup_sid(tmp_ctx, group_sid,
1630 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1634 DEBUG(3, ("Primary group %s for user %s is"
1635 " a %s and not a domain group\n",
1636 sid_string_dbg(group_sid), username,
1637 sid_type_lookup(type)));
1640 /* Everything else, failed.
1641 * Just set it to the 'Domain Users' RID of 513 which will
1642 always resolve to a name */
1643 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1646 sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1649 *_pwd = talloc_move(mem_ctx, &pwd);
1650 *_group_sid = talloc_move(mem_ctx, &group_sid);
1651 TALLOC_FREE(tmp_ctx);
1652 return NT_STATUS_OK;