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_compose(&sid
, get_global_sam_sid(), rid
);
85 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
86 strequal(domain
, builtin_domain_name()))
88 if (strlen(name
) == 0) {
89 /* Swap domain and name */
90 tmp
= name
; name
= domain
; domain
= tmp
;
91 sid_copy(&sid
, &global_sid_Builtin
);
92 type
= SID_NAME_DOMAIN
;
96 /* Explicit request for a name in BUILTIN */
97 if (lookup_builtin_name(name
, &rid
)) {
98 sid_compose(&sid
, &global_sid_Builtin
, rid
);
99 type
= SID_NAME_ALIAS
;
102 TALLOC_FREE(tmp_ctx
);
106 /* Try the explicit winbind lookup first, don't let it guess the
107 * domain yet at this point yet. This comes later. */
109 if ((domain
[0] != '\0') &&
110 (flags
& ~(LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
)) &&
111 (winbind_lookup_name(domain
, name
, &sid
, &type
))) {
115 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
116 && strequal(domain
, unix_users_domain_name())) {
117 if (lookup_unix_user_name(name
, &sid
)) {
118 type
= SID_NAME_USER
;
121 TALLOC_FREE(tmp_ctx
);
125 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
126 && strequal(domain
, unix_groups_domain_name())) {
127 if (lookup_unix_group_name(name
, &sid
)) {
128 type
= SID_NAME_DOM_GRP
;
131 TALLOC_FREE(tmp_ctx
);
135 if ((domain
[0] == '\0') && (!(flags
& LOOKUP_NAME_ISOLATED
))) {
136 TALLOC_FREE(tmp_ctx
);
140 /* Now the guesswork begins, we haven't been given an explicit
141 * domain. Try the sequence as documented on
142 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
143 * November 27, 2005 */
145 /* 1. well-known names */
147 if ((flags
& LOOKUP_NAME_WKN
) &&
148 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
150 type
= SID_NAME_WKN_GRP
;
154 /* 2. Builtin domain as such */
156 if ((flags
& (LOOKUP_NAME_BUILTIN
|LOOKUP_NAME_REMOTE
)) &&
157 strequal(name
, builtin_domain_name()))
159 /* Swap domain and name */
160 tmp
= name
; name
= domain
; domain
= tmp
;
161 sid_copy(&sid
, &global_sid_Builtin
);
162 type
= SID_NAME_DOMAIN
;
166 /* 3. Account domain */
168 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
169 strequal(name
, get_global_sam_name()))
171 if (!secrets_fetch_domain_sid(name
, &sid
)) {
172 DEBUG(3, ("Could not fetch my SID\n"));
173 TALLOC_FREE(tmp_ctx
);
176 /* Swap domain and name */
177 tmp
= name
; name
= domain
; domain
= tmp
;
178 type
= SID_NAME_DOMAIN
;
182 /* 4. Primary domain */
184 if ((flags
& LOOKUP_NAME_DOMAIN
) && !IS_DC
&&
185 strequal(name
, lp_workgroup()))
187 if (!secrets_fetch_domain_sid(name
, &sid
)) {
188 DEBUG(3, ("Could not fetch the domain SID\n"));
189 TALLOC_FREE(tmp_ctx
);
192 /* Swap domain and name */
193 tmp
= name
; name
= domain
; domain
= tmp
;
194 type
= SID_NAME_DOMAIN
;
198 /* 5. Trusted domains as such, to me it looks as if members don't do
199 this, tested an XP workstation in a NT domain -- vl */
201 if ((flags
& LOOKUP_NAME_REMOTE
) && IS_DC
&&
202 (pdb_get_trusteddom_pw(name
, NULL
, &sid
, NULL
)))
204 /* Swap domain and name */
205 tmp
= name
; name
= domain
; domain
= tmp
;
206 type
= SID_NAME_DOMAIN
;
210 /* 6. Builtin aliases */
212 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
213 lookup_builtin_name(name
, &rid
))
215 domain
= talloc_strdup(tmp_ctx
, builtin_domain_name());
216 sid_compose(&sid
, &global_sid_Builtin
, rid
);
217 type
= SID_NAME_ALIAS
;
221 /* 7. Local systems' SAM (DCs don't have a local SAM) */
222 /* 8. Primary SAM (On members, this is the domain) */
224 /* Both cases are done by looking at our passdb */
226 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
227 lookup_global_sam_name(name
, flags
, &rid
, &type
))
229 domain
= talloc_strdup(tmp_ctx
, get_global_sam_name());
230 sid_compose(&sid
, get_global_sam_sid(), rid
);
234 /* Now our local possibilities are exhausted. */
236 if (!(flags
& LOOKUP_NAME_REMOTE
)) {
237 TALLOC_FREE(tmp_ctx
);
241 /* If we are not a DC, we have to ask in our primary domain. Let
242 * winbind do that. */
245 (winbind_lookup_name(lp_workgroup(), name
, &sid
, &type
))) {
246 domain
= talloc_strdup(tmp_ctx
, lp_workgroup());
250 /* 9. Trusted domains */
252 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
253 * that (yet), but give it a chance. */
255 if (IS_DC
&& winbind_lookup_name("", name
, &sid
, &type
)) {
258 enum lsa_SidType domain_type
;
260 if (type
== SID_NAME_DOMAIN
) {
261 /* Swap name and type */
262 tmp
= name
; name
= domain
; domain
= tmp
;
266 /* Here we have to cope with a little deficiency in the
267 * winbind API: We have to ask it again for the name of the
268 * domain it figured out itself. Maybe fix that later... */
270 sid_copy(&dom_sid
, &sid
);
271 sid_split_rid(&dom_sid
, &tmp_rid
);
273 if (!winbind_lookup_sid(tmp_ctx
, &dom_sid
, &domain
, NULL
,
275 (domain_type
!= SID_NAME_DOMAIN
)) {
276 DEBUG(2, ("winbind could not find the domain's name "
277 "it just looked up for us\n"));
278 TALLOC_FREE(tmp_ctx
);
284 /* 10. Don't translate */
286 /* 11. Ok, windows would end here. Samba has two more options:
287 Unmapped users and unmapped groups */
289 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
290 && lookup_unix_user_name(name
, &sid
)) {
291 domain
= talloc_strdup(tmp_ctx
, unix_users_domain_name());
292 type
= SID_NAME_USER
;
296 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
297 && lookup_unix_group_name(name
, &sid
)) {
298 domain
= talloc_strdup(tmp_ctx
, unix_groups_domain_name());
299 type
= SID_NAME_DOM_GRP
;
304 * Ok, all possibilities tried. Fail.
307 TALLOC_FREE(tmp_ctx
);
311 if ((domain
== NULL
) || (name
== NULL
)) {
312 DEBUG(0, ("talloc failed\n"));
313 TALLOC_FREE(tmp_ctx
);
318 * Hand over the results to the talloc context we've been given.
321 if ((ret_name
!= NULL
) &&
322 !(*ret_name
= talloc_strdup(mem_ctx
, name
))) {
323 DEBUG(0, ("talloc failed\n"));
324 TALLOC_FREE(tmp_ctx
);
328 if (ret_domain
!= NULL
) {
330 if (!(tmp_dom
= talloc_strdup(mem_ctx
, domain
))) {
331 DEBUG(0, ("talloc failed\n"));
332 TALLOC_FREE(tmp_ctx
);
336 *ret_domain
= tmp_dom
;
339 if (ret_sid
!= NULL
) {
340 sid_copy(ret_sid
, &sid
);
343 if (ret_type
!= NULL
) {
347 TALLOC_FREE(tmp_ctx
);
351 /************************************************************************
352 Names from smb.conf can be unqualified. eg. valid users = foo
353 These names should never map to a remote name. Try global_sam_name()\foo,
354 and then "Unix Users"\foo (or "Unix Groups"\foo).
355 ************************************************************************/
357 bool lookup_name_smbconf(TALLOC_CTX
*mem_ctx
,
358 const char *full_name
, int flags
,
359 const char **ret_domain
, const char **ret_name
,
360 DOM_SID
*ret_sid
, enum lsa_SidType
*ret_type
)
362 char *qualified_name
;
365 /* NB. No winbindd_separator here as lookup_name needs \\' */
366 if ((p
= strchr_m(full_name
, *lp_winbind_separator())) != NULL
) {
368 /* The name is already qualified with a domain. */
370 if (*lp_winbind_separator() != '\\') {
373 /* lookup_name() needs '\\' as a separator */
375 tmp
= talloc_strdup(mem_ctx
, full_name
);
379 tmp
[p
- full_name
] = '\\';
383 return lookup_name(mem_ctx
, full_name
, flags
,
384 ret_domain
, ret_name
,
388 /* Try with our own SAM name. */
389 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
390 get_global_sam_name(),
392 if (!qualified_name
) {
396 if (lookup_name(mem_ctx
, qualified_name
, flags
,
397 ret_domain
, ret_name
,
398 ret_sid
, ret_type
)) {
402 /* Finally try with "Unix Users" or "Unix Group" */
403 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
404 flags
& LOOKUP_NAME_GROUP
?
405 unix_groups_domain_name() :
406 unix_users_domain_name(),
408 if (!qualified_name
) {
412 return lookup_name(mem_ctx
, qualified_name
, flags
,
413 ret_domain
, ret_name
,
417 static bool wb_lookup_rids(TALLOC_CTX
*mem_ctx
,
418 const DOM_SID
*domain_sid
,
419 int num_rids
, uint32
*rids
,
420 const char **domain_name
,
421 const char **names
, enum lsa_SidType
*types
)
424 const char **my_names
;
425 enum lsa_SidType
*my_types
;
428 if (!(tmp_ctx
= talloc_init("wb_lookup_rids"))) {
432 if (!winbind_lookup_rids(tmp_ctx
, domain_sid
, num_rids
, rids
,
433 domain_name
, &my_names
, &my_types
)) {
435 for (i
=0; i
<num_rids
; i
++) {
437 types
[i
] = SID_NAME_UNKNOWN
;
439 TALLOC_FREE(tmp_ctx
);
443 if (!(*domain_name
= talloc_strdup(mem_ctx
, *domain_name
))) {
444 TALLOC_FREE(tmp_ctx
);
449 * winbind_lookup_rids allocates its own array. We've been given the
450 * array, so copy it over
453 for (i
=0; i
<num_rids
; i
++) {
454 if (my_names
[i
] == NULL
) {
455 TALLOC_FREE(tmp_ctx
);
458 if (!(names
[i
] = talloc_strdup(names
, my_names
[i
]))) {
459 TALLOC_FREE(tmp_ctx
);
462 types
[i
] = my_types
[i
];
464 TALLOC_FREE(tmp_ctx
);
468 static bool lookup_rids(TALLOC_CTX
*mem_ctx
, const DOM_SID
*domain_sid
,
469 int num_rids
, uint32_t *rids
,
470 const char **domain_name
,
471 const char ***names
, enum lsa_SidType
**types
)
475 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
476 sid_string_dbg(domain_sid
)));
479 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, const char *, num_rids
);
480 *types
= TALLOC_ARRAY(mem_ctx
, enum lsa_SidType
, num_rids
);
482 if ((*names
== NULL
) || (*types
== NULL
)) {
486 for (i
= 0; i
< num_rids
; i
++)
487 (*types
)[i
] = SID_NAME_UNKNOWN
;
493 if (sid_check_is_domain(domain_sid
)) {
496 if (*domain_name
== NULL
) {
497 *domain_name
= talloc_strdup(
498 mem_ctx
, get_global_sam_name());
501 if (*domain_name
== NULL
) {
506 result
= pdb_lookup_rids(domain_sid
, num_rids
, rids
,
510 return (NT_STATUS_IS_OK(result
) ||
511 NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
) ||
512 NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
));
515 if (sid_check_is_builtin(domain_sid
)) {
517 if (*domain_name
== NULL
) {
518 *domain_name
= talloc_strdup(
519 mem_ctx
, builtin_domain_name());
522 if (*domain_name
== NULL
) {
526 for (i
=0; i
<num_rids
; i
++) {
527 if (lookup_builtin_rid(*names
, rids
[i
],
529 if ((*names
)[i
] == NULL
) {
532 (*types
)[i
] = SID_NAME_ALIAS
;
534 (*types
)[i
] = SID_NAME_UNKNOWN
;
540 if (sid_check_is_wellknown_domain(domain_sid
, NULL
)) {
541 for (i
=0; i
<num_rids
; i
++) {
543 sid_compose(&sid
, domain_sid
, rids
[i
]);
544 if (lookup_wellknown_sid(mem_ctx
, &sid
,
545 domain_name
, &(*names
)[i
])) {
546 if ((*names
)[i
] == NULL
) {
549 (*types
)[i
] = SID_NAME_WKN_GRP
;
551 (*types
)[i
] = SID_NAME_UNKNOWN
;
557 if (sid_check_is_unix_users(domain_sid
)) {
558 if (*domain_name
== NULL
) {
559 *domain_name
= talloc_strdup(
560 mem_ctx
, unix_users_domain_name());
561 if (*domain_name
== NULL
) {
565 for (i
=0; i
<num_rids
; i
++) {
566 (*names
)[i
] = talloc_strdup(
567 (*names
), uidtoname(rids
[i
]));
568 if ((*names
)[i
] == NULL
) {
571 (*types
)[i
] = SID_NAME_USER
;
576 if (sid_check_is_unix_groups(domain_sid
)) {
577 if (*domain_name
== NULL
) {
578 *domain_name
= talloc_strdup(
579 mem_ctx
, unix_groups_domain_name());
580 if (*domain_name
== NULL
) {
584 for (i
=0; i
<num_rids
; i
++) {
585 (*names
)[i
] = talloc_strdup(
586 (*names
), gidtoname(rids
[i
]));
587 if ((*names
)[i
] == NULL
) {
590 (*types
)[i
] = SID_NAME_DOM_GRP
;
595 return wb_lookup_rids(mem_ctx
, domain_sid
, num_rids
, rids
,
596 domain_name
, *names
, *types
);
600 * Is the SID a domain as such? If yes, lookup its name.
603 static bool lookup_as_domain(const DOM_SID
*sid
, TALLOC_CTX
*mem_ctx
,
607 enum lsa_SidType type
;
609 if (sid_check_is_domain(sid
)) {
610 *name
= talloc_strdup(mem_ctx
, get_global_sam_name());
614 if (sid_check_is_builtin(sid
)) {
615 *name
= talloc_strdup(mem_ctx
, builtin_domain_name());
619 if (sid_check_is_wellknown_domain(sid
, &tmp
)) {
620 *name
= talloc_strdup(mem_ctx
, tmp
);
624 if (sid_check_is_unix_users(sid
)) {
625 *name
= talloc_strdup(mem_ctx
, unix_users_domain_name());
629 if (sid_check_is_unix_groups(sid
)) {
630 *name
= talloc_strdup(mem_ctx
, unix_groups_domain_name());
634 if (sid
->num_auths
!= 4) {
635 /* This can't be a domain */
640 uint32 i
, num_domains
;
641 struct trustdom_info
**domains
;
643 /* This is relatively expensive, but it happens only on DCs
644 * and for SIDs that have 4 sub-authorities and thus look like
647 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx
,
653 for (i
=0; i
<num_domains
; i
++) {
654 if (sid_equal(sid
, &domains
[i
]->sid
)) {
655 *name
= talloc_strdup(mem_ctx
,
663 if (winbind_lookup_sid(mem_ctx
, sid
, &tmp
, NULL
, &type
) &&
664 (type
== SID_NAME_DOMAIN
)) {
673 * This tries to implement the rather weird rules for the lsa_lookup level
676 * This is as close as we can get to what W2k3 does. With this we survive the
677 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
678 * different, but I assume that's just being too liberal. For example, W2k3
679 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
680 * whereas NT4 does the same as level 1 (I think). I did not fully test that
681 * with NT4, this is what w2k3 does.
683 * Level 1: Ask everywhere
684 * Level 2: Ask domain and trusted domains, no builtin and wkn
685 * Level 3: Only ask domain
686 * Level 4: W2k3ad: Only ask AD trusts
687 * Level 5: Only ask transitive forest trusts
691 static bool check_dom_sid_to_level(const DOM_SID
*sid
, int level
)
700 ret
= (!sid_check_is_builtin(sid
) &&
701 !sid_check_is_wellknown_domain(sid
, NULL
));
706 ret
= sid_check_is_domain(sid
);
713 DEBUG(10, ("%s SID %s in level %d\n",
714 ret
? "Accepting" : "Rejecting",
715 sid_string_dbg(sid
), level
));
720 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
721 * references to domains, it is explicitly made for this.
723 * This attempts to be as efficient as possible: It collects all SIDs
724 * belonging to a domain and hands them in bulk to the appropriate lookup
725 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
726 * *hugely* from this. Winbind is going to be extended with a lookup_rids
727 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
731 NTSTATUS
lookup_sids(TALLOC_CTX
*mem_ctx
, int num_sids
,
732 const DOM_SID
**sids
, int level
,
733 struct lsa_dom_info
**ret_domains
,
734 struct lsa_name_info
**ret_names
)
737 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
738 struct lsa_name_info
*name_infos
;
739 struct lsa_dom_info
*dom_infos
= NULL
;
743 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
744 DEBUG(0, ("talloc_new failed\n"));
745 return NT_STATUS_NO_MEMORY
;
749 name_infos
= TALLOC_ARRAY(mem_ctx
, struct lsa_name_info
, num_sids
);
750 if (name_infos
== NULL
) {
751 result
= NT_STATUS_NO_MEMORY
;
758 dom_infos
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_dom_info
,
759 LSA_REF_DOMAIN_LIST_MULTIPLIER
);
760 if (dom_infos
== NULL
) {
761 result
= NT_STATUS_NO_MEMORY
;
765 /* First build up the data structures:
767 * dom_infos is a list of domains referenced in the list of
768 * SIDs. Later we will walk the list of domains and look up the RIDs
771 * name_infos is a shadow-copy of the SIDs array to collect the real
774 * dom_info->idxs is an index into the name_infos array. The
775 * difficulty we have here is that we need to keep the SIDs the client
776 * asked for in the same order for the reply
779 for (i
=0; i
<num_sids
; i
++) {
782 const char *domain_name
= NULL
;
784 sid_copy(&sid
, sids
[i
]);
785 name_infos
[i
].type
= SID_NAME_USE_NONE
;
787 if (lookup_as_domain(&sid
, name_infos
, &domain_name
)) {
788 /* We can't push that through the normal lookup
789 * process, as this would reference illegal
792 * For example S-1-5-32 would end up referencing
793 * domain S-1-5- with RID 32 which is clearly wrong.
795 if (domain_name
== NULL
) {
796 result
= NT_STATUS_NO_MEMORY
;
800 name_infos
[i
].rid
= 0;
801 name_infos
[i
].type
= SID_NAME_DOMAIN
;
802 name_infos
[i
].name
= NULL
;
804 if (sid_check_is_builtin(&sid
)) {
805 /* Yes, W2k3 returns "BUILTIN" both as domain
807 name_infos
[i
].name
= talloc_strdup(
808 name_infos
, builtin_domain_name());
809 if (name_infos
[i
].name
== NULL
) {
810 result
= NT_STATUS_NO_MEMORY
;
815 /* This is a normal SID with rid component */
816 if (!sid_split_rid(&sid
, &rid
)) {
817 result
= NT_STATUS_INVALID_SID
;
822 if (!check_dom_sid_to_level(&sid
, level
)) {
823 name_infos
[i
].rid
= 0;
824 name_infos
[i
].type
= SID_NAME_UNKNOWN
;
825 name_infos
[i
].name
= NULL
;
829 for (j
=0; j
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; j
++) {
830 if (!dom_infos
[j
].valid
) {
833 if (sid_equal(&sid
, &dom_infos
[j
].sid
)) {
838 if (j
== LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
839 /* TODO: What's the right error message here? */
840 result
= NT_STATUS_NONE_MAPPED
;
844 if (!dom_infos
[j
].valid
) {
845 /* We found a domain not yet referenced, create a new
847 dom_infos
[j
].valid
= true;
848 sid_copy(&dom_infos
[j
].sid
, &sid
);
850 if (domain_name
!= NULL
) {
851 /* This name was being found above in the case
852 * when we found a domain SID */
854 talloc_strdup(dom_infos
, domain_name
);
855 if (dom_infos
[j
].name
== NULL
) {
856 result
= NT_STATUS_NO_MEMORY
;
860 /* lookup_rids will take care of this */
861 dom_infos
[j
].name
= NULL
;
865 name_infos
[i
].dom_idx
= j
;
867 if (name_infos
[i
].type
== SID_NAME_USE_NONE
) {
868 name_infos
[i
].rid
= rid
;
870 ADD_TO_ARRAY(dom_infos
, int, i
, &dom_infos
[j
].idxs
,
871 &dom_infos
[j
].num_idxs
);
873 if (dom_infos
[j
].idxs
== NULL
) {
874 result
= NT_STATUS_NO_MEMORY
;
880 /* Iterate over the domains found */
882 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
884 const char *domain_name
= NULL
;
886 enum lsa_SidType
*types
;
887 struct lsa_dom_info
*dom
= &dom_infos
[i
];
890 /* No domains left, we're done */
895 if (!(rids
= TALLOC_ARRAY(tmp_ctx
, uint32
, dom
->num_idxs
))) {
896 result
= NT_STATUS_NO_MEMORY
;
903 for (j
=0; j
<dom
->num_idxs
; j
++) {
904 rids
[j
] = name_infos
[dom
->idxs
[j
]].rid
;
907 if (!lookup_rids(tmp_ctx
, &dom
->sid
,
908 dom
->num_idxs
, rids
, &domain_name
,
910 result
= NT_STATUS_NO_MEMORY
;
914 if (!(dom
->name
= talloc_strdup(dom_infos
, domain_name
))) {
915 result
= NT_STATUS_NO_MEMORY
;
919 for (j
=0; j
<dom
->num_idxs
; j
++) {
920 int idx
= dom
->idxs
[j
];
921 name_infos
[idx
].type
= types
[j
];
922 if (types
[j
] != SID_NAME_UNKNOWN
) {
923 name_infos
[idx
].name
=
924 talloc_strdup(name_infos
, names
[j
]);
925 if (name_infos
[idx
].name
== NULL
) {
926 result
= NT_STATUS_NO_MEMORY
;
930 name_infos
[idx
].name
= NULL
;
935 *ret_domains
= dom_infos
;
936 *ret_names
= name_infos
;
937 TALLOC_FREE(tmp_ctx
);
941 TALLOC_FREE(dom_infos
);
942 TALLOC_FREE(name_infos
);
943 TALLOC_FREE(tmp_ctx
);
947 /*****************************************************************
948 *THE CANONICAL* convert SID to name function.
949 *****************************************************************/
951 bool lookup_sid(TALLOC_CTX
*mem_ctx
, const DOM_SID
*sid
,
952 const char **ret_domain
, const char **ret_name
,
953 enum lsa_SidType
*ret_type
)
955 struct lsa_dom_info
*domain
;
956 struct lsa_name_info
*name
;
960 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid
)));
962 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
963 DEBUG(0, ("talloc_new failed\n"));
967 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx
, 1, &sid
, 1,
972 if (name
->type
== SID_NAME_UNKNOWN
) {
976 if ((ret_domain
!= NULL
) &&
977 !(*ret_domain
= talloc_strdup(mem_ctx
, domain
->name
))) {
981 if ((ret_name
!= NULL
) &&
982 !(*ret_name
= talloc_strdup(mem_ctx
, name
->name
))) {
986 if (ret_type
!= NULL
) {
987 *ret_type
= name
->type
;
994 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid
),
995 domain
->name
, name
->name
, name
->type
));
997 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid
)));
999 TALLOC_FREE(tmp_ctx
);
1003 /*****************************************************************
1004 Id mapping cache. This is to avoid Winbind mappings already
1005 seen by smbd to be queried too frequently, keeping winbindd
1006 busy, and blocking smbd while winbindd is busy with other
1007 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1008 modified to use linked lists by jra.
1009 *****************************************************************/
1011 /*****************************************************************
1012 Find a SID given a uid.
1013 *****************************************************************/
1015 static bool fetch_sid_from_uid_cache(DOM_SID
*psid
, uid_t uid
)
1017 DATA_BLOB cache_value
;
1019 if (!memcache_lookup(NULL
, UID_SID_CACHE
,
1020 data_blob_const(&uid
, sizeof(uid
)),
1025 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1026 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1027 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, NULL
, 0));
1032 /*****************************************************************
1033 Find a uid given a SID.
1034 *****************************************************************/
1036 static bool fetch_uid_from_cache( uid_t
*puid
, const DOM_SID
*psid
)
1038 DATA_BLOB cache_value
;
1040 if (!memcache_lookup(NULL
, SID_UID_CACHE
,
1041 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)),
1046 SMB_ASSERT(cache_value
.length
== sizeof(*puid
));
1047 memcpy(puid
, cache_value
.data
, sizeof(*puid
));
1052 /*****************************************************************
1053 Store uid to SID mapping in cache.
1054 *****************************************************************/
1056 void store_uid_sid_cache(const DOM_SID
*psid
, uid_t uid
)
1058 memcache_add(NULL
, SID_UID_CACHE
,
1059 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)),
1060 data_blob_const(&uid
, sizeof(uid
)));
1061 memcache_add(NULL
, UID_SID_CACHE
,
1062 data_blob_const(&uid
, sizeof(uid
)),
1063 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)));
1066 /*****************************************************************
1067 Find a SID given a gid.
1068 *****************************************************************/
1070 static bool fetch_sid_from_gid_cache(DOM_SID
*psid
, gid_t gid
)
1072 DATA_BLOB cache_value
;
1074 if (!memcache_lookup(NULL
, GID_SID_CACHE
,
1075 data_blob_const(&gid
, sizeof(gid
)),
1080 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1081 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1082 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, NULL
, 0));
1087 /*****************************************************************
1088 Find a gid given a SID.
1089 *****************************************************************/
1091 static bool fetch_gid_from_cache(gid_t
*pgid
, const DOM_SID
*psid
)
1093 DATA_BLOB cache_value
;
1095 if (!memcache_lookup(NULL
, SID_GID_CACHE
,
1096 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)),
1101 SMB_ASSERT(cache_value
.length
== sizeof(*pgid
));
1102 memcpy(pgid
, cache_value
.data
, sizeof(*pgid
));
1107 /*****************************************************************
1108 Store gid to SID mapping in cache.
1109 *****************************************************************/
1111 void store_gid_sid_cache(const DOM_SID
*psid
, gid_t gid
)
1113 memcache_add(NULL
, SID_GID_CACHE
,
1114 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)),
1115 data_blob_const(&gid
, sizeof(gid
)));
1116 memcache_add(NULL
, GID_SID_CACHE
,
1117 data_blob_const(&gid
, sizeof(gid
)),
1118 data_blob_const(psid
, ndr_size_dom_sid(psid
, NULL
, 0)));
1121 /*****************************************************************
1122 *THE LEGACY* convert uid_t to SID function.
1123 *****************************************************************/
1125 static void legacy_uid_to_sid(DOM_SID
*psid
, uid_t uid
)
1132 ret
= pdb_uid_to_sid(uid
, psid
);
1136 /* This is a mapped user */
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
;
1191 if (sid_check_is_in_our_domain(psid
)) {
1196 ret
= pdb_sid_to_id(psid
, &id
, &type
);
1200 if (type
!= SID_NAME_USER
) {
1201 DEBUG(5, ("sid %s is a %s, expected a user\n",
1202 sid_string_dbg(psid
),
1203 sid_type_lookup(type
)));
1210 /* This was ours, but it was not mapped. Fail */
1213 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1214 sid_string_dbg(psid
)));
1218 DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_dbg(psid
),
1219 (unsigned int)*puid
));
1221 store_uid_sid_cache(psid
, *puid
);
1225 /*****************************************************************
1226 *THE LEGACY* convert SID to gid function.
1227 Group mapping is used for gids that maps to Wellknown SIDs
1228 *****************************************************************/
1230 static bool legacy_sid_to_gid(const DOM_SID
*psid
, gid_t
*pgid
)
1234 enum lsa_SidType type
;
1236 if ((sid_check_is_in_builtin(psid
) ||
1237 sid_check_is_in_wellknown_domain(psid
))) {
1241 ret
= pdb_getgrsid(&map
, *psid
);
1248 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1249 sid_string_dbg(psid
)));
1253 if (sid_check_is_in_our_domain(psid
)) {
1257 ret
= pdb_sid_to_id(psid
, &id
, &type
);
1261 if ((type
!= SID_NAME_DOM_GRP
) &&
1262 (type
!= SID_NAME_ALIAS
)) {
1263 DEBUG(5, ("LEGACY: sid %s is a %s, expected "
1264 "a group\n", sid_string_dbg(psid
),
1265 sid_type_lookup(type
)));
1272 /* This was ours, but it was not mapped. Fail */
1275 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1276 sid_string_dbg(psid
)));
1280 DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid
),
1281 (unsigned int)*pgid
));
1283 store_gid_sid_cache(psid
, *pgid
);
1288 /*****************************************************************
1289 *THE CANONICAL* convert uid_t to SID function.
1290 *****************************************************************/
1292 void uid_to_sid(DOM_SID
*psid
, uid_t uid
)
1294 bool expired
= true;
1298 if (fetch_sid_from_uid_cache(psid
, uid
))
1301 /* Check the winbindd cache directly. */
1302 ret
= idmap_cache_find_uid2sid(uid
, psid
, &expired
);
1304 if (ret
&& !expired
&& is_null_sid(psid
)) {
1306 * Negative cache entry, we already asked.
1309 legacy_uid_to_sid(psid
, uid
);
1313 if (!ret
|| expired
) {
1314 /* Not in cache. Ask winbindd. */
1315 if (!winbind_uid_to_sid(psid
, uid
)) {
1317 * We shouldn't return the NULL SID
1318 * here if winbind was running and
1319 * couldn't map, as winbind will have
1320 * added a negative entry that will
1321 * cause us to go though the
1322 * legacy_uid_to_sid()
1323 * function anyway in the case above
1324 * the next time we ask.
1326 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1327 "for uid %u\n", (unsigned int)uid
));
1329 legacy_uid_to_sid(psid
, uid
);
1334 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid
,
1335 sid_string_dbg(psid
)));
1337 store_uid_sid_cache(psid
, uid
);
1341 /*****************************************************************
1342 *THE CANONICAL* convert gid_t to SID function.
1343 *****************************************************************/
1345 void gid_to_sid(DOM_SID
*psid
, gid_t gid
)
1347 bool expired
= true;
1351 if (fetch_sid_from_gid_cache(psid
, gid
))
1354 /* Check the winbindd cache directly. */
1355 ret
= idmap_cache_find_gid2sid(gid
, psid
, &expired
);
1357 if (ret
&& !expired
&& is_null_sid(psid
)) {
1359 * Negative cache entry, we already asked.
1362 legacy_gid_to_sid(psid
, gid
);
1366 if (!ret
|| expired
) {
1367 /* Not in cache. Ask winbindd. */
1368 if (!winbind_gid_to_sid(psid
, gid
)) {
1370 * We shouldn't return the NULL SID
1371 * here if winbind was running and
1372 * couldn't map, as winbind will have
1373 * added a negative entry that will
1374 * cause us to go though the
1375 * legacy_gid_to_sid()
1376 * function anyway in the case above
1377 * the next time we ask.
1379 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1380 "for gid %u\n", (unsigned int)gid
));
1382 legacy_gid_to_sid(psid
, gid
);
1387 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid
,
1388 sid_string_dbg(psid
)));
1390 store_gid_sid_cache(psid
, gid
);
1394 /*****************************************************************
1395 *THE CANONICAL* convert SID to uid function.
1396 *****************************************************************/
1398 bool sid_to_uid(const DOM_SID
*psid
, uid_t
*puid
)
1400 bool expired
= true;
1405 if (fetch_uid_from_cache(puid
, psid
))
1408 if (fetch_gid_from_cache(&gid
, psid
)) {
1412 /* Optimize for the Unix Users Domain
1413 * as the conversion is straightforward */
1414 if (sid_peek_check_rid(&global_sid_Unix_Users
, psid
, &rid
)) {
1418 /* return here, don't cache */
1419 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1420 (unsigned int)*puid
));
1424 /* Check the winbindd cache directly. */
1425 ret
= idmap_cache_find_sid2uid(psid
, puid
, &expired
);
1427 if (ret
&& !expired
&& (*puid
== (uid_t
)-1)) {
1429 * Negative cache entry, we already asked.
1432 return legacy_sid_to_uid(psid
, puid
);
1435 if (!ret
|| expired
) {
1436 /* Not in cache. Ask winbindd. */
1437 if (!winbind_sid_to_uid(puid
, psid
)) {
1438 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1439 sid_string_dbg(psid
)));
1440 /* winbind failed. do legacy */
1441 return legacy_sid_to_uid(psid
, puid
);
1445 /* TODO: Here would be the place to allocate both a gid and a uid for
1446 * the SID in question */
1448 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1449 (unsigned int)*puid
));
1451 store_uid_sid_cache(psid
, *puid
);
1455 /*****************************************************************
1456 *THE CANONICAL* convert SID to gid function.
1457 Group mapping is used for gids that maps to Wellknown SIDs
1458 *****************************************************************/
1460 bool sid_to_gid(const DOM_SID
*psid
, gid_t
*pgid
)
1462 bool expired
= true;
1467 if (fetch_gid_from_cache(pgid
, psid
))
1470 if (fetch_uid_from_cache(&uid
, psid
))
1473 /* Optimize for the Unix Groups Domain
1474 * as the conversion is straightforward */
1475 if (sid_peek_check_rid(&global_sid_Unix_Groups
, psid
, &rid
)) {
1479 /* return here, don't cache */
1480 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1481 (unsigned int)*pgid
));
1485 /* Check the winbindd cache directly. */
1486 ret
= idmap_cache_find_sid2gid(psid
, pgid
, &expired
);
1488 if (ret
&& !expired
&& (*pgid
== (gid_t
)-1)) {
1490 * Negative cache entry, we already asked.
1493 return legacy_sid_to_gid(psid
, pgid
);
1496 if (!ret
|| expired
) {
1497 /* Not in cache or negative. Ask winbindd. */
1498 /* Ask winbindd if it can map this sid to a gid.
1499 * (Idmap will check it is a valid SID and of the right type) */
1501 if ( !winbind_sid_to_gid(pgid
, psid
) ) {
1503 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1504 sid_string_dbg(psid
)));
1505 /* winbind failed. do legacy */
1506 return legacy_sid_to_gid(psid
, pgid
);
1510 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1511 (unsigned int)*pgid
));
1513 store_gid_sid_cache(psid
, *pgid
);