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/>.
23 #include "../librpc/gen_ndr/ndr_security.h"
26 /*****************************************************************
27 Dissect a user-provided name into domain, name, sid and type.
29 If an explicit domain name was given in the form domain\user, it
30 has to try that. If no explicit domain name was given, we have
32 *****************************************************************/
34 bool lookup_name(TALLOC_CTX
*mem_ctx
,
35 const char *full_name
, int flags
,
36 const char **ret_domain
, const char **ret_name
,
37 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
41 const char *domain
= NULL
;
42 const char *name
= NULL
;
45 enum lsa_SidType type
;
46 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
48 if (tmp_ctx
== NULL
) {
49 DEBUG(0, ("talloc_new failed\n"));
53 p
= strchr_m(full_name
, '\\');
56 domain
= talloc_strndup(tmp_ctx
, full_name
,
57 PTR_DIFF(p
, full_name
));
58 name
= talloc_strdup(tmp_ctx
, p
+1);
60 domain
= talloc_strdup(tmp_ctx
, "");
61 name
= talloc_strdup(tmp_ctx
, full_name
);
64 if ((domain
== NULL
) || (name
== NULL
)) {
65 DEBUG(0, ("talloc failed\n"));
70 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
71 full_name
, domain
, name
));
72 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags
));
74 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
75 strequal(domain
, get_global_sam_name()))
78 /* It's our own domain, lookup the name in passdb */
79 if (lookup_global_sam_name(name
, flags
, &rid
, &type
)) {
80 sid_compose(&sid
, get_global_sam_sid(), rid
);
87 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
88 strequal(domain
, builtin_domain_name()))
90 if (strlen(name
) == 0) {
91 /* Swap domain and name */
92 tmp
= name
; name
= domain
; domain
= tmp
;
93 sid_copy(&sid
, &global_sid_Builtin
);
94 type
= SID_NAME_DOMAIN
;
98 /* Explicit request for a name in BUILTIN */
99 if (lookup_builtin_name(name
, &rid
)) {
100 sid_compose(&sid
, &global_sid_Builtin
, rid
);
101 type
= SID_NAME_ALIAS
;
104 TALLOC_FREE(tmp_ctx
);
108 /* Try the explicit winbind lookup first, don't let it guess the
109 * domain yet at this point yet. This comes later. */
111 if ((domain
[0] != '\0') &&
112 (flags
& ~(LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
)) &&
113 (winbind_lookup_name(domain
, name
, &sid
, &type
))) {
117 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
118 && strequal(domain
, unix_users_domain_name())) {
119 if (lookup_unix_user_name(name
, &sid
)) {
120 type
= SID_NAME_USER
;
123 TALLOC_FREE(tmp_ctx
);
127 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
128 && strequal(domain
, unix_groups_domain_name())) {
129 if (lookup_unix_group_name(name
, &sid
)) {
130 type
= SID_NAME_DOM_GRP
;
133 TALLOC_FREE(tmp_ctx
);
137 if ((domain
[0] == '\0') && (!(flags
& LOOKUP_NAME_ISOLATED
))) {
138 TALLOC_FREE(tmp_ctx
);
142 /* Now the guesswork begins, we haven't been given an explicit
143 * domain. Try the sequence as documented on
144 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
145 * November 27, 2005 */
147 /* 1. well-known names */
149 if ((flags
& LOOKUP_NAME_WKN
) &&
150 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
152 type
= SID_NAME_WKN_GRP
;
156 /* 2. Builtin domain as such */
158 if ((flags
& (LOOKUP_NAME_BUILTIN
|LOOKUP_NAME_REMOTE
)) &&
159 strequal(name
, builtin_domain_name()))
161 /* Swap domain and name */
162 tmp
= name
; name
= domain
; domain
= tmp
;
163 sid_copy(&sid
, &global_sid_Builtin
);
164 type
= SID_NAME_DOMAIN
;
168 /* 3. Account domain */
170 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
171 strequal(name
, get_global_sam_name()))
173 if (!secrets_fetch_domain_sid(name
, &sid
)) {
174 DEBUG(3, ("Could not fetch my SID\n"));
175 TALLOC_FREE(tmp_ctx
);
178 /* Swap domain and name */
179 tmp
= name
; name
= domain
; domain
= tmp
;
180 type
= SID_NAME_DOMAIN
;
184 /* 4. Primary domain */
186 if ((flags
& LOOKUP_NAME_DOMAIN
) && !IS_DC
&&
187 strequal(name
, lp_workgroup()))
189 if (!secrets_fetch_domain_sid(name
, &sid
)) {
190 DEBUG(3, ("Could not fetch the domain SID\n"));
191 TALLOC_FREE(tmp_ctx
);
194 /* Swap domain and name */
195 tmp
= name
; name
= domain
; domain
= tmp
;
196 type
= SID_NAME_DOMAIN
;
200 /* 5. Trusted domains as such, to me it looks as if members don't do
201 this, tested an XP workstation in a NT domain -- vl */
203 if ((flags
& LOOKUP_NAME_REMOTE
) && IS_DC
&&
204 (pdb_get_trusteddom_pw(name
, NULL
, &sid
, NULL
)))
206 /* Swap domain and name */
207 tmp
= name
; name
= domain
; domain
= tmp
;
208 type
= SID_NAME_DOMAIN
;
212 /* 6. Builtin aliases */
214 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
215 lookup_builtin_name(name
, &rid
))
217 domain
= talloc_strdup(tmp_ctx
, builtin_domain_name());
218 sid_compose(&sid
, &global_sid_Builtin
, rid
);
219 type
= SID_NAME_ALIAS
;
223 /* 7. Local systems' SAM (DCs don't have a local SAM) */
224 /* 8. Primary SAM (On members, this is the domain) */
226 /* Both cases are done by looking at our passdb */
228 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
229 lookup_global_sam_name(name
, flags
, &rid
, &type
))
231 domain
= talloc_strdup(tmp_ctx
, get_global_sam_name());
232 sid_compose(&sid
, get_global_sam_sid(), rid
);
236 /* Now our local possibilities are exhausted. */
238 if (!(flags
& LOOKUP_NAME_REMOTE
)) {
239 TALLOC_FREE(tmp_ctx
);
243 /* If we are not a DC, we have to ask in our primary domain. Let
244 * winbind do that. */
247 (winbind_lookup_name(lp_workgroup(), name
, &sid
, &type
))) {
248 domain
= talloc_strdup(tmp_ctx
, lp_workgroup());
252 /* 9. Trusted domains */
254 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
255 * that (yet), but give it a chance. */
257 if (IS_DC
&& winbind_lookup_name("", name
, &sid
, &type
)) {
258 struct dom_sid dom_sid
;
260 enum lsa_SidType domain_type
;
262 if (type
== SID_NAME_DOMAIN
) {
263 /* Swap name and type */
264 tmp
= name
; name
= domain
; domain
= tmp
;
268 /* Here we have to cope with a little deficiency in the
269 * winbind API: We have to ask it again for the name of the
270 * domain it figured out itself. Maybe fix that later... */
272 sid_copy(&dom_sid
, &sid
);
273 sid_split_rid(&dom_sid
, &tmp_rid
);
275 if (!winbind_lookup_sid(tmp_ctx
, &dom_sid
, &domain
, NULL
,
277 (domain_type
!= SID_NAME_DOMAIN
)) {
278 DEBUG(2, ("winbind could not find the domain's name "
279 "it just looked up for us\n"));
280 TALLOC_FREE(tmp_ctx
);
286 /* 10. Don't translate */
288 /* 11. Ok, windows would end here. Samba has two more options:
289 Unmapped users and unmapped groups */
291 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
292 && lookup_unix_user_name(name
, &sid
)) {
293 domain
= talloc_strdup(tmp_ctx
, unix_users_domain_name());
294 type
= SID_NAME_USER
;
298 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
299 && lookup_unix_group_name(name
, &sid
)) {
300 domain
= talloc_strdup(tmp_ctx
, unix_groups_domain_name());
301 type
= SID_NAME_DOM_GRP
;
306 * Ok, all possibilities tried. Fail.
309 TALLOC_FREE(tmp_ctx
);
313 if ((domain
== NULL
) || (name
== NULL
)) {
314 DEBUG(0, ("talloc failed\n"));
315 TALLOC_FREE(tmp_ctx
);
320 * Hand over the results to the talloc context we've been given.
323 if ((ret_name
!= NULL
) &&
324 !(*ret_name
= talloc_strdup(mem_ctx
, name
))) {
325 DEBUG(0, ("talloc failed\n"));
326 TALLOC_FREE(tmp_ctx
);
330 if (ret_domain
!= NULL
) {
332 if (!(tmp_dom
= talloc_strdup(mem_ctx
, domain
))) {
333 DEBUG(0, ("talloc failed\n"));
334 TALLOC_FREE(tmp_ctx
);
338 *ret_domain
= tmp_dom
;
341 if (ret_sid
!= NULL
) {
342 sid_copy(ret_sid
, &sid
);
345 if (ret_type
!= NULL
) {
349 TALLOC_FREE(tmp_ctx
);
353 /************************************************************************
354 Names from smb.conf can be unqualified. eg. valid users = foo
355 These names should never map to a remote name. Try global_sam_name()\foo,
356 and then "Unix Users"\foo (or "Unix Groups"\foo).
357 ************************************************************************/
359 bool lookup_name_smbconf(TALLOC_CTX
*mem_ctx
,
360 const char *full_name
, int flags
,
361 const char **ret_domain
, const char **ret_name
,
362 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
364 char *qualified_name
;
367 /* NB. No winbindd_separator here as lookup_name needs \\' */
368 if ((p
= strchr_m(full_name
, *lp_winbind_separator())) != NULL
) {
370 /* The name is already qualified with a domain. */
372 if (*lp_winbind_separator() != '\\') {
375 /* lookup_name() needs '\\' as a separator */
377 tmp
= talloc_strdup(mem_ctx
, full_name
);
381 tmp
[p
- full_name
] = '\\';
385 return lookup_name(mem_ctx
, full_name
, flags
,
386 ret_domain
, ret_name
,
390 /* Try with our own SAM name. */
391 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
392 get_global_sam_name(),
394 if (!qualified_name
) {
398 if (lookup_name(mem_ctx
, qualified_name
, flags
,
399 ret_domain
, ret_name
,
400 ret_sid
, ret_type
)) {
404 /* Finally try with "Unix Users" or "Unix Group" */
405 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
406 flags
& LOOKUP_NAME_GROUP
?
407 unix_groups_domain_name() :
408 unix_users_domain_name(),
410 if (!qualified_name
) {
414 return lookup_name(mem_ctx
, qualified_name
, flags
,
415 ret_domain
, ret_name
,
419 static bool wb_lookup_rids(TALLOC_CTX
*mem_ctx
,
420 const struct dom_sid
*domain_sid
,
421 int num_rids
, uint32
*rids
,
422 const char **domain_name
,
423 const char **names
, enum lsa_SidType
*types
)
426 const char **my_names
;
427 enum lsa_SidType
*my_types
;
430 if (!(tmp_ctx
= talloc_init("wb_lookup_rids"))) {
434 if (!winbind_lookup_rids(tmp_ctx
, domain_sid
, num_rids
, rids
,
435 domain_name
, &my_names
, &my_types
)) {
437 for (i
=0; i
<num_rids
; i
++) {
439 types
[i
] = SID_NAME_UNKNOWN
;
441 TALLOC_FREE(tmp_ctx
);
445 if (!(*domain_name
= talloc_strdup(mem_ctx
, *domain_name
))) {
446 TALLOC_FREE(tmp_ctx
);
451 * winbind_lookup_rids allocates its own array. We've been given the
452 * array, so copy it over
455 for (i
=0; i
<num_rids
; i
++) {
456 if (my_names
[i
] == NULL
) {
457 TALLOC_FREE(tmp_ctx
);
460 if (!(names
[i
] = talloc_strdup(names
, my_names
[i
]))) {
461 TALLOC_FREE(tmp_ctx
);
464 types
[i
] = my_types
[i
];
466 TALLOC_FREE(tmp_ctx
);
470 static bool lookup_rids(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*domain_sid
,
471 int num_rids
, uint32_t *rids
,
472 const char **domain_name
,
473 const char ***names
, enum lsa_SidType
**types
)
477 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
478 sid_string_dbg(domain_sid
)));
481 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, const char *, num_rids
);
482 *types
= TALLOC_ARRAY(mem_ctx
, enum lsa_SidType
, num_rids
);
484 if ((*names
== NULL
) || (*types
== NULL
)) {
488 for (i
= 0; i
< num_rids
; i
++)
489 (*types
)[i
] = SID_NAME_UNKNOWN
;
495 if (sid_check_is_domain(domain_sid
)) {
498 if (*domain_name
== NULL
) {
499 *domain_name
= talloc_strdup(
500 mem_ctx
, get_global_sam_name());
503 if (*domain_name
== NULL
) {
508 result
= pdb_lookup_rids(domain_sid
, num_rids
, rids
,
512 return (NT_STATUS_IS_OK(result
) ||
513 NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
) ||
514 NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
));
517 if (sid_check_is_builtin(domain_sid
)) {
519 if (*domain_name
== NULL
) {
520 *domain_name
= talloc_strdup(
521 mem_ctx
, builtin_domain_name());
524 if (*domain_name
== NULL
) {
528 for (i
=0; i
<num_rids
; i
++) {
529 if (lookup_builtin_rid(*names
, rids
[i
],
531 if ((*names
)[i
] == NULL
) {
534 (*types
)[i
] = SID_NAME_ALIAS
;
536 (*types
)[i
] = SID_NAME_UNKNOWN
;
542 if (sid_check_is_wellknown_domain(domain_sid
, NULL
)) {
543 for (i
=0; i
<num_rids
; i
++) {
545 sid_compose(&sid
, domain_sid
, rids
[i
]);
546 if (lookup_wellknown_sid(mem_ctx
, &sid
,
547 domain_name
, &(*names
)[i
])) {
548 if ((*names
)[i
] == NULL
) {
551 (*types
)[i
] = SID_NAME_WKN_GRP
;
553 (*types
)[i
] = SID_NAME_UNKNOWN
;
559 if (sid_check_is_unix_users(domain_sid
)) {
560 if (*domain_name
== NULL
) {
561 *domain_name
= talloc_strdup(
562 mem_ctx
, unix_users_domain_name());
563 if (*domain_name
== NULL
) {
567 for (i
=0; i
<num_rids
; i
++) {
568 (*names
)[i
] = talloc_strdup(
569 (*names
), uidtoname(rids
[i
]));
570 if ((*names
)[i
] == NULL
) {
573 (*types
)[i
] = SID_NAME_USER
;
578 if (sid_check_is_unix_groups(domain_sid
)) {
579 if (*domain_name
== NULL
) {
580 *domain_name
= talloc_strdup(
581 mem_ctx
, unix_groups_domain_name());
582 if (*domain_name
== NULL
) {
586 for (i
=0; i
<num_rids
; i
++) {
587 (*names
)[i
] = talloc_strdup(
588 (*names
), gidtoname(rids
[i
]));
589 if ((*names
)[i
] == NULL
) {
592 (*types
)[i
] = SID_NAME_DOM_GRP
;
597 return wb_lookup_rids(mem_ctx
, domain_sid
, num_rids
, rids
,
598 domain_name
, *names
, *types
);
602 * Is the SID a domain as such? If yes, lookup its name.
605 static bool lookup_as_domain(const struct dom_sid
*sid
, TALLOC_CTX
*mem_ctx
,
609 enum lsa_SidType type
;
611 if (sid_check_is_domain(sid
)) {
612 *name
= talloc_strdup(mem_ctx
, get_global_sam_name());
616 if (sid_check_is_builtin(sid
)) {
617 *name
= talloc_strdup(mem_ctx
, builtin_domain_name());
621 if (sid_check_is_wellknown_domain(sid
, &tmp
)) {
622 *name
= talloc_strdup(mem_ctx
, tmp
);
626 if (sid_check_is_unix_users(sid
)) {
627 *name
= talloc_strdup(mem_ctx
, unix_users_domain_name());
631 if (sid_check_is_unix_groups(sid
)) {
632 *name
= talloc_strdup(mem_ctx
, unix_groups_domain_name());
636 if (sid
->num_auths
!= 4) {
637 /* This can't be a domain */
642 uint32 i
, num_domains
;
643 struct trustdom_info
**domains
;
645 /* This is relatively expensive, but it happens only on DCs
646 * and for SIDs that have 4 sub-authorities and thus look like
649 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx
,
655 for (i
=0; i
<num_domains
; i
++) {
656 if (sid_equal(sid
, &domains
[i
]->sid
)) {
657 *name
= talloc_strdup(mem_ctx
,
665 if (winbind_lookup_sid(mem_ctx
, sid
, &tmp
, NULL
, &type
) &&
666 (type
== SID_NAME_DOMAIN
)) {
675 * This tries to implement the rather weird rules for the lsa_lookup level
678 * This is as close as we can get to what W2k3 does. With this we survive the
679 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
680 * different, but I assume that's just being too liberal. For example, W2k3
681 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
682 * whereas NT4 does the same as level 1 (I think). I did not fully test that
683 * with NT4, this is what w2k3 does.
685 * Level 1: Ask everywhere
686 * Level 2: Ask domain and trusted domains, no builtin and wkn
687 * Level 3: Only ask domain
688 * Level 4: W2k3ad: Only ask AD trusts
689 * Level 5: Only ask transitive forest trusts
693 static bool check_dom_sid_to_level(const struct dom_sid
*sid
, int level
)
702 ret
= (!sid_check_is_builtin(sid
) &&
703 !sid_check_is_wellknown_domain(sid
, NULL
));
708 ret
= sid_check_is_domain(sid
);
715 DEBUG(10, ("%s SID %s in level %d\n",
716 ret
? "Accepting" : "Rejecting",
717 sid_string_dbg(sid
), level
));
722 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
723 * references to domains, it is explicitly made for this.
725 * This attempts to be as efficient as possible: It collects all SIDs
726 * belonging to a domain and hands them in bulk to the appropriate lookup
727 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
728 * *hugely* from this. Winbind is going to be extended with a lookup_rids
729 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
733 NTSTATUS
lookup_sids(TALLOC_CTX
*mem_ctx
, int num_sids
,
734 const struct dom_sid
**sids
, int level
,
735 struct lsa_dom_info
**ret_domains
,
736 struct lsa_name_info
**ret_names
)
739 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
740 struct lsa_name_info
*name_infos
;
741 struct lsa_dom_info
*dom_infos
= NULL
;
745 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
746 DEBUG(0, ("talloc_new failed\n"));
747 return NT_STATUS_NO_MEMORY
;
751 name_infos
= TALLOC_ARRAY(mem_ctx
, struct lsa_name_info
, num_sids
);
752 if (name_infos
== NULL
) {
753 result
= NT_STATUS_NO_MEMORY
;
760 dom_infos
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_dom_info
,
761 LSA_REF_DOMAIN_LIST_MULTIPLIER
);
762 if (dom_infos
== NULL
) {
763 result
= NT_STATUS_NO_MEMORY
;
767 /* First build up the data structures:
769 * dom_infos is a list of domains referenced in the list of
770 * SIDs. Later we will walk the list of domains and look up the RIDs
773 * name_infos is a shadow-copy of the SIDs array to collect the real
776 * dom_info->idxs is an index into the name_infos array. The
777 * difficulty we have here is that we need to keep the SIDs the client
778 * asked for in the same order for the reply
781 for (i
=0; i
<num_sids
; i
++) {
784 const char *domain_name
= NULL
;
786 sid_copy(&sid
, sids
[i
]);
787 name_infos
[i
].type
= SID_NAME_USE_NONE
;
789 if (lookup_as_domain(&sid
, name_infos
, &domain_name
)) {
790 /* We can't push that through the normal lookup
791 * process, as this would reference illegal
794 * For example S-1-5-32 would end up referencing
795 * domain S-1-5- with RID 32 which is clearly wrong.
797 if (domain_name
== NULL
) {
798 result
= NT_STATUS_NO_MEMORY
;
802 name_infos
[i
].rid
= 0;
803 name_infos
[i
].type
= SID_NAME_DOMAIN
;
804 name_infos
[i
].name
= NULL
;
806 if (sid_check_is_builtin(&sid
)) {
807 /* Yes, W2k3 returns "BUILTIN" both as domain
809 name_infos
[i
].name
= talloc_strdup(
810 name_infos
, builtin_domain_name());
811 if (name_infos
[i
].name
== NULL
) {
812 result
= NT_STATUS_NO_MEMORY
;
817 /* This is a normal SID with rid component */
818 if (!sid_split_rid(&sid
, &rid
)) {
819 result
= NT_STATUS_INVALID_SID
;
824 if (!check_dom_sid_to_level(&sid
, level
)) {
825 name_infos
[i
].rid
= 0;
826 name_infos
[i
].type
= SID_NAME_UNKNOWN
;
827 name_infos
[i
].name
= NULL
;
831 for (j
=0; j
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; j
++) {
832 if (!dom_infos
[j
].valid
) {
835 if (sid_equal(&sid
, &dom_infos
[j
].sid
)) {
840 if (j
== LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
841 /* TODO: What's the right error message here? */
842 result
= NT_STATUS_NONE_MAPPED
;
846 if (!dom_infos
[j
].valid
) {
847 /* We found a domain not yet referenced, create a new
849 dom_infos
[j
].valid
= true;
850 sid_copy(&dom_infos
[j
].sid
, &sid
);
852 if (domain_name
!= NULL
) {
853 /* This name was being found above in the case
854 * when we found a domain SID */
856 talloc_strdup(dom_infos
, domain_name
);
857 if (dom_infos
[j
].name
== NULL
) {
858 result
= NT_STATUS_NO_MEMORY
;
862 /* lookup_rids will take care of this */
863 dom_infos
[j
].name
= NULL
;
867 name_infos
[i
].dom_idx
= j
;
869 if (name_infos
[i
].type
== SID_NAME_USE_NONE
) {
870 name_infos
[i
].rid
= rid
;
872 ADD_TO_ARRAY(dom_infos
, int, i
, &dom_infos
[j
].idxs
,
873 &dom_infos
[j
].num_idxs
);
875 if (dom_infos
[j
].idxs
== NULL
) {
876 result
= NT_STATUS_NO_MEMORY
;
882 /* Iterate over the domains found */
884 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
886 const char *domain_name
= NULL
;
888 enum lsa_SidType
*types
;
889 struct lsa_dom_info
*dom
= &dom_infos
[i
];
892 /* No domains left, we're done */
897 if (!(rids
= TALLOC_ARRAY(tmp_ctx
, uint32
, dom
->num_idxs
))) {
898 result
= NT_STATUS_NO_MEMORY
;
905 for (j
=0; j
<dom
->num_idxs
; j
++) {
906 rids
[j
] = name_infos
[dom
->idxs
[j
]].rid
;
909 if (!lookup_rids(tmp_ctx
, &dom
->sid
,
910 dom
->num_idxs
, rids
, &domain_name
,
912 result
= NT_STATUS_NO_MEMORY
;
916 if (!(dom
->name
= talloc_strdup(dom_infos
, domain_name
))) {
917 result
= NT_STATUS_NO_MEMORY
;
921 for (j
=0; j
<dom
->num_idxs
; j
++) {
922 int idx
= dom
->idxs
[j
];
923 name_infos
[idx
].type
= types
[j
];
924 if (types
[j
] != SID_NAME_UNKNOWN
) {
925 name_infos
[idx
].name
=
926 talloc_strdup(name_infos
, names
[j
]);
927 if (name_infos
[idx
].name
== NULL
) {
928 result
= NT_STATUS_NO_MEMORY
;
932 name_infos
[idx
].name
= NULL
;
937 *ret_domains
= dom_infos
;
938 *ret_names
= name_infos
;
939 TALLOC_FREE(tmp_ctx
);
943 TALLOC_FREE(dom_infos
);
944 TALLOC_FREE(name_infos
);
945 TALLOC_FREE(tmp_ctx
);
949 /*****************************************************************
950 *THE CANONICAL* convert SID to name function.
951 *****************************************************************/
953 bool lookup_sid(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*sid
,
954 const char **ret_domain
, const char **ret_name
,
955 enum lsa_SidType
*ret_type
)
957 struct lsa_dom_info
*domain
;
958 struct lsa_name_info
*name
;
962 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid
)));
964 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
965 DEBUG(0, ("talloc_new failed\n"));
969 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx
, 1, &sid
, 1,
974 if (name
->type
== SID_NAME_UNKNOWN
) {
978 if ((ret_domain
!= NULL
) &&
979 !(*ret_domain
= talloc_strdup(mem_ctx
, domain
->name
))) {
983 if ((ret_name
!= NULL
) &&
984 !(*ret_name
= talloc_strdup(mem_ctx
, name
->name
))) {
988 if (ret_type
!= NULL
) {
989 *ret_type
= name
->type
;
996 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid
),
997 domain
->name
, name
->name
, name
->type
));
999 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid
)));
1001 TALLOC_FREE(tmp_ctx
);
1005 /*****************************************************************
1006 Id mapping cache. This is to avoid Winbind mappings already
1007 seen by smbd to be queried too frequently, keeping winbindd
1008 busy, and blocking smbd while winbindd is busy with other
1009 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1010 modified to use linked lists by jra.
1011 *****************************************************************/
1013 /*****************************************************************
1014 Find a SID given a uid.
1015 *****************************************************************/
1017 static bool fetch_sid_from_uid_cache(struct dom_sid
*psid
, uid_t uid
)
1019 DATA_BLOB cache_value
;
1021 if (!memcache_lookup(NULL
, UID_SID_CACHE
,
1022 data_blob_const(&uid
, sizeof(uid
)),
1027 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1028 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1029 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, 0));
1034 /*****************************************************************
1035 Find a uid given a SID.
1036 *****************************************************************/
1038 static bool fetch_uid_from_cache( uid_t
*puid
, const struct dom_sid
*psid
)
1040 DATA_BLOB cache_value
;
1042 if (!memcache_lookup(NULL
, SID_UID_CACHE
,
1043 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1048 SMB_ASSERT(cache_value
.length
== sizeof(*puid
));
1049 memcpy(puid
, cache_value
.data
, sizeof(*puid
));
1054 /*****************************************************************
1055 Store uid to SID mapping in cache.
1056 *****************************************************************/
1058 void store_uid_sid_cache(const struct dom_sid
*psid
, uid_t uid
)
1060 memcache_add(NULL
, SID_UID_CACHE
,
1061 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1062 data_blob_const(&uid
, sizeof(uid
)));
1063 memcache_add(NULL
, UID_SID_CACHE
,
1064 data_blob_const(&uid
, sizeof(uid
)),
1065 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)));
1068 /*****************************************************************
1069 Find a SID given a gid.
1070 *****************************************************************/
1072 static bool fetch_sid_from_gid_cache(struct dom_sid
*psid
, gid_t gid
)
1074 DATA_BLOB cache_value
;
1076 if (!memcache_lookup(NULL
, GID_SID_CACHE
,
1077 data_blob_const(&gid
, sizeof(gid
)),
1082 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1083 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1084 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, 0));
1089 /*****************************************************************
1090 Find a gid given a SID.
1091 *****************************************************************/
1093 static bool fetch_gid_from_cache(gid_t
*pgid
, const struct dom_sid
*psid
)
1095 DATA_BLOB cache_value
;
1097 if (!memcache_lookup(NULL
, SID_GID_CACHE
,
1098 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1103 SMB_ASSERT(cache_value
.length
== sizeof(*pgid
));
1104 memcpy(pgid
, cache_value
.data
, sizeof(*pgid
));
1109 /*****************************************************************
1110 Store gid to SID mapping in cache.
1111 *****************************************************************/
1113 void store_gid_sid_cache(const struct dom_sid
*psid
, gid_t gid
)
1115 memcache_add(NULL
, SID_GID_CACHE
,
1116 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1117 data_blob_const(&gid
, sizeof(gid
)));
1118 memcache_add(NULL
, GID_SID_CACHE
,
1119 data_blob_const(&gid
, sizeof(gid
)),
1120 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)));
1123 /*****************************************************************
1124 *THE LEGACY* convert uid_t to SID function.
1125 *****************************************************************/
1127 static void legacy_uid_to_sid(struct dom_sid
*psid
, uid_t uid
)
1134 ret
= pdb_uid_to_sid(uid
, psid
);
1138 /* This is a mapped user */
1142 /* This is an unmapped user */
1144 uid_to_unix_users_sid(uid
, psid
);
1147 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid
,
1148 sid_string_dbg(psid
)));
1150 store_uid_sid_cache(psid
, uid
);
1154 /*****************************************************************
1155 *THE LEGACY* convert gid_t to SID function.
1156 *****************************************************************/
1158 static void legacy_gid_to_sid(struct dom_sid
*psid
, gid_t gid
)
1165 ret
= pdb_gid_to_sid(gid
, psid
);
1169 /* This is a mapped group */
1173 /* This is an unmapped group */
1175 gid_to_unix_groups_sid(gid
, psid
);
1178 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid
,
1179 sid_string_dbg(psid
)));
1181 store_gid_sid_cache(psid
, gid
);
1185 /*****************************************************************
1186 *THE LEGACY* convert SID to uid function.
1187 *****************************************************************/
1189 static bool legacy_sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1191 enum lsa_SidType type
;
1193 if (sid_check_is_in_our_domain(psid
)) {
1198 ret
= pdb_sid_to_id(psid
, &id
, &type
);
1202 if (type
!= SID_NAME_USER
) {
1203 DEBUG(5, ("sid %s is a %s, expected a user\n",
1204 sid_string_dbg(psid
),
1205 sid_type_lookup(type
)));
1212 /* This was ours, but it was not mapped. Fail */
1215 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1216 sid_string_dbg(psid
)));
1220 DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_dbg(psid
),
1221 (unsigned int)*puid
));
1223 store_uid_sid_cache(psid
, *puid
);
1227 /*****************************************************************
1228 *THE LEGACY* convert SID to gid function.
1229 Group mapping is used for gids that maps to Wellknown SIDs
1230 *****************************************************************/
1232 static bool legacy_sid_to_gid(const struct 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_check_is_in_our_domain(psid
)) {
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(struct 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(struct 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 struct 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 struct 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
);
1520 * @brief This function gets the primary group SID mapping the primary
1521 * GID of the user as obtained by an actual getpwnam() call.
1522 * This is necessary to avoid issues with arbitrary group SIDs
1523 * stored in passdb. We try as hard as we can to get the SID
1524 * corresponding to the GID, including trying group mapping.
1525 * If nothing else works, we will force "Domain Users" as the
1527 * This is needed because we must always be able to lookup the
1528 * primary group SID, so we cannot settle for an arbitrary SID.
1530 * This call can be expensive. Use with moderation.
1531 * If you have a "samu" struct around use pdb_get_group_sid()
1532 * instead as it does properly cache results.
1534 * @param mem_ctx[in] The memory context iused to allocate the result.
1535 * @param username[in] The user's name
1536 * @param _pwd[in|out] If available, pass in user's passwd struct.
1537 * It will contain a tallocated passwd if NULL was
1539 * @param _group_sid[out] The user's Primary Group SID
1541 * @return NTSTATUS error code.
1543 NTSTATUS
get_primary_group_sid(TALLOC_CTX
*mem_ctx
,
1544 const char *username
,
1545 struct passwd
**_pwd
,
1546 struct dom_sid
**_group_sid
)
1548 TALLOC_CTX
*tmp_ctx
;
1549 bool need_lookup_sid
= false;
1550 struct dom_sid
*group_sid
;
1551 struct passwd
*pwd
= *_pwd
;
1553 tmp_ctx
= talloc_new(mem_ctx
);
1555 return NT_STATUS_NO_MEMORY
;
1559 pwd
= Get_Pwnam_alloc(mem_ctx
, username
);
1561 DEBUG(0, ("Failed to find a Unix account for %s",
1563 TALLOC_FREE(tmp_ctx
);
1564 return NT_STATUS_NO_SUCH_USER
;
1568 group_sid
= talloc_zero(mem_ctx
, struct dom_sid
);
1570 TALLOC_FREE(tmp_ctx
);
1571 return NT_STATUS_NO_MEMORY
;
1574 gid_to_sid(group_sid
, pwd
->pw_gid
);
1575 if (!is_null_sid(group_sid
)) {
1576 struct dom_sid domain_sid
;
1579 /* We need a sid within our domain */
1580 sid_copy(&domain_sid
, group_sid
);
1581 sid_split_rid(&domain_sid
, &rid
);
1582 if (sid_equal(&domain_sid
, get_global_sam_sid())) {
1584 * As shortcut for the expensive lookup_sid call
1585 * compare the domain sid part
1588 case DOMAIN_RID_ADMINS
:
1589 case DOMAIN_RID_USERS
:
1592 need_lookup_sid
= true;
1596 /* Try group mapping */
1597 ZERO_STRUCTP(group_sid
);
1598 if (pdb_gid_to_sid(pwd
->pw_gid
, group_sid
)) {
1599 need_lookup_sid
= true;
1604 /* We must verify that this is a valid SID that resolves to a
1605 * group of the correct type */
1606 if (need_lookup_sid
) {
1607 enum lsa_SidType type
= SID_NAME_UNKNOWN
;
1610 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1611 sid_string_dbg(group_sid
), username
));
1613 /* Now check that it's actually a domain group and
1614 * not something else */
1615 lookup_ret
= lookup_sid(tmp_ctx
, group_sid
,
1618 if (lookup_ret
&& (type
== SID_NAME_DOM_GRP
)) {
1622 DEBUG(3, ("Primary group %s for user %s is"
1623 " a %s and not a domain group\n",
1624 sid_string_dbg(group_sid
), username
,
1625 sid_type_lookup(type
)));
1628 /* Everything else, failed.
1629 * Just set it to the 'Domain Users' RID of 513 which will
1630 always resolve to a name */
1631 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1634 sid_compose(group_sid
, get_global_sam_sid(), DOMAIN_RID_USERS
);
1637 *_pwd
= talloc_move(mem_ctx
, &pwd
);
1638 *_group_sid
= talloc_move(mem_ctx
, &group_sid
);
1639 TALLOC_FREE(tmp_ctx
);
1640 return NT_STATUS_OK
;