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 "lib/util_unixsids.h"
25 #include "../librpc/gen_ndr/ndr_security.h"
27 #include "../lib/util/memcache.h"
28 #include "idmap_cache.h"
29 #include "../libcli/security/security.h"
30 #include "lib/winbind_util.h"
31 #include "../librpc/gen_ndr/idmap.h"
33 static bool lookup_unix_user_name(const char *name
, struct dom_sid
*sid
)
38 pwd
= Get_Pwnam_alloc(talloc_tos(), name
);
44 * For 64-bit uid's we have enough space in the whole SID,
45 * should they become necessary
47 ret
= sid_compose(sid
, &global_sid_Unix_Users
, pwd
->pw_uid
);
52 static bool lookup_unix_group_name(const char *name
, struct dom_sid
*sid
)
62 * For 64-bit gid's we have enough space in the whole SID,
63 * should they become necessary
65 return sid_compose(sid
, &global_sid_Unix_Groups
, grp
->gr_gid
);
68 /*****************************************************************
69 Dissect a user-provided name into domain, name, sid and type.
71 If an explicit domain name was given in the form domain\user, it
72 has to try that. If no explicit domain name was given, we have
74 *****************************************************************/
76 bool lookup_name(TALLOC_CTX
*mem_ctx
,
77 const char *full_name
, int flags
,
78 const char **ret_domain
, const char **ret_name
,
79 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
83 const char *domain
= NULL
;
84 const char *name
= NULL
;
87 enum lsa_SidType type
;
88 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
90 if (tmp_ctx
== NULL
) {
91 DEBUG(0, ("talloc_new failed\n"));
95 p
= strchr_m(full_name
, '\\');
98 domain
= talloc_strndup(tmp_ctx
, full_name
,
99 PTR_DIFF(p
, full_name
));
100 name
= talloc_strdup(tmp_ctx
, p
+1);
102 domain
= talloc_strdup(tmp_ctx
, "");
103 name
= talloc_strdup(tmp_ctx
, full_name
);
106 if ((domain
== NULL
) || (name
== NULL
)) {
107 DEBUG(0, ("talloc failed\n"));
108 TALLOC_FREE(tmp_ctx
);
112 DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
113 full_name
, domain
, name
));
114 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags
));
116 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
117 strequal(domain
, get_global_sam_name()))
120 /* It's our own domain, lookup the name in passdb */
121 if (lookup_global_sam_name(name
, flags
, &rid
, &type
)) {
122 sid_compose(&sid
, get_global_sam_sid(), rid
);
125 TALLOC_FREE(tmp_ctx
);
129 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
130 strequal(domain
, builtin_domain_name()))
132 if (strlen(name
) == 0) {
133 /* Swap domain and name */
134 tmp
= name
; name
= domain
; domain
= tmp
;
135 sid_copy(&sid
, &global_sid_Builtin
);
136 type
= SID_NAME_DOMAIN
;
140 /* Explicit request for a name in BUILTIN */
141 if (lookup_builtin_name(name
, &rid
)) {
142 sid_compose(&sid
, &global_sid_Builtin
, rid
);
143 type
= SID_NAME_ALIAS
;
146 TALLOC_FREE(tmp_ctx
);
150 /* Try the explicit winbind lookup first, don't let it guess the
151 * domain yet at this point yet. This comes later. */
153 if ((domain
[0] != '\0') &&
154 (flags
& ~(LOOKUP_NAME_DOMAIN
|LOOKUP_NAME_ISOLATED
)) &&
155 (winbind_lookup_name(domain
, name
, &sid
, &type
))) {
159 if (((flags
& (LOOKUP_NAME_NO_NSS
|LOOKUP_NAME_GROUP
)) == 0)
160 && strequal(domain
, unix_users_domain_name())) {
161 if (lookup_unix_user_name(name
, &sid
)) {
162 type
= SID_NAME_USER
;
165 TALLOC_FREE(tmp_ctx
);
169 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
170 && strequal(domain
, unix_groups_domain_name())) {
171 if (lookup_unix_group_name(name
, &sid
)) {
172 type
= SID_NAME_DOM_GRP
;
175 TALLOC_FREE(tmp_ctx
);
180 * Finally check for a well known domain name ("NT Authority"),
181 * this is being taken care of in lookup_wellknown_name().
183 if ((domain
[0] != '\0') &&
184 (flags
& LOOKUP_NAME_WKN
) &&
185 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
187 type
= SID_NAME_WKN_GRP
;
192 * If we're told not to look up 'isolated' names then we're
195 if (!(flags
& LOOKUP_NAME_ISOLATED
)) {
196 TALLOC_FREE(tmp_ctx
);
201 * No domain names beyond this point
203 if (domain
[0] != '\0') {
204 TALLOC_FREE(tmp_ctx
);
208 /* Now the guesswork begins, we haven't been given an explicit
209 * domain. Try the sequence as documented on
210 * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
211 * November 27, 2005 */
213 /* 1. well-known names */
216 * Check for well known names without a domain name.
217 * e.g. \Creator Owner.
220 if ((flags
& LOOKUP_NAME_WKN
) &&
221 lookup_wellknown_name(tmp_ctx
, name
, &sid
, &domain
))
223 type
= SID_NAME_WKN_GRP
;
227 /* 2. Builtin domain as such */
229 if ((flags
& (LOOKUP_NAME_BUILTIN
|LOOKUP_NAME_REMOTE
)) &&
230 strequal(name
, builtin_domain_name()))
232 /* Swap domain and name */
233 tmp
= name
; name
= domain
; domain
= tmp
;
234 sid_copy(&sid
, &global_sid_Builtin
);
235 type
= SID_NAME_DOMAIN
;
239 /* 3. Account domain */
241 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
242 strequal(name
, get_global_sam_name()))
244 if (!secrets_fetch_domain_sid(name
, &sid
)) {
245 DEBUG(3, ("Could not fetch my SID\n"));
246 TALLOC_FREE(tmp_ctx
);
249 /* Swap domain and name */
250 tmp
= name
; name
= domain
; domain
= tmp
;
251 type
= SID_NAME_DOMAIN
;
255 /* 4. Primary domain */
257 if ((flags
& LOOKUP_NAME_DOMAIN
) && !IS_DC
&&
258 strequal(name
, lp_workgroup()))
260 if (!secrets_fetch_domain_sid(name
, &sid
)) {
261 DEBUG(3, ("Could not fetch the domain SID\n"));
262 TALLOC_FREE(tmp_ctx
);
265 /* Swap domain and name */
266 tmp
= name
; name
= domain
; domain
= tmp
;
267 type
= SID_NAME_DOMAIN
;
271 /* 5. Trusted domains as such, to me it looks as if members don't do
272 this, tested an XP workstation in a NT domain -- vl */
274 if ((flags
& LOOKUP_NAME_REMOTE
) && IS_DC
&&
275 (pdb_get_trusteddom_pw(name
, NULL
, &sid
, NULL
)))
277 /* Swap domain and name */
278 tmp
= name
; name
= domain
; domain
= tmp
;
279 type
= SID_NAME_DOMAIN
;
283 /* 6. Builtin aliases */
285 if ((flags
& LOOKUP_NAME_BUILTIN
) &&
286 lookup_builtin_name(name
, &rid
))
288 domain
= talloc_strdup(tmp_ctx
, builtin_domain_name());
289 sid_compose(&sid
, &global_sid_Builtin
, rid
);
290 type
= SID_NAME_ALIAS
;
294 /* 7. Local systems' SAM (DCs don't have a local SAM) */
295 /* 8. Primary SAM (On members, this is the domain) */
297 /* Both cases are done by looking at our passdb */
299 if ((flags
& LOOKUP_NAME_DOMAIN
) &&
300 lookup_global_sam_name(name
, flags
, &rid
, &type
))
302 domain
= talloc_strdup(tmp_ctx
, get_global_sam_name());
303 sid_compose(&sid
, get_global_sam_sid(), rid
);
307 /* Now our local possibilities are exhausted. */
309 if (!(flags
& LOOKUP_NAME_REMOTE
)) {
310 TALLOC_FREE(tmp_ctx
);
314 /* If we are not a DC, we have to ask in our primary domain. Let
315 * winbind do that. */
318 (winbind_lookup_name(lp_workgroup(), name
, &sid
, &type
))) {
319 domain
= talloc_strdup(tmp_ctx
, lp_workgroup());
323 /* 9. Trusted domains */
325 /* If we're a DC we have to ask all trusted DC's. Winbind does not do
326 * that (yet), but give it a chance. */
328 if (IS_DC
&& winbind_lookup_name("", name
, &sid
, &type
)) {
329 struct dom_sid dom_sid
;
330 enum lsa_SidType domain_type
;
332 if (type
== SID_NAME_DOMAIN
) {
333 /* Swap name and type */
334 tmp
= name
; name
= domain
; domain
= tmp
;
338 /* Here we have to cope with a little deficiency in the
339 * winbind API: We have to ask it again for the name of the
340 * domain it figured out itself. Maybe fix that later... */
342 sid_copy(&dom_sid
, &sid
);
343 sid_split_rid(&dom_sid
, NULL
);
345 if (!winbind_lookup_sid(tmp_ctx
, &dom_sid
, &domain
, NULL
,
347 (domain_type
!= SID_NAME_DOMAIN
)) {
348 DEBUG(2, ("winbind could not find the domain's name "
349 "it just looked up for us\n"));
350 TALLOC_FREE(tmp_ctx
);
356 /* 10. Don't translate */
358 /* 11. Ok, windows would end here. Samba has two more options:
359 Unmapped users and unmapped groups */
361 if (((flags
& (LOOKUP_NAME_NO_NSS
|LOOKUP_NAME_GROUP
)) == 0)
362 && lookup_unix_user_name(name
, &sid
)) {
363 domain
= talloc_strdup(tmp_ctx
, unix_users_domain_name());
364 type
= SID_NAME_USER
;
368 if (((flags
& LOOKUP_NAME_NO_NSS
) == 0)
369 && lookup_unix_group_name(name
, &sid
)) {
370 domain
= talloc_strdup(tmp_ctx
, unix_groups_domain_name());
371 type
= SID_NAME_DOM_GRP
;
376 * Ok, all possibilities tried. Fail.
379 TALLOC_FREE(tmp_ctx
);
383 if ((domain
== NULL
) || (name
== NULL
)) {
384 DEBUG(0, ("talloc failed\n"));
385 TALLOC_FREE(tmp_ctx
);
390 * Hand over the results to the talloc context we've been given.
393 if ((ret_name
!= NULL
) &&
394 !(*ret_name
= talloc_strdup(mem_ctx
, name
))) {
395 DEBUG(0, ("talloc failed\n"));
396 TALLOC_FREE(tmp_ctx
);
400 if (ret_domain
!= NULL
) {
402 if (!(tmp_dom
= talloc_strdup(mem_ctx
, domain
))) {
403 DEBUG(0, ("talloc failed\n"));
404 TALLOC_FREE(tmp_ctx
);
407 if (!strupper_m(tmp_dom
)) {
408 TALLOC_FREE(tmp_ctx
);
411 *ret_domain
= tmp_dom
;
414 if (ret_sid
!= NULL
) {
415 sid_copy(ret_sid
, &sid
);
418 if (ret_type
!= NULL
) {
422 TALLOC_FREE(tmp_ctx
);
426 /************************************************************************
427 Names from smb.conf can be unqualified. eg. valid users = foo
428 These names should never map to a remote name. Try global_sam_name()\foo,
429 and then "Unix Users"\foo (or "Unix Groups"\foo).
430 ************************************************************************/
432 bool lookup_name_smbconf(TALLOC_CTX
*mem_ctx
,
433 const char *full_name
, int flags
,
434 const char **ret_domain
, const char **ret_name
,
435 struct dom_sid
*ret_sid
, enum lsa_SidType
*ret_type
)
437 char *qualified_name
;
440 if ((p
= strchr_m(full_name
, *lp_winbind_separator())) != NULL
) {
442 /* The name is already qualified with a domain. */
444 if (*lp_winbind_separator() != '\\') {
447 /* lookup_name() needs '\\' as a separator */
449 tmp
= talloc_strdup(mem_ctx
, full_name
);
453 tmp
[p
- full_name
] = '\\';
457 return lookup_name(mem_ctx
, full_name
, flags
,
458 ret_domain
, ret_name
,
462 /* Try with winbind default domain name. */
463 if (lp_winbind_use_default_domain()) {
466 qualified_name
= talloc_asprintf(mem_ctx
,
470 if (qualified_name
== NULL
) {
474 ok
= lookup_name(mem_ctx
,
486 /* Try with our own SAM name. */
487 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
488 get_global_sam_name(),
490 if (!qualified_name
) {
494 if (lookup_name(mem_ctx
, qualified_name
, flags
,
495 ret_domain
, ret_name
,
496 ret_sid
, ret_type
)) {
500 /* Finally try with "Unix Users" or "Unix Group" */
501 qualified_name
= talloc_asprintf(mem_ctx
, "%s\\%s",
502 flags
& LOOKUP_NAME_GROUP
?
503 unix_groups_domain_name() :
504 unix_users_domain_name(),
506 if (!qualified_name
) {
510 return lookup_name(mem_ctx
, qualified_name
, flags
,
511 ret_domain
, ret_name
,
515 static bool wb_lookup_rids(TALLOC_CTX
*mem_ctx
,
516 const struct dom_sid
*domain_sid
,
517 int num_rids
, uint32_t *rids
,
518 const char **domain_name
,
519 const char **names
, enum lsa_SidType
*types
)
522 const char **my_names
;
523 enum lsa_SidType
*my_types
;
526 if (!(tmp_ctx
= talloc_init("wb_lookup_rids"))) {
530 if (!winbind_lookup_rids(tmp_ctx
, domain_sid
, num_rids
, rids
,
531 domain_name
, &my_names
, &my_types
)) {
533 for (i
=0; i
<num_rids
; i
++) {
535 types
[i
] = SID_NAME_UNKNOWN
;
537 TALLOC_FREE(tmp_ctx
);
541 if (!(*domain_name
= talloc_strdup(mem_ctx
, *domain_name
))) {
542 TALLOC_FREE(tmp_ctx
);
547 * winbind_lookup_rids allocates its own array. We've been given the
548 * array, so copy it over
551 for (i
=0; i
<num_rids
; i
++) {
552 if (my_names
[i
] == NULL
) {
553 TALLOC_FREE(tmp_ctx
);
556 if (!(names
[i
] = talloc_strdup(names
, my_names
[i
]))) {
557 TALLOC_FREE(tmp_ctx
);
560 types
[i
] = my_types
[i
];
562 TALLOC_FREE(tmp_ctx
);
566 static bool lookup_rids(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*domain_sid
,
567 int num_rids
, uint32_t *rids
,
568 const char **domain_name
,
569 const char ***names
, enum lsa_SidType
**types
)
573 DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
574 sid_string_dbg(domain_sid
)));
577 *names
= talloc_zero_array(mem_ctx
, const char *, num_rids
);
578 *types
= talloc_array(mem_ctx
, enum lsa_SidType
, num_rids
);
580 if ((*names
== NULL
) || (*types
== NULL
)) {
584 for (i
= 0; i
< num_rids
; i
++)
585 (*types
)[i
] = SID_NAME_UNKNOWN
;
591 if (sid_check_is_our_sam(domain_sid
)) {
594 if (*domain_name
== NULL
) {
595 *domain_name
= talloc_strdup(
596 mem_ctx
, get_global_sam_name());
599 if (*domain_name
== NULL
) {
604 result
= pdb_lookup_rids(domain_sid
, num_rids
, rids
,
608 return (NT_STATUS_IS_OK(result
) ||
609 NT_STATUS_EQUAL(result
, NT_STATUS_NONE_MAPPED
) ||
610 NT_STATUS_EQUAL(result
, STATUS_SOME_UNMAPPED
));
613 if (sid_check_is_builtin(domain_sid
)) {
615 if (*domain_name
== NULL
) {
616 *domain_name
= talloc_strdup(
617 mem_ctx
, builtin_domain_name());
620 if (*domain_name
== NULL
) {
624 for (i
=0; i
<num_rids
; i
++) {
625 if (lookup_builtin_rid(*names
, rids
[i
],
627 if ((*names
)[i
] == NULL
) {
630 (*types
)[i
] = SID_NAME_ALIAS
;
632 (*types
)[i
] = SID_NAME_UNKNOWN
;
638 if (sid_check_is_wellknown_domain(domain_sid
, NULL
)) {
639 for (i
=0; i
<num_rids
; i
++) {
641 sid_compose(&sid
, domain_sid
, rids
[i
]);
642 if (lookup_wellknown_sid(mem_ctx
, &sid
,
643 domain_name
, &(*names
)[i
])) {
644 if ((*names
)[i
] == NULL
) {
647 (*types
)[i
] = SID_NAME_WKN_GRP
;
649 (*types
)[i
] = SID_NAME_UNKNOWN
;
655 if (sid_check_is_unix_users(domain_sid
)) {
656 if (*domain_name
== NULL
) {
657 *domain_name
= talloc_strdup(
658 mem_ctx
, unix_users_domain_name());
659 if (*domain_name
== NULL
) {
663 for (i
=0; i
<num_rids
; i
++) {
664 (*names
)[i
] = talloc_strdup(
665 (*names
), uidtoname(rids
[i
]));
666 if ((*names
)[i
] == NULL
) {
669 (*types
)[i
] = SID_NAME_USER
;
674 if (sid_check_is_unix_groups(domain_sid
)) {
675 if (*domain_name
== NULL
) {
676 *domain_name
= talloc_strdup(
677 mem_ctx
, unix_groups_domain_name());
678 if (*domain_name
== NULL
) {
682 for (i
=0; i
<num_rids
; i
++) {
683 (*names
)[i
] = talloc_strdup(
684 (*names
), gidtoname(rids
[i
]));
685 if ((*names
)[i
] == NULL
) {
688 (*types
)[i
] = SID_NAME_DOM_GRP
;
693 return wb_lookup_rids(mem_ctx
, domain_sid
, num_rids
, rids
,
694 domain_name
, *names
, *types
);
698 * Is the SID a domain as such? If yes, lookup its name.
701 static bool lookup_as_domain(const struct dom_sid
*sid
, TALLOC_CTX
*mem_ctx
,
705 enum lsa_SidType type
;
707 if (sid_check_is_our_sam(sid
)) {
708 *name
= talloc_strdup(mem_ctx
, get_global_sam_name());
712 if (sid_check_is_builtin(sid
)) {
713 *name
= talloc_strdup(mem_ctx
, builtin_domain_name());
717 if (sid_check_is_wellknown_domain(sid
, &tmp
)) {
718 *name
= talloc_strdup(mem_ctx
, tmp
);
722 if (sid_check_is_unix_users(sid
)) {
723 *name
= talloc_strdup(mem_ctx
, unix_users_domain_name());
727 if (sid_check_is_unix_groups(sid
)) {
728 *name
= talloc_strdup(mem_ctx
, unix_groups_domain_name());
732 if (sid
->num_auths
!= 4) {
733 /* This can't be a domain */
738 uint32_t i
, num_domains
;
739 struct trustdom_info
**domains
;
741 /* This is relatively expensive, but it happens only on DCs
742 * and for SIDs that have 4 sub-authorities and thus look like
745 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx
,
751 for (i
=0; i
<num_domains
; i
++) {
752 if (dom_sid_equal(sid
, &domains
[i
]->sid
)) {
753 *name
= talloc_strdup(mem_ctx
,
761 if (winbind_lookup_sid(mem_ctx
, sid
, &tmp
, NULL
, &type
) &&
762 (type
== SID_NAME_DOMAIN
)) {
771 * This tries to implement the rather weird rules for the lsa_lookup level
774 * This is as close as we can get to what W2k3 does. With this we survive the
775 * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
776 * different, but I assume that's just being too liberal. For example, W2k3
777 * replies to everything else but the levels 1-6 with INVALID_PARAMETER
778 * whereas NT4 does the same as level 1 (I think). I did not fully test that
779 * with NT4, this is what w2k3 does.
781 * Level 1: Ask everywhere
782 * Level 2: Ask domain and trusted domains, no builtin and wkn
783 * Level 3: Only ask domain
784 * Level 4: W2k3ad: Only ask AD trusts
785 * Level 5: Only ask transitive forest trusts
789 static bool check_dom_sid_to_level(const struct dom_sid
*sid
, int level
)
798 ret
= (!sid_check_is_builtin(sid
) &&
799 !sid_check_is_wellknown_domain(sid
, NULL
));
804 ret
= sid_check_is_our_sam(sid
);
811 DEBUG(10, ("%s SID %s in level %d\n",
812 ret
? "Accepting" : "Rejecting",
813 sid_string_dbg(sid
), level
));
818 * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
819 * references to domains, it is explicitly made for this.
821 * This attempts to be as efficient as possible: It collects all SIDs
822 * belonging to a domain and hands them in bulk to the appropriate lookup
823 * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
824 * *hugely* from this.
827 NTSTATUS
lookup_sids(TALLOC_CTX
*mem_ctx
, int num_sids
,
828 const struct dom_sid
**sids
, int level
,
829 struct lsa_dom_info
**ret_domains
,
830 struct lsa_name_info
**ret_names
)
833 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
834 struct lsa_name_info
*name_infos
;
835 struct lsa_dom_info
*dom_infos
= NULL
;
839 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
840 DEBUG(0, ("talloc_new failed\n"));
841 return NT_STATUS_NO_MEMORY
;
845 name_infos
= talloc_array(mem_ctx
, struct lsa_name_info
, num_sids
);
846 if (name_infos
== NULL
) {
847 result
= NT_STATUS_NO_MEMORY
;
854 dom_infos
= talloc_zero_array(mem_ctx
, struct lsa_dom_info
,
855 LSA_REF_DOMAIN_LIST_MULTIPLIER
);
856 if (dom_infos
== NULL
) {
857 result
= NT_STATUS_NO_MEMORY
;
861 /* First build up the data structures:
863 * dom_infos is a list of domains referenced in the list of
864 * SIDs. Later we will walk the list of domains and look up the RIDs
867 * name_infos is a shadow-copy of the SIDs array to collect the real
870 * dom_info->idxs is an index into the name_infos array. The
871 * difficulty we have here is that we need to keep the SIDs the client
872 * asked for in the same order for the reply
875 for (i
=0; i
<num_sids
; i
++) {
878 const char *domain_name
= NULL
;
880 sid_copy(&sid
, sids
[i
]);
881 name_infos
[i
].type
= SID_NAME_USE_NONE
;
883 if (lookup_as_domain(&sid
, name_infos
, &domain_name
)) {
884 /* We can't push that through the normal lookup
885 * process, as this would reference illegal
888 * For example S-1-5-32 would end up referencing
889 * domain S-1-5- with RID 32 which is clearly wrong.
891 if (domain_name
== NULL
) {
892 result
= NT_STATUS_NO_MEMORY
;
896 name_infos
[i
].rid
= 0;
897 name_infos
[i
].type
= SID_NAME_DOMAIN
;
898 name_infos
[i
].name
= NULL
;
900 if (sid_check_is_builtin(&sid
)) {
901 /* Yes, W2k3 returns "BUILTIN" both as domain
903 name_infos
[i
].name
= talloc_strdup(
904 name_infos
, builtin_domain_name());
905 if (name_infos
[i
].name
== NULL
) {
906 result
= NT_STATUS_NO_MEMORY
;
911 /* This is a normal SID with rid component */
912 if (!sid_split_rid(&sid
, &rid
)) {
913 result
= NT_STATUS_INVALID_SID
;
918 if (!check_dom_sid_to_level(&sid
, level
)) {
919 name_infos
[i
].rid
= 0;
920 name_infos
[i
].type
= SID_NAME_UNKNOWN
;
921 name_infos
[i
].name
= NULL
;
925 for (j
=0; j
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; j
++) {
926 if (!dom_infos
[j
].valid
) {
929 if (dom_sid_equal(&sid
, &dom_infos
[j
].sid
)) {
934 if (j
== LSA_REF_DOMAIN_LIST_MULTIPLIER
) {
935 /* TODO: What's the right error message here? */
936 result
= NT_STATUS_NONE_MAPPED
;
940 if (!dom_infos
[j
].valid
) {
941 /* We found a domain not yet referenced, create a new
943 dom_infos
[j
].valid
= true;
944 sid_copy(&dom_infos
[j
].sid
, &sid
);
946 if (domain_name
!= NULL
) {
947 /* This name was being found above in the case
948 * when we found a domain SID */
950 talloc_strdup(dom_infos
, domain_name
);
951 if (dom_infos
[j
].name
== NULL
) {
952 result
= NT_STATUS_NO_MEMORY
;
956 /* lookup_rids will take care of this */
957 dom_infos
[j
].name
= NULL
;
961 name_infos
[i
].dom_idx
= j
;
963 if (name_infos
[i
].type
== SID_NAME_USE_NONE
) {
964 name_infos
[i
].rid
= rid
;
966 ADD_TO_ARRAY(dom_infos
, int, i
, &dom_infos
[j
].idxs
,
967 &dom_infos
[j
].num_idxs
);
969 if (dom_infos
[j
].idxs
== NULL
) {
970 result
= NT_STATUS_NO_MEMORY
;
976 /* Iterate over the domains found */
978 for (i
=0; i
<LSA_REF_DOMAIN_LIST_MULTIPLIER
; i
++) {
980 const char *domain_name
= NULL
;
982 enum lsa_SidType
*types
;
983 struct lsa_dom_info
*dom
= &dom_infos
[i
];
986 /* No domains left, we're done */
990 if (dom
->num_idxs
== 0) {
992 * This happens only if the only sid related to
993 * this domain is the domain sid itself, which
994 * is mapped to SID_NAME_DOMAIN above.
999 if (!(rids
= talloc_array(tmp_ctx
, uint32_t, dom
->num_idxs
))) {
1000 result
= NT_STATUS_NO_MEMORY
;
1004 for (j
=0; j
<dom
->num_idxs
; j
++) {
1005 rids
[j
] = name_infos
[dom
->idxs
[j
]].rid
;
1008 if (!lookup_rids(tmp_ctx
, &dom
->sid
,
1009 dom
->num_idxs
, rids
, &domain_name
,
1011 result
= NT_STATUS_NO_MEMORY
;
1015 if (!(dom
->name
= talloc_strdup(dom_infos
, domain_name
))) {
1016 result
= NT_STATUS_NO_MEMORY
;
1020 for (j
=0; j
<dom
->num_idxs
; j
++) {
1021 int idx
= dom
->idxs
[j
];
1022 name_infos
[idx
].type
= types
[j
];
1023 if (types
[j
] != SID_NAME_UNKNOWN
) {
1024 name_infos
[idx
].name
=
1025 talloc_strdup(name_infos
, names
[j
]);
1026 if (name_infos
[idx
].name
== NULL
) {
1027 result
= NT_STATUS_NO_MEMORY
;
1031 name_infos
[idx
].name
= NULL
;
1036 *ret_domains
= dom_infos
;
1037 *ret_names
= name_infos
;
1038 TALLOC_FREE(tmp_ctx
);
1039 return NT_STATUS_OK
;
1042 TALLOC_FREE(dom_infos
);
1043 TALLOC_FREE(name_infos
);
1044 TALLOC_FREE(tmp_ctx
);
1048 /*****************************************************************
1049 *THE CANONICAL* convert SID to name function.
1050 *****************************************************************/
1052 bool lookup_sid(TALLOC_CTX
*mem_ctx
, const struct dom_sid
*sid
,
1053 const char **ret_domain
, const char **ret_name
,
1054 enum lsa_SidType
*ret_type
)
1056 struct lsa_dom_info
*domain
;
1057 struct lsa_name_info
*name
;
1058 TALLOC_CTX
*tmp_ctx
;
1061 DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid
)));
1063 if (!(tmp_ctx
= talloc_new(mem_ctx
))) {
1064 DEBUG(0, ("talloc_new failed\n"));
1068 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx
, 1, &sid
, 1,
1073 if (name
->type
== SID_NAME_UNKNOWN
) {
1077 if ((ret_domain
!= NULL
) &&
1078 !(*ret_domain
= talloc_strdup(mem_ctx
, domain
->name
))) {
1082 if ((ret_name
!= NULL
) &&
1083 !(*ret_name
= talloc_strdup(mem_ctx
, name
->name
))) {
1087 if (ret_type
!= NULL
) {
1088 *ret_type
= name
->type
;
1095 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid
),
1096 domain
->name
, name
->name
, name
->type
));
1098 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid
)));
1100 TALLOC_FREE(tmp_ctx
);
1104 /*****************************************************************
1105 *THE LEGACY* convert SID to id function.
1106 *****************************************************************/
1108 static bool legacy_sid_to_unixid(const struct dom_sid
*psid
, struct unixid
*id
)
1113 ret
= pdb_sid_to_id(psid
, id
);
1117 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1118 sid_string_dbg(psid
)));
1125 static bool legacy_sid_to_gid(const struct dom_sid
*psid
, gid_t
*pgid
)
1128 if (!legacy_sid_to_unixid(psid
, &id
)) {
1131 if (id
.type
== ID_TYPE_GID
|| id
.type
== ID_TYPE_BOTH
) {
1138 static bool legacy_sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1141 if (!legacy_sid_to_unixid(psid
, &id
)) {
1144 if (id
.type
== ID_TYPE_UID
|| id
.type
== ID_TYPE_BOTH
) {
1151 void xid_to_sid(struct dom_sid
*psid
, const struct unixid
*xid
)
1153 bool expired
= true;
1155 struct dom_sid_buf buf
;
1157 SMB_ASSERT(xid
->type
== ID_TYPE_UID
|| xid
->type
== ID_TYPE_GID
);
1159 *psid
= (struct dom_sid
) {0};
1161 ret
= idmap_cache_find_xid2sid(xid
, psid
, &expired
);
1162 if (ret
&& !expired
) {
1163 DBG_DEBUG("%cID %"PRIu32
" -> %s from cache\n",
1164 xid
->type
== ID_TYPE_UID
? 'U' : 'G',
1166 dom_sid_str_buf(psid
, &buf
));
1170 ret
= winbind_xid_to_sid(psid
, xid
);
1173 * winbind can return an explicit negative mapping
1174 * here. It's up to winbind to prime the cache either
1175 * positively or negatively, don't mess with the cache
1178 DBG_DEBUG("%cID %"PRIu32
" -> %s from cache\n",
1179 xid
->type
== ID_TYPE_UID
? 'U' : 'G',
1181 dom_sid_str_buf(psid
, &buf
));
1187 * Make a copy, pdb_id_to_sid might want to turn
1188 * xid->type into ID_TYPE_BOTH, which we ignore here.
1190 struct unixid rw_xid
= *xid
;
1193 ret
= pdb_id_to_sid(&rw_xid
, psid
);
1198 DBG_DEBUG("%cID %"PRIu32
" -> %s from passdb\n",
1199 xid
->type
== ID_TYPE_UID
? 'U' : 'G',
1201 dom_sid_str_buf(psid
, &buf
));
1206 if (is_null_sid(psid
)) {
1208 * Nobody found anything: Return S-1-22-xx-yy. Don't
1209 * store that in caches, this is up to the layers
1212 if (xid
->type
== ID_TYPE_UID
) {
1213 uid_to_unix_users_sid(xid
->id
, psid
);
1215 gid_to_unix_groups_sid(xid
->id
, psid
);
1218 DBG_DEBUG("%cID %"PRIu32
" -> %s fallback\n",
1219 xid
->type
== ID_TYPE_UID
? 'U' : 'G',
1221 dom_sid_str_buf(psid
, &buf
));
1225 void uid_to_sid(struct dom_sid
*psid
, uid_t uid
)
1227 struct unixid xid
= { .type
= ID_TYPE_UID
, .id
= uid
};
1228 xid_to_sid(psid
, &xid
);
1231 void gid_to_sid(struct dom_sid
*psid
, gid_t gid
)
1233 struct unixid xid
= { .type
= ID_TYPE_GID
, .id
= gid
};
1234 xid_to_sid(psid
, &xid
);
1237 bool sids_to_unixids(const struct dom_sid
*sids
, uint32_t num_sids
,
1240 struct wbcDomainSid
*wbc_sids
= NULL
;
1241 struct wbcUnixId
*wbc_ids
= NULL
;
1242 uint32_t i
, num_not_cached
;
1246 wbc_sids
= talloc_array(talloc_tos(), struct wbcDomainSid
, num_sids
);
1247 if (wbc_sids
== NULL
) {
1253 for (i
=0; i
<num_sids
; i
++) {
1257 if (sid_peek_check_rid(&global_sid_Unix_Users
,
1259 ids
[i
].type
= ID_TYPE_UID
;
1263 if (sid_peek_check_rid(&global_sid_Unix_Groups
,
1265 ids
[i
].type
= ID_TYPE_GID
;
1269 if (idmap_cache_find_sid2unixid(&sids
[i
], &ids
[i
], &expired
)
1274 ids
[i
].type
= ID_TYPE_NOT_SPECIFIED
;
1275 memcpy(&wbc_sids
[num_not_cached
], &sids
[i
],
1276 ndr_size_dom_sid(&sids
[i
], 0));
1277 num_not_cached
+= 1;
1279 if (num_not_cached
== 0) {
1282 wbc_ids
= talloc_array(talloc_tos(), struct wbcUnixId
, num_not_cached
);
1283 if (wbc_ids
== NULL
) {
1286 for (i
=0; i
<num_not_cached
; i
++) {
1287 wbc_ids
[i
].type
= WBC_ID_TYPE_NOT_SPECIFIED
;
1289 err
= wbcSidsToUnixIds(wbc_sids
, num_not_cached
, wbc_ids
);
1290 if (!WBC_ERROR_IS_OK(err
)) {
1291 DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1292 wbcErrorString(err
)));
1297 for (i
=0; i
<num_sids
; i
++) {
1298 if (ids
[i
].type
== ID_TYPE_NOT_SPECIFIED
) {
1299 switch (wbc_ids
[num_not_cached
].type
) {
1300 case WBC_ID_TYPE_UID
:
1301 ids
[i
].type
= ID_TYPE_UID
;
1302 ids
[i
].id
= wbc_ids
[num_not_cached
].id
.uid
;
1304 case WBC_ID_TYPE_GID
:
1305 ids
[i
].type
= ID_TYPE_GID
;
1306 ids
[i
].id
= wbc_ids
[num_not_cached
].id
.gid
;
1309 /* The types match, and wbcUnixId -> id is a union anyway */
1310 ids
[i
].type
= (enum id_type
)wbc_ids
[num_not_cached
].type
;
1311 ids
[i
].id
= wbc_ids
[num_not_cached
].id
.gid
;
1314 num_not_cached
+= 1;
1318 for (i
=0; i
<num_sids
; i
++) {
1319 if (ids
[i
].type
!= ID_TYPE_NOT_SPECIFIED
) {
1322 if (legacy_sid_to_gid(&sids
[i
], &ids
[i
].id
)) {
1323 ids
[i
].type
= ID_TYPE_GID
;
1326 if (legacy_sid_to_uid(&sids
[i
], &ids
[i
].id
)) {
1327 ids
[i
].type
= ID_TYPE_UID
;
1332 for (i
=0; i
<num_sids
; i
++) {
1333 switch(ids
[i
].type
) {
1334 case WBC_ID_TYPE_GID
:
1335 case WBC_ID_TYPE_UID
:
1336 case WBC_ID_TYPE_BOTH
:
1337 if (ids
[i
].id
== -1) {
1338 ids
[i
].type
= ID_TYPE_NOT_SPECIFIED
;
1341 case WBC_ID_TYPE_NOT_SPECIFIED
:
1348 TALLOC_FREE(wbc_ids
);
1349 TALLOC_FREE(wbc_sids
);
1353 /*****************************************************************
1354 *THE CANONICAL* convert SID to uid function.
1355 *****************************************************************/
1357 bool sid_to_uid(const struct dom_sid
*psid
, uid_t
*puid
)
1359 bool expired
= true;
1363 /* Optimize for the Unix Users Domain
1364 * as the conversion is straightforward */
1365 if (sid_peek_check_rid(&global_sid_Unix_Users
, psid
, &rid
)) {
1369 /* return here, don't cache */
1370 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1371 (unsigned int)*puid
));
1375 /* Check the winbindd cache directly. */
1376 ret
= idmap_cache_find_sid2uid(psid
, puid
, &expired
);
1378 if (ret
&& !expired
&& (*puid
== (uid_t
)-1)) {
1380 * Negative cache entry, we already asked.
1383 return legacy_sid_to_uid(psid
, puid
);
1386 if (!ret
|| expired
) {
1387 /* Not in cache. Ask winbindd. */
1388 if (!winbind_sid_to_uid(puid
, psid
)) {
1389 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1390 sid_string_dbg(psid
)));
1391 /* winbind failed. do legacy */
1392 return legacy_sid_to_uid(psid
, puid
);
1396 /* TODO: Here would be the place to allocate both a gid and a uid for
1397 * the SID in question */
1399 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid
),
1400 (unsigned int)*puid
));
1405 /*****************************************************************
1406 *THE CANONICAL* convert SID to gid function.
1407 Group mapping is used for gids that maps to Wellknown SIDs
1408 *****************************************************************/
1410 bool sid_to_gid(const struct dom_sid
*psid
, gid_t
*pgid
)
1412 bool expired
= true;
1416 /* Optimize for the Unix Groups Domain
1417 * as the conversion is straightforward */
1418 if (sid_peek_check_rid(&global_sid_Unix_Groups
, psid
, &rid
)) {
1422 /* return here, don't cache */
1423 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1424 (unsigned int)*pgid
));
1428 /* Check the winbindd cache directly. */
1429 ret
= idmap_cache_find_sid2gid(psid
, pgid
, &expired
);
1431 if (ret
&& !expired
&& (*pgid
== (gid_t
)-1)) {
1433 * Negative cache entry, we already asked.
1436 return legacy_sid_to_gid(psid
, pgid
);
1439 if (!ret
|| expired
) {
1440 /* Not in cache or negative. Ask winbindd. */
1441 /* Ask winbindd if it can map this sid to a gid.
1442 * (Idmap will check it is a valid SID and of the right type) */
1444 if ( !winbind_sid_to_gid(pgid
, psid
) ) {
1446 DEBUG(10,("winbind failed to find a gid for sid %s\n",
1447 sid_string_dbg(psid
)));
1448 /* winbind failed. do legacy */
1449 return legacy_sid_to_gid(psid
, pgid
);
1453 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid
),
1454 (unsigned int)*pgid
));
1460 * @brief This function gets the primary group SID mapping the primary
1461 * GID of the user as obtained by an actual getpwnam() call.
1462 * This is necessary to avoid issues with arbitrary group SIDs
1463 * stored in passdb. We try as hard as we can to get the SID
1464 * corresponding to the GID, including trying group mapping.
1465 * If nothing else works, we will force "Domain Users" as the
1467 * This is needed because we must always be able to lookup the
1468 * primary group SID, so we cannot settle for an arbitrary SID.
1470 * This call can be expensive. Use with moderation.
1471 * If you have a "samu" struct around use pdb_get_group_sid()
1472 * instead as it does properly cache results.
1474 * @param mem_ctx[in] The memory context iused to allocate the result.
1475 * @param username[in] The user's name
1476 * @param _pwd[in|out] If available, pass in user's passwd struct.
1477 * It will contain a tallocated passwd if NULL was
1479 * @param _group_sid[out] The user's Primary Group SID
1481 * @return NTSTATUS error code.
1483 NTSTATUS
get_primary_group_sid(TALLOC_CTX
*mem_ctx
,
1484 const char *username
,
1485 struct passwd
**_pwd
,
1486 struct dom_sid
**_group_sid
)
1488 TALLOC_CTX
*tmp_ctx
;
1489 bool need_lookup_sid
= false;
1490 struct dom_sid
*group_sid
;
1491 struct passwd
*pwd
= *_pwd
;
1493 tmp_ctx
= talloc_new(mem_ctx
);
1495 return NT_STATUS_NO_MEMORY
;
1499 pwd
= Get_Pwnam_alloc(mem_ctx
, username
);
1501 DEBUG(0, ("Failed to find a Unix account for %s\n",
1503 TALLOC_FREE(tmp_ctx
);
1504 return NT_STATUS_NO_SUCH_USER
;
1508 group_sid
= talloc_zero(mem_ctx
, struct dom_sid
);
1510 TALLOC_FREE(tmp_ctx
);
1511 return NT_STATUS_NO_MEMORY
;
1514 gid_to_sid(group_sid
, pwd
->pw_gid
);
1515 if (!is_null_sid(group_sid
)) {
1516 struct dom_sid domain_sid
;
1519 /* We need a sid within our domain */
1520 sid_copy(&domain_sid
, group_sid
);
1521 sid_split_rid(&domain_sid
, &rid
);
1522 if (dom_sid_equal(&domain_sid
, get_global_sam_sid())) {
1524 * As shortcut for the expensive lookup_sid call
1525 * compare the domain sid part
1528 case DOMAIN_RID_ADMINS
:
1529 case DOMAIN_RID_USERS
:
1532 need_lookup_sid
= true;
1536 /* Try group mapping */
1539 id
.id
= pwd
->pw_gid
;
1540 id
.type
= ID_TYPE_GID
;
1542 ZERO_STRUCTP(group_sid
);
1543 if (pdb_id_to_sid(&id
, group_sid
)) {
1544 need_lookup_sid
= true;
1549 /* We must verify that this is a valid SID that resolves to a
1550 * group of the correct type */
1551 if (need_lookup_sid
) {
1552 enum lsa_SidType type
= SID_NAME_UNKNOWN
;
1555 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1556 sid_string_dbg(group_sid
), username
));
1558 /* Now check that it's actually a domain group and
1559 * not something else */
1560 lookup_ret
= lookup_sid(tmp_ctx
, group_sid
,
1563 if (lookup_ret
&& (type
== SID_NAME_DOM_GRP
)) {
1567 DEBUG(3, ("Primary group %s for user %s is"
1568 " a %s and not a domain group\n",
1569 sid_string_dbg(group_sid
), username
,
1570 sid_type_lookup(type
)));
1573 /* Everything else, failed.
1574 * Just set it to the 'Domain Users' RID of 513 which will
1575 always resolve to a name */
1576 DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1579 sid_compose(group_sid
, get_global_sam_sid(), DOMAIN_RID_USERS
);
1582 *_pwd
= talloc_move(mem_ctx
, &pwd
);
1583 *_group_sid
= talloc_move(mem_ctx
, &group_sid
);
1584 TALLOC_FREE(tmp_ctx
);
1585 return NT_STATUS_OK
;