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 /*****************************************************************
25 Dissect a user-provided name into domain, name, sid and type.
27 If an explicit domain name was given in the form domain\user, it
28 has to try that. If no explicit domain name was given, we have
30 *****************************************************************/
32 bool lookup_name(TALLOC_CTX
*mem_ctx
,
33 const char *full_name
, int flags
,
34 const char **ret_domain
, const char **ret_name
,
35 DOM_SID
*ret_sid
, enum lsa_SidType
*ret_type
)
39 const char *domain
= NULL
;
40 const char *name
= NULL
;
43 enum lsa_SidType type
;
44 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
46 if (tmp_ctx
== NULL
) {
47 DEBUG(0, ("talloc_new failed\n"));
51 p
= strchr_m(full_name
, '\\');
54 domain
= talloc_strndup(tmp_ctx
, full_name
,
55 PTR_DIFF(p
, full_name
));
56 name
= talloc_strdup(tmp_ctx
, p
+1);
58 domain
= talloc_strdup(tmp_ctx
, "");
59 name
= talloc_strdup(tmp_ctx
, full_name
);
62 if ((domain
== NULL
) || (name
== NULL
)) {
63 DEBUG(0, ("talloc failed\n"));
68 DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n",
69 full_name
, domain
, name
));
70 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags
));
72 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
73 strequal(domain
, get_global_sam_name()))
76 /* It's our own domain, lookup the name in passdb */
77 if (lookup_global_sam_name(name
, flags
, &rid
, &type
)) {
78 sid_copy(&sid
, get_global_sam_sid());
79 sid_append_rid(&sid
, rid
);
86 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
87 strequal(domain
, builtin_domain_name()))
89 /* Explicit request for a name in BUILTIN */
90 if (lookup_builtin_name(name
, &rid
)) {
91 sid_copy(&sid
, &global_sid_Builtin
);
92 sid_append_rid(&sid
, rid
);
93 type
= SID_NAME_ALIAS
;
100 /* Try the explicit winbind lookup first, don't let it guess the
101 * domain yet at this point yet. This comes later. */
103 if ((domain
[0] != '\0') &&
104 (flags
& ~(LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
)) &&
105 (winbind_lookup_name(domain
, name
, &sid
, &type
))) {
109 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
110 && strequal(domain
, unix_users_domain_name())) {
111 if (lookup_unix_user_name(name
, &sid
)) {
112 type
= SID_NAME_USER
;
115 TALLOC_FREE(tmp_ctx
);
119 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
120 && strequal(domain
, unix_groups_domain_name())) {
121 if (lookup_unix_group_name(name
, &sid
)) {
122 type
= SID_NAME_DOM_GRP
;
125 TALLOC_FREE(tmp_ctx
);
129 if ((domain
[0] == '\0') && (!(flags
& LOOKUP_NAME_ISOLATED
))) {
130 TALLOC_FREE(tmp_ctx
);
134 /* Now the guesswork begins, we haven't been given an explicit
135 * domain. Try the sequence as documented on
136 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
137 * November 27, 2005 */
139 /* 1. well-known names */
141 if ((flags
& LOOKUP_NAME_WKN
) &&
142 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
144 type
= SID_NAME_WKN_GRP
;
148 /* 2. Builtin domain as such */
150 if ((flags
& (LOOKUP_NAME_BUILTIN
|LOOKUP_NAME_REMOTE
)) &&
151 strequal(name
, builtin_domain_name()))
153 /* Swap domain and name */
154 tmp
= name
; name
= domain
; domain
= tmp
;
155 sid_copy(&sid
, &global_sid_Builtin
);
156 type
= SID_NAME_DOMAIN
;
160 /* 3. Account domain */
162 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
163 strequal(name
, get_global_sam_name()))
165 if (!secrets_fetch_domain_sid(name
, &sid
)) {
166 DEBUG(3, ("Could not fetch my SID\n"));
167 TALLOC_FREE(tmp_ctx
);
170 /* Swap domain and name */
171 tmp
= name
; name
= domain
; domain
= tmp
;
172 type
= SID_NAME_DOMAIN
;
176 /* 4. Primary domain */
178 if ((flags
& LOOKUP_NAME_DOMAIN
) && !IS_DC
&&
179 strequal(name
, lp_workgroup()))
181 if (!secrets_fetch_domain_sid(name
, &sid
)) {
182 DEBUG(3, ("Could not fetch the domain SID\n"));
183 TALLOC_FREE(tmp_ctx
);
186 /* Swap domain and name */
187 tmp
= name
; name
= domain
; domain
= tmp
;
188 type
= SID_NAME_DOMAIN
;
192 /* 5. Trusted domains as such, to me it looks as if members don't do
193 this, tested an XP workstation in a NT domain -- vl */
195 if ((flags
& LOOKUP_NAME_REMOTE
) && IS_DC
&&
196 (pdb_get_trusteddom_pw(name
, NULL
, &sid
, NULL
)))
198 /* Swap domain and name */
199 tmp
= name
; name
= domain
; domain
= tmp
;
200 type
= SID_NAME_DOMAIN
;
204 /* 6. Builtin aliases */
206 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
207 lookup_builtin_name(name
, &rid
))
209 domain
= talloc_strdup(tmp_ctx
, builtin_domain_name());
210 sid_copy(&sid
, &global_sid_Builtin
);
211 sid_append_rid(&sid
, rid
);
212 type
= SID_NAME_ALIAS
;
216 /* 7. Local systems' SAM (DCs don't have a local SAM) */
217 /* 8. Primary SAM (On members, this is the domain) */
219 /* Both cases are done by looking at our passdb */
221 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
222 lookup_global_sam_name(name
, flags
, &rid
, &type
))
224 domain
= talloc_strdup(tmp_ctx
, get_global_sam_name());
225 sid_copy(&sid
, get_global_sam_sid());
226 sid_append_rid(&sid
, rid
);
230 /* Now our local possibilities are exhausted. */
232 if (!(flags
& LOOKUP_NAME_REMOTE
)) {
233 TALLOC_FREE(tmp_ctx
);
237 /* If we are not a DC, we have to ask in our primary domain. Let
238 * winbind do that. */
241 (winbind_lookup_name(lp_workgroup(), name
, &sid
, &type
))) {
242 domain
= talloc_strdup(tmp_ctx
, lp_workgroup());
246 /* 9. Trusted domains */
248 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
249 * that (yet), but give it a chance. */
251 if (IS_DC
&& winbind_lookup_name("", name
, &sid
, &type
)) {
254 enum lsa_SidType domain_type
;
256 if (type
== SID_NAME_DOMAIN
) {
257 /* Swap name and type */
258 tmp
= name
; name
= domain
; domain
= tmp
;
262 /* Here we have to cope with a little deficiency in the
263 * winbind API: We have to ask it again for the name of the
264 * domain it figured out itself. Maybe fix that later... */
266 sid_copy(&dom_sid
, &sid
);
267 sid_split_rid(&dom_sid
, &tmp_rid
);
269 if (!winbind_lookup_sid(tmp_ctx
, &dom_sid
, &domain
, NULL
,
271 (domain_type
!= SID_NAME_DOMAIN
)) {
272 DEBUG(2, ("winbind could not find the domain's name "
273 "it just looked up for us\n"));
274 TALLOC_FREE(tmp_ctx
);
280 /* 10. Don't translate */
282 /* 11. Ok, windows would end here. Samba has two more options:
283 Unmapped users and unmapped groups */
285 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
286 && lookup_unix_user_name(name
, &sid
)) {
287 domain
= talloc_strdup(tmp_ctx
, unix_users_domain_name());
288 type
= SID_NAME_USER
;
292 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
293 && lookup_unix_group_name(name
, &sid
)) {
294 domain
= talloc_strdup(tmp_ctx
, unix_groups_domain_name());
295 type
= SID_NAME_DOM_GRP
;
300 * Ok, all possibilities tried. Fail.
303 TALLOC_FREE(tmp_ctx
);
307 if ((domain
== NULL
) || (name
== NULL
)) {
308 DEBUG(0, ("talloc failed\n"));
309 TALLOC_FREE(tmp_ctx
);
314 * Hand over the results to the talloc context we've been given.
317 if ((ret_name
!= NULL
) &&
318 !(*ret_name
= talloc_strdup(mem_ctx
, name
))) {
319 DEBUG(0, ("talloc failed\n"));
320 TALLOC_FREE(tmp_ctx
);
324 if (ret_domain
!= NULL
) {
326 if (!(tmp_dom
= talloc_strdup(mem_ctx
, domain
))) {
327 DEBUG(0, ("talloc failed\n"));
328 TALLOC_FREE(tmp_ctx
);
332 *ret_domain
= tmp_dom
;
335 if (ret_sid
!= NULL
) {
336 sid_copy(ret_sid
, &sid
);
339 if (ret_type
!= NULL
) {
343 TALLOC_FREE(tmp_ctx
);
347 /************************************************************************
348 Names from smb.conf can be unqualified. eg. valid users = foo
349 These names should never map to a remote name. Try global_sam_name()\foo,
350 and then "Unix Users"\foo (or "Unix Groups"\foo).
351 ************************************************************************/
353 bool lookup_name_smbconf(TALLOC_CTX
*mem_ctx
,
354 const char *full_name
, int flags
,
355 const char **ret_domain
, const char **ret_name
,
356 DOM_SID
*ret_sid
, enum lsa_SidType
*ret_type
)
358 char *qualified_name
;
361 /* NB. No winbindd_separator here as lookup_name needs \\' */
362 if ((p
= strchr_m(full_name
, *lp_winbind_separator())) != NULL
) {
364 /* The name is already qualified with a domain. */
366 if (*lp_winbind_separator() != '\\') {
369 /* lookup_name() needs '\\' as a separator */
371 tmp
= talloc_strdup(mem_ctx
, full_name
);
375 tmp
[p
- full_name
] = '\\';
379 return lookup_name(mem_ctx
, full_name
, flags
,
380 ret_domain
, ret_name
,
384 /* Try with our own SAM name. */
385 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
386 get_global_sam_name(),
388 if (!qualified_name
) {
392 if (lookup_name(mem_ctx
, qualified_name
, flags
,
393 ret_domain
, ret_name
,
394 ret_sid
, ret_type
)) {
398 /* Finally try with "Unix Users" or "Unix Group" */
399 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
400 flags
& LOOKUP_NAME_GROUP
?
401 unix_groups_domain_name() :
402 unix_users_domain_name(),
404 if (!qualified_name
) {
408 return lookup_name(mem_ctx
, qualified_name
, flags
,
409 ret_domain
, ret_name
,
413 static bool wb_lookup_rids(TALLOC_CTX
*mem_ctx
,
414 const DOM_SID
*domain_sid
,
415 int num_rids
, uint32
*rids
,
416 const char **domain_name
,
417 const char **names
, enum lsa_SidType
*types
)
420 const char **my_names
;
421 enum lsa_SidType
*my_types
;
424 if (!(tmp_ctx
= talloc_init("wb_lookup_rids"))) {
428 if (!winbind_lookup_rids(tmp_ctx
, domain_sid
, num_rids
, rids
,
429 domain_name
, &my_names
, &my_types
)) {
431 for (i
=0; i
<num_rids
; i
++) {
433 types
[i
] = SID_NAME_UNKNOWN
;
435 TALLOC_FREE(tmp_ctx
);
439 if (!(*domain_name
= talloc_strdup(mem_ctx
, *domain_name
))) {
440 TALLOC_FREE(tmp_ctx
);
445 * winbind_lookup_rids allocates its own array. We've been given the
446 * array, so copy it over
449 for (i
=0; i
<num_rids
; i
++) {
450 if (my_names
[i
] == NULL
) {
451 TALLOC_FREE(tmp_ctx
);
454 if (!(names
[i
] = talloc_strdup(names
, my_names
[i
]))) {
455 TALLOC_FREE(tmp_ctx
);
458 types
[i
] = my_types
[i
];
460 TALLOC_FREE(tmp_ctx
);
464 static bool lookup_rids(TALLOC_CTX
*mem_ctx
, const DOM_SID
*domain_sid
,
465 int num_rids
, uint32_t *rids
,
466 const char **domain_name
,
467 const char ***names
, enum lsa_SidType
**types
)
471 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
472 sid_string_dbg(domain_sid
)));
475 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, const char *, num_rids
);
476 *types
= TALLOC_ARRAY(mem_ctx
, enum lsa_SidType
, num_rids
);
478 if ((*names
== NULL
) || (*types
== NULL
)) {
482 for (i
= 0; i
< num_rids
; i
++)
483 (*types
)[i
] = SID_NAME_UNKNOWN
;
489 if (sid_check_is_domain(domain_sid
)) {
492 if (*domain_name
== NULL
) {
493 *domain_name
= talloc_strdup(
494 mem_ctx
, get_global_sam_name());
497 if (*domain_name
== NULL
) {
502 result
= pdb_lookup_rids(domain_sid
, num_rids
, rids
,
506 return (NT_STATUS_IS_OK(result
) ||
507 NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
) ||
508 NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
));
511 if (sid_check_is_builtin(domain_sid
)) {
513 if (*domain_name
== NULL
) {
514 *domain_name
= talloc_strdup(
515 mem_ctx
, builtin_domain_name());
518 if (*domain_name
== NULL
) {
522 for (i
=0; i
<num_rids
; i
++) {
523 if (lookup_builtin_rid(*names
, rids
[i
],
525 if ((*names
)[i
] == NULL
) {
528 (*types
)[i
] = SID_NAME_ALIAS
;
530 (*types
)[i
] = SID_NAME_UNKNOWN
;
536 if (sid_check_is_wellknown_domain(domain_sid
, NULL
)) {
537 for (i
=0; i
<num_rids
; i
++) {
539 sid_copy(&sid
, domain_sid
);
540 sid_append_rid(&sid
, rids
[i
]);
541 if (lookup_wellknown_sid(mem_ctx
, &sid
,
542 domain_name
, &(*names
)[i
])) {
543 if ((*names
)[i
] == NULL
) {
546 (*types
)[i
] = SID_NAME_WKN_GRP
;
548 (*types
)[i
] = SID_NAME_UNKNOWN
;
554 if (sid_check_is_unix_users(domain_sid
)) {
555 if (*domain_name
== NULL
) {
556 *domain_name
= talloc_strdup(
557 mem_ctx
, unix_users_domain_name());
558 if (*domain_name
== NULL
) {
562 for (i
=0; i
<num_rids
; i
++) {
563 (*names
)[i
] = talloc_strdup(
564 (*names
), uidtoname(rids
[i
]));
565 if ((*names
)[i
] == NULL
) {
568 (*types
)[i
] = SID_NAME_USER
;
573 if (sid_check_is_unix_groups(domain_sid
)) {
574 if (*domain_name
== NULL
) {
575 *domain_name
= talloc_strdup(
576 mem_ctx
, unix_groups_domain_name());
577 if (*domain_name
== NULL
) {
581 for (i
=0; i
<num_rids
; i
++) {
582 (*names
)[i
] = talloc_strdup(
583 (*names
), gidtoname(rids
[i
]));
584 if ((*names
)[i
] == NULL
) {
587 (*types
)[i
] = SID_NAME_DOM_GRP
;
592 return wb_lookup_rids(mem_ctx
, domain_sid
, num_rids
, rids
,
593 domain_name
, *names
, *types
);
597 * Is the SID a domain as such? If yes, lookup its name.
600 static bool lookup_as_domain(const DOM_SID
*sid
, TALLOC_CTX
*mem_ctx
,
604 enum lsa_SidType type
;
606 if (sid_check_is_domain(sid
)) {
607 *name
= talloc_strdup(mem_ctx
, get_global_sam_name());
611 if (sid_check_is_builtin(sid
)) {
612 *name
= talloc_strdup(mem_ctx
, builtin_domain_name());
616 if (sid_check_is_wellknown_domain(sid
, &tmp
)) {
617 *name
= talloc_strdup(mem_ctx
, tmp
);
621 if (sid_check_is_unix_users(sid
)) {
622 *name
= talloc_strdup(mem_ctx
, unix_users_domain_name());
626 if (sid_check_is_unix_groups(sid
)) {
627 *name
= talloc_strdup(mem_ctx
, unix_groups_domain_name());
631 if (sid
->num_auths
!= 4) {
632 /* This can't be a domain */
637 uint32 i
, num_domains
;
638 struct trustdom_info
**domains
;
640 /* This is relatively expensive, but it happens only on DCs
641 * and for SIDs that have 4 sub-authorities and thus look like
644 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx
,
650 for (i
=0; i
<num_domains
; i
++) {
651 if (sid_equal(sid
, &domains
[i
]->sid
)) {
652 *name
= talloc_strdup(mem_ctx
,
660 if (winbind_lookup_sid(mem_ctx
, sid
, &tmp
, NULL
, &type
) &&
661 (type
== SID_NAME_DOMAIN
)) {
670 * This tries to implement the rather weird rules for the lsa_lookup level
673 * This is as close as we can get to what W2k3 does. With this we survive the
674 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
675 * different, but I assume that's just being too liberal. For example, W2k3
676 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
677 * whereas NT4 does the same as level 1 (I think). I did not fully test that
678 * with NT4, this is what w2k3 does.
680 * Level 1: Ask everywhere
681 * Level 2: Ask domain and trusted domains, no builtin and wkn
682 * Level 3: Only ask domain
683 * Level 4: W2k3ad: Only ask AD trusts
684 * Level 5: Only ask transitive forest trusts
688 static bool check_dom_sid_to_level(const DOM_SID
*sid
, int level
)
697 ret
= (!sid_check_is_builtin(sid
) &&
698 !sid_check_is_wellknown_domain(sid
, NULL
));
703 ret
= sid_check_is_domain(sid
);
710 DEBUG(10, ("%s SID %s in level %d\n",
711 ret
? "Accepting" : "Rejecting",
712 sid_string_dbg(sid
), level
));
717 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
718 * references to domains, it is explicitly made for this.
720 * This attempts to be as efficient as possible: It collects all SIDs
721 * belonging to a domain and hands them in bulk to the appropriate lookup
722 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
723 * *hugely* from this. Winbind is going to be extended with a lookup_rids
724 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
728 NTSTATUS
lookup_sids(TALLOC_CTX
*mem_ctx
, int num_sids
,
729 const DOM_SID
**sids
, int level
,
730 struct lsa_dom_info
**ret_domains
,
731 struct lsa_name_info
**ret_names
)
734 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
735 struct lsa_name_info
*name_infos
;
736 struct lsa_dom_info
*dom_infos
= NULL
;
740 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
741 DEBUG(0, ("talloc_new failed\n"));
742 return NT_STATUS_NO_MEMORY
;
746 name_infos
= TALLOC_ARRAY(mem_ctx
, struct lsa_name_info
, num_sids
);
747 if (name_infos
== NULL
) {
748 result
= NT_STATUS_NO_MEMORY
;
755 dom_infos
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_dom_info
,
756 LSA_REF_DOMAIN_LIST_MULTIPLIER
);
757 if (dom_infos
== NULL
) {
758 result
= NT_STATUS_NO_MEMORY
;
762 /* First build up the data structures:
764 * dom_infos is a list of domains referenced in the list of
765 * SIDs. Later we will walk the list of domains and look up the RIDs
768 * name_infos is a shadow-copy of the SIDs array to collect the real
771 * dom_info->idxs is an index into the name_infos array. The
772 * difficulty we have here is that we need to keep the SIDs the client
773 * asked for in the same order for the reply
776 for (i
=0; i
<num_sids
; i
++) {
779 const char *domain_name
= NULL
;
781 sid_copy(&sid
, sids
[i
]);
782 name_infos
[i
].type
= SID_NAME_USE_NONE
;
784 if (lookup_as_domain(&sid
, name_infos
, &domain_name
)) {
785 /* We can't push that through the normal lookup
786 * process, as this would reference illegal
789 * For example S-1-5-32 would end up referencing
790 * domain S-1-5- with RID 32 which is clearly wrong.
792 if (domain_name
== NULL
) {
793 result
= NT_STATUS_NO_MEMORY
;
797 name_infos
[i
].rid
= 0;
798 name_infos
[i
].type
= SID_NAME_DOMAIN
;
799 name_infos
[i
].name
= NULL
;
801 if (sid_check_is_builtin(&sid
)) {
802 /* Yes, W2k3 returns "BUILTIN" both as domain
804 name_infos
[i
].name
= talloc_strdup(
805 name_infos
, builtin_domain_name());
806 if (name_infos
[i
].name
== NULL
) {
807 result
= NT_STATUS_NO_MEMORY
;
812 /* This is a normal SID with rid component */
813 if (!sid_split_rid(&sid
, &rid
)) {
814 result
= NT_STATUS_INVALID_SID
;
819 if (!check_dom_sid_to_level(&sid
, level
)) {
820 name_infos
[i
].rid
= 0;
821 name_infos
[i
].type
= SID_NAME_UNKNOWN
;
822 name_infos
[i
].name
= NULL
;
826 for (j
=0; j
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; j
++) {
827 if (!dom_infos
[j
].valid
) {
830 if (sid_equal(&sid
, &dom_infos
[j
].sid
)) {
835 if (j
== LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
836 /* TODO: What's the right error message here? */
837 result
= NT_STATUS_NONE_MAPPED
;
841 if (!dom_infos
[j
].valid
) {
842 /* We found a domain not yet referenced, create a new
844 dom_infos
[j
].valid
= true;
845 sid_copy(&dom_infos
[j
].sid
, &sid
);
847 if (domain_name
!= NULL
) {
848 /* This name was being found above in the case
849 * when we found a domain SID */
851 talloc_strdup(dom_infos
, domain_name
);
852 if (dom_infos
[j
].name
== NULL
) {
853 result
= NT_STATUS_NO_MEMORY
;
857 /* lookup_rids will take care of this */
858 dom_infos
[j
].name
= NULL
;
862 name_infos
[i
].dom_idx
= j
;
864 if (name_infos
[i
].type
== SID_NAME_USE_NONE
) {
865 name_infos
[i
].rid
= rid
;
867 ADD_TO_ARRAY(dom_infos
, int, i
, &dom_infos
[j
].idxs
,
868 &dom_infos
[j
].num_idxs
);
870 if (dom_infos
[j
].idxs
== NULL
) {
871 result
= NT_STATUS_NO_MEMORY
;
877 /* Iterate over the domains found */
879 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
881 const char *domain_name
= NULL
;
883 enum lsa_SidType
*types
;
884 struct lsa_dom_info
*dom
= &dom_infos
[i
];
887 /* No domains left, we're done */
892 if (!(rids
= TALLOC_ARRAY(tmp_ctx
, uint32
, dom
->num_idxs
))) {
893 result
= NT_STATUS_NO_MEMORY
;
900 for (j
=0; j
<dom
->num_idxs
; j
++) {
901 rids
[j
] = name_infos
[dom
->idxs
[j
]].rid
;
904 if (!lookup_rids(tmp_ctx
, &dom
->sid
,
905 dom
->num_idxs
, rids
, &domain_name
,
907 result
= NT_STATUS_NO_MEMORY
;
911 if (!(dom
->name
= talloc_strdup(dom_infos
, domain_name
))) {
912 result
= NT_STATUS_NO_MEMORY
;
916 for (j
=0; j
<dom
->num_idxs
; j
++) {
917 int idx
= dom
->idxs
[j
];
918 name_infos
[idx
].type
= types
[j
];
919 if (types
[j
] != SID_NAME_UNKNOWN
) {
920 name_infos
[idx
].name
=
921 talloc_strdup(name_infos
, names
[j
]);
922 if (name_infos
[idx
].name
== NULL
) {
923 result
= NT_STATUS_NO_MEMORY
;
927 name_infos
[idx
].name
= NULL
;
932 *ret_domains
= dom_infos
;
933 *ret_names
= name_infos
;
934 TALLOC_FREE(tmp_ctx
);
938 TALLOC_FREE(dom_infos
);
939 TALLOC_FREE(name_infos
);
940 TALLOC_FREE(tmp_ctx
);
944 /*****************************************************************
945 *THE CANONICAL* convert SID to name function.
946 *****************************************************************/
948 bool lookup_sid(TALLOC_CTX
*mem_ctx
, const DOM_SID
*sid
,
949 const char **ret_domain
, const char **ret_name
,
950 enum lsa_SidType
*ret_type
)
952 struct lsa_dom_info
*domain
;
953 struct lsa_name_info
*name
;
957 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid
)));
959 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
960 DEBUG(0, ("talloc_new failed\n"));
964 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx
, 1, &sid
, 1,
969 if (name
->type
== SID_NAME_UNKNOWN
) {
973 if ((ret_domain
!= NULL
) &&
974 !(*ret_domain
= talloc_strdup(mem_ctx
, domain
->name
))) {
978 if ((ret_name
!= NULL
) &&
979 !(*ret_name
= talloc_strdup(mem_ctx
, name
->name
))) {
983 if (ret_type
!= NULL
) {
984 *ret_type
= name
->type
;
991 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid
),
992 domain
->name
, name
->name
, name
->type
));
994 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid
)));
996 TALLOC_FREE(tmp_ctx
);
1000 /*****************************************************************
1001 Id mapping cache. This is to avoid Winbind mappings already
1002 seen by smbd to be queried too frequently, keeping winbindd
1003 busy, and blocking smbd while winbindd is busy with other
1004 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1005 modified to use linked lists by jra.
1006 *****************************************************************/
1008 /*****************************************************************
1009 Find a SID given a uid.
1010 *****************************************************************/
1012 static bool fetch_sid_from_uid_cache(DOM_SID
*psid
, uid_t uid
)
1014 DATA_BLOB cache_value
;
1016 if (!memcache_lookup(NULL
, UID_SID_CACHE
,
1017 data_blob_const(&uid
, sizeof(uid
)),
1022 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1023 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1024 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, NULL
, 0));
1029 /*****************************************************************
1030 Find a uid given a SID.
1031 *****************************************************************/
1033 static bool fetch_uid_from_cache( uid_t
*puid
, const DOM_SID
*psid
)
1035 DATA_BLOB cache_value
;
1037 if (!memcache_lookup(NULL
, SID_UID_CACHE
,
1038 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)),
1043 SMB_ASSERT(cache_value
.length
== sizeof(*puid
));
1044 memcpy(puid
, cache_value
.data
, sizeof(*puid
));
1049 /*****************************************************************
1050 Store uid to SID mapping in cache.
1051 *****************************************************************/
1053 void store_uid_sid_cache(const DOM_SID
*psid
, uid_t uid
)
1055 memcache_add(NULL
, SID_UID_CACHE
,
1056 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)),
1057 data_blob_const(&uid
, sizeof(uid
)));
1058 memcache_add(NULL
, UID_SID_CACHE
,
1059 data_blob_const(&uid
, sizeof(uid
)),
1060 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)));
1063 /*****************************************************************
1064 Find a SID given a gid.
1065 *****************************************************************/
1067 static bool fetch_sid_from_gid_cache(DOM_SID
*psid
, gid_t gid
)
1069 DATA_BLOB cache_value
;
1071 if (!memcache_lookup(NULL
, GID_SID_CACHE
,
1072 data_blob_const(&gid
, sizeof(gid
)),
1077 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1078 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1079 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, NULL
, 0));
1084 /*****************************************************************
1085 Find a gid given a SID.
1086 *****************************************************************/
1088 static bool fetch_gid_from_cache(gid_t
*pgid
, const DOM_SID
*psid
)
1090 DATA_BLOB cache_value
;
1092 if (!memcache_lookup(NULL
, SID_GID_CACHE
,
1093 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)),
1098 SMB_ASSERT(cache_value
.length
== sizeof(*pgid
));
1099 memcpy(pgid
, cache_value
.data
, sizeof(*pgid
));
1104 /*****************************************************************
1105 Store gid to SID mapping in cache.
1106 *****************************************************************/
1108 void store_gid_sid_cache(const DOM_SID
*psid
, gid_t gid
)
1110 memcache_add(NULL
, SID_GID_CACHE
,
1111 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)),
1112 data_blob_const(&gid
, sizeof(gid
)));
1113 memcache_add(NULL
, GID_SID_CACHE
,
1114 data_blob_const(&gid
, sizeof(gid
)),
1115 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)));
1118 /*****************************************************************
1119 *THE LEGACY* convert uid_t to SID function.
1120 *****************************************************************/
1122 static void legacy_uid_to_sid(DOM_SID
*psid
, uid_t uid
)
1130 ret
= pdb_uid_to_rid(uid
, &rid
);
1134 /* This is a mapped user */
1135 sid_copy(psid
, get_global_sam_sid());
1136 sid_append_rid(psid
, rid
);
1140 /* This is an unmapped user */
1142 uid_to_unix_users_sid(uid
, psid
);
1145 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid
,
1146 sid_string_dbg(psid
)));
1148 store_uid_sid_cache(psid
, uid
);
1152 /*****************************************************************
1153 *THE LEGACY* convert gid_t to SID function.
1154 *****************************************************************/
1156 static void legacy_gid_to_sid(DOM_SID
*psid
, gid_t gid
)
1163 ret
= pdb_gid_to_sid(gid
, psid
);
1167 /* This is a mapped group */
1171 /* This is an unmapped group */
1173 gid_to_unix_groups_sid(gid
, psid
);
1176 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid
,
1177 sid_string_dbg(psid
)));
1179 store_gid_sid_cache(psid
, gid
);
1183 /*****************************************************************
1184 *THE LEGACY* convert SID to uid function.
1185 *****************************************************************/
1187 static bool legacy_sid_to_uid(const DOM_SID
*psid
, uid_t
*puid
)
1189 enum lsa_SidType type
;
1192 if (sid_peek_check_rid(get_global_sam_sid(), psid
, &rid
)) {
1197 ret
= pdb_sid_to_id(psid
, &id
, &type
);
1201 if (type
!= SID_NAME_USER
) {
1202 DEBUG(5, ("sid %s is a %s, expected a user\n",
1203 sid_string_dbg(psid
),
1204 sid_type_lookup(type
)));
1211 /* This was ours, but it was not mapped. Fail */
1214 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1215 sid_string_dbg(psid
)));
1219 DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_dbg(psid
),
1220 (unsigned int)*puid
));
1222 store_uid_sid_cache(psid
, *puid
);
1226 /*****************************************************************
1227 *THE LEGACY* convert SID to gid function.
1228 Group mapping is used for gids that maps to Wellknown SIDs
1229 *****************************************************************/
1231 static bool legacy_sid_to_gid(const DOM_SID
*psid
, gid_t
*pgid
)
1236 enum lsa_SidType type
;
1238 if ((sid_check_is_in_builtin(psid
) ||
1239 sid_check_is_in_wellknown_domain(psid
))) {
1243 ret
= pdb_getgrsid(&map
, *psid
);
1250 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1251 sid_string_dbg(psid
)));
1255 if (sid_peek_check_rid(get_global_sam_sid(), psid
, &rid
)) {
1259 ret
= pdb_sid_to_id(psid
, &id
, &type
);
1263 if ((type
!= SID_NAME_DOM_GRP
) &&
1264 (type
!= SID_NAME_ALIAS
)) {
1265 DEBUG(5, ("LEGACY: sid %s is a %s, expected "
1266 "a group\n", sid_string_dbg(psid
),
1267 sid_type_lookup(type
)));
1274 /* This was ours, but it was not mapped. Fail */
1277 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1278 sid_string_dbg(psid
)));
1282 DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid
),
1283 (unsigned int)*pgid
));
1285 store_gid_sid_cache(psid
, *pgid
);
1290 /*****************************************************************
1291 *THE CANONICAL* convert uid_t to SID function.
1292 *****************************************************************/
1294 void uid_to_sid(DOM_SID
*psid
, uid_t uid
)
1296 bool expired
= true;
1300 if (fetch_sid_from_uid_cache(psid
, uid
))
1303 /* Check the winbindd cache directly. */
1304 ret
= idmap_cache_find_uid2sid(uid
, psid
, &expired
);
1306 if (ret
&& !expired
&& is_null_sid(psid
)) {
1308 * Negative cache entry, we already asked.
1311 legacy_uid_to_sid(psid
, uid
);
1315 if (!ret
|| expired
) {
1316 /* Not in cache. Ask winbindd. */
1317 if (!winbind_uid_to_sid(psid
, uid
)) {
1319 * We shouldn't return the NULL SID
1320 * here if winbind was running and
1321 * couldn't map, as winbind will have
1322 * added a negative entry that will
1323 * cause us to go though the
1324 * legacy_uid_to_sid()
1325 * function anyway in the case above
1326 * the next time we ask.
1328 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1329 "for uid %u\n", (unsigned int)uid
));
1331 legacy_uid_to_sid(psid
, uid
);
1336 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid
,
1337 sid_string_dbg(psid
)));
1339 store_uid_sid_cache(psid
, uid
);
1343 /*****************************************************************
1344 *THE CANONICAL* convert gid_t to SID function.
1345 *****************************************************************/
1347 void gid_to_sid(DOM_SID
*psid
, gid_t gid
)
1349 bool expired
= true;
1353 if (fetch_sid_from_gid_cache(psid
, gid
))
1356 /* Check the winbindd cache directly. */
1357 ret
= idmap_cache_find_gid2sid(gid
, psid
, &expired
);
1359 if (ret
&& !expired
&& is_null_sid(psid
)) {
1361 * Negative cache entry, we already asked.
1364 legacy_gid_to_sid(psid
, gid
);
1368 if (!ret
|| expired
) {
1369 /* Not in cache. Ask winbindd. */
1370 if (!winbind_gid_to_sid(psid
, gid
)) {
1372 * We shouldn't return the NULL SID
1373 * here if winbind was running and
1374 * couldn't map, as winbind will have
1375 * added a negative entry that will
1376 * cause us to go though the
1377 * legacy_gid_to_sid()
1378 * function anyway in the case above
1379 * the next time we ask.
1381 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1382 "for gid %u\n", (unsigned int)gid
));
1384 legacy_gid_to_sid(psid
, gid
);
1389 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid
,
1390 sid_string_dbg(psid
)));
1392 store_gid_sid_cache(psid
, gid
);
1396 /*****************************************************************
1397 *THE CANONICAL* convert SID to uid function.
1398 *****************************************************************/
1400 bool sid_to_uid(const DOM_SID
*psid
, uid_t
*puid
)
1402 bool expired
= true;
1407 if (fetch_uid_from_cache(puid
, psid
))
1410 if (fetch_gid_from_cache(&gid
, psid
)) {
1414 /* Optimize for the Unix Users Domain
1415 * as the conversion is straightforward */
1416 if (sid_peek_check_rid(&global_sid_Unix_Users
, psid
, &rid
)) {
1420 /* return here, don't cache */
1421 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1422 (unsigned int)*puid
));
1426 /* Check the winbindd cache directly. */
1427 ret
= idmap_cache_find_sid2uid(psid
, puid
, &expired
);
1429 if (ret
&& !expired
&& (*puid
== (uid_t
)-1)) {
1431 * Negative cache entry, we already asked.
1434 return legacy_sid_to_uid(psid
, puid
);
1437 if (!ret
|| expired
) {
1438 /* Not in cache. Ask winbindd. */
1439 if (!winbind_sid_to_uid(puid
, psid
)) {
1440 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1441 sid_string_dbg(psid
)));
1442 /* winbind failed. do legacy */
1443 return legacy_sid_to_uid(psid
, puid
);
1447 /* TODO: Here would be the place to allocate both a gid and a uid for
1448 * the SID in question */
1450 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1451 (unsigned int)*puid
));
1453 store_uid_sid_cache(psid
, *puid
);
1457 /*****************************************************************
1458 *THE CANONICAL* convert SID to gid function.
1459 Group mapping is used for gids that maps to Wellknown SIDs
1460 *****************************************************************/
1462 bool sid_to_gid(const DOM_SID
*psid
, gid_t
*pgid
)
1464 bool expired
= true;
1469 if (fetch_gid_from_cache(pgid
, psid
))
1472 if (fetch_uid_from_cache(&uid
, psid
))
1475 /* Optimize for the Unix Groups Domain
1476 * as the conversion is straightforward */
1477 if (sid_peek_check_rid(&global_sid_Unix_Groups
, psid
, &rid
)) {
1481 /* return here, don't cache */
1482 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1483 (unsigned int)*pgid
));
1487 /* Check the winbindd cache directly. */
1488 ret
= idmap_cache_find_sid2gid(psid
, pgid
, &expired
);
1490 if (ret
&& !expired
&& (*pgid
== (gid_t
)-1)) {
1492 * Negative cache entry, we already asked.
1495 return legacy_sid_to_gid(psid
, pgid
);
1498 if (!ret
|| expired
) {
1499 /* Not in cache or negative. Ask winbindd. */
1500 /* Ask winbindd if it can map this sid to a gid.
1501 * (Idmap will check it is a valid SID and of the right type) */
1503 if ( !winbind_sid_to_gid(pgid
, psid
) ) {
1505 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1506 sid_string_dbg(psid
)));
1507 /* winbind failed. do legacy */
1508 return legacy_sid_to_gid(psid
, pgid
);
1512 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1513 (unsigned int)*pgid
));
1515 store_gid_sid_cache(psid
, *pgid
);