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"
25 /*****************************************************************
26 Dissect a user-provided name into domain, name, sid and type.
28 If an explicit domain name was given in the form domain\user, it
29 has to try that. If no explicit domain name was given, we have
31 *****************************************************************/
33 bool lookup_name(TALLOC_CTX
*mem_ctx
,
34 const char *full_name
, int flags
,
35 const char **ret_domain
, const char **ret_name
,
36 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
40 const char *domain
= NULL
;
41 const char *name
= NULL
;
44 enum lsa_SidType type
;
45 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
47 if (tmp_ctx
== NULL
) {
48 DEBUG(0, ("talloc_new failed\n"));
52 p
= strchr_m(full_name
, '\\');
55 domain
= talloc_strndup(tmp_ctx
, full_name
,
56 PTR_DIFF(p
, full_name
));
57 name
= talloc_strdup(tmp_ctx
, p
+1);
59 domain
= talloc_strdup(tmp_ctx
, "");
60 name
= talloc_strdup(tmp_ctx
, full_name
);
63 if ((domain
== NULL
) || (name
== NULL
)) {
64 DEBUG(0, ("talloc failed\n"));
69 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
70 full_name
, domain
, name
));
71 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags
));
73 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
74 strequal(domain
, get_global_sam_name()))
77 /* It's our own domain, lookup the name in passdb */
78 if (lookup_global_sam_name(name
, flags
, &rid
, &type
)) {
79 sid_compose(&sid
, get_global_sam_sid(), rid
);
86 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
87 strequal(domain
, builtin_domain_name()))
89 if (strlen(name
) == 0) {
90 /* Swap domain and name */
91 tmp
= name
; name
= domain
; domain
= tmp
;
92 sid_copy(&sid
, &global_sid_Builtin
);
93 type
= SID_NAME_DOMAIN
;
97 /* Explicit request for a name in BUILTIN */
98 if (lookup_builtin_name(name
, &rid
)) {
99 sid_compose(&sid
, &global_sid_Builtin
, rid
);
100 type
= SID_NAME_ALIAS
;
103 TALLOC_FREE(tmp_ctx
);
107 /* Try the explicit winbind lookup first, don't let it guess the
108 * domain yet at this point yet. This comes later. */
110 if ((domain
[0] != '\0') &&
111 (flags
& ~(LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
)) &&
112 (winbind_lookup_name(domain
, name
, &sid
, &type
))) {
116 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
117 && strequal(domain
, unix_users_domain_name())) {
118 if (lookup_unix_user_name(name
, &sid
)) {
119 type
= SID_NAME_USER
;
122 TALLOC_FREE(tmp_ctx
);
126 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
127 && strequal(domain
, unix_groups_domain_name())) {
128 if (lookup_unix_group_name(name
, &sid
)) {
129 type
= SID_NAME_DOM_GRP
;
132 TALLOC_FREE(tmp_ctx
);
136 if ((domain
[0] == '\0') && (!(flags
& LOOKUP_NAME_ISOLATED
))) {
137 TALLOC_FREE(tmp_ctx
);
141 /* Now the guesswork begins, we haven't been given an explicit
142 * domain. Try the sequence as documented on
143 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
144 * November 27, 2005 */
146 /* 1. well-known names */
148 if ((flags
& LOOKUP_NAME_WKN
) &&
149 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
151 type
= SID_NAME_WKN_GRP
;
155 /* 2. Builtin domain as such */
157 if ((flags
& (LOOKUP_NAME_BUILTIN
|LOOKUP_NAME_REMOTE
)) &&
158 strequal(name
, builtin_domain_name()))
160 /* Swap domain and name */
161 tmp
= name
; name
= domain
; domain
= tmp
;
162 sid_copy(&sid
, &global_sid_Builtin
);
163 type
= SID_NAME_DOMAIN
;
167 /* 3. Account domain */
169 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
170 strequal(name
, get_global_sam_name()))
172 if (!secrets_fetch_domain_sid(name
, &sid
)) {
173 DEBUG(3, ("Could not fetch my SID\n"));
174 TALLOC_FREE(tmp_ctx
);
177 /* Swap domain and name */
178 tmp
= name
; name
= domain
; domain
= tmp
;
179 type
= SID_NAME_DOMAIN
;
183 /* 4. Primary domain */
185 if ((flags
& LOOKUP_NAME_DOMAIN
) && !IS_DC
&&
186 strequal(name
, lp_workgroup()))
188 if (!secrets_fetch_domain_sid(name
, &sid
)) {
189 DEBUG(3, ("Could not fetch the domain SID\n"));
190 TALLOC_FREE(tmp_ctx
);
193 /* Swap domain and name */
194 tmp
= name
; name
= domain
; domain
= tmp
;
195 type
= SID_NAME_DOMAIN
;
199 /* 5. Trusted domains as such, to me it looks as if members don't do
200 this, tested an XP workstation in a NT domain -- vl */
202 if ((flags
& LOOKUP_NAME_REMOTE
) && IS_DC
&&
203 (pdb_get_trusteddom_pw(name
, NULL
, &sid
, NULL
)))
205 /* Swap domain and name */
206 tmp
= name
; name
= domain
; domain
= tmp
;
207 type
= SID_NAME_DOMAIN
;
211 /* 6. Builtin aliases */
213 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
214 lookup_builtin_name(name
, &rid
))
216 domain
= talloc_strdup(tmp_ctx
, builtin_domain_name());
217 sid_compose(&sid
, &global_sid_Builtin
, rid
);
218 type
= SID_NAME_ALIAS
;
222 /* 7. Local systems' SAM (DCs don't have a local SAM) */
223 /* 8. Primary SAM (On members, this is the domain) */
225 /* Both cases are done by looking at our passdb */
227 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
228 lookup_global_sam_name(name
, flags
, &rid
, &type
))
230 domain
= talloc_strdup(tmp_ctx
, get_global_sam_name());
231 sid_compose(&sid
, get_global_sam_sid(), rid
);
235 /* Now our local possibilities are exhausted. */
237 if (!(flags
& LOOKUP_NAME_REMOTE
)) {
238 TALLOC_FREE(tmp_ctx
);
242 /* If we are not a DC, we have to ask in our primary domain. Let
243 * winbind do that. */
246 (winbind_lookup_name(lp_workgroup(), name
, &sid
, &type
))) {
247 domain
= talloc_strdup(tmp_ctx
, lp_workgroup());
251 /* 9. Trusted domains */
253 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
254 * that (yet), but give it a chance. */
256 if (IS_DC
&& winbind_lookup_name("", name
, &sid
, &type
)) {
257 struct dom_sid dom_sid
;
259 enum lsa_SidType domain_type
;
261 if (type
== SID_NAME_DOMAIN
) {
262 /* Swap name and type */
263 tmp
= name
; name
= domain
; domain
= tmp
;
267 /* Here we have to cope with a little deficiency in the
268 * winbind API: We have to ask it again for the name of the
269 * domain it figured out itself. Maybe fix that later... */
271 sid_copy(&dom_sid
, &sid
);
272 sid_split_rid(&dom_sid
, &tmp_rid
);
274 if (!winbind_lookup_sid(tmp_ctx
, &dom_sid
, &domain
, NULL
,
276 (domain_type
!= SID_NAME_DOMAIN
)) {
277 DEBUG(2, ("winbind could not find the domain's name "
278 "it just looked up for us\n"));
279 TALLOC_FREE(tmp_ctx
);
285 /* 10. Don't translate */
287 /* 11. Ok, windows would end here. Samba has two more options:
288 Unmapped users and unmapped groups */
290 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
291 && lookup_unix_user_name(name
, &sid
)) {
292 domain
= talloc_strdup(tmp_ctx
, unix_users_domain_name());
293 type
= SID_NAME_USER
;
297 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
298 && lookup_unix_group_name(name
, &sid
)) {
299 domain
= talloc_strdup(tmp_ctx
, unix_groups_domain_name());
300 type
= SID_NAME_DOM_GRP
;
305 * Ok, all possibilities tried. Fail.
308 TALLOC_FREE(tmp_ctx
);
312 if ((domain
== NULL
) || (name
== NULL
)) {
313 DEBUG(0, ("talloc failed\n"));
314 TALLOC_FREE(tmp_ctx
);
319 * Hand over the results to the talloc context we've been given.
322 if ((ret_name
!= NULL
) &&
323 !(*ret_name
= talloc_strdup(mem_ctx
, name
))) {
324 DEBUG(0, ("talloc failed\n"));
325 TALLOC_FREE(tmp_ctx
);
329 if (ret_domain
!= NULL
) {
331 if (!(tmp_dom
= talloc_strdup(mem_ctx
, domain
))) {
332 DEBUG(0, ("talloc failed\n"));
333 TALLOC_FREE(tmp_ctx
);
337 *ret_domain
= tmp_dom
;
340 if (ret_sid
!= NULL
) {
341 sid_copy(ret_sid
, &sid
);
344 if (ret_type
!= NULL
) {
348 TALLOC_FREE(tmp_ctx
);
352 /************************************************************************
353 Names from smb.conf can be unqualified. eg. valid users = foo
354 These names should never map to a remote name. Try global_sam_name()\foo,
355 and then "Unix Users"\foo (or "Unix Groups"\foo).
356 ************************************************************************/
358 bool lookup_name_smbconf(TALLOC_CTX
*mem_ctx
,
359 const char *full_name
, int flags
,
360 const char **ret_domain
, const char **ret_name
,
361 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
363 char *qualified_name
;
366 /* NB. No winbindd_separator here as lookup_name needs \\' */
367 if ((p
= strchr_m(full_name
, *lp_winbind_separator())) != NULL
) {
369 /* The name is already qualified with a domain. */
371 if (*lp_winbind_separator() != '\\') {
374 /* lookup_name() needs '\\' as a separator */
376 tmp
= talloc_strdup(mem_ctx
, full_name
);
380 tmp
[p
- full_name
] = '\\';
384 return lookup_name(mem_ctx
, full_name
, flags
,
385 ret_domain
, ret_name
,
389 /* Try with our own SAM name. */
390 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
391 get_global_sam_name(),
393 if (!qualified_name
) {
397 if (lookup_name(mem_ctx
, qualified_name
, flags
,
398 ret_domain
, ret_name
,
399 ret_sid
, ret_type
)) {
403 /* Finally try with "Unix Users" or "Unix Group" */
404 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
405 flags
& LOOKUP_NAME_GROUP
?
406 unix_groups_domain_name() :
407 unix_users_domain_name(),
409 if (!qualified_name
) {
413 return lookup_name(mem_ctx
, qualified_name
, flags
,
414 ret_domain
, ret_name
,
418 static bool wb_lookup_rids(TALLOC_CTX
*mem_ctx
,
419 const struct dom_sid
*domain_sid
,
420 int num_rids
, uint32
*rids
,
421 const char **domain_name
,
422 const char **names
, enum lsa_SidType
*types
)
425 const char **my_names
;
426 enum lsa_SidType
*my_types
;
429 if (!(tmp_ctx
= talloc_init("wb_lookup_rids"))) {
433 if (!winbind_lookup_rids(tmp_ctx
, domain_sid
, num_rids
, rids
,
434 domain_name
, &my_names
, &my_types
)) {
436 for (i
=0; i
<num_rids
; i
++) {
438 types
[i
] = SID_NAME_UNKNOWN
;
440 TALLOC_FREE(tmp_ctx
);
444 if (!(*domain_name
= talloc_strdup(mem_ctx
, *domain_name
))) {
445 TALLOC_FREE(tmp_ctx
);
450 * winbind_lookup_rids allocates its own array. We've been given the
451 * array, so copy it over
454 for (i
=0; i
<num_rids
; i
++) {
455 if (my_names
[i
] == NULL
) {
456 TALLOC_FREE(tmp_ctx
);
459 if (!(names
[i
] = talloc_strdup(names
, my_names
[i
]))) {
460 TALLOC_FREE(tmp_ctx
);
463 types
[i
] = my_types
[i
];
465 TALLOC_FREE(tmp_ctx
);
469 static bool lookup_rids(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*domain_sid
,
470 int num_rids
, uint32_t *rids
,
471 const char **domain_name
,
472 const char ***names
, enum lsa_SidType
**types
)
476 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
477 sid_string_dbg(domain_sid
)));
480 *names
= TALLOC_ZERO_ARRAY(mem_ctx
, const char *, num_rids
);
481 *types
= TALLOC_ARRAY(mem_ctx
, enum lsa_SidType
, num_rids
);
483 if ((*names
== NULL
) || (*types
== NULL
)) {
487 for (i
= 0; i
< num_rids
; i
++)
488 (*types
)[i
] = SID_NAME_UNKNOWN
;
494 if (sid_check_is_domain(domain_sid
)) {
497 if (*domain_name
== NULL
) {
498 *domain_name
= talloc_strdup(
499 mem_ctx
, get_global_sam_name());
502 if (*domain_name
== NULL
) {
507 result
= pdb_lookup_rids(domain_sid
, num_rids
, rids
,
511 return (NT_STATUS_IS_OK(result
) ||
512 NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
) ||
513 NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
));
516 if (sid_check_is_builtin(domain_sid
)) {
518 if (*domain_name
== NULL
) {
519 *domain_name
= talloc_strdup(
520 mem_ctx
, builtin_domain_name());
523 if (*domain_name
== NULL
) {
527 for (i
=0; i
<num_rids
; i
++) {
528 if (lookup_builtin_rid(*names
, rids
[i
],
530 if ((*names
)[i
] == NULL
) {
533 (*types
)[i
] = SID_NAME_ALIAS
;
535 (*types
)[i
] = SID_NAME_UNKNOWN
;
541 if (sid_check_is_wellknown_domain(domain_sid
, NULL
)) {
542 for (i
=0; i
<num_rids
; i
++) {
544 sid_compose(&sid
, domain_sid
, rids
[i
]);
545 if (lookup_wellknown_sid(mem_ctx
, &sid
,
546 domain_name
, &(*names
)[i
])) {
547 if ((*names
)[i
] == NULL
) {
550 (*types
)[i
] = SID_NAME_WKN_GRP
;
552 (*types
)[i
] = SID_NAME_UNKNOWN
;
558 if (sid_check_is_unix_users(domain_sid
)) {
559 if (*domain_name
== NULL
) {
560 *domain_name
= talloc_strdup(
561 mem_ctx
, unix_users_domain_name());
562 if (*domain_name
== NULL
) {
566 for (i
=0; i
<num_rids
; i
++) {
567 (*names
)[i
] = talloc_strdup(
568 (*names
), uidtoname(rids
[i
]));
569 if ((*names
)[i
] == NULL
) {
572 (*types
)[i
] = SID_NAME_USER
;
577 if (sid_check_is_unix_groups(domain_sid
)) {
578 if (*domain_name
== NULL
) {
579 *domain_name
= talloc_strdup(
580 mem_ctx
, unix_groups_domain_name());
581 if (*domain_name
== NULL
) {
585 for (i
=0; i
<num_rids
; i
++) {
586 (*names
)[i
] = talloc_strdup(
587 (*names
), gidtoname(rids
[i
]));
588 if ((*names
)[i
] == NULL
) {
591 (*types
)[i
] = SID_NAME_DOM_GRP
;
596 return wb_lookup_rids(mem_ctx
, domain_sid
, num_rids
, rids
,
597 domain_name
, *names
, *types
);
601 * Is the SID a domain as such? If yes, lookup its name.
604 static bool lookup_as_domain(const struct dom_sid
*sid
, TALLOC_CTX
*mem_ctx
,
608 enum lsa_SidType type
;
610 if (sid_check_is_domain(sid
)) {
611 *name
= talloc_strdup(mem_ctx
, get_global_sam_name());
615 if (sid_check_is_builtin(sid
)) {
616 *name
= talloc_strdup(mem_ctx
, builtin_domain_name());
620 if (sid_check_is_wellknown_domain(sid
, &tmp
)) {
621 *name
= talloc_strdup(mem_ctx
, tmp
);
625 if (sid_check_is_unix_users(sid
)) {
626 *name
= talloc_strdup(mem_ctx
, unix_users_domain_name());
630 if (sid_check_is_unix_groups(sid
)) {
631 *name
= talloc_strdup(mem_ctx
, unix_groups_domain_name());
635 if (sid
->num_auths
!= 4) {
636 /* This can't be a domain */
641 uint32 i
, num_domains
;
642 struct trustdom_info
**domains
;
644 /* This is relatively expensive, but it happens only on DCs
645 * and for SIDs that have 4 sub-authorities and thus look like
648 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx
,
654 for (i
=0; i
<num_domains
; i
++) {
655 if (sid_equal(sid
, &domains
[i
]->sid
)) {
656 *name
= talloc_strdup(mem_ctx
,
664 if (winbind_lookup_sid(mem_ctx
, sid
, &tmp
, NULL
, &type
) &&
665 (type
== SID_NAME_DOMAIN
)) {
674 * This tries to implement the rather weird rules for the lsa_lookup level
677 * This is as close as we can get to what W2k3 does. With this we survive the
678 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
679 * different, but I assume that's just being too liberal. For example, W2k3
680 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
681 * whereas NT4 does the same as level 1 (I think). I did not fully test that
682 * with NT4, this is what w2k3 does.
684 * Level 1: Ask everywhere
685 * Level 2: Ask domain and trusted domains, no builtin and wkn
686 * Level 3: Only ask domain
687 * Level 4: W2k3ad: Only ask AD trusts
688 * Level 5: Only ask transitive forest trusts
692 static bool check_dom_sid_to_level(const struct dom_sid
*sid
, int level
)
701 ret
= (!sid_check_is_builtin(sid
) &&
702 !sid_check_is_wellknown_domain(sid
, NULL
));
707 ret
= sid_check_is_domain(sid
);
714 DEBUG(10, ("%s SID %s in level %d\n",
715 ret
? "Accepting" : "Rejecting",
716 sid_string_dbg(sid
), level
));
721 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
722 * references to domains, it is explicitly made for this.
724 * This attempts to be as efficient as possible: It collects all SIDs
725 * belonging to a domain and hands them in bulk to the appropriate lookup
726 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
727 * *hugely* from this. Winbind is going to be extended with a lookup_rids
728 * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
732 NTSTATUS
lookup_sids(TALLOC_CTX
*mem_ctx
, int num_sids
,
733 const struct dom_sid
**sids
, int level
,
734 struct lsa_dom_info
**ret_domains
,
735 struct lsa_name_info
**ret_names
)
738 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
739 struct lsa_name_info
*name_infos
;
740 struct lsa_dom_info
*dom_infos
= NULL
;
744 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
745 DEBUG(0, ("talloc_new failed\n"));
746 return NT_STATUS_NO_MEMORY
;
750 name_infos
= TALLOC_ARRAY(mem_ctx
, struct lsa_name_info
, num_sids
);
751 if (name_infos
== NULL
) {
752 result
= NT_STATUS_NO_MEMORY
;
759 dom_infos
= TALLOC_ZERO_ARRAY(mem_ctx
, struct lsa_dom_info
,
760 LSA_REF_DOMAIN_LIST_MULTIPLIER
);
761 if (dom_infos
== NULL
) {
762 result
= NT_STATUS_NO_MEMORY
;
766 /* First build up the data structures:
768 * dom_infos is a list of domains referenced in the list of
769 * SIDs. Later we will walk the list of domains and look up the RIDs
772 * name_infos is a shadow-copy of the SIDs array to collect the real
775 * dom_info->idxs is an index into the name_infos array. The
776 * difficulty we have here is that we need to keep the SIDs the client
777 * asked for in the same order for the reply
780 for (i
=0; i
<num_sids
; i
++) {
783 const char *domain_name
= NULL
;
785 sid_copy(&sid
, sids
[i
]);
786 name_infos
[i
].type
= SID_NAME_USE_NONE
;
788 if (lookup_as_domain(&sid
, name_infos
, &domain_name
)) {
789 /* We can't push that through the normal lookup
790 * process, as this would reference illegal
793 * For example S-1-5-32 would end up referencing
794 * domain S-1-5- with RID 32 which is clearly wrong.
796 if (domain_name
== NULL
) {
797 result
= NT_STATUS_NO_MEMORY
;
801 name_infos
[i
].rid
= 0;
802 name_infos
[i
].type
= SID_NAME_DOMAIN
;
803 name_infos
[i
].name
= NULL
;
805 if (sid_check_is_builtin(&sid
)) {
806 /* Yes, W2k3 returns "BUILTIN" both as domain
808 name_infos
[i
].name
= talloc_strdup(
809 name_infos
, builtin_domain_name());
810 if (name_infos
[i
].name
== NULL
) {
811 result
= NT_STATUS_NO_MEMORY
;
816 /* This is a normal SID with rid component */
817 if (!sid_split_rid(&sid
, &rid
)) {
818 result
= NT_STATUS_INVALID_SID
;
823 if (!check_dom_sid_to_level(&sid
, level
)) {
824 name_infos
[i
].rid
= 0;
825 name_infos
[i
].type
= SID_NAME_UNKNOWN
;
826 name_infos
[i
].name
= NULL
;
830 for (j
=0; j
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; j
++) {
831 if (!dom_infos
[j
].valid
) {
834 if (sid_equal(&sid
, &dom_infos
[j
].sid
)) {
839 if (j
== LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
840 /* TODO: What's the right error message here? */
841 result
= NT_STATUS_NONE_MAPPED
;
845 if (!dom_infos
[j
].valid
) {
846 /* We found a domain not yet referenced, create a new
848 dom_infos
[j
].valid
= true;
849 sid_copy(&dom_infos
[j
].sid
, &sid
);
851 if (domain_name
!= NULL
) {
852 /* This name was being found above in the case
853 * when we found a domain SID */
855 talloc_strdup(dom_infos
, domain_name
);
856 if (dom_infos
[j
].name
== NULL
) {
857 result
= NT_STATUS_NO_MEMORY
;
861 /* lookup_rids will take care of this */
862 dom_infos
[j
].name
= NULL
;
866 name_infos
[i
].dom_idx
= j
;
868 if (name_infos
[i
].type
== SID_NAME_USE_NONE
) {
869 name_infos
[i
].rid
= rid
;
871 ADD_TO_ARRAY(dom_infos
, int, i
, &dom_infos
[j
].idxs
,
872 &dom_infos
[j
].num_idxs
);
874 if (dom_infos
[j
].idxs
== NULL
) {
875 result
= NT_STATUS_NO_MEMORY
;
881 /* Iterate over the domains found */
883 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
885 const char *domain_name
= NULL
;
887 enum lsa_SidType
*types
;
888 struct lsa_dom_info
*dom
= &dom_infos
[i
];
891 /* No domains left, we're done */
896 if (!(rids
= TALLOC_ARRAY(tmp_ctx
, uint32
, dom
->num_idxs
))) {
897 result
= NT_STATUS_NO_MEMORY
;
904 for (j
=0; j
<dom
->num_idxs
; j
++) {
905 rids
[j
] = name_infos
[dom
->idxs
[j
]].rid
;
908 if (!lookup_rids(tmp_ctx
, &dom
->sid
,
909 dom
->num_idxs
, rids
, &domain_name
,
911 result
= NT_STATUS_NO_MEMORY
;
915 if (!(dom
->name
= talloc_strdup(dom_infos
, domain_name
))) {
916 result
= NT_STATUS_NO_MEMORY
;
920 for (j
=0; j
<dom
->num_idxs
; j
++) {
921 int idx
= dom
->idxs
[j
];
922 name_infos
[idx
].type
= types
[j
];
923 if (types
[j
] != SID_NAME_UNKNOWN
) {
924 name_infos
[idx
].name
=
925 talloc_strdup(name_infos
, names
[j
]);
926 if (name_infos
[idx
].name
== NULL
) {
927 result
= NT_STATUS_NO_MEMORY
;
931 name_infos
[idx
].name
= NULL
;
936 *ret_domains
= dom_infos
;
937 *ret_names
= name_infos
;
938 TALLOC_FREE(tmp_ctx
);
942 TALLOC_FREE(dom_infos
);
943 TALLOC_FREE(name_infos
);
944 TALLOC_FREE(tmp_ctx
);
948 /*****************************************************************
949 *THE CANONICAL* convert SID to name function.
950 *****************************************************************/
952 bool lookup_sid(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*sid
,
953 const char **ret_domain
, const char **ret_name
,
954 enum lsa_SidType
*ret_type
)
956 struct lsa_dom_info
*domain
;
957 struct lsa_name_info
*name
;
961 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid
)));
963 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
964 DEBUG(0, ("talloc_new failed\n"));
968 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx
, 1, &sid
, 1,
973 if (name
->type
== SID_NAME_UNKNOWN
) {
977 if ((ret_domain
!= NULL
) &&
978 !(*ret_domain
= talloc_strdup(mem_ctx
, domain
->name
))) {
982 if ((ret_name
!= NULL
) &&
983 !(*ret_name
= talloc_strdup(mem_ctx
, name
->name
))) {
987 if (ret_type
!= NULL
) {
988 *ret_type
= name
->type
;
995 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid
),
996 domain
->name
, name
->name
, name
->type
));
998 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid
)));
1000 TALLOC_FREE(tmp_ctx
);
1004 /*****************************************************************
1005 Id mapping cache. This is to avoid Winbind mappings already
1006 seen by smbd to be queried too frequently, keeping winbindd
1007 busy, and blocking smbd while winbindd is busy with other
1008 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1009 modified to use linked lists by jra.
1010 *****************************************************************/
1012 /*****************************************************************
1013 Find a SID given a uid.
1014 *****************************************************************/
1016 static bool fetch_sid_from_uid_cache(struct dom_sid
*psid
, uid_t uid
)
1018 DATA_BLOB cache_value
;
1020 if (!memcache_lookup(NULL
, UID_SID_CACHE
,
1021 data_blob_const(&uid
, sizeof(uid
)),
1026 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1027 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1028 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, 0));
1033 /*****************************************************************
1034 Find a uid given a SID.
1035 *****************************************************************/
1037 static bool fetch_uid_from_cache( uid_t
*puid
, const struct dom_sid
*psid
)
1039 DATA_BLOB cache_value
;
1041 if (!memcache_lookup(NULL
, SID_UID_CACHE
,
1042 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1047 SMB_ASSERT(cache_value
.length
== sizeof(*puid
));
1048 memcpy(puid
, cache_value
.data
, sizeof(*puid
));
1053 /*****************************************************************
1054 Store uid to SID mapping in cache.
1055 *****************************************************************/
1057 void store_uid_sid_cache(const struct dom_sid
*psid
, uid_t uid
)
1059 memcache_add(NULL
, SID_UID_CACHE
,
1060 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1061 data_blob_const(&uid
, sizeof(uid
)));
1062 memcache_add(NULL
, UID_SID_CACHE
,
1063 data_blob_const(&uid
, sizeof(uid
)),
1064 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)));
1067 /*****************************************************************
1068 Find a SID given a gid.
1069 *****************************************************************/
1071 static bool fetch_sid_from_gid_cache(struct dom_sid
*psid
, gid_t gid
)
1073 DATA_BLOB cache_value
;
1075 if (!memcache_lookup(NULL
, GID_SID_CACHE
,
1076 data_blob_const(&gid
, sizeof(gid
)),
1081 memcpy(psid
, cache_value
.data
, MIN(sizeof(*psid
), cache_value
.length
));
1082 SMB_ASSERT(cache_value
.length
>= offsetof(struct dom_sid
, id_auth
));
1083 SMB_ASSERT(cache_value
.length
== ndr_size_dom_sid(psid
, 0));
1088 /*****************************************************************
1089 Find a gid given a SID.
1090 *****************************************************************/
1092 static bool fetch_gid_from_cache(gid_t
*pgid
, const struct dom_sid
*psid
)
1094 DATA_BLOB cache_value
;
1096 if (!memcache_lookup(NULL
, SID_GID_CACHE
,
1097 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1102 SMB_ASSERT(cache_value
.length
== sizeof(*pgid
));
1103 memcpy(pgid
, cache_value
.data
, sizeof(*pgid
));
1108 /*****************************************************************
1109 Store gid to SID mapping in cache.
1110 *****************************************************************/
1112 void store_gid_sid_cache(const struct dom_sid
*psid
, gid_t gid
)
1114 memcache_add(NULL
, SID_GID_CACHE
,
1115 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)),
1116 data_blob_const(&gid
, sizeof(gid
)));
1117 memcache_add(NULL
, GID_SID_CACHE
,
1118 data_blob_const(&gid
, sizeof(gid
)),
1119 data_blob_const(psid
, ndr_size_dom_sid(psid
, 0)));
1122 /*****************************************************************
1123 *THE LEGACY* convert uid_t to SID function.
1124 *****************************************************************/
1126 static void legacy_uid_to_sid(struct dom_sid
*psid
, uid_t uid
)
1133 ret
= pdb_uid_to_sid(uid
, psid
);
1137 /* This is a mapped user */
1141 /* This is an unmapped user */
1143 uid_to_unix_users_sid(uid
, psid
);
1146 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid
,
1147 sid_string_dbg(psid
)));
1149 store_uid_sid_cache(psid
, uid
);
1153 /*****************************************************************
1154 *THE LEGACY* convert gid_t to SID function.
1155 *****************************************************************/
1157 static void legacy_gid_to_sid(struct dom_sid
*psid
, gid_t gid
)
1164 ret
= pdb_gid_to_sid(gid
, psid
);
1168 /* This is a mapped group */
1172 /* This is an unmapped group */
1174 gid_to_unix_groups_sid(gid
, psid
);
1177 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid
,
1178 sid_string_dbg(psid
)));
1180 store_gid_sid_cache(psid
, gid
);
1184 /*****************************************************************
1185 *THE LEGACY* convert SID to uid function.
1186 *****************************************************************/
1188 static bool legacy_sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1190 enum lsa_SidType type
;
1192 if (sid_check_is_in_our_domain(psid
)) {
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 struct dom_sid
*psid
, gid_t
*pgid
)
1235 enum lsa_SidType type
;
1237 if ((sid_check_is_in_builtin(psid
) ||
1238 sid_check_is_in_wellknown_domain(psid
))) {
1242 ret
= pdb_getgrsid(&map
, *psid
);
1249 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1250 sid_string_dbg(psid
)));
1254 if (sid_check_is_in_our_domain(psid
)) {
1258 ret
= pdb_sid_to_id(psid
, &id
, &type
);
1262 if ((type
!= SID_NAME_DOM_GRP
) &&
1263 (type
!= SID_NAME_ALIAS
)) {
1264 DEBUG(5, ("LEGACY: sid %s is a %s, expected "
1265 "a group\n", sid_string_dbg(psid
),
1266 sid_type_lookup(type
)));
1273 /* This was ours, but it was not mapped. Fail */
1276 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1277 sid_string_dbg(psid
)));
1281 DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_dbg(psid
),
1282 (unsigned int)*pgid
));
1284 store_gid_sid_cache(psid
, *pgid
);
1289 /*****************************************************************
1290 *THE CANONICAL* convert uid_t to SID function.
1291 *****************************************************************/
1293 void uid_to_sid(struct dom_sid
*psid
, uid_t uid
)
1295 bool expired
= true;
1299 if (fetch_sid_from_uid_cache(psid
, uid
))
1302 /* Check the winbindd cache directly. */
1303 ret
= idmap_cache_find_uid2sid(uid
, psid
, &expired
);
1305 if (ret
&& !expired
&& is_null_sid(psid
)) {
1307 * Negative cache entry, we already asked.
1310 legacy_uid_to_sid(psid
, uid
);
1314 if (!ret
|| expired
) {
1315 /* Not in cache. Ask winbindd. */
1316 if (!winbind_uid_to_sid(psid
, uid
)) {
1318 * We shouldn't return the NULL SID
1319 * here if winbind was running and
1320 * couldn't map, as winbind will have
1321 * added a negative entry that will
1322 * cause us to go though the
1323 * legacy_uid_to_sid()
1324 * function anyway in the case above
1325 * the next time we ask.
1327 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1328 "for uid %u\n", (unsigned int)uid
));
1330 legacy_uid_to_sid(psid
, uid
);
1335 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid
,
1336 sid_string_dbg(psid
)));
1338 store_uid_sid_cache(psid
, uid
);
1342 /*****************************************************************
1343 *THE CANONICAL* convert gid_t to SID function.
1344 *****************************************************************/
1346 void gid_to_sid(struct dom_sid
*psid
, gid_t gid
)
1348 bool expired
= true;
1352 if (fetch_sid_from_gid_cache(psid
, gid
))
1355 /* Check the winbindd cache directly. */
1356 ret
= idmap_cache_find_gid2sid(gid
, psid
, &expired
);
1358 if (ret
&& !expired
&& is_null_sid(psid
)) {
1360 * Negative cache entry, we already asked.
1363 legacy_gid_to_sid(psid
, gid
);
1367 if (!ret
|| expired
) {
1368 /* Not in cache. Ask winbindd. */
1369 if (!winbind_gid_to_sid(psid
, gid
)) {
1371 * We shouldn't return the NULL SID
1372 * here if winbind was running and
1373 * couldn't map, as winbind will have
1374 * added a negative entry that will
1375 * cause us to go though the
1376 * legacy_gid_to_sid()
1377 * function anyway in the case above
1378 * the next time we ask.
1380 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1381 "for gid %u\n", (unsigned int)gid
));
1383 legacy_gid_to_sid(psid
, gid
);
1388 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid
,
1389 sid_string_dbg(psid
)));
1391 store_gid_sid_cache(psid
, gid
);
1395 /*****************************************************************
1396 *THE CANONICAL* convert SID to uid function.
1397 *****************************************************************/
1399 bool sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1401 bool expired
= true;
1406 if (fetch_uid_from_cache(puid
, psid
))
1409 if (fetch_gid_from_cache(&gid
, psid
)) {
1413 /* Optimize for the Unix Users Domain
1414 * as the conversion is straightforward */
1415 if (sid_peek_check_rid(&global_sid_Unix_Users
, psid
, &rid
)) {
1419 /* return here, don't cache */
1420 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1421 (unsigned int)*puid
));
1425 /* Check the winbindd cache directly. */
1426 ret
= idmap_cache_find_sid2uid(psid
, puid
, &expired
);
1428 if (ret
&& !expired
&& (*puid
== (uid_t
)-1)) {
1430 * Negative cache entry, we already asked.
1433 return legacy_sid_to_uid(psid
, puid
);
1436 if (!ret
|| expired
) {
1437 /* Not in cache. Ask winbindd. */
1438 if (!winbind_sid_to_uid(puid
, psid
)) {
1439 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1440 sid_string_dbg(psid
)));
1441 /* winbind failed. do legacy */
1442 return legacy_sid_to_uid(psid
, puid
);
1446 /* TODO: Here would be the place to allocate both a gid and a uid for
1447 * the SID in question */
1449 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1450 (unsigned int)*puid
));
1452 store_uid_sid_cache(psid
, *puid
);
1456 /*****************************************************************
1457 *THE CANONICAL* convert SID to gid function.
1458 Group mapping is used for gids that maps to Wellknown SIDs
1459 *****************************************************************/
1461 bool sid_to_gid(const struct dom_sid
*psid
, gid_t
*pgid
)
1463 bool expired
= true;
1468 if (fetch_gid_from_cache(pgid
, psid
))
1471 if (fetch_uid_from_cache(&uid
, psid
))
1474 /* Optimize for the Unix Groups Domain
1475 * as the conversion is straightforward */
1476 if (sid_peek_check_rid(&global_sid_Unix_Groups
, psid
, &rid
)) {
1480 /* return here, don't cache */
1481 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1482 (unsigned int)*pgid
));
1486 /* Check the winbindd cache directly. */
1487 ret
= idmap_cache_find_sid2gid(psid
, pgid
, &expired
);
1489 if (ret
&& !expired
&& (*pgid
== (gid_t
)-1)) {
1491 * Negative cache entry, we already asked.
1494 return legacy_sid_to_gid(psid
, pgid
);
1497 if (!ret
|| expired
) {
1498 /* Not in cache or negative. Ask winbindd. */
1499 /* Ask winbindd if it can map this sid to a gid.
1500 * (Idmap will check it is a valid SID and of the right type) */
1502 if ( !winbind_sid_to_gid(pgid
, psid
) ) {
1504 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1505 sid_string_dbg(psid
)));
1506 /* winbind failed. do legacy */
1507 return legacy_sid_to_gid(psid
, pgid
);
1511 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1512 (unsigned int)*pgid
));
1514 store_gid_sid_cache(psid
, *pgid
);
1519 * @brief This function gets the primary group SID mapping the primary
1520 * GID of the user as obtained by an actual getpwnam() call.
1521 * This is necessary to avoid issues with arbitrary group SIDs
1522 * stored in passdb. We try as hard as we can to get the SID
1523 * corresponding to the GID, including trying group mapping.
1524 * If nothing else works, we will force "Domain Users" as the
1526 * This is needed because we must always be able to lookup the
1527 * primary group SID, so we cannot settle for an arbitrary SID.
1529 * This call can be expensive. Use with moderation.
1530 * If you have a "samu" struct around use pdb_get_group_sid()
1531 * instead as it does properly cache results.
1533 * @param mem_ctx[in] The memory context iused to allocate the result.
1534 * @param username[in] The user's name
1535 * @param _pwd[in|out] If available, pass in user's passwd struct.
1536 * It will contain a tallocated passwd if NULL was
1538 * @param _group_sid[out] The user's Primary Group SID
1540 * @return NTSTATUS error code.
1542 NTSTATUS
get_primary_group_sid(TALLOC_CTX
*mem_ctx
,
1543 const char *username
,
1544 struct passwd
**_pwd
,
1545 struct dom_sid
**_group_sid
)
1547 TALLOC_CTX
*tmp_ctx
;
1548 bool need_lookup_sid
= false;
1549 struct dom_sid
*group_sid
;
1550 struct passwd
*pwd
= *_pwd
;
1552 tmp_ctx
= talloc_new(mem_ctx
);
1554 return NT_STATUS_NO_MEMORY
;
1558 pwd
= Get_Pwnam_alloc(mem_ctx
, username
);
1560 DEBUG(0, ("Failed to find a Unix account for %s",
1562 TALLOC_FREE(tmp_ctx
);
1563 return NT_STATUS_NO_SUCH_USER
;
1567 group_sid
= talloc_zero(mem_ctx
, struct dom_sid
);
1569 TALLOC_FREE(tmp_ctx
);
1570 return NT_STATUS_NO_MEMORY
;
1573 gid_to_sid(group_sid
, pwd
->pw_gid
);
1574 if (!is_null_sid(group_sid
)) {
1575 struct dom_sid domain_sid
;
1578 /* We need a sid within our domain */
1579 sid_copy(&domain_sid
, group_sid
);
1580 sid_split_rid(&domain_sid
, &rid
);
1581 if (sid_equal(&domain_sid
, get_global_sam_sid())) {
1583 * As shortcut for the expensive lookup_sid call
1584 * compare the domain sid part
1587 case DOMAIN_RID_ADMINS
:
1588 case DOMAIN_RID_USERS
:
1591 need_lookup_sid
= true;
1595 /* Try group mapping */
1596 ZERO_STRUCTP(group_sid
);
1597 if (pdb_gid_to_sid(pwd
->pw_gid
, group_sid
)) {
1598 need_lookup_sid
= true;
1603 /* We must verify that this is a valid SID that resolves to a
1604 * group of the correct type */
1605 if (need_lookup_sid
) {
1606 enum lsa_SidType type
= SID_NAME_UNKNOWN
;
1609 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1610 sid_string_dbg(group_sid
), username
));
1612 /* Now check that it's actually a domain group and
1613 * not something else */
1614 lookup_ret
= lookup_sid(tmp_ctx
, group_sid
,
1617 if (lookup_ret
&& (type
== SID_NAME_DOM_GRP
)) {
1621 DEBUG(3, ("Primary group %s for user %s is"
1622 " a %s and not a domain group\n",
1623 sid_string_dbg(group_sid
), username
,
1624 sid_type_lookup(type
)));
1627 /* Everything else, failed.
1628 * Just set it to the 'Domain Users' RID of 513 which will
1629 always resolve to a name */
1630 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1633 sid_compose(group_sid
, get_global_sam_sid(), DOMAIN_RID_USERS
);
1636 *_pwd
= talloc_move(mem_ctx
, &pwd
);
1637 *_group_sid
= talloc_move(mem_ctx
, &group_sid
);
1638 TALLOC_FREE(tmp_ctx
);
1639 return NT_STATUS_OK
;