2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Gerald (Jerry) Carter 2003
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "../librpc/gen_ndr/ndr_security.h"
27 #include "idmap_cache.h"
28 #include "../libcli/security/security.h"
29 #include "lib/winbind_util.h"
30 #include "../librpc/gen_ndr/idmap.h"
32 /*****************************************************************
33 Dissect a user-provided name into domain, name, sid and type.
35 If an explicit domain name was given in the form domain\user, it
36 has to try that. If no explicit domain name was given, we have
38 *****************************************************************/
40 bool lookup_name(TALLOC_CTX
*mem_ctx
,
41 const char *full_name
, int flags
,
42 const char **ret_domain
, const char **ret_name
,
43 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
47 const char *domain
= NULL
;
48 const char *name
= NULL
;
51 enum lsa_SidType type
;
52 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
54 if (tmp_ctx
== NULL
) {
55 DEBUG(0, ("talloc_new failed\n"));
59 p
= strchr_m(full_name
, '\\');
62 domain
= talloc_strndup(tmp_ctx
, full_name
,
63 PTR_DIFF(p
, full_name
));
64 name
= talloc_strdup(tmp_ctx
, p
+1);
66 domain
= talloc_strdup(tmp_ctx
, "");
67 name
= talloc_strdup(tmp_ctx
, full_name
);
70 if ((domain
== NULL
) || (name
== NULL
)) {
71 DEBUG(0, ("talloc failed\n"));
76 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
77 full_name
, domain
, name
));
78 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags
));
80 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
81 strequal(domain
, get_global_sam_name()))
84 /* It's our own domain, lookup the name in passdb */
85 if (lookup_global_sam_name(name
, flags
, &rid
, &type
)) {
86 sid_compose(&sid
, get_global_sam_sid(), rid
);
93 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
94 strequal(domain
, builtin_domain_name()))
96 if (strlen(name
) == 0) {
97 /* Swap domain and name */
98 tmp
= name
; name
= domain
; domain
= tmp
;
99 sid_copy(&sid
, &global_sid_Builtin
);
100 type
= SID_NAME_DOMAIN
;
104 /* Explicit request for a name in BUILTIN */
105 if (lookup_builtin_name(name
, &rid
)) {
106 sid_compose(&sid
, &global_sid_Builtin
, rid
);
107 type
= SID_NAME_ALIAS
;
110 TALLOC_FREE(tmp_ctx
);
114 /* Try the explicit winbind lookup first, don't let it guess the
115 * domain yet at this point yet. This comes later. */
117 if ((domain
[0] != '\0') &&
118 (flags
& ~(LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
)) &&
119 (winbind_lookup_name(domain
, name
, &sid
, &type
))) {
123 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
124 && strequal(domain
, unix_users_domain_name())) {
125 if (lookup_unix_user_name(name
, &sid
)) {
126 type
= SID_NAME_USER
;
129 TALLOC_FREE(tmp_ctx
);
133 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
134 && strequal(domain
, unix_groups_domain_name())) {
135 if (lookup_unix_group_name(name
, &sid
)) {
136 type
= SID_NAME_DOM_GRP
;
139 TALLOC_FREE(tmp_ctx
);
143 if ((domain
[0] == '\0') && (!(flags
& LOOKUP_NAME_ISOLATED
))) {
144 TALLOC_FREE(tmp_ctx
);
148 /* Now the guesswork begins, we haven't been given an explicit
149 * domain. Try the sequence as documented on
150 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
151 * November 27, 2005 */
153 /* 1. well-known names */
155 if ((flags
& LOOKUP_NAME_WKN
) &&
156 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
158 type
= SID_NAME_WKN_GRP
;
162 /* 2. Builtin domain as such */
164 if ((flags
& (LOOKUP_NAME_BUILTIN
|LOOKUP_NAME_REMOTE
)) &&
165 strequal(name
, builtin_domain_name()))
167 /* Swap domain and name */
168 tmp
= name
; name
= domain
; domain
= tmp
;
169 sid_copy(&sid
, &global_sid_Builtin
);
170 type
= SID_NAME_DOMAIN
;
174 /* 3. Account domain */
176 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
177 strequal(name
, get_global_sam_name()))
179 if (!secrets_fetch_domain_sid(name
, &sid
)) {
180 DEBUG(3, ("Could not fetch my SID\n"));
181 TALLOC_FREE(tmp_ctx
);
184 /* Swap domain and name */
185 tmp
= name
; name
= domain
; domain
= tmp
;
186 type
= SID_NAME_DOMAIN
;
190 /* 4. Primary domain */
192 if ((flags
& LOOKUP_NAME_DOMAIN
) && !IS_DC
&&
193 strequal(name
, lp_workgroup()))
195 if (!secrets_fetch_domain_sid(name
, &sid
)) {
196 DEBUG(3, ("Could not fetch the domain SID\n"));
197 TALLOC_FREE(tmp_ctx
);
200 /* Swap domain and name */
201 tmp
= name
; name
= domain
; domain
= tmp
;
202 type
= SID_NAME_DOMAIN
;
206 /* 5. Trusted domains as such, to me it looks as if members don't do
207 this, tested an XP workstation in a NT domain -- vl */
209 if ((flags
& LOOKUP_NAME_REMOTE
) && IS_DC
&&
210 (pdb_get_trusteddom_pw(name
, NULL
, &sid
, NULL
)))
212 /* Swap domain and name */
213 tmp
= name
; name
= domain
; domain
= tmp
;
214 type
= SID_NAME_DOMAIN
;
218 /* 6. Builtin aliases */
220 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
221 lookup_builtin_name(name
, &rid
))
223 domain
= talloc_strdup(tmp_ctx
, builtin_domain_name());
224 sid_compose(&sid
, &global_sid_Builtin
, rid
);
225 type
= SID_NAME_ALIAS
;
229 /* 7. Local systems' SAM (DCs don't have a local SAM) */
230 /* 8. Primary SAM (On members, this is the domain) */
232 /* Both cases are done by looking at our passdb */
234 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
235 lookup_global_sam_name(name
, flags
, &rid
, &type
))
237 domain
= talloc_strdup(tmp_ctx
, get_global_sam_name());
238 sid_compose(&sid
, get_global_sam_sid(), rid
);
242 /* Now our local possibilities are exhausted. */
244 if (!(flags
& LOOKUP_NAME_REMOTE
)) {
245 TALLOC_FREE(tmp_ctx
);
249 /* If we are not a DC, we have to ask in our primary domain. Let
250 * winbind do that. */
253 (winbind_lookup_name(lp_workgroup(), name
, &sid
, &type
))) {
254 domain
= talloc_strdup(tmp_ctx
, lp_workgroup());
258 /* 9. Trusted domains */
260 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
261 * that (yet), but give it a chance. */
263 if (IS_DC
&& winbind_lookup_name("", name
, &sid
, &type
)) {
264 struct dom_sid dom_sid
;
265 enum lsa_SidType domain_type
;
267 if (type
== SID_NAME_DOMAIN
) {
268 /* Swap name and type */
269 tmp
= name
; name
= domain
; domain
= tmp
;
273 /* Here we have to cope with a little deficiency in the
274 * winbind API: We have to ask it again for the name of the
275 * domain it figured out itself. Maybe fix that later... */
277 sid_copy(&dom_sid
, &sid
);
278 sid_split_rid(&dom_sid
, NULL
);
280 if (!winbind_lookup_sid(tmp_ctx
, &dom_sid
, &domain
, NULL
,
282 (domain_type
!= SID_NAME_DOMAIN
)) {
283 DEBUG(2, ("winbind could not find the domain's name "
284 "it just looked up for us\n"));
285 TALLOC_FREE(tmp_ctx
);
291 /* 10. Don't translate */
293 /* 11. Ok, windows would end here. Samba has two more options:
294 Unmapped users and unmapped groups */
296 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
297 && lookup_unix_user_name(name
, &sid
)) {
298 domain
= talloc_strdup(tmp_ctx
, unix_users_domain_name());
299 type
= SID_NAME_USER
;
303 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
304 && lookup_unix_group_name(name
, &sid
)) {
305 domain
= talloc_strdup(tmp_ctx
, unix_groups_domain_name());
306 type
= SID_NAME_DOM_GRP
;
311 * Ok, all possibilities tried. Fail.
314 TALLOC_FREE(tmp_ctx
);
318 if ((domain
== NULL
) || (name
== NULL
)) {
319 DEBUG(0, ("talloc failed\n"));
320 TALLOC_FREE(tmp_ctx
);
325 * Hand over the results to the talloc context we've been given.
328 if ((ret_name
!= NULL
) &&
329 !(*ret_name
= talloc_strdup(mem_ctx
, name
))) {
330 DEBUG(0, ("talloc failed\n"));
331 TALLOC_FREE(tmp_ctx
);
335 if (ret_domain
!= NULL
) {
337 if (!(tmp_dom
= talloc_strdup(mem_ctx
, domain
))) {
338 DEBUG(0, ("talloc failed\n"));
339 TALLOC_FREE(tmp_ctx
);
342 if (!strupper_m(tmp_dom
)) {
343 TALLOC_FREE(tmp_ctx
);
346 *ret_domain
= tmp_dom
;
349 if (ret_sid
!= NULL
) {
350 sid_copy(ret_sid
, &sid
);
353 if (ret_type
!= NULL
) {
357 TALLOC_FREE(tmp_ctx
);
361 /************************************************************************
362 Names from smb.conf can be unqualified. eg. valid users = foo
363 These names should never map to a remote name. Try global_sam_name()\foo,
364 and then "Unix Users"\foo (or "Unix Groups"\foo).
365 ************************************************************************/
367 bool lookup_name_smbconf(TALLOC_CTX
*mem_ctx
,
368 const char *full_name
, int flags
,
369 const char **ret_domain
, const char **ret_name
,
370 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
372 char *qualified_name
;
375 /* NB. No winbindd_separator here as lookup_name needs \\' */
376 if ((p
= strchr_m(full_name
, *lp_winbind_separator())) != NULL
) {
378 /* The name is already qualified with a domain. */
380 if (*lp_winbind_separator() != '\\') {
383 /* lookup_name() needs '\\' as a separator */
385 tmp
= talloc_strdup(mem_ctx
, full_name
);
389 tmp
[p
- full_name
] = '\\';
393 return lookup_name(mem_ctx
, full_name
, flags
,
394 ret_domain
, ret_name
,
398 /* Try with our own SAM name. */
399 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
400 get_global_sam_name(),
402 if (!qualified_name
) {
406 if (lookup_name(mem_ctx
, qualified_name
, flags
,
407 ret_domain
, ret_name
,
408 ret_sid
, ret_type
)) {
412 /* Finally try with "Unix Users" or "Unix Group" */
413 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
414 flags
& LOOKUP_NAME_GROUP
?
415 unix_groups_domain_name() :
416 unix_users_domain_name(),
418 if (!qualified_name
) {
422 return lookup_name(mem_ctx
, qualified_name
, flags
,
423 ret_domain
, ret_name
,
427 static bool wb_lookup_rids(TALLOC_CTX
*mem_ctx
,
428 const struct dom_sid
*domain_sid
,
429 int num_rids
, uint32
*rids
,
430 const char **domain_name
,
431 const char **names
, enum lsa_SidType
*types
)
434 const char **my_names
;
435 enum lsa_SidType
*my_types
;
438 if (!(tmp_ctx
= talloc_init("wb_lookup_rids"))) {
442 if (!winbind_lookup_rids(tmp_ctx
, domain_sid
, num_rids
, rids
,
443 domain_name
, &my_names
, &my_types
)) {
445 for (i
=0; i
<num_rids
; i
++) {
447 types
[i
] = SID_NAME_UNKNOWN
;
449 TALLOC_FREE(tmp_ctx
);
453 if (!(*domain_name
= talloc_strdup(mem_ctx
, *domain_name
))) {
454 TALLOC_FREE(tmp_ctx
);
459 * winbind_lookup_rids allocates its own array. We've been given the
460 * array, so copy it over
463 for (i
=0; i
<num_rids
; i
++) {
464 if (my_names
[i
] == NULL
) {
465 TALLOC_FREE(tmp_ctx
);
468 if (!(names
[i
] = talloc_strdup(names
, my_names
[i
]))) {
469 TALLOC_FREE(tmp_ctx
);
472 types
[i
] = my_types
[i
];
474 TALLOC_FREE(tmp_ctx
);
478 static bool lookup_rids(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*domain_sid
,
479 int num_rids
, uint32_t *rids
,
480 const char **domain_name
,
481 const char ***names
, enum lsa_SidType
**types
)
485 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
486 sid_string_dbg(domain_sid
)));
489 *names
= talloc_zero_array(mem_ctx
, const char *, num_rids
);
490 *types
= talloc_array(mem_ctx
, enum lsa_SidType
, num_rids
);
492 if ((*names
== NULL
) || (*types
== NULL
)) {
496 for (i
= 0; i
< num_rids
; i
++)
497 (*types
)[i
] = SID_NAME_UNKNOWN
;
503 if (sid_check_is_our_sam(domain_sid
)) {
506 if (*domain_name
== NULL
) {
507 *domain_name
= talloc_strdup(
508 mem_ctx
, get_global_sam_name());
511 if (*domain_name
== NULL
) {
516 result
= pdb_lookup_rids(domain_sid
, num_rids
, rids
,
520 return (NT_STATUS_IS_OK(result
) ||
521 NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
) ||
522 NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
));
525 if (sid_check_is_builtin(domain_sid
)) {
527 if (*domain_name
== NULL
) {
528 *domain_name
= talloc_strdup(
529 mem_ctx
, builtin_domain_name());
532 if (*domain_name
== NULL
) {
536 for (i
=0; i
<num_rids
; i
++) {
537 if (lookup_builtin_rid(*names
, rids
[i
],
539 if ((*names
)[i
] == NULL
) {
542 (*types
)[i
] = SID_NAME_ALIAS
;
544 (*types
)[i
] = SID_NAME_UNKNOWN
;
550 if (sid_check_is_wellknown_domain(domain_sid
, NULL
)) {
551 for (i
=0; i
<num_rids
; i
++) {
553 sid_compose(&sid
, domain_sid
, rids
[i
]);
554 if (lookup_wellknown_sid(mem_ctx
, &sid
,
555 domain_name
, &(*names
)[i
])) {
556 if ((*names
)[i
] == NULL
) {
559 (*types
)[i
] = SID_NAME_WKN_GRP
;
561 (*types
)[i
] = SID_NAME_UNKNOWN
;
567 if (sid_check_is_unix_users(domain_sid
)) {
568 if (*domain_name
== NULL
) {
569 *domain_name
= talloc_strdup(
570 mem_ctx
, unix_users_domain_name());
571 if (*domain_name
== NULL
) {
575 for (i
=0; i
<num_rids
; i
++) {
576 (*names
)[i
] = talloc_strdup(
577 (*names
), uidtoname(rids
[i
]));
578 if ((*names
)[i
] == NULL
) {
581 (*types
)[i
] = SID_NAME_USER
;
586 if (sid_check_is_unix_groups(domain_sid
)) {
587 if (*domain_name
== NULL
) {
588 *domain_name
= talloc_strdup(
589 mem_ctx
, unix_groups_domain_name());
590 if (*domain_name
== NULL
) {
594 for (i
=0; i
<num_rids
; i
++) {
595 (*names
)[i
] = talloc_strdup(
596 (*names
), gidtoname(rids
[i
]));
597 if ((*names
)[i
] == NULL
) {
600 (*types
)[i
] = SID_NAME_DOM_GRP
;
605 return wb_lookup_rids(mem_ctx
, domain_sid
, num_rids
, rids
,
606 domain_name
, *names
, *types
);
610 * Is the SID a domain as such? If yes, lookup its name.
613 static bool lookup_as_domain(const struct dom_sid
*sid
, TALLOC_CTX
*mem_ctx
,
617 enum lsa_SidType type
;
619 if (sid_check_is_our_sam(sid
)) {
620 *name
= talloc_strdup(mem_ctx
, get_global_sam_name());
624 if (sid_check_is_builtin(sid
)) {
625 *name
= talloc_strdup(mem_ctx
, builtin_domain_name());
629 if (sid_check_is_wellknown_domain(sid
, &tmp
)) {
630 *name
= talloc_strdup(mem_ctx
, tmp
);
634 if (sid_check_is_unix_users(sid
)) {
635 *name
= talloc_strdup(mem_ctx
, unix_users_domain_name());
639 if (sid_check_is_unix_groups(sid
)) {
640 *name
= talloc_strdup(mem_ctx
, unix_groups_domain_name());
644 if (sid
->num_auths
!= 4) {
645 /* This can't be a domain */
650 uint32 i
, num_domains
;
651 struct trustdom_info
**domains
;
653 /* This is relatively expensive, but it happens only on DCs
654 * and for SIDs that have 4 sub-authorities and thus look like
657 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx
,
663 for (i
=0; i
<num_domains
; i
++) {
664 if (dom_sid_equal(sid
, &domains
[i
]->sid
)) {
665 *name
= talloc_strdup(mem_ctx
,
673 if (winbind_lookup_sid(mem_ctx
, sid
, &tmp
, NULL
, &type
) &&
674 (type
== SID_NAME_DOMAIN
)) {
683 * This tries to implement the rather weird rules for the lsa_lookup level
686 * This is as close as we can get to what W2k3 does. With this we survive the
687 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
688 * different, but I assume that's just being too liberal. For example, W2k3
689 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
690 * whereas NT4 does the same as level 1 (I think). I did not fully test that
691 * with NT4, this is what w2k3 does.
693 * Level 1: Ask everywhere
694 * Level 2: Ask domain and trusted domains, no builtin and wkn
695 * Level 3: Only ask domain
696 * Level 4: W2k3ad: Only ask AD trusts
697 * Level 5: Only ask transitive forest trusts
701 static bool check_dom_sid_to_level(const struct dom_sid
*sid
, int level
)
710 ret
= (!sid_check_is_builtin(sid
) &&
711 !sid_check_is_wellknown_domain(sid
, NULL
));
716 ret
= sid_check_is_our_sam(sid
);
723 DEBUG(10, ("%s SID %s in level %d\n",
724 ret
? "Accepting" : "Rejecting",
725 sid_string_dbg(sid
), level
));
730 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
731 * references to domains, it is explicitly made for this.
733 * This attempts to be as efficient as possible: It collects all SIDs
734 * belonging to a domain and hands them in bulk to the appropriate lookup
735 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
736 * *hugely* from this.
739 NTSTATUS
lookup_sids(TALLOC_CTX
*mem_ctx
, int num_sids
,
740 const struct dom_sid
**sids
, int level
,
741 struct lsa_dom_info
**ret_domains
,
742 struct lsa_name_info
**ret_names
)
745 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
746 struct lsa_name_info
*name_infos
;
747 struct lsa_dom_info
*dom_infos
= NULL
;
751 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
752 DEBUG(0, ("talloc_new failed\n"));
753 return NT_STATUS_NO_MEMORY
;
757 name_infos
= talloc_array(mem_ctx
, struct lsa_name_info
, num_sids
);
758 if (name_infos
== NULL
) {
759 result
= NT_STATUS_NO_MEMORY
;
766 dom_infos
= talloc_zero_array(mem_ctx
, struct lsa_dom_info
,
767 LSA_REF_DOMAIN_LIST_MULTIPLIER
);
768 if (dom_infos
== NULL
) {
769 result
= NT_STATUS_NO_MEMORY
;
773 /* First build up the data structures:
775 * dom_infos is a list of domains referenced in the list of
776 * SIDs. Later we will walk the list of domains and look up the RIDs
779 * name_infos is a shadow-copy of the SIDs array to collect the real
782 * dom_info->idxs is an index into the name_infos array. The
783 * difficulty we have here is that we need to keep the SIDs the client
784 * asked for in the same order for the reply
787 for (i
=0; i
<num_sids
; i
++) {
790 const char *domain_name
= NULL
;
792 sid_copy(&sid
, sids
[i
]);
793 name_infos
[i
].type
= SID_NAME_USE_NONE
;
795 if (lookup_as_domain(&sid
, name_infos
, &domain_name
)) {
796 /* We can't push that through the normal lookup
797 * process, as this would reference illegal
800 * For example S-1-5-32 would end up referencing
801 * domain S-1-5- with RID 32 which is clearly wrong.
803 if (domain_name
== NULL
) {
804 result
= NT_STATUS_NO_MEMORY
;
808 name_infos
[i
].rid
= 0;
809 name_infos
[i
].type
= SID_NAME_DOMAIN
;
810 name_infos
[i
].name
= NULL
;
812 if (sid_check_is_builtin(&sid
)) {
813 /* Yes, W2k3 returns "BUILTIN" both as domain
815 name_infos
[i
].name
= talloc_strdup(
816 name_infos
, builtin_domain_name());
817 if (name_infos
[i
].name
== NULL
) {
818 result
= NT_STATUS_NO_MEMORY
;
823 /* This is a normal SID with rid component */
824 if (!sid_split_rid(&sid
, &rid
)) {
825 result
= NT_STATUS_INVALID_SID
;
830 if (!check_dom_sid_to_level(&sid
, level
)) {
831 name_infos
[i
].rid
= 0;
832 name_infos
[i
].type
= SID_NAME_UNKNOWN
;
833 name_infos
[i
].name
= NULL
;
837 for (j
=0; j
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; j
++) {
838 if (!dom_infos
[j
].valid
) {
841 if (dom_sid_equal(&sid
, &dom_infos
[j
].sid
)) {
846 if (j
== LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
847 /* TODO: What's the right error message here? */
848 result
= NT_STATUS_NONE_MAPPED
;
852 if (!dom_infos
[j
].valid
) {
853 /* We found a domain not yet referenced, create a new
855 dom_infos
[j
].valid
= true;
856 sid_copy(&dom_infos
[j
].sid
, &sid
);
858 if (domain_name
!= NULL
) {
859 /* This name was being found above in the case
860 * when we found a domain SID */
862 talloc_strdup(dom_infos
, domain_name
);
863 if (dom_infos
[j
].name
== NULL
) {
864 result
= NT_STATUS_NO_MEMORY
;
868 /* lookup_rids will take care of this */
869 dom_infos
[j
].name
= NULL
;
873 name_infos
[i
].dom_idx
= j
;
875 if (name_infos
[i
].type
== SID_NAME_USE_NONE
) {
876 name_infos
[i
].rid
= rid
;
878 ADD_TO_ARRAY(dom_infos
, int, i
, &dom_infos
[j
].idxs
,
879 &dom_infos
[j
].num_idxs
);
881 if (dom_infos
[j
].idxs
== NULL
) {
882 result
= NT_STATUS_NO_MEMORY
;
888 /* Iterate over the domains found */
890 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
892 const char *domain_name
= NULL
;
894 enum lsa_SidType
*types
;
895 struct lsa_dom_info
*dom
= &dom_infos
[i
];
898 /* No domains left, we're done */
903 if (!(rids
= talloc_array(tmp_ctx
, uint32
, dom
->num_idxs
))) {
904 result
= NT_STATUS_NO_MEMORY
;
911 for (j
=0; j
<dom
->num_idxs
; j
++) {
912 rids
[j
] = name_infos
[dom
->idxs
[j
]].rid
;
915 if (!lookup_rids(tmp_ctx
, &dom
->sid
,
916 dom
->num_idxs
, rids
, &domain_name
,
918 result
= NT_STATUS_NO_MEMORY
;
922 if (!(dom
->name
= talloc_strdup(dom_infos
, domain_name
))) {
923 result
= NT_STATUS_NO_MEMORY
;
927 for (j
=0; j
<dom
->num_idxs
; j
++) {
928 int idx
= dom
->idxs
[j
];
929 name_infos
[idx
].type
= types
[j
];
930 if (types
[j
] != SID_NAME_UNKNOWN
) {
931 name_infos
[idx
].name
=
932 talloc_strdup(name_infos
, names
[j
]);
933 if (name_infos
[idx
].name
== NULL
) {
934 result
= NT_STATUS_NO_MEMORY
;
938 name_infos
[idx
].name
= NULL
;
943 *ret_domains
= dom_infos
;
944 *ret_names
= name_infos
;
945 TALLOC_FREE(tmp_ctx
);
949 TALLOC_FREE(dom_infos
);
950 TALLOC_FREE(name_infos
);
951 TALLOC_FREE(tmp_ctx
);
955 /*****************************************************************
956 *THE CANONICAL* convert SID to name function.
957 *****************************************************************/
959 bool lookup_sid(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*sid
,
960 const char **ret_domain
, const char **ret_name
,
961 enum lsa_SidType
*ret_type
)
963 struct lsa_dom_info
*domain
;
964 struct lsa_name_info
*name
;
968 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid
)));
970 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
971 DEBUG(0, ("talloc_new failed\n"));
975 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx
, 1, &sid
, 1,
980 if (name
->type
== SID_NAME_UNKNOWN
) {
984 if ((ret_domain
!= NULL
) &&
985 !(*ret_domain
= talloc_strdup(mem_ctx
, domain
->name
))) {
989 if ((ret_name
!= NULL
) &&
990 !(*ret_name
= talloc_strdup(mem_ctx
, name
->name
))) {
994 if (ret_type
!= NULL
) {
995 *ret_type
= name
->type
;
1002 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid
),
1003 domain
->name
, name
->name
, name
->type
));
1005 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid
)));
1007 TALLOC_FREE(tmp_ctx
);
1011 /*****************************************************************
1012 Id mapping cache. This is to avoid Winbind mappings already
1013 seen by smbd to be queried too frequently, keeping winbindd
1014 busy, and blocking smbd while winbindd is busy with other
1015 stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1016 modified to use linked lists by jra.
1017 *****************************************************************/
1020 /*****************************************************************
1021 *THE LEGACY* convert uid_t to SID function.
1022 *****************************************************************/
1024 static void legacy_uid_to_sid(struct dom_sid
*psid
, uid_t uid
)
1031 ret
= pdb_uid_to_sid(uid
, psid
);
1035 /* This is a mapped user */
1039 /* This is an unmapped user */
1041 uid_to_unix_users_sid(uid
, psid
);
1044 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid
,
1045 sid_string_dbg(psid
)));
1050 /*****************************************************************
1051 *THE LEGACY* convert gid_t to SID function.
1052 *****************************************************************/
1054 static void legacy_gid_to_sid(struct dom_sid
*psid
, gid_t gid
)
1061 ret
= pdb_gid_to_sid(gid
, psid
);
1065 /* This is a mapped group */
1069 /* This is an unmapped group */
1071 gid_to_unix_groups_sid(gid
, psid
);
1074 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid
,
1075 sid_string_dbg(psid
)));
1080 /*****************************************************************
1081 *THE LEGACY* convert SID to id function.
1082 *****************************************************************/
1084 static bool legacy_sid_to_unixid(const struct dom_sid
*psid
, struct unixid
*id
)
1090 ret
= pdb_sid_to_id(psid
, id
);
1097 if ((sid_check_is_in_builtin(psid
) ||
1098 sid_check_is_in_wellknown_domain(psid
))) {
1099 map
= talloc_zero(NULL
, GROUP_MAP
);
1105 ret
= pdb_getgrsid(map
, *psid
);
1110 id
->type
= ID_TYPE_GID
;
1115 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1116 sid_string_dbg(psid
)));
1120 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1121 sid_string_dbg(psid
)));
1128 static bool legacy_sid_to_gid(const struct dom_sid
*psid
, gid_t
*pgid
)
1131 if (!legacy_sid_to_unixid(psid
, &id
)) {
1134 if (id
.type
== ID_TYPE_GID
|| id
.type
== ID_TYPE_BOTH
) {
1141 static bool legacy_sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1144 if (!legacy_sid_to_unixid(psid
, &id
)) {
1147 if (id
.type
== ID_TYPE_UID
|| id
.type
== ID_TYPE_BOTH
) {
1154 /*****************************************************************
1155 *THE CANONICAL* convert uid_t to SID function.
1156 *****************************************************************/
1158 void uid_to_sid(struct dom_sid
*psid
, uid_t uid
)
1160 bool expired
= true;
1164 /* Check the winbindd cache directly. */
1165 ret
= idmap_cache_find_uid2sid(uid
, psid
, &expired
);
1167 if (ret
&& !expired
&& is_null_sid(psid
)) {
1169 * Negative cache entry, we already asked.
1172 legacy_uid_to_sid(psid
, uid
);
1176 if (!ret
|| expired
) {
1177 /* Not in cache. Ask winbindd. */
1178 if (!winbind_uid_to_sid(psid
, uid
)) {
1180 * We shouldn't return the NULL SID
1181 * here if winbind was running and
1182 * couldn't map, as winbind will have
1183 * added a negative entry that will
1184 * cause us to go though the
1185 * legacy_uid_to_sid()
1186 * function anyway in the case above
1187 * the next time we ask.
1189 DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1190 "for uid %u\n", (unsigned int)uid
));
1192 legacy_uid_to_sid(psid
, uid
);
1197 DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid
,
1198 sid_string_dbg(psid
)));
1203 /*****************************************************************
1204 *THE CANONICAL* convert gid_t to SID function.
1205 *****************************************************************/
1207 void gid_to_sid(struct dom_sid
*psid
, gid_t gid
)
1209 bool expired
= true;
1213 /* Check the winbindd cache directly. */
1214 ret
= idmap_cache_find_gid2sid(gid
, psid
, &expired
);
1216 if (ret
&& !expired
&& is_null_sid(psid
)) {
1218 * Negative cache entry, we already asked.
1221 legacy_gid_to_sid(psid
, gid
);
1225 if (!ret
|| expired
) {
1226 /* Not in cache. Ask winbindd. */
1227 if (!winbind_gid_to_sid(psid
, gid
)) {
1229 * We shouldn't return the NULL SID
1230 * here if winbind was running and
1231 * couldn't map, as winbind will have
1232 * added a negative entry that will
1233 * cause us to go though the
1234 * legacy_gid_to_sid()
1235 * function anyway in the case above
1236 * the next time we ask.
1238 DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1239 "for gid %u\n", (unsigned int)gid
));
1241 legacy_gid_to_sid(psid
, gid
);
1246 DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid
,
1247 sid_string_dbg(psid
)));
1252 bool sids_to_unixids(const struct dom_sid
*sids
, uint32_t num_sids
,
1255 struct wbcDomainSid
*wbc_sids
= NULL
;
1256 struct wbcUnixId
*wbc_ids
= NULL
;
1257 uint32_t i
, num_not_cached
;
1261 wbc_sids
= talloc_array(talloc_tos(), struct wbcDomainSid
, num_sids
);
1262 if (wbc_sids
== NULL
) {
1268 for (i
=0; i
<num_sids
; i
++) {
1272 if (sid_peek_check_rid(&global_sid_Unix_Users
,
1274 ids
[i
].type
= ID_TYPE_UID
;
1278 if (sid_peek_check_rid(&global_sid_Unix_Groups
,
1280 ids
[i
].type
= ID_TYPE_GID
;
1284 if (idmap_cache_find_sid2unixid(&sids
[i
], &ids
[i
], &expired
)
1289 ids
[i
].type
= ID_TYPE_NOT_SPECIFIED
;
1290 memcpy(&wbc_sids
[num_not_cached
], &sids
[i
],
1291 ndr_size_dom_sid(&sids
[i
], 0));
1292 num_not_cached
+= 1;
1294 if (num_not_cached
== 0) {
1297 wbc_ids
= talloc_array(talloc_tos(), struct wbcUnixId
, num_not_cached
);
1298 if (wbc_ids
== NULL
) {
1301 for (i
=0; i
<num_not_cached
; i
++) {
1302 wbc_ids
[i
].type
= WBC_ID_TYPE_NOT_SPECIFIED
;
1304 err
= wbcSidsToUnixIds(wbc_sids
, num_not_cached
, wbc_ids
);
1305 if (!WBC_ERROR_IS_OK(err
)) {
1306 DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1307 wbcErrorString(err
)));
1312 for (i
=0; i
<num_sids
; i
++) {
1313 if (ids
[i
].type
== ID_TYPE_NOT_SPECIFIED
) {
1314 switch (wbc_ids
[num_not_cached
].type
) {
1315 case WBC_ID_TYPE_UID
:
1316 ids
[i
].type
= ID_TYPE_UID
;
1317 ids
[i
].id
= wbc_ids
[num_not_cached
].id
.uid
;
1319 case WBC_ID_TYPE_GID
:
1320 ids
[i
].type
= ID_TYPE_GID
;
1321 ids
[i
].id
= wbc_ids
[num_not_cached
].id
.gid
;
1324 /* The types match, and wbcUnixId -> id is a union anyway */
1325 ids
[i
].type
= (enum id_type
)wbc_ids
[num_not_cached
].type
;
1326 ids
[i
].id
= wbc_ids
[num_not_cached
].id
.gid
;
1329 num_not_cached
+= 1;
1333 for (i
=0; i
<num_sids
; i
++) {
1334 if (ids
[i
].type
!= ID_TYPE_NOT_SPECIFIED
) {
1337 if (legacy_sid_to_gid(&sids
[i
], &ids
[i
].id
)) {
1338 ids
[i
].type
= ID_TYPE_GID
;
1341 if (legacy_sid_to_uid(&sids
[i
], &ids
[i
].id
)) {
1342 ids
[i
].type
= ID_TYPE_UID
;
1347 for (i
=0; i
<num_sids
; i
++) {
1348 switch(ids
[i
].type
) {
1349 case WBC_ID_TYPE_GID
:
1350 case WBC_ID_TYPE_UID
:
1351 case WBC_ID_TYPE_BOTH
:
1352 if (ids
[i
].id
== -1) {
1353 ids
[i
].type
= ID_TYPE_NOT_SPECIFIED
;
1356 case WBC_ID_TYPE_NOT_SPECIFIED
:
1363 TALLOC_FREE(wbc_ids
);
1364 TALLOC_FREE(wbc_sids
);
1368 /*****************************************************************
1369 *THE CANONICAL* convert SID to uid function.
1370 *****************************************************************/
1372 bool sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1374 bool expired
= true;
1378 /* Optimize for the Unix Users Domain
1379 * as the conversion is straightforward */
1380 if (sid_peek_check_rid(&global_sid_Unix_Users
, psid
, &rid
)) {
1384 /* return here, don't cache */
1385 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1386 (unsigned int)*puid
));
1390 /* Check the winbindd cache directly. */
1391 ret
= idmap_cache_find_sid2uid(psid
, puid
, &expired
);
1393 if (ret
&& !expired
&& (*puid
== (uid_t
)-1)) {
1395 * Negative cache entry, we already asked.
1398 return legacy_sid_to_uid(psid
, puid
);
1401 if (!ret
|| expired
) {
1402 /* Not in cache. Ask winbindd. */
1403 if (!winbind_sid_to_uid(puid
, psid
)) {
1404 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1405 sid_string_dbg(psid
)));
1406 /* winbind failed. do legacy */
1407 return legacy_sid_to_uid(psid
, puid
);
1411 /* TODO: Here would be the place to allocate both a gid and a uid for
1412 * the SID in question */
1414 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1415 (unsigned int)*puid
));
1420 /*****************************************************************
1421 *THE CANONICAL* convert SID to gid function.
1422 Group mapping is used for gids that maps to Wellknown SIDs
1423 *****************************************************************/
1425 bool sid_to_gid(const struct dom_sid
*psid
, gid_t
*pgid
)
1427 bool expired
= true;
1431 /* Optimize for the Unix Groups Domain
1432 * as the conversion is straightforward */
1433 if (sid_peek_check_rid(&global_sid_Unix_Groups
, psid
, &rid
)) {
1437 /* return here, don't cache */
1438 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1439 (unsigned int)*pgid
));
1443 /* Check the winbindd cache directly. */
1444 ret
= idmap_cache_find_sid2gid(psid
, pgid
, &expired
);
1446 if (ret
&& !expired
&& (*pgid
== (gid_t
)-1)) {
1448 * Negative cache entry, we already asked.
1451 return legacy_sid_to_gid(psid
, pgid
);
1454 if (!ret
|| expired
) {
1455 /* Not in cache or negative. Ask winbindd. */
1456 /* Ask winbindd if it can map this sid to a gid.
1457 * (Idmap will check it is a valid SID and of the right type) */
1459 if ( !winbind_sid_to_gid(pgid
, psid
) ) {
1461 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1462 sid_string_dbg(psid
)));
1463 /* winbind failed. do legacy */
1464 return legacy_sid_to_gid(psid
, pgid
);
1468 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1469 (unsigned int)*pgid
));
1475 * @brief This function gets the primary group SID mapping the primary
1476 * GID of the user as obtained by an actual getpwnam() call.
1477 * This is necessary to avoid issues with arbitrary group SIDs
1478 * stored in passdb. We try as hard as we can to get the SID
1479 * corresponding to the GID, including trying group mapping.
1480 * If nothing else works, we will force "Domain Users" as the
1482 * This is needed because we must always be able to lookup the
1483 * primary group SID, so we cannot settle for an arbitrary SID.
1485 * This call can be expensive. Use with moderation.
1486 * If you have a "samu" struct around use pdb_get_group_sid()
1487 * instead as it does properly cache results.
1489 * @param mem_ctx[in] The memory context iused to allocate the result.
1490 * @param username[in] The user's name
1491 * @param _pwd[in|out] If available, pass in user's passwd struct.
1492 * It will contain a tallocated passwd if NULL was
1494 * @param _group_sid[out] The user's Primary Group SID
1496 * @return NTSTATUS error code.
1498 NTSTATUS
get_primary_group_sid(TALLOC_CTX
*mem_ctx
,
1499 const char *username
,
1500 struct passwd
**_pwd
,
1501 struct dom_sid
**_group_sid
)
1503 TALLOC_CTX
*tmp_ctx
;
1504 bool need_lookup_sid
= false;
1505 struct dom_sid
*group_sid
;
1506 struct passwd
*pwd
= *_pwd
;
1508 tmp_ctx
= talloc_new(mem_ctx
);
1510 return NT_STATUS_NO_MEMORY
;
1514 pwd
= Get_Pwnam_alloc(mem_ctx
, username
);
1516 DEBUG(0, ("Failed to find a Unix account for %s",
1518 TALLOC_FREE(tmp_ctx
);
1519 return NT_STATUS_NO_SUCH_USER
;
1523 group_sid
= talloc_zero(mem_ctx
, struct dom_sid
);
1525 TALLOC_FREE(tmp_ctx
);
1526 return NT_STATUS_NO_MEMORY
;
1529 gid_to_sid(group_sid
, pwd
->pw_gid
);
1530 if (!is_null_sid(group_sid
)) {
1531 struct dom_sid domain_sid
;
1534 /* We need a sid within our domain */
1535 sid_copy(&domain_sid
, group_sid
);
1536 sid_split_rid(&domain_sid
, &rid
);
1537 if (dom_sid_equal(&domain_sid
, get_global_sam_sid())) {
1539 * As shortcut for the expensive lookup_sid call
1540 * compare the domain sid part
1543 case DOMAIN_RID_ADMINS
:
1544 case DOMAIN_RID_USERS
:
1547 need_lookup_sid
= true;
1551 /* Try group mapping */
1552 ZERO_STRUCTP(group_sid
);
1553 if (pdb_gid_to_sid(pwd
->pw_gid
, group_sid
)) {
1554 need_lookup_sid
= true;
1559 /* We must verify that this is a valid SID that resolves to a
1560 * group of the correct type */
1561 if (need_lookup_sid
) {
1562 enum lsa_SidType type
= SID_NAME_UNKNOWN
;
1565 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1566 sid_string_dbg(group_sid
), username
));
1568 /* Now check that it's actually a domain group and
1569 * not something else */
1570 lookup_ret
= lookup_sid(tmp_ctx
, group_sid
,
1573 if (lookup_ret
&& (type
== SID_NAME_DOM_GRP
)) {
1577 DEBUG(3, ("Primary group %s for user %s is"
1578 " a %s and not a domain group\n",
1579 sid_string_dbg(group_sid
), username
,
1580 sid_type_lookup(type
)));
1583 /* Everything else, failed.
1584 * Just set it to the 'Domain Users' RID of 513 which will
1585 always resolve to a name */
1586 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1589 sid_compose(group_sid
, get_global_sam_sid(), DOMAIN_RID_USERS
);
1592 *_pwd
= talloc_move(mem_ctx
, &pwd
);
1593 *_group_sid
= talloc_move(mem_ctx
, &group_sid
);
1594 TALLOC_FREE(tmp_ctx
);
1595 return NT_STATUS_OK
;