Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : uid/user handling
4 : Copyright (C) Andrew Tridgell 1992-1998
5 : Copyright (C) Gerald (Jerry) Carter 2003
6 : Copyright (C) Volker Lendecke 2005
7 :
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.
12 :
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.
17 :
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/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "passdb.h"
24 : #include "lib/util_unixsids.h"
25 : #include "../librpc/gen_ndr/ndr_security.h"
26 : #include "secrets.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"
32 : #include "lib/util/bitmap.h"
33 :
34 50 : static bool lookup_unix_user_name(const char *name, struct dom_sid *sid)
35 : {
36 0 : struct passwd *pwd;
37 0 : bool ret;
38 :
39 50 : pwd = Get_Pwnam_alloc(talloc_tos(), name);
40 50 : if (pwd == NULL) {
41 42 : return False;
42 : }
43 :
44 : /*
45 : * For 64-bit uid's we have enough space in the whole SID,
46 : * should they become necessary
47 : */
48 8 : ret = sid_compose(sid, &global_sid_Unix_Users, pwd->pw_uid);
49 8 : TALLOC_FREE(pwd);
50 8 : return ret;
51 : }
52 :
53 186 : static bool lookup_unix_group_name(const char *name, struct dom_sid *sid)
54 : {
55 0 : struct group *grp;
56 :
57 186 : grp = getgrnam(name);
58 186 : if (grp == NULL) {
59 0 : return False;
60 : }
61 :
62 : /*
63 : * For 64-bit gid's we have enough space in the whole SID,
64 : * should they become necessary
65 : */
66 186 : return sid_compose(sid, &global_sid_Unix_Groups, grp->gr_gid);
67 : }
68 :
69 : /*****************************************************************
70 : Dissect a user-provided name into domain, name, sid and type.
71 :
72 : If an explicit domain name was given in the form domain\user, it
73 : has to try that. If no explicit domain name was given, we have
74 : to do guesswork.
75 : *****************************************************************/
76 :
77 3662 : bool lookup_name(TALLOC_CTX *mem_ctx,
78 : const char *full_name, int flags,
79 : const char **ret_domain, const char **ret_name,
80 : struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
81 : {
82 0 : char *p;
83 0 : const char *tmp;
84 3662 : const char *domain = NULL;
85 3662 : const char *name = NULL;
86 0 : uint32_t rid;
87 0 : struct dom_sid sid;
88 0 : enum lsa_SidType type;
89 3662 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
90 :
91 3662 : if (tmp_ctx == NULL) {
92 0 : DEBUG(0, ("talloc_new failed\n"));
93 0 : return false;
94 : }
95 :
96 3662 : p = strchr_m(full_name, '\\');
97 :
98 3662 : if (p != NULL) {
99 3452 : domain = talloc_strndup(tmp_ctx, full_name,
100 1726 : PTR_DIFF(p, full_name));
101 1726 : name = talloc_strdup(tmp_ctx, p+1);
102 : } else {
103 1936 : char *q = strchr_m(full_name, '@');
104 :
105 : /* Set the domain for UPNs */
106 1936 : if (q != NULL) {
107 0 : name = talloc_strndup(tmp_ctx,
108 : full_name,
109 0 : PTR_DIFF(q, full_name));
110 0 : domain = talloc_strdup(tmp_ctx, q + 1);
111 : } else {
112 1936 : domain = talloc_strdup(tmp_ctx, "");
113 1936 : name = talloc_strdup(tmp_ctx, full_name);
114 : }
115 : }
116 :
117 3662 : if ((domain == NULL) || (name == NULL)) {
118 0 : DEBUG(0, ("talloc failed\n"));
119 0 : TALLOC_FREE(tmp_ctx);
120 0 : return false;
121 : }
122 :
123 3662 : DEBUG(10,("lookup_name: %s => domain=[%s], name=[%s]\n",
124 : full_name, domain, name));
125 3662 : DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
126 :
127 3662 : if ((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) {
128 3662 : bool check_global_sam = false;
129 :
130 3662 : check_global_sam = strequal(domain, get_global_sam_name());
131 :
132 : /* If we are running on a DC that has PASSDB module with domain
133 : * information, check if DNS forest name is matching the domain
134 : * name. This is the case of IPA domain controller when
135 : * trusted AD DC looks up users found in a Global Catalog of
136 : * the forest root domain. */
137 3662 : if (!check_global_sam && (IS_DC)) {
138 1942 : struct pdb_domain_info *dom_info = NULL;
139 1942 : dom_info = pdb_get_domain_info(tmp_ctx);
140 :
141 1942 : if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
142 4 : check_global_sam = strequal(domain, dom_info->dns_forest);
143 : }
144 :
145 1942 : TALLOC_FREE(dom_info);
146 : }
147 :
148 3662 : if (check_global_sam) {
149 : /* It's our own domain, lookup the name in passdb */
150 1096 : if (lookup_global_sam_name(name, flags, &rid, &type)) {
151 689 : sid_compose(&sid, get_global_sam_sid(), rid);
152 689 : goto ok;
153 : }
154 407 : TALLOC_FREE(tmp_ctx);
155 407 : return false;
156 : }
157 : }
158 :
159 5132 : if ((flags & LOOKUP_NAME_BUILTIN) &&
160 2566 : strequal(domain, builtin_domain_name()))
161 : {
162 12 : if (strlen(name) == 0) {
163 : /* Swap domain and name */
164 0 : tmp = name; name = domain; domain = tmp;
165 0 : sid_copy(&sid, &global_sid_Builtin);
166 0 : type = SID_NAME_DOMAIN;
167 0 : goto ok;
168 : }
169 :
170 : /* Explicit request for a name in BUILTIN */
171 12 : if (lookup_builtin_name(name, &rid)) {
172 12 : sid_compose(&sid, &global_sid_Builtin, rid);
173 12 : type = SID_NAME_ALIAS;
174 12 : goto ok;
175 : }
176 0 : TALLOC_FREE(tmp_ctx);
177 0 : return false;
178 : }
179 :
180 : /* Try the explicit winbind lookup first, don't let it guess the
181 : * domain yet at this point yet. This comes later. */
182 :
183 2554 : if ((domain[0] != '\0') &&
184 1236 : (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
185 618 : (winbind_lookup_name(domain, name, &sid, &type))) {
186 462 : goto ok;
187 : }
188 :
189 2092 : if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
190 1946 : && strequal(domain, unix_users_domain_name())) {
191 10 : if (lookup_unix_user_name(name, &sid)) {
192 8 : type = SID_NAME_USER;
193 8 : goto ok;
194 : }
195 2 : TALLOC_FREE(tmp_ctx);
196 2 : return false;
197 : }
198 :
199 2082 : if (((flags & LOOKUP_NAME_NO_NSS) == 0)
200 2082 : && strequal(domain, unix_groups_domain_name())) {
201 146 : if (lookup_unix_group_name(name, &sid)) {
202 146 : type = SID_NAME_DOM_GRP;
203 146 : goto ok;
204 : }
205 0 : TALLOC_FREE(tmp_ctx);
206 0 : return false;
207 : }
208 :
209 : /*
210 : * Finally check for a well known domain name ("NT Authority"),
211 : * this is being taken care of in lookup_wellknown_name().
212 : */
213 1936 : if ((domain[0] != '\0') &&
214 0 : (flags & LOOKUP_NAME_WKN) &&
215 0 : lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
216 : {
217 0 : type = SID_NAME_WKN_GRP;
218 0 : goto ok;
219 : }
220 :
221 : /*
222 : * If we're told not to look up 'isolated' names then we're
223 : * done.
224 : */
225 1936 : if (!(flags & LOOKUP_NAME_ISOLATED)) {
226 0 : TALLOC_FREE(tmp_ctx);
227 0 : return false;
228 : }
229 :
230 : /*
231 : * No domain names beyond this point
232 : */
233 1936 : if (domain[0] != '\0') {
234 0 : TALLOC_FREE(tmp_ctx);
235 0 : return false;
236 : }
237 :
238 : /* Now the guesswork begins, we haven't been given an explicit
239 : * domain. Try the sequence as documented on
240 : * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
241 : * November 27, 2005 */
242 :
243 : /* 1. well-known names */
244 :
245 : /*
246 : * Check for well known names without a domain name.
247 : * e.g. \Creator Owner.
248 : */
249 :
250 3872 : if ((flags & LOOKUP_NAME_WKN) &&
251 1936 : lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
252 : {
253 24 : type = SID_NAME_WKN_GRP;
254 24 : goto ok;
255 : }
256 :
257 : /* 2. Builtin domain as such */
258 :
259 3824 : if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
260 1912 : strequal(name, builtin_domain_name()))
261 : {
262 : /* Swap domain and name */
263 0 : tmp = name; name = domain; domain = tmp;
264 0 : sid_copy(&sid, &global_sid_Builtin);
265 0 : type = SID_NAME_DOMAIN;
266 0 : goto ok;
267 : }
268 :
269 : /* 3. Account domain */
270 :
271 3824 : if ((flags & LOOKUP_NAME_DOMAIN) &&
272 1912 : strequal(name, get_global_sam_name()))
273 : {
274 0 : if (!secrets_fetch_domain_sid(name, &sid)) {
275 0 : DEBUG(3, ("Could not fetch my SID\n"));
276 0 : TALLOC_FREE(tmp_ctx);
277 0 : return false;
278 : }
279 : /* Swap domain and name */
280 0 : tmp = name; name = domain; domain = tmp;
281 0 : type = SID_NAME_DOMAIN;
282 0 : goto ok;
283 : }
284 :
285 : /* 4. Primary domain */
286 :
287 2050 : if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
288 138 : strequal(name, lp_workgroup()))
289 : {
290 0 : if (!secrets_fetch_domain_sid(name, &sid)) {
291 0 : DEBUG(3, ("Could not fetch the domain SID\n"));
292 0 : TALLOC_FREE(tmp_ctx);
293 0 : return false;
294 : }
295 : /* Swap domain and name */
296 0 : tmp = name; name = domain; domain = tmp;
297 0 : type = SID_NAME_DOMAIN;
298 0 : goto ok;
299 : }
300 :
301 : /* 5. Trusted domains as such, to me it looks as if members don't do
302 : this, tested an XP workstation in a NT domain -- vl */
303 :
304 2712 : if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
305 800 : (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
306 : {
307 : /* Swap domain and name */
308 0 : tmp = name; name = domain; domain = tmp;
309 0 : type = SID_NAME_DOMAIN;
310 0 : goto ok;
311 : }
312 :
313 : /* 6. Builtin aliases */
314 :
315 3824 : if ((flags & LOOKUP_NAME_BUILTIN) &&
316 1912 : lookup_builtin_name(name, &rid))
317 : {
318 800 : domain = talloc_strdup(tmp_ctx, builtin_domain_name());
319 800 : sid_compose(&sid, &global_sid_Builtin, rid);
320 800 : type = SID_NAME_ALIAS;
321 800 : goto ok;
322 : }
323 :
324 : /* 7. Local systems' SAM (DCs don't have a local SAM) */
325 : /* 8. Primary SAM (On members, this is the domain) */
326 :
327 : /* Both cases are done by looking at our passdb */
328 :
329 2224 : if ((flags & LOOKUP_NAME_DOMAIN) &&
330 1112 : lookup_global_sam_name(name, flags, &rid, &type))
331 : {
332 116 : domain = talloc_strdup(tmp_ctx, get_global_sam_name());
333 116 : sid_compose(&sid, get_global_sam_sid(), rid);
334 116 : goto ok;
335 : }
336 :
337 : /* Now our local possibilities are exhausted. */
338 :
339 996 : if (!(flags & LOOKUP_NAME_REMOTE)) {
340 956 : TALLOC_FREE(tmp_ctx);
341 956 : return false;
342 : }
343 :
344 : /* If we are not a DC, we have to ask in our primary domain. Let
345 : * winbind do that. */
346 :
347 80 : if (!IS_DC &&
348 40 : (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
349 0 : domain = talloc_strdup(tmp_ctx, lp_workgroup());
350 0 : goto ok;
351 : }
352 :
353 : /* 9. Trusted domains */
354 :
355 : /* If we're a DC we have to ask all trusted DC's. Winbind does not do
356 : * that (yet), but give it a chance. */
357 :
358 40 : if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
359 0 : struct dom_sid dom_sid;
360 0 : enum lsa_SidType domain_type;
361 :
362 0 : if (type == SID_NAME_DOMAIN) {
363 : /* Swap name and type */
364 0 : tmp = name; name = domain; domain = tmp;
365 0 : goto ok;
366 : }
367 :
368 : /* Here we have to cope with a little deficiency in the
369 : * winbind API: We have to ask it again for the name of the
370 : * domain it figured out itself. Maybe fix that later... */
371 :
372 0 : sid_copy(&dom_sid, &sid);
373 0 : sid_split_rid(&dom_sid, NULL);
374 :
375 0 : if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
376 0 : &domain_type) ||
377 0 : (domain_type != SID_NAME_DOMAIN)) {
378 0 : DEBUG(2, ("winbind could not find the domain's name "
379 : "it just looked up for us\n"));
380 0 : TALLOC_FREE(tmp_ctx);
381 0 : return false;
382 : }
383 0 : goto ok;
384 : }
385 :
386 : /* 10. Don't translate */
387 :
388 : /* 11. Ok, windows would end here. Samba has two more options:
389 : Unmapped users and unmapped groups */
390 :
391 40 : if (((flags & (LOOKUP_NAME_NO_NSS|LOOKUP_NAME_GROUP)) == 0)
392 40 : && lookup_unix_user_name(name, &sid)) {
393 0 : domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
394 0 : type = SID_NAME_USER;
395 0 : goto ok;
396 : }
397 :
398 40 : if (((flags & LOOKUP_NAME_NO_NSS) == 0)
399 40 : && lookup_unix_group_name(name, &sid)) {
400 40 : domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
401 40 : type = SID_NAME_DOM_GRP;
402 40 : goto ok;
403 : }
404 :
405 : /*
406 : * Ok, all possibilities tried. Fail.
407 : */
408 :
409 0 : TALLOC_FREE(tmp_ctx);
410 0 : return false;
411 :
412 2297 : ok:
413 2297 : if ((domain == NULL) || (name == NULL)) {
414 0 : DEBUG(0, ("talloc failed\n"));
415 0 : TALLOC_FREE(tmp_ctx);
416 0 : return false;
417 : }
418 :
419 : /*
420 : * Hand over the results to the talloc context we've been given.
421 : */
422 :
423 2297 : if ((ret_name != NULL) &&
424 372 : !(*ret_name = talloc_strdup(mem_ctx, name))) {
425 0 : DEBUG(0, ("talloc failed\n"));
426 0 : TALLOC_FREE(tmp_ctx);
427 0 : return false;
428 : }
429 :
430 2297 : if (ret_domain != NULL) {
431 0 : char *tmp_dom;
432 1350 : if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
433 0 : DEBUG(0, ("talloc failed\n"));
434 0 : TALLOC_FREE(tmp_ctx);
435 0 : return false;
436 : }
437 1350 : if (!strupper_m(tmp_dom)) {
438 0 : TALLOC_FREE(tmp_ctx);
439 0 : return false;
440 : }
441 1350 : *ret_domain = tmp_dom;
442 : }
443 :
444 2297 : if (ret_sid != NULL) {
445 2289 : sid_copy(ret_sid, &sid);
446 : }
447 :
448 2297 : if (ret_type != NULL) {
449 2245 : *ret_type = type;
450 : }
451 :
452 2297 : TALLOC_FREE(tmp_ctx);
453 2297 : return true;
454 : }
455 :
456 : /************************************************************************
457 : Names from smb.conf can be unqualified. eg. valid users = foo
458 : These names should never map to a remote name. Try global_sam_name()\foo,
459 : and then "Unix Users"\foo (or "Unix Groups"\foo).
460 : ************************************************************************/
461 :
462 1145 : bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
463 : const char *full_name, int flags,
464 : const char **ret_domain, const char **ret_name,
465 : struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
466 : {
467 1145 : char *qualified_name = NULL;
468 1145 : const char *p = strchr_m(full_name, *lp_winbind_separator());
469 1145 : bool is_qualified = p != NULL || strchr_m(full_name, '@') != NULL;
470 :
471 : /* For DOMAIN\user or user@REALM directly call lookup_name(). */
472 1145 : if (is_qualified) {
473 :
474 : /* The name is already qualified with a domain. */
475 :
476 158 : if (p != NULL && *lp_winbind_separator() != '\\') {
477 : /* lookup_name() needs '\\' as a separator */
478 :
479 158 : qualified_name = talloc_strdup(mem_ctx, full_name);
480 158 : if (qualified_name == NULL) {
481 0 : return false;
482 : }
483 158 : qualified_name[p - full_name] = '\\';
484 158 : full_name = qualified_name;
485 : }
486 :
487 158 : return lookup_name(mem_ctx, full_name, flags,
488 : ret_domain, ret_name,
489 : ret_sid, ret_type);
490 : }
491 :
492 : /* Try with winbind default domain name. */
493 987 : if (lp_winbind_use_default_domain()) {
494 0 : bool ok;
495 :
496 0 : qualified_name = talloc_asprintf(mem_ctx,
497 : "%s\\%s",
498 : lp_workgroup(),
499 : full_name);
500 0 : if (qualified_name == NULL) {
501 0 : return false;
502 : }
503 :
504 0 : ok = lookup_name(mem_ctx,
505 : qualified_name,
506 : flags,
507 : ret_domain,
508 : ret_name,
509 : ret_sid,
510 : ret_type);
511 0 : if (ok) {
512 0 : return true;
513 : }
514 : }
515 :
516 : /* Try with our own SAM name. */
517 987 : qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
518 : get_global_sam_name(),
519 : full_name );
520 987 : if (!qualified_name) {
521 0 : return false;
522 : }
523 :
524 987 : if (lookup_name(mem_ctx, qualified_name, flags,
525 : ret_domain, ret_name,
526 : ret_sid, ret_type)) {
527 593 : return true;
528 : }
529 :
530 : /* Finally try with "Unix Users" or "Unix Group" */
531 394 : qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
532 394 : flags & LOOKUP_NAME_GROUP ?
533 146 : unix_groups_domain_name() :
534 248 : unix_users_domain_name(),
535 : full_name );
536 394 : if (!qualified_name) {
537 0 : return false;
538 : }
539 :
540 394 : return lookup_name(mem_ctx, qualified_name, flags,
541 : ret_domain, ret_name,
542 : ret_sid, ret_type);
543 : }
544 :
545 150 : static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
546 : const struct dom_sid *domain_sid,
547 : int num_rids, uint32_t *rids,
548 : const char **domain_name,
549 : const char **names, enum lsa_SidType *types)
550 : {
551 0 : int i;
552 0 : const char **my_names;
553 0 : enum lsa_SidType *my_types;
554 0 : TALLOC_CTX *tmp_ctx;
555 :
556 150 : if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
557 0 : return false;
558 : }
559 :
560 150 : if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
561 : domain_name, &my_names, &my_types)) {
562 150 : *domain_name = "";
563 300 : for (i=0; i<num_rids; i++) {
564 150 : names[i] = "";
565 150 : types[i] = SID_NAME_UNKNOWN;
566 : }
567 150 : TALLOC_FREE(tmp_ctx);
568 150 : return true;
569 : }
570 :
571 0 : if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
572 0 : TALLOC_FREE(tmp_ctx);
573 0 : return false;
574 : }
575 :
576 : /*
577 : * winbind_lookup_rids allocates its own array. We've been given the
578 : * array, so copy it over
579 : */
580 :
581 0 : for (i=0; i<num_rids; i++) {
582 0 : if (my_names[i] == NULL) {
583 0 : TALLOC_FREE(tmp_ctx);
584 0 : return false;
585 : }
586 0 : if (!(names[i] = talloc_strdup(names, my_names[i]))) {
587 0 : TALLOC_FREE(tmp_ctx);
588 0 : return false;
589 : }
590 0 : types[i] = my_types[i];
591 : }
592 0 : TALLOC_FREE(tmp_ctx);
593 0 : return true;
594 : }
595 :
596 6462 : static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
597 : int num_rids, uint32_t *rids,
598 : const char **domain_name,
599 : const char ***names, enum lsa_SidType **types)
600 : {
601 270 : int i;
602 270 : struct dom_sid_buf buf;
603 :
604 6462 : DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
605 : dom_sid_str_buf(domain_sid, &buf)));
606 :
607 6462 : if (num_rids) {
608 6462 : *names = talloc_zero_array(mem_ctx, const char *, num_rids);
609 6462 : *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
610 :
611 6462 : if ((*names == NULL) || (*types == NULL)) {
612 0 : return false;
613 : }
614 :
615 13716 : for (i = 0; i < num_rids; i++)
616 7254 : (*types)[i] = SID_NAME_UNKNOWN;
617 : } else {
618 0 : *names = NULL;
619 0 : *types = NULL;
620 : }
621 :
622 6462 : if (sid_check_is_our_sam(domain_sid)) {
623 270 : NTSTATUS result;
624 :
625 4982 : if (*domain_name == NULL) {
626 4982 : *domain_name = talloc_strdup(
627 : mem_ctx, get_global_sam_name());
628 : }
629 :
630 4982 : if (*domain_name == NULL) {
631 0 : return false;
632 : }
633 :
634 4982 : become_root();
635 4982 : result = pdb_lookup_rids(domain_sid, num_rids, rids,
636 : *names, *types);
637 4982 : unbecome_root();
638 :
639 4712 : return (NT_STATUS_IS_OK(result) ||
640 4982 : NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
641 0 : NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
642 : }
643 :
644 1480 : if (sid_check_is_builtin(domain_sid)) {
645 :
646 1040 : if (*domain_name == NULL) {
647 1040 : *domain_name = talloc_strdup(
648 : mem_ctx, builtin_domain_name());
649 : }
650 :
651 1040 : if (*domain_name == NULL) {
652 0 : return false;
653 : }
654 :
655 2872 : for (i=0; i<num_rids; i++) {
656 1832 : if (lookup_builtin_rid(*names, rids[i],
657 1832 : &(*names)[i])) {
658 1832 : if ((*names)[i] == NULL) {
659 0 : return false;
660 : }
661 1832 : (*types)[i] = SID_NAME_ALIAS;
662 : } else {
663 0 : (*types)[i] = SID_NAME_UNKNOWN;
664 : }
665 : }
666 1040 : return true;
667 : }
668 :
669 440 : if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
670 248 : for (i=0; i<num_rids; i++) {
671 0 : struct dom_sid sid;
672 124 : sid_compose(&sid, domain_sid, rids[i]);
673 124 : if (lookup_wellknown_sid(mem_ctx, &sid,
674 124 : domain_name, &(*names)[i])) {
675 124 : if ((*names)[i] == NULL) {
676 0 : return false;
677 : }
678 124 : (*types)[i] = SID_NAME_WKN_GRP;
679 : } else {
680 0 : (*types)[i] = SID_NAME_UNKNOWN;
681 : }
682 : }
683 124 : return true;
684 : }
685 :
686 316 : if (sid_check_is_unix_users(domain_sid)) {
687 158 : if (*domain_name == NULL) {
688 158 : *domain_name = talloc_strdup(
689 : mem_ctx, unix_users_domain_name());
690 158 : if (*domain_name == NULL) {
691 0 : return false;
692 : }
693 : }
694 316 : for (i=0; i<num_rids; i++) {
695 158 : (*names)[i] = talloc_strdup(
696 158 : (*names), uidtoname(rids[i]));
697 158 : if ((*names)[i] == NULL) {
698 0 : return false;
699 : }
700 158 : (*types)[i] = SID_NAME_USER;
701 : }
702 158 : return true;
703 : }
704 :
705 158 : if (sid_check_is_unix_groups(domain_sid)) {
706 8 : if (*domain_name == NULL) {
707 8 : *domain_name = talloc_strdup(
708 : mem_ctx, unix_groups_domain_name());
709 8 : if (*domain_name == NULL) {
710 0 : return false;
711 : }
712 : }
713 16 : for (i=0; i<num_rids; i++) {
714 8 : (*names)[i] = talloc_strdup(
715 8 : (*names), gidtoname(rids[i]));
716 8 : if ((*names)[i] == NULL) {
717 0 : return false;
718 : }
719 8 : (*types)[i] = SID_NAME_DOM_GRP;
720 : }
721 8 : return true;
722 : }
723 :
724 150 : return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
725 : domain_name, *names, *types);
726 : }
727 :
728 : /*
729 : * Is the SID a domain as such? If yes, lookup its name.
730 : */
731 :
732 7254 : static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
733 : const char **name)
734 : {
735 270 : const char *tmp;
736 270 : enum lsa_SidType type;
737 :
738 7254 : if (sid_check_is_our_sam(sid)) {
739 0 : *name = talloc_strdup(mem_ctx, get_global_sam_name());
740 0 : return true;
741 : }
742 :
743 7254 : if (sid_check_is_builtin(sid)) {
744 0 : *name = talloc_strdup(mem_ctx, builtin_domain_name());
745 0 : return true;
746 : }
747 :
748 7254 : if (sid_check_is_wellknown_domain(sid, &tmp)) {
749 0 : *name = talloc_strdup(mem_ctx, tmp);
750 0 : return true;
751 : }
752 :
753 7254 : if (sid_check_is_unix_users(sid)) {
754 0 : *name = talloc_strdup(mem_ctx, unix_users_domain_name());
755 0 : return true;
756 : }
757 :
758 7254 : if (sid_check_is_unix_groups(sid)) {
759 0 : *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
760 0 : return true;
761 : }
762 :
763 7254 : if (sid->num_auths != 4) {
764 : /* This can't be a domain */
765 6984 : return false;
766 : }
767 :
768 0 : if (IS_DC) {
769 0 : uint32_t i, num_domains;
770 0 : struct trustdom_info **domains;
771 :
772 : /* This is relatively expensive, but it happens only on DCs
773 : * and for SIDs that have 4 sub-authorities and thus look like
774 : * domains */
775 :
776 0 : if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
777 : &num_domains,
778 : &domains))) {
779 0 : return false;
780 : }
781 :
782 0 : for (i=0; i<num_domains; i++) {
783 0 : if (dom_sid_equal(sid, &domains[i]->sid)) {
784 0 : *name = talloc_strdup(mem_ctx,
785 0 : domains[i]->name);
786 0 : return true;
787 : }
788 : }
789 0 : return false;
790 : }
791 :
792 0 : if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
793 0 : (type == SID_NAME_DOMAIN)) {
794 0 : *name = tmp;
795 0 : return true;
796 : }
797 :
798 0 : return false;
799 : }
800 :
801 : /*
802 : * This tries to implement the rather weird rules for the lsa_lookup level
803 : * parameter.
804 : *
805 : * This is as close as we can get to what W2k3 does. With this we survive the
806 : * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
807 : * different, but I assume that's just being too liberal. For example, W2k3
808 : * replies to everything else but the levels 1-6 with INVALID_PARAMETER
809 : * whereas NT4 does the same as level 1 (I think). I did not fully test that
810 : * with NT4, this is what w2k3 does.
811 : *
812 : * Level 1: Ask everywhere
813 : * Level 2: Ask domain and trusted domains, no builtin and wkn
814 : * Level 3: Only ask domain
815 : * Level 4: W2k3ad: Only ask AD trusts
816 : * Level 5: Only ask transitive forest trusts
817 : * Level 6: Like 4
818 : */
819 :
820 7254 : static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
821 : {
822 270 : struct dom_sid_buf buf;
823 7254 : int ret = false;
824 :
825 7254 : switch(level) {
826 7254 : case 1:
827 7254 : ret = true;
828 7254 : break;
829 0 : case 2:
830 0 : ret = (!sid_check_is_builtin(sid) &&
831 0 : !sid_check_is_wellknown_domain(sid, NULL));
832 0 : break;
833 0 : case 3:
834 : case 4:
835 : case 6:
836 0 : ret = sid_check_is_our_sam(sid);
837 0 : break;
838 0 : case 5:
839 0 : ret = false;
840 0 : break;
841 : }
842 :
843 7254 : DEBUG(10, ("%s SID %s in level %d\n",
844 : ret ? "Accepting" : "Rejecting",
845 : dom_sid_str_buf(sid, &buf),
846 : level));
847 7254 : return ret;
848 : }
849 :
850 : /*
851 : * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
852 : * references to domains, it is explicitly made for this.
853 : *
854 : * This attempts to be as efficient as possible: It collects all SIDs
855 : * belonging to a domain and hands them in bulk to the appropriate lookup
856 : * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
857 : * *hugely* from this.
858 : */
859 :
860 6462 : NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
861 : const struct dom_sid **sids, int level,
862 : struct lsa_dom_info **ret_domains,
863 : struct lsa_name_info **ret_names)
864 : {
865 270 : TALLOC_CTX *tmp_ctx;
866 270 : NTSTATUS result;
867 270 : struct lsa_name_info *name_infos;
868 6462 : struct lsa_dom_info *dom_infos = NULL;
869 :
870 270 : int i, j;
871 :
872 6462 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
873 0 : DEBUG(0, ("talloc_new failed\n"));
874 0 : return NT_STATUS_NO_MEMORY;
875 : }
876 :
877 6462 : if (num_sids) {
878 6462 : name_infos = talloc_array(mem_ctx, struct lsa_name_info, num_sids);
879 6462 : if (name_infos == NULL) {
880 0 : result = NT_STATUS_NO_MEMORY;
881 0 : goto fail;
882 : }
883 : } else {
884 0 : name_infos = NULL;
885 : }
886 :
887 6462 : dom_infos = talloc_zero_array(mem_ctx, struct lsa_dom_info,
888 : LSA_REF_DOMAIN_LIST_MULTIPLIER);
889 6462 : if (dom_infos == NULL) {
890 0 : result = NT_STATUS_NO_MEMORY;
891 0 : goto fail;
892 : }
893 :
894 : /* First build up the data structures:
895 : *
896 : * dom_infos is a list of domains referenced in the list of
897 : * SIDs. Later we will walk the list of domains and look up the RIDs
898 : * in bulk.
899 : *
900 : * name_infos is a shadow-copy of the SIDs array to collect the real
901 : * data.
902 : *
903 : * dom_info->idxs is an index into the name_infos array. The
904 : * difficulty we have here is that we need to keep the SIDs the client
905 : * asked for in the same order for the reply
906 : */
907 :
908 13716 : for (i=0; i<num_sids; i++) {
909 270 : struct dom_sid sid;
910 7254 : uint32_t rid = 0;
911 7254 : const char *domain_name = NULL;
912 :
913 7254 : sid_copy(&sid, sids[i]);
914 7254 : name_infos[i].type = SID_NAME_USE_NONE;
915 :
916 7254 : if (lookup_as_domain(&sid, name_infos, &domain_name)) {
917 : /* We can't push that through the normal lookup
918 : * process, as this would reference illegal
919 : * domains.
920 : *
921 : * For example S-1-5-32 would end up referencing
922 : * domain S-1-5- with RID 32 which is clearly wrong.
923 : */
924 0 : if (domain_name == NULL) {
925 0 : result = NT_STATUS_NO_MEMORY;
926 0 : goto fail;
927 : }
928 :
929 0 : name_infos[i].rid = 0;
930 0 : name_infos[i].type = SID_NAME_DOMAIN;
931 0 : name_infos[i].name = NULL;
932 :
933 0 : if (sid_check_is_builtin(&sid)) {
934 : /* Yes, W2k3 returns "BUILTIN" both as domain
935 : * and name here */
936 0 : name_infos[i].name = talloc_strdup(
937 : name_infos, builtin_domain_name());
938 0 : if (name_infos[i].name == NULL) {
939 0 : result = NT_STATUS_NO_MEMORY;
940 0 : goto fail;
941 : }
942 : }
943 : } else {
944 : /* This is a normal SID with rid component */
945 7254 : if (!sid_split_rid(&sid, &rid)) {
946 0 : result = NT_STATUS_INVALID_SID;
947 0 : goto fail;
948 : }
949 : }
950 :
951 7254 : if (!check_dom_sid_to_level(&sid, level)) {
952 0 : name_infos[i].rid = 0;
953 0 : name_infos[i].type = SID_NAME_UNKNOWN;
954 0 : name_infos[i].name = NULL;
955 0 : continue;
956 : }
957 :
958 7254 : for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
959 7254 : if (!dom_infos[j].valid) {
960 6192 : break;
961 : }
962 792 : if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
963 792 : break;
964 : }
965 : }
966 :
967 7254 : if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
968 : /* TODO: What's the right error message here? */
969 0 : result = NT_STATUS_NONE_MAPPED;
970 0 : goto fail;
971 : }
972 :
973 7254 : if (!dom_infos[j].valid) {
974 : /* We found a domain not yet referenced, create a new
975 : * ref. */
976 6462 : dom_infos[j].valid = true;
977 6462 : sid_copy(&dom_infos[j].sid, &sid);
978 :
979 6462 : if (domain_name != NULL) {
980 : /* This name was being found above in the case
981 : * when we found a domain SID */
982 0 : dom_infos[j].name =
983 0 : talloc_strdup(dom_infos, domain_name);
984 0 : if (dom_infos[j].name == NULL) {
985 0 : result = NT_STATUS_NO_MEMORY;
986 0 : goto fail;
987 : }
988 : } else {
989 : /* lookup_rids will take care of this */
990 6462 : dom_infos[j].name = NULL;
991 : }
992 : }
993 :
994 7254 : name_infos[i].dom_idx = j;
995 :
996 7254 : if (name_infos[i].type == SID_NAME_USE_NONE) {
997 7254 : name_infos[i].rid = rid;
998 :
999 7254 : ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
1000 : &dom_infos[j].num_idxs);
1001 :
1002 7254 : if (dom_infos[j].idxs == NULL) {
1003 0 : result = NT_STATUS_NO_MEMORY;
1004 0 : goto fail;
1005 : }
1006 : }
1007 : }
1008 :
1009 : /* Iterate over the domains found */
1010 :
1011 12924 : for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
1012 540 : uint32_t *rids;
1013 12924 : const char *domain_name = NULL;
1014 540 : const char **names;
1015 540 : enum lsa_SidType *types;
1016 12924 : struct lsa_dom_info *dom = &dom_infos[i];
1017 :
1018 12924 : if (!dom->valid) {
1019 : /* No domains left, we're done */
1020 6192 : break;
1021 : }
1022 :
1023 6462 : if (dom->num_idxs == 0) {
1024 : /*
1025 : * This happens only if the only sid related to
1026 : * this domain is the domain sid itself, which
1027 : * is mapped to SID_NAME_DOMAIN above.
1028 : */
1029 0 : continue;
1030 : }
1031 :
1032 6462 : if (!(rids = talloc_array(tmp_ctx, uint32_t, dom->num_idxs))) {
1033 0 : result = NT_STATUS_NO_MEMORY;
1034 0 : goto fail;
1035 : }
1036 :
1037 13716 : for (j=0; j<dom->num_idxs; j++) {
1038 7254 : rids[j] = name_infos[dom->idxs[j]].rid;
1039 : }
1040 :
1041 6462 : if (!lookup_rids(tmp_ctx, &dom->sid,
1042 : dom->num_idxs, rids, &domain_name,
1043 : &names, &types)) {
1044 0 : result = NT_STATUS_NO_MEMORY;
1045 0 : goto fail;
1046 : }
1047 :
1048 6462 : if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
1049 0 : result = NT_STATUS_NO_MEMORY;
1050 0 : goto fail;
1051 : }
1052 :
1053 13716 : for (j=0; j<dom->num_idxs; j++) {
1054 7254 : int idx = dom->idxs[j];
1055 7254 : name_infos[idx].type = types[j];
1056 7254 : if (types[j] != SID_NAME_UNKNOWN) {
1057 14208 : name_infos[idx].name =
1058 7104 : talloc_strdup(name_infos, names[j]);
1059 7104 : if (name_infos[idx].name == NULL) {
1060 0 : result = NT_STATUS_NO_MEMORY;
1061 0 : goto fail;
1062 : }
1063 : } else {
1064 150 : name_infos[idx].name = NULL;
1065 : }
1066 : }
1067 : }
1068 :
1069 6462 : *ret_domains = dom_infos;
1070 6462 : *ret_names = name_infos;
1071 6462 : TALLOC_FREE(tmp_ctx);
1072 6462 : return NT_STATUS_OK;
1073 :
1074 0 : fail:
1075 0 : TALLOC_FREE(dom_infos);
1076 0 : TALLOC_FREE(name_infos);
1077 0 : TALLOC_FREE(tmp_ctx);
1078 0 : return result;
1079 : }
1080 :
1081 : /*****************************************************************
1082 : *THE CANONICAL* convert SID to name function.
1083 : *****************************************************************/
1084 :
1085 5946 : bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
1086 : const char **ret_domain, const char **ret_name,
1087 : enum lsa_SidType *ret_type)
1088 : {
1089 270 : struct lsa_dom_info *domain;
1090 270 : struct lsa_name_info *name;
1091 270 : struct dom_sid_buf buf;
1092 270 : TALLOC_CTX *tmp_ctx;
1093 5946 : bool ret = false;
1094 :
1095 5946 : DEBUG(10, ("lookup_sid called for SID '%s'\n",
1096 : dom_sid_str_buf(sid, &buf)));
1097 :
1098 5946 : if (!(tmp_ctx = talloc_new(mem_ctx))) {
1099 0 : DEBUG(0, ("talloc_new failed\n"));
1100 0 : return false;
1101 : }
1102 :
1103 5946 : if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
1104 : &domain, &name))) {
1105 0 : goto done;
1106 : }
1107 :
1108 5946 : if (name->type == SID_NAME_UNKNOWN) {
1109 0 : goto done;
1110 : }
1111 :
1112 5946 : if ((ret_domain != NULL) &&
1113 14 : !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
1114 0 : goto done;
1115 : }
1116 :
1117 5946 : if ((ret_name != NULL) &&
1118 181 : !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
1119 0 : goto done;
1120 : }
1121 :
1122 5946 : if (ret_type != NULL) {
1123 5932 : *ret_type = name->type;
1124 : }
1125 :
1126 5946 : ret = true;
1127 :
1128 5676 : done:
1129 5676 : if (ret) {
1130 5946 : DEBUG(10, ("Sid %s -> %s\\%s(%d)\n",
1131 : dom_sid_str_buf(sid, &buf),
1132 : domain->name, name->name, name->type));
1133 : } else {
1134 0 : DEBUG(10, ("failed to lookup sid %s\n",
1135 : dom_sid_str_buf(sid, &buf)));
1136 : }
1137 5946 : TALLOC_FREE(tmp_ctx);
1138 5946 : return ret;
1139 : }
1140 :
1141 : /*****************************************************************
1142 : *THE LEGACY* convert SID to id function.
1143 : *****************************************************************/
1144 :
1145 60886 : static bool legacy_sid_to_unixid(const struct dom_sid *psid, struct unixid *id)
1146 : {
1147 55 : bool ret;
1148 :
1149 60886 : become_root();
1150 60886 : ret = pdb_sid_to_id(psid, id);
1151 60886 : unbecome_root();
1152 :
1153 60886 : if (!ret) {
1154 21 : struct dom_sid_buf buf;
1155 60445 : DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1156 : dom_sid_str_buf(psid, &buf)));
1157 60445 : return false;
1158 : }
1159 :
1160 407 : return true;
1161 : }
1162 :
1163 30262 : static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1164 : {
1165 43 : struct unixid id;
1166 30262 : if (!legacy_sid_to_unixid(psid, &id)) {
1167 29920 : return false;
1168 : }
1169 325 : if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) {
1170 273 : *pgid = id.id;
1171 273 : return true;
1172 : }
1173 52 : return false;
1174 : }
1175 :
1176 30624 : static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1177 : {
1178 12 : struct unixid id;
1179 30624 : if (!legacy_sid_to_unixid(psid, &id)) {
1180 30504 : return false;
1181 : }
1182 116 : if (id.type == ID_TYPE_UID || id.type == ID_TYPE_BOTH) {
1183 116 : *puid = id.id;
1184 116 : return true;
1185 : }
1186 0 : return false;
1187 : }
1188 :
1189 1691113 : void xid_to_sid(struct dom_sid *psid, const struct unixid *xid)
1190 : {
1191 1691113 : bool expired = true;
1192 6452 : bool ret;
1193 6452 : struct dom_sid_buf buf;
1194 :
1195 1691113 : SMB_ASSERT(xid->type == ID_TYPE_UID || xid->type == ID_TYPE_GID);
1196 :
1197 1691113 : *psid = (struct dom_sid) {0};
1198 :
1199 1691113 : ret = idmap_cache_find_xid2sid(xid, psid, &expired);
1200 1691113 : if (ret && !expired) {
1201 1504915 : DBG_DEBUG("%cID %"PRIu32" -> %s from cache\n",
1202 : xid->type == ID_TYPE_UID ? 'U' : 'G',
1203 : xid->id,
1204 : dom_sid_str_buf(psid, &buf));
1205 1504915 : goto done;
1206 : }
1207 :
1208 186198 : ret = winbind_xid_to_sid(psid, xid);
1209 186198 : if (ret) {
1210 : /*
1211 : * winbind can return an explicit negative mapping
1212 : * here. It's up to winbind to prime the cache either
1213 : * positively or negatively, don't mess with the cache
1214 : * here.
1215 : */
1216 11678 : DBG_DEBUG("%cID %"PRIu32" -> %s from cache\n",
1217 : xid->type == ID_TYPE_UID ? 'U' : 'G',
1218 : xid->id,
1219 : dom_sid_str_buf(psid, &buf));
1220 11678 : goto done;
1221 : }
1222 :
1223 : {
1224 : /*
1225 : * Make a copy, pdb_id_to_sid might want to turn
1226 : * xid->type into ID_TYPE_BOTH, which we ignore here.
1227 : */
1228 174520 : struct unixid rw_xid = *xid;
1229 :
1230 174520 : become_root();
1231 174520 : ret = pdb_id_to_sid(&rw_xid, psid);
1232 174520 : unbecome_root();
1233 : }
1234 :
1235 174520 : if (ret) {
1236 114 : DBG_DEBUG("%cID %"PRIu32" -> %s from passdb\n",
1237 : xid->type == ID_TYPE_UID ? 'U' : 'G',
1238 : xid->id,
1239 : dom_sid_str_buf(psid, &buf));
1240 114 : goto done;
1241 : }
1242 :
1243 174406 : done:
1244 1691113 : if (is_null_sid(psid)) {
1245 : /*
1246 : * Nobody found anything: Return S-1-22-xx-yy. Don't
1247 : * store that in caches, this is up to the layers
1248 : * beneath us.
1249 : */
1250 344320 : if (xid->type == ID_TYPE_UID) {
1251 798 : uid_to_unix_users_sid(xid->id, psid);
1252 : } else {
1253 343522 : gid_to_unix_groups_sid(xid->id, psid);
1254 : }
1255 :
1256 344320 : DBG_DEBUG("%cID %"PRIu32" -> %s fallback\n",
1257 : xid->type == ID_TYPE_UID ? 'U' : 'G',
1258 : xid->id,
1259 : dom_sid_str_buf(psid, &buf));
1260 : }
1261 1691113 : }
1262 :
1263 719185 : void uid_to_sid(struct dom_sid *psid, uid_t uid)
1264 : {
1265 719185 : struct unixid xid = { .type = ID_TYPE_UID, .id = uid};
1266 719185 : xid_to_sid(psid, &xid);
1267 719185 : }
1268 :
1269 971928 : void gid_to_sid(struct dom_sid *psid, gid_t gid)
1270 : {
1271 971928 : struct unixid xid = { .type = ID_TYPE_GID, .id = gid};
1272 971928 : xid_to_sid(psid, &xid);
1273 971928 : }
1274 :
1275 391311 : bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
1276 : struct unixid *ids)
1277 : {
1278 391311 : struct wbcDomainSid *wbc_sids = NULL;
1279 391311 : struct wbcUnixId *wbc_ids = NULL;
1280 391311 : struct bitmap *found = NULL;
1281 1379 : uint32_t i, num_not_cached;
1282 391311 : uint32_t wbc_ids_size = 0;
1283 1379 : wbcErr err;
1284 391311 : bool ret = false;
1285 :
1286 391311 : wbc_sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_sids);
1287 391311 : if (wbc_sids == NULL) {
1288 0 : return false;
1289 : }
1290 391311 : found = bitmap_talloc(wbc_sids, num_sids);
1291 391311 : if (found == NULL) {
1292 0 : goto fail;
1293 : }
1294 :
1295 : /*
1296 : * We go through the requested SID array three times.
1297 : * First time to look for global_sid_Unix_Users
1298 : * and global_sid_Unix_Groups SIDS, and to look
1299 : * for mappings cached in the idmap_cache.
1300 : *
1301 : * Use bitmap_set() to mark an ids[] array entry as
1302 : * being mapped.
1303 : */
1304 :
1305 389932 : num_not_cached = 0;
1306 :
1307 924520 : for (i=0; i<num_sids; i++) {
1308 1379 : bool expired;
1309 1379 : uint32_t rid;
1310 :
1311 533209 : if (sid_peek_check_rid(&global_sid_Unix_Users,
1312 533209 : &sids[i], &rid)) {
1313 124 : ids[i].type = ID_TYPE_UID;
1314 124 : ids[i].id = rid;
1315 124 : bitmap_set(found, i);
1316 501681 : continue;
1317 : }
1318 533085 : if (sid_peek_check_rid(&global_sid_Unix_Groups,
1319 531706 : &sids[i], &rid)) {
1320 41452 : ids[i].type = ID_TYPE_GID;
1321 41452 : ids[i].id = rid;
1322 41452 : bitmap_set(found, i);
1323 41452 : continue;
1324 : }
1325 491633 : if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
1326 460105 : && !expired)
1327 : {
1328 460105 : bitmap_set(found, i);
1329 460105 : continue;
1330 : }
1331 31528 : ids[i].type = ID_TYPE_NOT_SPECIFIED;
1332 63035 : memcpy(&wbc_sids[num_not_cached], &sids[i],
1333 31507 : ndr_size_dom_sid(&sids[i], 0));
1334 31528 : num_not_cached += 1;
1335 : }
1336 391311 : if (num_not_cached == 0) {
1337 377186 : goto done;
1338 : }
1339 :
1340 : /*
1341 : * For the ones that we couldn't map in the loop above, query winbindd
1342 : * via wbcSidsToUnixIds().
1343 : */
1344 :
1345 14125 : wbc_ids_size = num_not_cached;
1346 14125 : wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, wbc_ids_size);
1347 14125 : if (wbc_ids == NULL) {
1348 0 : goto fail;
1349 : }
1350 45653 : for (i=0; i<wbc_ids_size; i++) {
1351 31528 : wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
1352 31528 : wbc_ids[i].id.gid = (uint32_t)-1;
1353 : }
1354 14125 : err = wbcSidsToUnixIds(wbc_sids, wbc_ids_size, wbc_ids);
1355 14125 : if (!WBC_ERROR_IS_OK(err)) {
1356 12839 : DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1357 : wbcErrorString(err)));
1358 : }
1359 :
1360 : /*
1361 : * Second time through the SID array, replace
1362 : * the ids[] entries that wbcSidsToUnixIds() was able to
1363 : * map.
1364 : *
1365 : * Use bitmap_set() to mark an ids[] array entry as
1366 : * being mapped.
1367 : */
1368 :
1369 14104 : num_not_cached = 0;
1370 :
1371 108221 : for (i=0; i<num_sids; i++) {
1372 94096 : if (bitmap_query(found, i)) {
1373 62568 : continue;
1374 : }
1375 :
1376 31528 : SMB_ASSERT(num_not_cached < wbc_ids_size);
1377 :
1378 31528 : switch (wbc_ids[num_not_cached].type) {
1379 8 : case WBC_ID_TYPE_UID:
1380 8 : ids[i].type = ID_TYPE_UID;
1381 8 : ids[i].id = wbc_ids[num_not_cached].id.uid;
1382 8 : bitmap_set(found, i);
1383 8 : break;
1384 97 : case WBC_ID_TYPE_GID:
1385 97 : ids[i].type = ID_TYPE_GID;
1386 97 : ids[i].id = wbc_ids[num_not_cached].id.gid;
1387 97 : bitmap_set(found, i);
1388 97 : break;
1389 1244 : case WBC_ID_TYPE_BOTH:
1390 1244 : ids[i].type = ID_TYPE_BOTH;
1391 1244 : ids[i].id = wbc_ids[num_not_cached].id.uid;
1392 1244 : bitmap_set(found, i);
1393 1244 : break;
1394 30179 : case WBC_ID_TYPE_NOT_SPECIFIED:
1395 : /*
1396 : * wbcSidsToUnixIds() wasn't able to map this
1397 : * so we still need to check legacy_sid_to_XXX()
1398 : * below. Don't mark the bitmap entry
1399 : * as being found so the final loop knows
1400 : * to try and map this entry.
1401 : */
1402 30179 : ids[i].type = ID_TYPE_NOT_SPECIFIED;
1403 30179 : ids[i].id = (uint32_t)-1;
1404 30179 : break;
1405 0 : default:
1406 : /*
1407 : * A successful return from wbcSidsToUnixIds()
1408 : * cannot return anything other than the values
1409 : * checked for above. Ensure this is so.
1410 : */
1411 0 : smb_panic(__location__);
1412 21 : break;
1413 : }
1414 31528 : num_not_cached += 1;
1415 : }
1416 :
1417 : /*
1418 : * Third and final time through the SID array,
1419 : * try legacy_sid_to_gid()/legacy_sid_to_uid()
1420 : * for entries we haven't already been able to
1421 : * map.
1422 : *
1423 : * Use bitmap_set() to mark an ids[] array entry as
1424 : * being mapped.
1425 : */
1426 :
1427 108221 : for (i=0; i<num_sids; i++) {
1428 94096 : if (bitmap_query(found, i)) {
1429 63917 : continue;
1430 : }
1431 30179 : if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
1432 224 : ids[i].type = ID_TYPE_GID;
1433 224 : bitmap_set(found, i);
1434 224 : continue;
1435 : }
1436 29955 : if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
1437 52 : ids[i].type = ID_TYPE_UID;
1438 52 : bitmap_set(found, i);
1439 52 : continue;
1440 : }
1441 : }
1442 14125 : done:
1443 : /*
1444 : * Pass through the return array for consistency.
1445 : * Any ids[].id mapped to (uint32_t)-1 must be returned
1446 : * as ID_TYPE_NOT_SPECIFIED.
1447 : */
1448 924520 : for (i=0; i<num_sids; i++) {
1449 533209 : switch(ids[i].type) {
1450 502617 : case ID_TYPE_GID:
1451 : case ID_TYPE_UID:
1452 : case ID_TYPE_BOTH:
1453 502617 : if (ids[i].id == (uint32_t)-1) {
1454 0 : ids[i].type = ID_TYPE_NOT_SPECIFIED;
1455 : }
1456 501239 : break;
1457 30591 : case ID_TYPE_NOT_SPECIFIED:
1458 30591 : break;
1459 0 : case ID_TYPE_WB_REQUIRE_TYPE:
1460 : /*
1461 : * these are internal between winbindd
1462 : * parent and child.
1463 : */
1464 0 : smb_panic(__location__);
1465 1379 : break;
1466 : }
1467 : }
1468 :
1469 389932 : ret = true;
1470 391311 : fail:
1471 391311 : TALLOC_FREE(wbc_ids);
1472 391311 : TALLOC_FREE(wbc_sids);
1473 391311 : return ret;
1474 : }
1475 :
1476 : /*****************************************************************
1477 : *THE CANONICAL* convert SID to uid function.
1478 : *****************************************************************/
1479 :
1480 177888 : bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1481 : {
1482 177888 : bool expired = true;
1483 459 : bool ret;
1484 459 : uint32_t rid;
1485 459 : struct dom_sid_buf buf;
1486 :
1487 : /* Optimize for the Unix Users Domain
1488 : * as the conversion is straightforward */
1489 177888 : if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1490 528 : uid_t uid = rid;
1491 528 : *puid = uid;
1492 :
1493 : /* return here, don't cache */
1494 528 : DEBUG(10,("sid %s -> uid %u\n",
1495 : dom_sid_str_buf(psid, &buf),
1496 : (unsigned int)*puid ));
1497 528 : return true;
1498 : }
1499 :
1500 177360 : if (sid_check_is_in_unix_groups(psid)) {
1501 0 : DBG_DEBUG("SID %s is a group, failing\n",
1502 : dom_sid_str_buf(psid, &buf));
1503 0 : return false;
1504 : }
1505 :
1506 : /* Check the winbindd cache directly. */
1507 177360 : ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1508 :
1509 177360 : if (ret && !expired && (*puid == (uid_t)-1)) {
1510 : /*
1511 : * Negative cache entry, we already asked.
1512 : * do legacy.
1513 : */
1514 597 : return legacy_sid_to_uid(psid, puid);
1515 : }
1516 :
1517 176763 : if (!ret || expired) {
1518 : /* Not in cache. Ask winbindd. */
1519 2431 : if (!winbind_sid_to_uid(puid, psid)) {
1520 72 : DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1521 : dom_sid_str_buf(psid, &buf)));
1522 : /* winbind failed. do legacy */
1523 72 : return legacy_sid_to_uid(psid, puid);
1524 : }
1525 : }
1526 :
1527 : /* TODO: Here would be the place to allocate both a gid and a uid for
1528 : * the SID in question */
1529 :
1530 176691 : DEBUG(10,("sid %s -> uid %u\n",
1531 : dom_sid_str_buf(psid, &buf),
1532 : (unsigned int)*puid ));
1533 :
1534 176243 : return true;
1535 : }
1536 :
1537 : /*****************************************************************
1538 : *THE CANONICAL* convert SID to gid function.
1539 : Group mapping is used for gids that maps to Wellknown SIDs
1540 : *****************************************************************/
1541 :
1542 152285 : bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1543 : {
1544 152285 : bool expired = true;
1545 474 : bool ret;
1546 474 : uint32_t rid;
1547 474 : struct dom_sid_buf buf;
1548 :
1549 : /* Optimize for the Unix Groups Domain
1550 : * as the conversion is straightforward */
1551 152285 : if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1552 328 : gid_t gid = rid;
1553 328 : *pgid = gid;
1554 :
1555 : /* return here, don't cache */
1556 328 : DEBUG(10,("sid %s -> gid %u\n",
1557 : dom_sid_str_buf(psid, &buf),
1558 : (unsigned int)*pgid ));
1559 328 : return true;
1560 : }
1561 :
1562 151957 : if (sid_check_is_in_unix_users(psid)) {
1563 0 : DBG_DEBUG("SID %s is a user, failing\n",
1564 : dom_sid_str_buf(psid, &buf));
1565 0 : return false;
1566 : }
1567 :
1568 : /* Check the winbindd cache directly. */
1569 151957 : ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1570 :
1571 151957 : if (ret && !expired && (*pgid == (gid_t)-1)) {
1572 : /*
1573 : * Negative cache entry, we already asked.
1574 : * do legacy.
1575 : */
1576 16 : return legacy_sid_to_gid(psid, pgid);
1577 : }
1578 :
1579 151941 : if (!ret || expired) {
1580 : /* Not in cache or negative. Ask winbindd. */
1581 : /* Ask winbindd if it can map this sid to a gid.
1582 : * (Idmap will check it is a valid SID and of the right type) */
1583 :
1584 1319 : if ( !winbind_sid_to_gid(pgid, psid) ) {
1585 :
1586 67 : DEBUG(10,("winbind failed to find a gid for sid %s\n",
1587 : dom_sid_str_buf(psid, &buf)));
1588 : /* winbind failed. do legacy */
1589 67 : return legacy_sid_to_gid(psid, pgid);
1590 : }
1591 : }
1592 :
1593 151874 : DEBUG(10,("sid %s -> gid %u\n",
1594 : dom_sid_str_buf(psid, &buf),
1595 : (unsigned int)*pgid ));
1596 :
1597 151422 : return true;
1598 : }
1599 :
1600 : /**
1601 : * @brief This function gets the primary group SID mapping the primary
1602 : * GID of the user as obtained by an actual getpwnam() call.
1603 : * This is necessary to avoid issues with arbitrary group SIDs
1604 : * stored in passdb. We try as hard as we can to get the SID
1605 : * corresponding to the GID, including trying group mapping.
1606 : * If nothing else works, we will force "Domain Users" as the
1607 : * primary group.
1608 : * This is needed because we must always be able to lookup the
1609 : * primary group SID, so we cannot settle for an arbitrary SID.
1610 : *
1611 : * This call can be expensive. Use with moderation.
1612 : * If you have a "samu" struct around use pdb_get_group_sid()
1613 : * instead as it does properly cache results.
1614 : *
1615 : * @param mem_ctx[in] The memory context iused to allocate the result.
1616 : * @param username[in] The user's name
1617 : * @param _pwd[in|out] If available, pass in user's passwd struct.
1618 : * It will contain a tallocated passwd if NULL was
1619 : * passed in.
1620 : * @param _group_sid[out] The user's Primary Group SID
1621 : *
1622 : * @return NTSTATUS error code.
1623 : */
1624 45998 : NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1625 : const char *username,
1626 : struct passwd **_pwd,
1627 : struct dom_sid **_group_sid)
1628 : {
1629 1 : TALLOC_CTX *tmp_ctx;
1630 45998 : bool need_lookup_sid = false;
1631 1 : struct dom_sid *group_sid;
1632 45998 : struct passwd *pwd = *_pwd;
1633 :
1634 45998 : tmp_ctx = talloc_new(mem_ctx);
1635 45998 : if (!tmp_ctx) {
1636 0 : return NT_STATUS_NO_MEMORY;
1637 : }
1638 :
1639 45998 : if (!pwd) {
1640 45444 : pwd = Get_Pwnam_alloc(mem_ctx, username);
1641 45444 : if (!pwd) {
1642 0 : DEBUG(0, ("Failed to find a Unix account for %s\n",
1643 : username));
1644 0 : TALLOC_FREE(tmp_ctx);
1645 0 : return NT_STATUS_NO_SUCH_USER;
1646 : }
1647 : }
1648 :
1649 45998 : group_sid = talloc_zero(mem_ctx, struct dom_sid);
1650 45998 : if (!group_sid) {
1651 0 : TALLOC_FREE(tmp_ctx);
1652 0 : return NT_STATUS_NO_MEMORY;
1653 : }
1654 :
1655 45998 : gid_to_sid(group_sid, pwd->pw_gid);
1656 45998 : if (!is_null_sid(group_sid)) {
1657 1 : struct dom_sid domain_sid;
1658 1 : uint32_t rid;
1659 :
1660 : /* We need a sid within our domain */
1661 45998 : sid_copy(&domain_sid, group_sid);
1662 45998 : sid_split_rid(&domain_sid, &rid);
1663 45998 : if (dom_sid_equal(&domain_sid, get_global_sam_sid())) {
1664 : /*
1665 : * As shortcut for the expensive lookup_sid call
1666 : * compare the domain sid part
1667 : */
1668 200 : switch (rid) {
1669 200 : case DOMAIN_RID_ADMINS:
1670 : case DOMAIN_RID_USERS:
1671 200 : goto done;
1672 0 : default:
1673 0 : need_lookup_sid = true;
1674 0 : break;
1675 : }
1676 : } else {
1677 : /* Try group mapping */
1678 1 : struct unixid id;
1679 :
1680 45798 : id.id = pwd->pw_gid;
1681 45798 : id.type = ID_TYPE_GID;
1682 :
1683 45798 : ZERO_STRUCTP(group_sid);
1684 45798 : if (pdb_id_to_sid(&id, group_sid)) {
1685 8 : need_lookup_sid = true;
1686 : }
1687 : }
1688 : }
1689 :
1690 : /* We must verify that this is a valid SID that resolves to a
1691 : * group of the correct type */
1692 45798 : if (need_lookup_sid) {
1693 8 : enum lsa_SidType type = SID_NAME_UNKNOWN;
1694 0 : bool lookup_ret;
1695 0 : struct dom_sid_buf buf;
1696 :
1697 8 : DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1698 : dom_sid_str_buf(group_sid, &buf),
1699 : username));
1700 :
1701 : /* Now check that it's actually a domain group and
1702 : * not something else */
1703 8 : lookup_ret = lookup_sid(tmp_ctx, group_sid,
1704 : NULL, NULL, &type);
1705 :
1706 8 : if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1707 0 : goto done;
1708 : }
1709 :
1710 8 : DEBUG(3, ("Primary group %s for user %s is"
1711 : " a %s and not a domain group\n",
1712 : dom_sid_str_buf(group_sid, &buf),
1713 : username,
1714 : sid_type_lookup(type)));
1715 : }
1716 :
1717 : /* Everything else, failed.
1718 : * Just set it to the 'Domain Users' RID of 513 which will
1719 : always resolve to a name */
1720 45798 : DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1721 : username));
1722 :
1723 45798 : sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1724 :
1725 45998 : done:
1726 45998 : *_pwd = talloc_move(mem_ctx, &pwd);
1727 45998 : *_group_sid = talloc_move(mem_ctx, &group_sid);
1728 45998 : TALLOC_FREE(tmp_ctx);
1729 45998 : return NT_STATUS_OK;
1730 : }
1731 :
|