530fa6bfa0a477500aa7d2860c488511d92cc73f
[metze/samba/wip.git] / source3 / passdb / lookup_sid.c
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 "../librpc/gen_ndr/ndr_security.h"
25 #include "secrets.h"
26 #include "memcache.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"
31
32 /*****************************************************************
33  Dissect a user-provided name into domain, name, sid and type.
34
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
37  to do guesswork.
38 *****************************************************************/  
39
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)
44 {
45         char *p;
46         const char *tmp;
47         const char *domain = NULL;
48         const char *name = NULL;
49         uint32 rid;
50         struct dom_sid sid;
51         enum lsa_SidType type;
52         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
53
54         if (tmp_ctx == NULL) {
55                 DEBUG(0, ("talloc_new failed\n"));
56                 return false;
57         }
58
59         p = strchr_m(full_name, '\\');
60
61         if (p != NULL) {
62                 domain = talloc_strndup(tmp_ctx, full_name,
63                                         PTR_DIFF(p, full_name));
64                 name = talloc_strdup(tmp_ctx, p+1);
65         } else {
66                 domain = talloc_strdup(tmp_ctx, "");
67                 name = talloc_strdup(tmp_ctx, full_name);
68         }
69
70         if ((domain == NULL) || (name == NULL)) {
71                 DEBUG(0, ("talloc failed\n"));
72                 TALLOC_FREE(tmp_ctx);
73                 return false;
74         }
75
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));
79
80         if ((flags & LOOKUP_NAME_DOMAIN) &&
81             strequal(domain, get_global_sam_name()))
82         {
83
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);
87                         goto ok;
88                 }
89                 TALLOC_FREE(tmp_ctx);
90                 return false;
91         }
92
93         if ((flags & LOOKUP_NAME_BUILTIN) &&
94             strequal(domain, builtin_domain_name()))
95         {
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;
101                         goto ok;
102                 }
103
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;
108                         goto ok;
109                 }
110                 TALLOC_FREE(tmp_ctx);
111                 return false;
112         }
113
114         /* Try the explicit winbind lookup first, don't let it guess the
115          * domain yet at this point yet. This comes later. */
116
117         if ((domain[0] != '\0') &&
118             (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
119             (winbind_lookup_name(domain, name, &sid, &type))) {
120                         goto ok;
121         }
122
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;
127                         goto ok;
128                 }
129                 TALLOC_FREE(tmp_ctx);
130                 return false;
131         }
132
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;
137                         goto ok;
138                 }
139                 TALLOC_FREE(tmp_ctx);
140                 return false;
141         }
142
143         if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
144                 TALLOC_FREE(tmp_ctx);
145                 return false;
146         }
147
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 */
152
153         /* 1. well-known names */
154
155         if ((flags & LOOKUP_NAME_WKN) &&
156             lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
157         {
158                 type = SID_NAME_WKN_GRP;
159                 goto ok;
160         }
161
162         /* 2. Builtin domain as such */
163
164         if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
165             strequal(name, builtin_domain_name()))
166         {
167                 /* Swap domain and name */
168                 tmp = name; name = domain; domain = tmp;
169                 sid_copy(&sid, &global_sid_Builtin);
170                 type = SID_NAME_DOMAIN;
171                 goto ok;
172         }
173
174         /* 3. Account domain */
175
176         if ((flags & LOOKUP_NAME_DOMAIN) &&
177             strequal(name, get_global_sam_name()))
178         {
179                 if (!secrets_fetch_domain_sid(name, &sid)) {
180                         DEBUG(3, ("Could not fetch my SID\n"));
181                         TALLOC_FREE(tmp_ctx);
182                         return false;
183                 }
184                 /* Swap domain and name */
185                 tmp = name; name = domain; domain = tmp;
186                 type = SID_NAME_DOMAIN;
187                 goto ok;
188         }
189
190         /* 4. Primary domain */
191
192         if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
193             strequal(name, lp_workgroup()))
194         {
195                 if (!secrets_fetch_domain_sid(name, &sid)) {
196                         DEBUG(3, ("Could not fetch the domain SID\n"));
197                         TALLOC_FREE(tmp_ctx);
198                         return false;
199                 }
200                 /* Swap domain and name */
201                 tmp = name; name = domain; domain = tmp;
202                 type = SID_NAME_DOMAIN;
203                 goto ok;
204         }
205
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 */
208
209         if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
210             (pdb_get_trusteddom_pw(name, NULL, &sid, NULL)))
211         {
212                 /* Swap domain and name */
213                 tmp = name; name = domain; domain = tmp;
214                 type = SID_NAME_DOMAIN;
215                 goto ok;
216         }
217
218         /* 6. Builtin aliases */        
219
220         if ((flags & LOOKUP_NAME_BUILTIN) &&
221             lookup_builtin_name(name, &rid))
222         {
223                 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
224                 sid_compose(&sid, &global_sid_Builtin, rid);
225                 type = SID_NAME_ALIAS;
226                 goto ok;
227         }
228
229         /* 7. Local systems' SAM (DCs don't have a local SAM) */
230         /* 8. Primary SAM (On members, this is the domain) */
231
232         /* Both cases are done by looking at our passdb */
233
234         if ((flags & LOOKUP_NAME_DOMAIN) &&
235             lookup_global_sam_name(name, flags, &rid, &type))
236         {
237                 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
238                 sid_compose(&sid, get_global_sam_sid(), rid);
239                 goto ok;
240         }
241
242         /* Now our local possibilities are exhausted. */
243
244         if (!(flags & LOOKUP_NAME_REMOTE)) {
245                 TALLOC_FREE(tmp_ctx);
246                 return false;
247         }
248
249         /* If we are not a DC, we have to ask in our primary domain. Let
250          * winbind do that. */
251
252         if (!IS_DC &&
253             (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
254                 domain = talloc_strdup(tmp_ctx, lp_workgroup());
255                 goto ok;
256         }
257
258         /* 9. Trusted domains */
259
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. */
262
263         if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
264                 struct dom_sid dom_sid;
265                 enum lsa_SidType domain_type;
266
267                 if (type == SID_NAME_DOMAIN) {
268                         /* Swap name and type */
269                         tmp = name; name = domain; domain = tmp;
270                         goto ok;
271                 }
272
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... */
276
277                 sid_copy(&dom_sid, &sid);
278                 sid_split_rid(&dom_sid, NULL);
279
280                 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
281                                         &domain_type) ||
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);
286                         return false;
287                 }
288                 goto ok;
289         }
290
291         /* 10. Don't translate */
292
293         /* 11. Ok, windows would end here. Samba has two more options:
294                Unmapped users and unmapped groups */
295
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;
300                 goto ok;
301         }
302
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;
307                 goto ok;
308         }
309
310         /*
311          * Ok, all possibilities tried. Fail.
312          */
313
314         TALLOC_FREE(tmp_ctx);
315         return false;
316
317  ok:
318         if ((domain == NULL) || (name == NULL)) {
319                 DEBUG(0, ("talloc failed\n"));
320                 TALLOC_FREE(tmp_ctx);
321                 return false;
322         }
323
324         /*
325          * Hand over the results to the talloc context we've been given.
326          */
327
328         if ((ret_name != NULL) &&
329             !(*ret_name = talloc_strdup(mem_ctx, name))) {
330                 DEBUG(0, ("talloc failed\n"));
331                 TALLOC_FREE(tmp_ctx);
332                 return false;
333         }
334
335         if (ret_domain != NULL) {
336                 char *tmp_dom;
337                 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
338                         DEBUG(0, ("talloc failed\n"));
339                         TALLOC_FREE(tmp_ctx);
340                         return false;
341                 }
342                 if (!strupper_m(tmp_dom)) {
343                         TALLOC_FREE(tmp_ctx);
344                         return false;
345                 }
346                 *ret_domain = tmp_dom;
347         }
348
349         if (ret_sid != NULL) {
350                 sid_copy(ret_sid, &sid);
351         }
352
353         if (ret_type != NULL) {
354                 *ret_type = type;
355         }
356
357         TALLOC_FREE(tmp_ctx);
358         return true;
359 }
360
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 ************************************************************************/
366
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)
371 {
372         char *qualified_name;
373         const char *p;
374
375         /* NB. No winbindd_separator here as lookup_name needs \\' */
376         if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
377
378                 /* The name is already qualified with a domain. */
379
380                 if (*lp_winbind_separator() != '\\') {
381                         char *tmp;
382
383                         /* lookup_name() needs '\\' as a separator */
384
385                         tmp = talloc_strdup(mem_ctx, full_name);
386                         if (!tmp) {
387                                 return false;
388                         }
389                         tmp[p - full_name] = '\\';
390                         full_name = tmp;
391                 }
392
393                 return lookup_name(mem_ctx, full_name, flags,
394                                 ret_domain, ret_name,
395                                 ret_sid, ret_type);
396         }
397
398         /* Try with our own SAM name. */
399         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
400                                 get_global_sam_name(),
401                                 full_name );
402         if (!qualified_name) {
403                 return false;
404         }
405
406         if (lookup_name(mem_ctx, qualified_name, flags,
407                                 ret_domain, ret_name,
408                                 ret_sid, ret_type)) {
409                 return true;
410         }
411
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(),
417                                 full_name );
418         if (!qualified_name) {
419                 return false;
420         }
421
422         return lookup_name(mem_ctx, qualified_name, flags,
423                                 ret_domain, ret_name,
424                                 ret_sid, ret_type);
425 }
426
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)
432 {
433         int i;
434         const char **my_names;
435         enum lsa_SidType *my_types;
436         TALLOC_CTX *tmp_ctx;
437
438         if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
439                 return false;
440         }
441
442         if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
443                                  domain_name, &my_names, &my_types)) {
444                 *domain_name = "";
445                 for (i=0; i<num_rids; i++) {
446                         names[i] = "";
447                         types[i] = SID_NAME_UNKNOWN;
448                 }
449                 TALLOC_FREE(tmp_ctx);
450                 return true;
451         }
452
453         if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
454                 TALLOC_FREE(tmp_ctx);
455                 return false;
456         }
457
458         /*
459          * winbind_lookup_rids allocates its own array. We've been given the
460          * array, so copy it over
461          */
462
463         for (i=0; i<num_rids; i++) {
464                 if (my_names[i] == NULL) {
465                         TALLOC_FREE(tmp_ctx);
466                         return false;
467                 }
468                 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
469                         TALLOC_FREE(tmp_ctx);
470                         return false;
471                 }
472                 types[i] = my_types[i];
473         }
474         TALLOC_FREE(tmp_ctx);
475         return true;
476 }
477
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)
482 {
483         int i;
484
485         DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
486                    sid_string_dbg(domain_sid)));
487
488         if (num_rids) {
489                 *names = talloc_zero_array(mem_ctx, const char *, num_rids);
490                 *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
491
492                 if ((*names == NULL) || (*types == NULL)) {
493                         return false;
494                 }
495
496                 for (i = 0; i < num_rids; i++)
497                         (*types)[i] = SID_NAME_UNKNOWN;
498         } else {
499                 *names = NULL;
500                 *types = NULL;
501         }
502
503         if (sid_check_is_our_sam(domain_sid)) {
504                 NTSTATUS result;
505
506                 if (*domain_name == NULL) {
507                         *domain_name = talloc_strdup(
508                                 mem_ctx, get_global_sam_name());
509                 }
510
511                 if (*domain_name == NULL) {
512                         return false;
513                 }
514
515                 become_root();
516                 result = pdb_lookup_rids(domain_sid, num_rids, rids,
517                                          *names, *types);
518                 unbecome_root();
519
520                 return (NT_STATUS_IS_OK(result) ||
521                         NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
522                         NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
523         }
524
525         if (sid_check_is_builtin(domain_sid)) {
526
527                 if (*domain_name == NULL) {
528                         *domain_name = talloc_strdup(
529                                 mem_ctx, builtin_domain_name());
530                 }
531
532                 if (*domain_name == NULL) {
533                         return false;
534                 }
535
536                 for (i=0; i<num_rids; i++) {
537                         if (lookup_builtin_rid(*names, rids[i],
538                                                &(*names)[i])) {
539                                 if ((*names)[i] == NULL) {
540                                         return false;
541                                 }
542                                 (*types)[i] = SID_NAME_ALIAS;
543                         } else {
544                                 (*types)[i] = SID_NAME_UNKNOWN;
545                         }
546                 }
547                 return true;
548         }
549
550         if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
551                 for (i=0; i<num_rids; i++) {
552                         struct dom_sid sid;
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) {
557                                         return false;
558                                 }
559                                 (*types)[i] = SID_NAME_WKN_GRP;
560                         } else {
561                                 (*types)[i] = SID_NAME_UNKNOWN;
562                         }
563                 }
564                 return true;
565         }
566
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) {
572                                 return false;
573                         }
574                 }
575                 for (i=0; i<num_rids; i++) {
576                         (*names)[i] = talloc_strdup(
577                                 (*names), uidtoname(rids[i]));
578                         if ((*names)[i] == NULL) {
579                                 return false;
580                         }
581                         (*types)[i] = SID_NAME_USER;
582                 }
583                 return true;
584         }
585
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) {
591                                 return false;
592                         }
593                 }
594                 for (i=0; i<num_rids; i++) {
595                         (*names)[i] = talloc_strdup(
596                                 (*names), gidtoname(rids[i]));
597                         if ((*names)[i] == NULL) {
598                                 return false;
599                         }
600                         (*types)[i] = SID_NAME_DOM_GRP;
601                 }
602                 return true;
603         }
604
605         return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
606                               domain_name, *names, *types);
607 }
608
609 /*
610  * Is the SID a domain as such? If yes, lookup its name.
611  */
612
613 static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
614                              const char **name)
615 {
616         const char *tmp;
617         enum lsa_SidType type;
618
619         if (sid_check_is_our_sam(sid)) {
620                 *name = talloc_strdup(mem_ctx, get_global_sam_name());
621                 return true;
622         }
623
624         if (sid_check_is_builtin(sid)) {
625                 *name = talloc_strdup(mem_ctx, builtin_domain_name());
626                 return true;
627         }
628
629         if (sid_check_is_wellknown_domain(sid, &tmp)) {
630                 *name = talloc_strdup(mem_ctx, tmp);
631                 return true;
632         }
633
634         if (sid_check_is_unix_users(sid)) {
635                 *name = talloc_strdup(mem_ctx, unix_users_domain_name());
636                 return true;
637         }
638
639         if (sid_check_is_unix_groups(sid)) {
640                 *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
641                 return true;
642         }
643
644         if (sid->num_auths != 4) {
645                 /* This can't be a domain */
646                 return false;
647         }
648
649         if (IS_DC) {
650                 uint32 i, num_domains;
651                 struct trustdom_info **domains;
652
653                 /* This is relatively expensive, but it happens only on DCs
654                  * and for SIDs that have 4 sub-authorities and thus look like
655                  * domains */
656
657                 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
658                                                           &num_domains,
659                                                           &domains))) {
660                         return false;
661                 }
662
663                 for (i=0; i<num_domains; i++) {
664                         if (dom_sid_equal(sid, &domains[i]->sid)) {
665                                 *name = talloc_strdup(mem_ctx,
666                                                       domains[i]->name);
667                                 return true;
668                         }
669                 }
670                 return false;
671         }
672
673         if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
674             (type == SID_NAME_DOMAIN)) {
675                 *name = tmp;
676                 return true;
677         }
678
679         return false;
680 }
681
682 /*
683  * This tries to implement the rather weird rules for the lsa_lookup level
684  * parameter.
685  *
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.
692  *
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
698  * Level 6: Like 4
699  */
700
701 static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
702 {
703         int ret = false;
704
705         switch(level) {
706         case 1:
707                 ret = true;
708                 break;
709         case 2:
710                 ret = (!sid_check_is_builtin(sid) &&
711                        !sid_check_is_wellknown_domain(sid, NULL));
712                 break;
713         case 3:
714         case 4:
715         case 6:
716                 ret = sid_check_is_our_sam(sid);
717                 break;
718         case 5:
719                 ret = false;
720                 break;
721         }
722
723         DEBUG(10, ("%s SID %s in level %d\n",
724                    ret ? "Accepting" : "Rejecting",
725                    sid_string_dbg(sid), level));
726         return ret;
727 }
728
729 /*
730  * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
731  * references to domains, it is explicitly made for this.
732  *
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.
737  */
738
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)
743 {
744         TALLOC_CTX *tmp_ctx;
745         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
746         struct lsa_name_info *name_infos;
747         struct lsa_dom_info *dom_infos = NULL;
748
749         int i, j;
750
751         if (!(tmp_ctx = talloc_new(mem_ctx))) {
752                 DEBUG(0, ("talloc_new failed\n"));
753                 return NT_STATUS_NO_MEMORY;
754         }
755
756         if (num_sids) {
757                 name_infos = talloc_array(mem_ctx, struct lsa_name_info, num_sids);
758                 if (name_infos == NULL) {
759                         result = NT_STATUS_NO_MEMORY;
760                         goto fail;
761                 }
762         } else {
763                 name_infos = NULL;
764         }
765
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;
770                 goto fail;
771         }
772
773         /* First build up the data structures:
774          * 
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
777          * in bulk.
778          *
779          * name_infos is a shadow-copy of the SIDs array to collect the real
780          * data.
781          *
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
785          */
786
787         for (i=0; i<num_sids; i++) {
788                 struct dom_sid sid;
789                 uint32_t rid = 0;
790                 const char *domain_name = NULL;
791
792                 sid_copy(&sid, sids[i]);
793                 name_infos[i].type = SID_NAME_USE_NONE;
794
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
798                          * domains.
799                          *
800                          * For example S-1-5-32 would end up referencing
801                          * domain S-1-5- with RID 32 which is clearly wrong.
802                          */
803                         if (domain_name == NULL) {
804                                 result = NT_STATUS_NO_MEMORY;
805                                 goto fail;
806                         }
807
808                         name_infos[i].rid = 0;
809                         name_infos[i].type = SID_NAME_DOMAIN;
810                         name_infos[i].name = NULL;
811
812                         if (sid_check_is_builtin(&sid)) {
813                                 /* Yes, W2k3 returns "BUILTIN" both as domain
814                                  * and name here */
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;
819                                         goto fail;
820                                 }
821                         }
822                 } else {
823                         /* This is a normal SID with rid component */
824                         if (!sid_split_rid(&sid, &rid)) {
825                                 result = NT_STATUS_INVALID_SID;
826                                 goto fail;
827                         }
828                 }
829
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;
834                         continue;
835                 }
836
837                 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
838                         if (!dom_infos[j].valid) {
839                                 break;
840                         }
841                         if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
842                                 break;
843                         }
844                 }
845
846                 if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
847                         /* TODO: What's the right error message here? */
848                         result = NT_STATUS_NONE_MAPPED;
849                         goto fail;
850                 }
851
852                 if (!dom_infos[j].valid) {
853                         /* We found a domain not yet referenced, create a new
854                          * ref. */
855                         dom_infos[j].valid = true;
856                         sid_copy(&dom_infos[j].sid, &sid);
857
858                         if (domain_name != NULL) {
859                                 /* This name was being found above in the case
860                                  * when we found a domain SID */
861                                 dom_infos[j].name =
862                                         talloc_strdup(dom_infos, domain_name);
863                                 if (dom_infos[j].name == NULL) {
864                                         result = NT_STATUS_NO_MEMORY;
865                                         goto fail;
866                                 }
867                         } else {
868                                 /* lookup_rids will take care of this */
869                                 dom_infos[j].name = NULL;
870                         }
871                 }
872
873                 name_infos[i].dom_idx = j;
874
875                 if (name_infos[i].type == SID_NAME_USE_NONE) {
876                         name_infos[i].rid = rid;
877
878                         ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
879                                      &dom_infos[j].num_idxs);
880
881                         if (dom_infos[j].idxs == NULL) {
882                                 result = NT_STATUS_NO_MEMORY;
883                                 goto fail;
884                         }
885                 }
886         }
887
888         /* Iterate over the domains found */
889
890         for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
891                 uint32_t *rids;
892                 const char *domain_name = NULL;
893                 const char **names;
894                 enum lsa_SidType *types;
895                 struct lsa_dom_info *dom = &dom_infos[i];
896
897                 if (!dom->valid) {
898                         /* No domains left, we're done */
899                         break;
900                 }
901
902                 if (dom->num_idxs) {
903                         if (!(rids = talloc_array(tmp_ctx, uint32, dom->num_idxs))) {
904                                 result = NT_STATUS_NO_MEMORY;
905                                 goto fail;
906                         }
907                 } else {
908                         rids = NULL;
909                 }
910
911                 for (j=0; j<dom->num_idxs; j++) {
912                         rids[j] = name_infos[dom->idxs[j]].rid;
913                 }
914
915                 if (!lookup_rids(tmp_ctx, &dom->sid,
916                                  dom->num_idxs, rids, &domain_name,
917                                  &names, &types)) {
918                         result = NT_STATUS_NO_MEMORY;
919                         goto fail;
920                 }
921
922                 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
923                         result = NT_STATUS_NO_MEMORY;
924                         goto fail;
925                 }
926
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;
935                                         goto fail;
936                                 }
937                         } else {
938                                 name_infos[idx].name = NULL;
939                         }
940                 }
941         }
942
943         *ret_domains = dom_infos;
944         *ret_names = name_infos;
945         TALLOC_FREE(tmp_ctx);
946         return NT_STATUS_OK;
947
948  fail:
949         TALLOC_FREE(dom_infos);
950         TALLOC_FREE(name_infos);
951         TALLOC_FREE(tmp_ctx);
952         return result;
953 }
954
955 /*****************************************************************
956  *THE CANONICAL* convert SID to name function.
957 *****************************************************************/  
958
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)
962 {
963         struct lsa_dom_info *domain;
964         struct lsa_name_info *name;
965         TALLOC_CTX *tmp_ctx;
966         bool ret = false;
967
968         DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid)));
969
970         if (!(tmp_ctx = talloc_new(mem_ctx))) {
971                 DEBUG(0, ("talloc_new failed\n"));
972                 return false;
973         }
974
975         if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
976                                          &domain, &name))) {
977                 goto done;
978         }
979
980         if (name->type == SID_NAME_UNKNOWN) {
981                 goto done;
982         }
983
984         if ((ret_domain != NULL) &&
985             !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
986                 goto done;
987         }
988
989         if ((ret_name != NULL) && 
990             !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
991                 goto done;
992         }
993
994         if (ret_type != NULL) {
995                 *ret_type = name->type;
996         }
997
998         ret = true;
999
1000  done:
1001         if (ret) {
1002                 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid),
1003                            domain->name, name->name, name->type));
1004         } else {
1005                 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid)));
1006         }
1007         TALLOC_FREE(tmp_ctx);
1008         return ret;
1009 }
1010
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 *****************************************************************/  
1018
1019
1020 /*****************************************************************
1021  *THE LEGACY* convert uid_t to SID function.
1022 *****************************************************************/  
1023
1024 static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
1025 {
1026         bool ret;
1027
1028         ZERO_STRUCTP(psid);
1029
1030         become_root();
1031         ret = pdb_uid_to_sid(uid, psid);
1032         unbecome_root();
1033
1034         if (ret) {
1035                 /* This is a mapped user */
1036                 goto done;
1037         }
1038
1039         /* This is an unmapped user */
1040
1041         uid_to_unix_users_sid(uid, psid);
1042
1043  done:
1044         DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid,
1045                   sid_string_dbg(psid)));
1046
1047         return;
1048 }
1049
1050 /*****************************************************************
1051  *THE LEGACY* convert gid_t to SID function.
1052 *****************************************************************/  
1053
1054 static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid)
1055 {
1056         bool ret;
1057
1058         ZERO_STRUCTP(psid);
1059
1060         become_root();
1061         ret = pdb_gid_to_sid(gid, psid);
1062         unbecome_root();
1063
1064         if (ret) {
1065                 /* This is a mapped group */
1066                 goto done;
1067         }
1068
1069         /* This is an unmapped group */
1070
1071         gid_to_unix_groups_sid(gid, psid);
1072
1073  done:
1074         DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid,
1075                   sid_string_dbg(psid)));
1076
1077         return;
1078 }
1079
1080 /*****************************************************************
1081  *THE LEGACY* convert SID to id function.
1082 *****************************************************************/  
1083
1084 static bool legacy_sid_to_unixid(const struct dom_sid *psid, struct unixid *id)
1085 {
1086         GROUP_MAP *map;
1087         bool ret;
1088         
1089         become_root();
1090         ret = pdb_sid_to_id(psid, id);
1091         unbecome_root();
1092         
1093         if (ret) {
1094                 goto done;
1095         }
1096         
1097         if ((sid_check_is_in_builtin(psid) ||
1098              sid_check_is_in_wellknown_domain(psid))) {
1099                 bool ret;
1100
1101                 map = talloc_zero(NULL, GROUP_MAP);
1102                 if (!map) {
1103                         return false;
1104                 }
1105
1106                 become_root();
1107                 ret = pdb_getgrsid(map, *psid);
1108                 unbecome_root();
1109
1110                 if (ret) {
1111                         id->id = map->gid;
1112                         id->type = ID_TYPE_GID;
1113                         TALLOC_FREE(map);
1114                         goto done;
1115                 }
1116                 TALLOC_FREE(map);
1117                 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1118                           sid_string_dbg(psid)));
1119                 return false;
1120         }
1121
1122         DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1123                   sid_string_dbg(psid)));
1124         return false;
1125
1126 done:
1127         return true;
1128 }
1129
1130 static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1131 {
1132         struct unixid id;
1133         if (!legacy_sid_to_unixid(psid, &id)) {
1134                 return false;
1135         }
1136         if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) {
1137                 *pgid = id.id;
1138                 return true;
1139         }
1140         return false;
1141 }
1142
1143 static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1144 {
1145         struct unixid id;
1146         if (!legacy_sid_to_unixid(psid, &id)) {
1147                 return false;
1148         }
1149         if (id.type == ID_TYPE_UID || id.type == ID_TYPE_BOTH) {
1150                 *puid = id.id;
1151                 return true;
1152         }
1153         return false;
1154 }
1155
1156 /*****************************************************************
1157  *THE CANONICAL* convert uid_t to SID function.
1158 *****************************************************************/  
1159
1160 void uid_to_sid(struct dom_sid *psid, uid_t uid)
1161 {
1162         bool expired = true;
1163         bool ret;
1164         ZERO_STRUCTP(psid);
1165
1166         /* Check the winbindd cache directly. */
1167         ret = idmap_cache_find_uid2sid(uid, psid, &expired);
1168
1169         if (ret && !expired && is_null_sid(psid)) {
1170                 /*
1171                  * Negative cache entry, we already asked.
1172                  * do legacy.
1173                  */
1174                 legacy_uid_to_sid(psid, uid);
1175                 return;
1176         }
1177
1178         if (!ret || expired) {
1179                 /* Not in cache. Ask winbindd. */
1180                 if (!winbind_uid_to_sid(psid, uid)) {
1181                         /*
1182                          * We shouldn't return the NULL SID
1183                          * here if winbind was running and
1184                          * couldn't map, as winbind will have
1185                          * added a negative entry that will
1186                          * cause us to go though the
1187                          * legacy_uid_to_sid()
1188                          * function anyway in the case above
1189                          * the next time we ask.
1190                          */
1191                         DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1192                                   "for uid %u\n", (unsigned int)uid));
1193
1194                         legacy_uid_to_sid(psid, uid);
1195                         return;
1196                 }
1197         }
1198
1199         DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid,
1200                   sid_string_dbg(psid)));
1201
1202         return;
1203 }
1204
1205 /*****************************************************************
1206  *THE CANONICAL* convert gid_t to SID function.
1207 *****************************************************************/  
1208
1209 void gid_to_sid(struct dom_sid *psid, gid_t gid)
1210 {
1211         bool expired = true;
1212         bool ret;
1213         ZERO_STRUCTP(psid);
1214
1215         /* Check the winbindd cache directly. */
1216         ret = idmap_cache_find_gid2sid(gid, psid, &expired);
1217
1218         if (ret && !expired && is_null_sid(psid)) {
1219                 /*
1220                  * Negative cache entry, we already asked.
1221                  * do legacy.
1222                  */
1223                 legacy_gid_to_sid(psid, gid);
1224                 return;
1225         }
1226
1227         if (!ret || expired) {
1228                 /* Not in cache. Ask winbindd. */
1229                 if (!winbind_gid_to_sid(psid, gid)) {
1230                         /*
1231                          * We shouldn't return the NULL SID
1232                          * here if winbind was running and
1233                          * couldn't map, as winbind will have
1234                          * added a negative entry that will
1235                          * cause us to go though the
1236                          * legacy_gid_to_sid()
1237                          * function anyway in the case above
1238                          * the next time we ask.
1239                          */
1240                         DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1241                                   "for gid %u\n", (unsigned int)gid));
1242
1243                         legacy_gid_to_sid(psid, gid);
1244                         return;
1245                 }
1246         }
1247
1248         DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid,
1249                   sid_string_dbg(psid)));
1250
1251         return;
1252 }
1253
1254 bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
1255                      struct unixid *ids)
1256 {
1257         struct wbcDomainSid *wbc_sids = NULL;
1258         struct wbcUnixId *wbc_ids = NULL;
1259         uint32_t i, num_not_cached;
1260         wbcErr err;
1261         bool ret = false;
1262
1263         wbc_sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_sids);
1264         if (wbc_sids == NULL) {
1265                 return false;
1266         }
1267
1268         num_not_cached = 0;
1269
1270         for (i=0; i<num_sids; i++) {
1271                 bool expired;
1272                 uint32_t rid;
1273
1274                 if (sid_peek_check_rid(&global_sid_Unix_Users,
1275                                        &sids[i], &rid)) {
1276                         ids[i].type = ID_TYPE_UID;
1277                         ids[i].id = rid;
1278                         continue;
1279                 }
1280                 if (sid_peek_check_rid(&global_sid_Unix_Groups,
1281                                        &sids[i], &rid)) {
1282                         ids[i].type = ID_TYPE_GID;
1283                         ids[i].id = rid;
1284                         continue;
1285                 }
1286                 if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
1287                     && !expired)
1288                 {
1289                         continue;
1290                 }
1291                 ids[i].type = ID_TYPE_NOT_SPECIFIED;
1292                 memcpy(&wbc_sids[num_not_cached], &sids[i],
1293                        ndr_size_dom_sid(&sids[i], 0));
1294                 num_not_cached += 1;
1295         }
1296         if (num_not_cached == 0) {
1297                 goto done;
1298         }
1299         wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, num_not_cached);
1300         if (wbc_ids == NULL) {
1301                 goto fail;
1302         }
1303         for (i=0; i<num_not_cached; i++) {
1304                 wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
1305         }
1306         err = wbcSidsToUnixIds(wbc_sids, num_not_cached, wbc_ids);
1307         if (!WBC_ERROR_IS_OK(err)) {
1308                 DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1309                            wbcErrorString(err)));
1310         }
1311
1312         num_not_cached = 0;
1313
1314         for (i=0; i<num_sids; i++) {
1315                 if (ids[i].type == ID_TYPE_NOT_SPECIFIED) {
1316                         switch (wbc_ids[num_not_cached].type) {
1317                         case WBC_ID_TYPE_UID:
1318                                 ids[i].type = ID_TYPE_UID;
1319                                 ids[i].id = wbc_ids[num_not_cached].id.uid;
1320                                 break;
1321                         case WBC_ID_TYPE_GID:
1322                                 ids[i].type = ID_TYPE_GID;
1323                                 ids[i].id = wbc_ids[num_not_cached].id.gid;
1324                                 break;
1325                         default:
1326                                 /* The types match, and wbcUnixId -> id is a union anyway */
1327                                 ids[i].type = (enum id_type)wbc_ids[num_not_cached].type;
1328                                 ids[i].id = wbc_ids[num_not_cached].id.gid;
1329                                 break;
1330                         }
1331                         num_not_cached += 1;
1332                 }
1333         }
1334
1335         for (i=0; i<num_sids; i++) {
1336                 if (ids[i].type != ID_TYPE_NOT_SPECIFIED) {
1337                         continue;
1338                 }
1339                 if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
1340                         ids[i].type = ID_TYPE_GID;
1341                         continue;
1342                 }
1343                 if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
1344                         ids[i].type = ID_TYPE_UID;
1345                         continue;
1346                 }
1347         }
1348 done:
1349         for (i=0; i<num_sids; i++) {
1350                 switch(ids[i].type) {
1351                 case WBC_ID_TYPE_GID:
1352                 case WBC_ID_TYPE_UID:
1353                 case WBC_ID_TYPE_BOTH:
1354                         if (ids[i].id == -1) {
1355                                 ids[i].type = ID_TYPE_NOT_SPECIFIED;
1356                         }
1357                         break;
1358                 case WBC_ID_TYPE_NOT_SPECIFIED:
1359                         break;
1360                 }
1361         }
1362
1363         ret = true;
1364 fail:
1365         TALLOC_FREE(wbc_ids);
1366         TALLOC_FREE(wbc_sids);
1367         return ret;
1368 }
1369
1370 /*****************************************************************
1371  *THE CANONICAL* convert SID to uid function.
1372 *****************************************************************/  
1373
1374 bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1375 {
1376         bool expired = true;
1377         bool ret;
1378         uint32 rid;
1379
1380         /* Optimize for the Unix Users Domain
1381          * as the conversion is straightforward */
1382         if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1383                 uid_t uid = rid;
1384                 *puid = uid;
1385
1386                 /* return here, don't cache */
1387                 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1388                         (unsigned int)*puid ));
1389                 return true;
1390         }
1391
1392         /* Check the winbindd cache directly. */
1393         ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1394
1395         if (ret && !expired && (*puid == (uid_t)-1)) {
1396                 /*
1397                  * Negative cache entry, we already asked.
1398                  * do legacy.
1399                  */
1400                 return legacy_sid_to_uid(psid, puid);
1401         }
1402
1403         if (!ret || expired) {
1404                 /* Not in cache. Ask winbindd. */
1405                 if (!winbind_sid_to_uid(puid, psid)) {
1406                         DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1407                                   sid_string_dbg(psid)));
1408                         /* winbind failed. do legacy */
1409                         return legacy_sid_to_uid(psid, puid);
1410                 }
1411         }
1412
1413         /* TODO: Here would be the place to allocate both a gid and a uid for
1414          * the SID in question */
1415
1416         DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1417                 (unsigned int)*puid ));
1418
1419         return true;
1420 }
1421
1422 /*****************************************************************
1423  *THE CANONICAL* convert SID to gid function.
1424  Group mapping is used for gids that maps to Wellknown SIDs
1425 *****************************************************************/  
1426
1427 bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1428 {
1429         bool expired = true;
1430         bool ret;
1431         uint32 rid;
1432
1433         /* Optimize for the Unix Groups Domain
1434          * as the conversion is straightforward */
1435         if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1436                 gid_t gid = rid;
1437                 *pgid = gid;
1438
1439                 /* return here, don't cache */
1440                 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1441                         (unsigned int)*pgid ));
1442                 return true;
1443         }
1444
1445         /* Check the winbindd cache directly. */
1446         ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1447
1448         if (ret && !expired && (*pgid == (gid_t)-1)) {
1449                 /*
1450                  * Negative cache entry, we already asked.
1451                  * do legacy.
1452                  */
1453                 return legacy_sid_to_gid(psid, pgid);
1454         }
1455
1456         if (!ret || expired) {
1457                 /* Not in cache or negative. Ask winbindd. */
1458                 /* Ask winbindd if it can map this sid to a gid.
1459                  * (Idmap will check it is a valid SID and of the right type) */
1460
1461                 if ( !winbind_sid_to_gid(pgid, psid) ) {
1462
1463                         DEBUG(10,("winbind failed to find a gid for sid %s\n",
1464                                   sid_string_dbg(psid)));
1465                         /* winbind failed. do legacy */
1466                         return legacy_sid_to_gid(psid, pgid);
1467                 }
1468         }
1469
1470         DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1471                   (unsigned int)*pgid ));
1472
1473         return true;
1474 }
1475
1476 /**
1477  * @brief This function gets the primary group SID mapping the primary
1478  *        GID of the user as obtained by an actual getpwnam() call.
1479  *        This is necessary to avoid issues with arbitrary group SIDs
1480  *        stored in passdb. We try as hard as we can to get the SID
1481  *        corresponding to the GID, including trying group mapping.
1482  *        If nothing else works, we will force "Domain Users" as the
1483  *        primary group.
1484  *        This is needed because we must always be able to lookup the
1485  *        primary group SID, so we cannot settle for an arbitrary SID.
1486  *
1487  *        This call can be expensive. Use with moderation.
1488  *        If you have a "samu" struct around use pdb_get_group_sid()
1489  *        instead as it does properly cache results.
1490  *
1491  * @param mem_ctx[in]     The memory context iused to allocate the result.
1492  * @param username[in]    The user's name
1493  * @param _pwd[in|out]    If available, pass in user's passwd struct.
1494  *                        It will contain a tallocated passwd if NULL was
1495  *                        passed in.
1496  * @param _group_sid[out] The user's Primary Group SID
1497  *
1498  * @return NTSTATUS error code.
1499  */
1500 NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1501                                 const char *username,
1502                                 struct passwd **_pwd,
1503                                 struct dom_sid **_group_sid)
1504 {
1505         TALLOC_CTX *tmp_ctx;
1506         bool need_lookup_sid = false;
1507         struct dom_sid *group_sid;
1508         struct passwd *pwd = *_pwd;
1509
1510         tmp_ctx = talloc_new(mem_ctx);
1511         if (!tmp_ctx) {
1512                 return NT_STATUS_NO_MEMORY;
1513         }
1514
1515         if (!pwd) {
1516                 pwd = Get_Pwnam_alloc(mem_ctx, username);
1517                 if (!pwd) {
1518                         DEBUG(0, ("Failed to find a Unix account for %s",
1519                                   username));
1520                         TALLOC_FREE(tmp_ctx);
1521                         return NT_STATUS_NO_SUCH_USER;
1522                 }
1523         }
1524
1525         group_sid = talloc_zero(mem_ctx, struct dom_sid);
1526         if (!group_sid) {
1527                 TALLOC_FREE(tmp_ctx);
1528                 return NT_STATUS_NO_MEMORY;
1529         }
1530
1531         gid_to_sid(group_sid, pwd->pw_gid);
1532         if (!is_null_sid(group_sid)) {
1533                 struct dom_sid domain_sid;
1534                 uint32_t rid;
1535
1536                 /* We need a sid within our domain */
1537                 sid_copy(&domain_sid, group_sid);
1538                 sid_split_rid(&domain_sid, &rid);
1539                 if (dom_sid_equal(&domain_sid, get_global_sam_sid())) {
1540                         /*
1541                          * As shortcut for the expensive lookup_sid call
1542                          * compare the domain sid part
1543                          */
1544                         switch (rid) {
1545                         case DOMAIN_RID_ADMINS:
1546                         case DOMAIN_RID_USERS:
1547                                 goto done;
1548                         default:
1549                                 need_lookup_sid = true;
1550                                 break;
1551                         }
1552                 } else {
1553                         /* Try group mapping */
1554                         ZERO_STRUCTP(group_sid);
1555                         if (pdb_gid_to_sid(pwd->pw_gid, group_sid)) {
1556                                 need_lookup_sid = true;
1557                         }
1558                 }
1559         }
1560
1561         /* We must verify that this is a valid SID that resolves to a
1562          * group of the correct type */
1563         if (need_lookup_sid) {
1564                 enum lsa_SidType type = SID_NAME_UNKNOWN;
1565                 bool lookup_ret;
1566
1567                 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1568                            sid_string_dbg(group_sid), username));
1569
1570                 /* Now check that it's actually a domain group and
1571                  * not something else */
1572                 lookup_ret = lookup_sid(tmp_ctx, group_sid,
1573                                         NULL, NULL, &type);
1574
1575                 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1576                         goto done;
1577                 }
1578
1579                 DEBUG(3, ("Primary group %s for user %s is"
1580                           " a %s and not a domain group\n",
1581                           sid_string_dbg(group_sid), username,
1582                           sid_type_lookup(type)));
1583         }
1584
1585         /* Everything else, failed.
1586          * Just set it to the 'Domain Users' RID of 513 which will
1587            always resolve to a name */
1588         DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1589                   username));
1590
1591         sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1592
1593 done:
1594         *_pwd = talloc_move(mem_ctx, &pwd);
1595         *_group_sid = talloc_move(mem_ctx, &group_sid);
1596         TALLOC_FREE(tmp_ctx);
1597         return NT_STATUS_OK;
1598 }
1599