9b2f548e550779035b79831f6e792da65cea5862
[mat/samba.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                 strupper_m(tmp_dom);
343                 *ret_domain = tmp_dom;
344         }
345
346         if (ret_sid != NULL) {
347                 sid_copy(ret_sid, &sid);
348         }
349
350         if (ret_type != NULL) {
351                 *ret_type = type;
352         }
353
354         TALLOC_FREE(tmp_ctx);
355         return true;
356 }
357
358 /************************************************************************
359  Names from smb.conf can be unqualified. eg. valid users = foo
360  These names should never map to a remote name. Try global_sam_name()\foo,
361  and then "Unix Users"\foo (or "Unix Groups"\foo).
362 ************************************************************************/
363
364 bool lookup_name_smbconf(TALLOC_CTX *mem_ctx,
365                  const char *full_name, int flags,
366                  const char **ret_domain, const char **ret_name,
367                  struct dom_sid *ret_sid, enum lsa_SidType *ret_type)
368 {
369         char *qualified_name;
370         const char *p;
371
372         /* NB. No winbindd_separator here as lookup_name needs \\' */
373         if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
374
375                 /* The name is already qualified with a domain. */
376
377                 if (*lp_winbind_separator() != '\\') {
378                         char *tmp;
379
380                         /* lookup_name() needs '\\' as a separator */
381
382                         tmp = talloc_strdup(mem_ctx, full_name);
383                         if (!tmp) {
384                                 return false;
385                         }
386                         tmp[p - full_name] = '\\';
387                         full_name = tmp;
388                 }
389
390                 return lookup_name(mem_ctx, full_name, flags,
391                                 ret_domain, ret_name,
392                                 ret_sid, ret_type);
393         }
394
395         /* Try with our own SAM name. */
396         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
397                                 get_global_sam_name(),
398                                 full_name );
399         if (!qualified_name) {
400                 return false;
401         }
402
403         if (lookup_name(mem_ctx, qualified_name, flags,
404                                 ret_domain, ret_name,
405                                 ret_sid, ret_type)) {
406                 return true;
407         }
408
409         /* Finally try with "Unix Users" or "Unix Group" */
410         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
411                                 flags & LOOKUP_NAME_GROUP ?
412                                         unix_groups_domain_name() :
413                                         unix_users_domain_name(),
414                                 full_name );
415         if (!qualified_name) {
416                 return false;
417         }
418
419         return lookup_name(mem_ctx, qualified_name, flags,
420                                 ret_domain, ret_name,
421                                 ret_sid, ret_type);
422 }
423
424 static bool wb_lookup_rids(TALLOC_CTX *mem_ctx,
425                            const struct dom_sid *domain_sid,
426                            int num_rids, uint32 *rids,
427                            const char **domain_name,
428                            const char **names, enum lsa_SidType *types)
429 {
430         int i;
431         const char **my_names;
432         enum lsa_SidType *my_types;
433         TALLOC_CTX *tmp_ctx;
434
435         if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
436                 return false;
437         }
438
439         if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
440                                  domain_name, &my_names, &my_types)) {
441                 *domain_name = "";
442                 for (i=0; i<num_rids; i++) {
443                         names[i] = "";
444                         types[i] = SID_NAME_UNKNOWN;
445                 }
446                 TALLOC_FREE(tmp_ctx);
447                 return true;
448         }
449
450         if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
451                 TALLOC_FREE(tmp_ctx);
452                 return false;
453         }
454
455         /*
456          * winbind_lookup_rids allocates its own array. We've been given the
457          * array, so copy it over
458          */
459
460         for (i=0; i<num_rids; i++) {
461                 if (my_names[i] == NULL) {
462                         TALLOC_FREE(tmp_ctx);
463                         return false;
464                 }
465                 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
466                         TALLOC_FREE(tmp_ctx);
467                         return false;
468                 }
469                 types[i] = my_types[i];
470         }
471         TALLOC_FREE(tmp_ctx);
472         return true;
473 }
474
475 static bool lookup_rids(TALLOC_CTX *mem_ctx, const struct dom_sid *domain_sid,
476                         int num_rids, uint32_t *rids,
477                         const char **domain_name,
478                         const char ***names, enum lsa_SidType **types)
479 {
480         int i;
481
482         DEBUG(10, ("lookup_rids called for domain sid '%s'\n",
483                    sid_string_dbg(domain_sid)));
484
485         if (num_rids) {
486                 *names = talloc_zero_array(mem_ctx, const char *, num_rids);
487                 *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids);
488
489                 if ((*names == NULL) || (*types == NULL)) {
490                         return false;
491                 }
492
493                 for (i = 0; i < num_rids; i++)
494                         (*types)[i] = SID_NAME_UNKNOWN;
495         } else {
496                 *names = NULL;
497                 *types = NULL;
498         }
499
500         if (sid_check_is_our_sam(domain_sid)) {
501                 NTSTATUS result;
502
503                 if (*domain_name == NULL) {
504                         *domain_name = talloc_strdup(
505                                 mem_ctx, get_global_sam_name());
506                 }
507
508                 if (*domain_name == NULL) {
509                         return false;
510                 }
511
512                 become_root();
513                 result = pdb_lookup_rids(domain_sid, num_rids, rids,
514                                          *names, *types);
515                 unbecome_root();
516
517                 return (NT_STATUS_IS_OK(result) ||
518                         NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
519                         NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
520         }
521
522         if (sid_check_is_builtin(domain_sid)) {
523
524                 if (*domain_name == NULL) {
525                         *domain_name = talloc_strdup(
526                                 mem_ctx, builtin_domain_name());
527                 }
528
529                 if (*domain_name == NULL) {
530                         return false;
531                 }
532
533                 for (i=0; i<num_rids; i++) {
534                         if (lookup_builtin_rid(*names, rids[i],
535                                                &(*names)[i])) {
536                                 if ((*names)[i] == NULL) {
537                                         return false;
538                                 }
539                                 (*types)[i] = SID_NAME_ALIAS;
540                         } else {
541                                 (*types)[i] = SID_NAME_UNKNOWN;
542                         }
543                 }
544                 return true;
545         }
546
547         if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
548                 for (i=0; i<num_rids; i++) {
549                         struct dom_sid sid;
550                         sid_compose(&sid, domain_sid, rids[i]);
551                         if (lookup_wellknown_sid(mem_ctx, &sid,
552                                                  domain_name, &(*names)[i])) {
553                                 if ((*names)[i] == NULL) {
554                                         return false;
555                                 }
556                                 (*types)[i] = SID_NAME_WKN_GRP;
557                         } else {
558                                 (*types)[i] = SID_NAME_UNKNOWN;
559                         }
560                 }
561                 return true;
562         }
563
564         if (sid_check_is_unix_users(domain_sid)) {
565                 if (*domain_name == NULL) {
566                         *domain_name = talloc_strdup(
567                                 mem_ctx, unix_users_domain_name());
568                         if (*domain_name == NULL) {
569                                 return false;
570                         }
571                 }
572                 for (i=0; i<num_rids; i++) {
573                         (*names)[i] = talloc_strdup(
574                                 (*names), uidtoname(rids[i]));
575                         if ((*names)[i] == NULL) {
576                                 return false;
577                         }
578                         (*types)[i] = SID_NAME_USER;
579                 }
580                 return true;
581         }
582
583         if (sid_check_is_unix_groups(domain_sid)) {
584                 if (*domain_name == NULL) {
585                         *domain_name = talloc_strdup(
586                                 mem_ctx, unix_groups_domain_name());
587                         if (*domain_name == NULL) {
588                                 return false;
589                         }
590                 }
591                 for (i=0; i<num_rids; i++) {
592                         (*names)[i] = talloc_strdup(
593                                 (*names), gidtoname(rids[i]));
594                         if ((*names)[i] == NULL) {
595                                 return false;
596                         }
597                         (*types)[i] = SID_NAME_DOM_GRP;
598                 }
599                 return true;
600         }
601
602         return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
603                               domain_name, *names, *types);
604 }
605
606 /*
607  * Is the SID a domain as such? If yes, lookup its name.
608  */
609
610 static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx,
611                              const char **name)
612 {
613         const char *tmp;
614         enum lsa_SidType type;
615
616         if (sid_check_is_our_sam(sid)) {
617                 *name = talloc_strdup(mem_ctx, get_global_sam_name());
618                 return true;
619         }
620
621         if (sid_check_is_builtin(sid)) {
622                 *name = talloc_strdup(mem_ctx, builtin_domain_name());
623                 return true;
624         }
625
626         if (sid_check_is_wellknown_domain(sid, &tmp)) {
627                 *name = talloc_strdup(mem_ctx, tmp);
628                 return true;
629         }
630
631         if (sid_check_is_unix_users(sid)) {
632                 *name = talloc_strdup(mem_ctx, unix_users_domain_name());
633                 return true;
634         }
635
636         if (sid_check_is_unix_groups(sid)) {
637                 *name = talloc_strdup(mem_ctx, unix_groups_domain_name());
638                 return true;
639         }
640
641         if (sid->num_auths != 4) {
642                 /* This can't be a domain */
643                 return false;
644         }
645
646         if (IS_DC) {
647                 uint32 i, num_domains;
648                 struct trustdom_info **domains;
649
650                 /* This is relatively expensive, but it happens only on DCs
651                  * and for SIDs that have 4 sub-authorities and thus look like
652                  * domains */
653
654                 if (!NT_STATUS_IS_OK(pdb_enum_trusteddoms(mem_ctx,
655                                                           &num_domains,
656                                                           &domains))) {
657                         return false;
658                 }
659
660                 for (i=0; i<num_domains; i++) {
661                         if (dom_sid_equal(sid, &domains[i]->sid)) {
662                                 *name = talloc_strdup(mem_ctx,
663                                                       domains[i]->name);
664                                 return true;
665                         }
666                 }
667                 return false;
668         }
669
670         if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
671             (type == SID_NAME_DOMAIN)) {
672                 *name = tmp;
673                 return true;
674         }
675
676         return false;
677 }
678
679 /*
680  * This tries to implement the rather weird rules for the lsa_lookup level
681  * parameter.
682  *
683  * This is as close as we can get to what W2k3 does. With this we survive the
684  * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
685  * different, but I assume that's just being too liberal. For example, W2k3
686  * replies to everything else but the levels 1-6 with INVALID_PARAMETER
687  * whereas NT4 does the same as level 1 (I think). I did not fully test that
688  * with NT4, this is what w2k3 does.
689  *
690  * Level 1: Ask everywhere
691  * Level 2: Ask domain and trusted domains, no builtin and wkn
692  * Level 3: Only ask domain
693  * Level 4: W2k3ad: Only ask AD trusts
694  * Level 5: Only ask transitive forest trusts
695  * Level 6: Like 4
696  */
697
698 static bool check_dom_sid_to_level(const struct dom_sid *sid, int level)
699 {
700         int ret = false;
701
702         switch(level) {
703         case 1:
704                 ret = true;
705                 break;
706         case 2:
707                 ret = (!sid_check_is_builtin(sid) &&
708                        !sid_check_is_wellknown_domain(sid, NULL));
709                 break;
710         case 3:
711         case 4:
712         case 6:
713                 ret = sid_check_is_our_sam(sid);
714                 break;
715         case 5:
716                 ret = false;
717                 break;
718         }
719
720         DEBUG(10, ("%s SID %s in level %d\n",
721                    ret ? "Accepting" : "Rejecting",
722                    sid_string_dbg(sid), level));
723         return ret;
724 }
725
726 /*
727  * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
728  * references to domains, it is explicitly made for this.
729  *
730  * This attempts to be as efficient as possible: It collects all SIDs
731  * belonging to a domain and hands them in bulk to the appropriate lookup
732  * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
733  * *hugely* from this.
734  */
735
736 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
737                      const struct dom_sid **sids, int level,
738                      struct lsa_dom_info **ret_domains,
739                      struct lsa_name_info **ret_names)
740 {
741         TALLOC_CTX *tmp_ctx;
742         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
743         struct lsa_name_info *name_infos;
744         struct lsa_dom_info *dom_infos = NULL;
745
746         int i, j;
747
748         if (!(tmp_ctx = talloc_new(mem_ctx))) {
749                 DEBUG(0, ("talloc_new failed\n"));
750                 return NT_STATUS_NO_MEMORY;
751         }
752
753         if (num_sids) {
754                 name_infos = talloc_array(mem_ctx, struct lsa_name_info, num_sids);
755                 if (name_infos == NULL) {
756                         result = NT_STATUS_NO_MEMORY;
757                         goto fail;
758                 }
759         } else {
760                 name_infos = NULL;
761         }
762
763         dom_infos = talloc_zero_array(mem_ctx, struct lsa_dom_info,
764                                       LSA_REF_DOMAIN_LIST_MULTIPLIER);
765         if (dom_infos == NULL) {
766                 result = NT_STATUS_NO_MEMORY;
767                 goto fail;
768         }
769
770         /* First build up the data structures:
771          * 
772          * dom_infos is a list of domains referenced in the list of
773          * SIDs. Later we will walk the list of domains and look up the RIDs
774          * in bulk.
775          *
776          * name_infos is a shadow-copy of the SIDs array to collect the real
777          * data.
778          *
779          * dom_info->idxs is an index into the name_infos array. The
780          * difficulty we have here is that we need to keep the SIDs the client
781          * asked for in the same order for the reply
782          */
783
784         for (i=0; i<num_sids; i++) {
785                 struct dom_sid sid;
786                 uint32_t rid = 0;
787                 const char *domain_name = NULL;
788
789                 sid_copy(&sid, sids[i]);
790                 name_infos[i].type = SID_NAME_USE_NONE;
791
792                 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
793                         /* We can't push that through the normal lookup
794                          * process, as this would reference illegal
795                          * domains.
796                          *
797                          * For example S-1-5-32 would end up referencing
798                          * domain S-1-5- with RID 32 which is clearly wrong.
799                          */
800                         if (domain_name == NULL) {
801                                 result = NT_STATUS_NO_MEMORY;
802                                 goto fail;
803                         }
804
805                         name_infos[i].rid = 0;
806                         name_infos[i].type = SID_NAME_DOMAIN;
807                         name_infos[i].name = NULL;
808
809                         if (sid_check_is_builtin(&sid)) {
810                                 /* Yes, W2k3 returns "BUILTIN" both as domain
811                                  * and name here */
812                                 name_infos[i].name = talloc_strdup(
813                                         name_infos, builtin_domain_name());
814                                 if (name_infos[i].name == NULL) {
815                                         result = NT_STATUS_NO_MEMORY;
816                                         goto fail;
817                                 }
818                         }
819                 } else {
820                         /* This is a normal SID with rid component */
821                         if (!sid_split_rid(&sid, &rid)) {
822                                 result = NT_STATUS_INVALID_SID;
823                                 goto fail;
824                         }
825                 }
826
827                 if (!check_dom_sid_to_level(&sid, level)) {
828                         name_infos[i].rid = 0;
829                         name_infos[i].type = SID_NAME_UNKNOWN;
830                         name_infos[i].name = NULL;
831                         continue;
832                 }
833
834                 for (j=0; j<LSA_REF_DOMAIN_LIST_MULTIPLIER; j++) {
835                         if (!dom_infos[j].valid) {
836                                 break;
837                         }
838                         if (dom_sid_equal(&sid, &dom_infos[j].sid)) {
839                                 break;
840                         }
841                 }
842
843                 if (j == LSA_REF_DOMAIN_LIST_MULTIPLIER) {
844                         /* TODO: What's the right error message here? */
845                         result = NT_STATUS_NONE_MAPPED;
846                         goto fail;
847                 }
848
849                 if (!dom_infos[j].valid) {
850                         /* We found a domain not yet referenced, create a new
851                          * ref. */
852                         dom_infos[j].valid = true;
853                         sid_copy(&dom_infos[j].sid, &sid);
854
855                         if (domain_name != NULL) {
856                                 /* This name was being found above in the case
857                                  * when we found a domain SID */
858                                 dom_infos[j].name =
859                                         talloc_strdup(dom_infos, domain_name);
860                                 if (dom_infos[j].name == NULL) {
861                                         result = NT_STATUS_NO_MEMORY;
862                                         goto fail;
863                                 }
864                         } else {
865                                 /* lookup_rids will take care of this */
866                                 dom_infos[j].name = NULL;
867                         }
868                 }
869
870                 name_infos[i].dom_idx = j;
871
872                 if (name_infos[i].type == SID_NAME_USE_NONE) {
873                         name_infos[i].rid = rid;
874
875                         ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
876                                      &dom_infos[j].num_idxs);
877
878                         if (dom_infos[j].idxs == NULL) {
879                                 result = NT_STATUS_NO_MEMORY;
880                                 goto fail;
881                         }
882                 }
883         }
884
885         /* Iterate over the domains found */
886
887         for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
888                 uint32_t *rids;
889                 const char *domain_name = NULL;
890                 const char **names;
891                 enum lsa_SidType *types;
892                 struct lsa_dom_info *dom = &dom_infos[i];
893
894                 if (!dom->valid) {
895                         /* No domains left, we're done */
896                         break;
897                 }
898
899                 if (dom->num_idxs) {
900                         if (!(rids = talloc_array(tmp_ctx, uint32, dom->num_idxs))) {
901                                 result = NT_STATUS_NO_MEMORY;
902                                 goto fail;
903                         }
904                 } else {
905                         rids = NULL;
906                 }
907
908                 for (j=0; j<dom->num_idxs; j++) {
909                         rids[j] = name_infos[dom->idxs[j]].rid;
910                 }
911
912                 if (!lookup_rids(tmp_ctx, &dom->sid,
913                                  dom->num_idxs, rids, &domain_name,
914                                  &names, &types)) {
915                         result = NT_STATUS_NO_MEMORY;
916                         goto fail;
917                 }
918
919                 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
920                         result = NT_STATUS_NO_MEMORY;
921                         goto fail;
922                 }
923
924                 for (j=0; j<dom->num_idxs; j++) {
925                         int idx = dom->idxs[j];
926                         name_infos[idx].type = types[j];
927                         if (types[j] != SID_NAME_UNKNOWN) {
928                                 name_infos[idx].name =
929                                         talloc_strdup(name_infos, names[j]);
930                                 if (name_infos[idx].name == NULL) {
931                                         result = NT_STATUS_NO_MEMORY;
932                                         goto fail;
933                                 }
934                         } else {
935                                 name_infos[idx].name = NULL;
936                         }
937                 }
938         }
939
940         *ret_domains = dom_infos;
941         *ret_names = name_infos;
942         TALLOC_FREE(tmp_ctx);
943         return NT_STATUS_OK;
944
945  fail:
946         TALLOC_FREE(dom_infos);
947         TALLOC_FREE(name_infos);
948         TALLOC_FREE(tmp_ctx);
949         return result;
950 }
951
952 /*****************************************************************
953  *THE CANONICAL* convert SID to name function.
954 *****************************************************************/  
955
956 bool lookup_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
957                 const char **ret_domain, const char **ret_name,
958                 enum lsa_SidType *ret_type)
959 {
960         struct lsa_dom_info *domain;
961         struct lsa_name_info *name;
962         TALLOC_CTX *tmp_ctx;
963         bool ret = false;
964
965         DEBUG(10, ("lookup_sid called for SID '%s'\n", sid_string_dbg(sid)));
966
967         if (!(tmp_ctx = talloc_new(mem_ctx))) {
968                 DEBUG(0, ("talloc_new failed\n"));
969                 return false;
970         }
971
972         if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
973                                          &domain, &name))) {
974                 goto done;
975         }
976
977         if (name->type == SID_NAME_UNKNOWN) {
978                 goto done;
979         }
980
981         if ((ret_domain != NULL) &&
982             !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
983                 goto done;
984         }
985
986         if ((ret_name != NULL) && 
987             !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
988                 goto done;
989         }
990
991         if (ret_type != NULL) {
992                 *ret_type = name->type;
993         }
994
995         ret = true;
996
997  done:
998         if (ret) {
999                 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n", sid_string_dbg(sid),
1000                            domain->name, name->name, name->type));
1001         } else {
1002                 DEBUG(10, ("failed to lookup sid %s\n", sid_string_dbg(sid)));
1003         }
1004         TALLOC_FREE(tmp_ctx);
1005         return ret;
1006 }
1007
1008 /*****************************************************************
1009  Id mapping cache.  This is to avoid Winbind mappings already
1010  seen by smbd to be queried too frequently, keeping winbindd
1011  busy, and blocking smbd while winbindd is busy with other
1012  stuff. Written by Michael Steffens <michael.steffens@hp.com>,
1013  modified to use linked lists by jra.
1014 *****************************************************************/  
1015
1016
1017 /*****************************************************************
1018  *THE LEGACY* convert uid_t to SID function.
1019 *****************************************************************/  
1020
1021 static void legacy_uid_to_sid(struct dom_sid *psid, uid_t uid)
1022 {
1023         bool ret;
1024
1025         ZERO_STRUCTP(psid);
1026
1027         become_root();
1028         ret = pdb_uid_to_sid(uid, psid);
1029         unbecome_root();
1030
1031         if (ret) {
1032                 /* This is a mapped user */
1033                 goto done;
1034         }
1035
1036         /* This is an unmapped user */
1037
1038         uid_to_unix_users_sid(uid, psid);
1039
1040  done:
1041         DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid,
1042                   sid_string_dbg(psid)));
1043
1044         return;
1045 }
1046
1047 /*****************************************************************
1048  *THE LEGACY* convert gid_t to SID function.
1049 *****************************************************************/  
1050
1051 static void legacy_gid_to_sid(struct dom_sid *psid, gid_t gid)
1052 {
1053         bool ret;
1054
1055         ZERO_STRUCTP(psid);
1056
1057         become_root();
1058         ret = pdb_gid_to_sid(gid, psid);
1059         unbecome_root();
1060
1061         if (ret) {
1062                 /* This is a mapped group */
1063                 goto done;
1064         }
1065
1066         /* This is an unmapped group */
1067
1068         gid_to_unix_groups_sid(gid, psid);
1069
1070  done:
1071         DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid,
1072                   sid_string_dbg(psid)));
1073
1074         return;
1075 }
1076
1077 /*****************************************************************
1078  *THE LEGACY* convert SID to id function.
1079 *****************************************************************/  
1080
1081 static bool legacy_sid_to_unixid(const struct dom_sid *psid, struct unixid *id)
1082 {
1083         GROUP_MAP *map;
1084         if (sid_check_is_in_our_domain(psid)) {
1085                 bool ret;
1086
1087                 become_root();
1088                 ret = pdb_sid_to_id(psid, id);
1089                 unbecome_root();
1090
1091                 if (ret) {
1092                         goto done;
1093                 }
1094
1095                 /* This was ours, but it was not mapped.  Fail */
1096         }
1097
1098         if ((sid_check_is_in_builtin(psid) ||
1099              sid_check_is_in_wellknown_domain(psid))) {
1100                 bool ret;
1101
1102                 map = talloc_zero(NULL, GROUP_MAP);
1103                 if (!map) {
1104                         return false;
1105                 }
1106
1107                 become_root();
1108                 ret = pdb_getgrsid(map, *psid);
1109                 unbecome_root();
1110
1111                 if (ret) {
1112                         id->id = map->gid;
1113                         id->type = ID_TYPE_GID;
1114                         TALLOC_FREE(map);
1115                         goto done;
1116                 }
1117                 TALLOC_FREE(map);
1118                 DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1119                           sid_string_dbg(psid)));
1120                 return false;
1121         }
1122
1123         DEBUG(10,("LEGACY: mapping failed for sid %s\n",
1124                   sid_string_dbg(psid)));
1125         return false;
1126
1127 done:
1128         return true;
1129 }
1130
1131 static bool legacy_sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1132 {
1133         struct unixid id;
1134         if (!legacy_sid_to_unixid(psid, &id)) {
1135                 return false;
1136         }
1137         if (id.type == ID_TYPE_GID || id.type == ID_TYPE_BOTH) {
1138                 *pgid = id.id;
1139                 return true;
1140         }
1141         return false;
1142 }
1143
1144 static bool legacy_sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1145 {
1146         struct unixid id;
1147         if (!legacy_sid_to_unixid(psid, &id)) {
1148                 return false;
1149         }
1150         if (id.type == ID_TYPE_UID || id.type == ID_TYPE_BOTH) {
1151                 *puid = id.id;
1152                 return true;
1153         }
1154         return false;
1155 }
1156
1157 /*****************************************************************
1158  *THE CANONICAL* convert uid_t to SID function.
1159 *****************************************************************/  
1160
1161 void uid_to_sid(struct dom_sid *psid, uid_t uid)
1162 {
1163         bool expired = true;
1164         bool ret;
1165         ZERO_STRUCTP(psid);
1166
1167         /* Check the winbindd cache directly. */
1168         ret = idmap_cache_find_uid2sid(uid, psid, &expired);
1169
1170         if (ret && !expired && is_null_sid(psid)) {
1171                 /*
1172                  * Negative cache entry, we already asked.
1173                  * do legacy.
1174                  */
1175                 legacy_uid_to_sid(psid, uid);
1176                 return;
1177         }
1178
1179         if (!ret || expired) {
1180                 /* Not in cache. Ask winbindd. */
1181                 if (!winbind_uid_to_sid(psid, uid)) {
1182                         /*
1183                          * We shouldn't return the NULL SID
1184                          * here if winbind was running and
1185                          * couldn't map, as winbind will have
1186                          * added a negative entry that will
1187                          * cause us to go though the
1188                          * legacy_uid_to_sid()
1189                          * function anyway in the case above
1190                          * the next time we ask.
1191                          */
1192                         DEBUG(5, ("uid_to_sid: winbind failed to find a sid "
1193                                   "for uid %u\n", (unsigned int)uid));
1194
1195                         legacy_uid_to_sid(psid, uid);
1196                         return;
1197                 }
1198         }
1199
1200         DEBUG(10,("uid %u -> sid %s\n", (unsigned int)uid,
1201                   sid_string_dbg(psid)));
1202
1203         return;
1204 }
1205
1206 /*****************************************************************
1207  *THE CANONICAL* convert gid_t to SID function.
1208 *****************************************************************/  
1209
1210 void gid_to_sid(struct dom_sid *psid, gid_t gid)
1211 {
1212         bool expired = true;
1213         bool ret;
1214         ZERO_STRUCTP(psid);
1215
1216         /* Check the winbindd cache directly. */
1217         ret = idmap_cache_find_gid2sid(gid, psid, &expired);
1218
1219         if (ret && !expired && is_null_sid(psid)) {
1220                 /*
1221                  * Negative cache entry, we already asked.
1222                  * do legacy.
1223                  */
1224                 legacy_gid_to_sid(psid, gid);
1225                 return;
1226         }
1227
1228         if (!ret || expired) {
1229                 /* Not in cache. Ask winbindd. */
1230                 if (!winbind_gid_to_sid(psid, gid)) {
1231                         /*
1232                          * We shouldn't return the NULL SID
1233                          * here if winbind was running and
1234                          * couldn't map, as winbind will have
1235                          * added a negative entry that will
1236                          * cause us to go though the
1237                          * legacy_gid_to_sid()
1238                          * function anyway in the case above
1239                          * the next time we ask.
1240                          */
1241                         DEBUG(5, ("gid_to_sid: winbind failed to find a sid "
1242                                   "for gid %u\n", (unsigned int)gid));
1243
1244                         legacy_gid_to_sid(psid, gid);
1245                         return;
1246                 }
1247         }
1248
1249         DEBUG(10,("gid %u -> sid %s\n", (unsigned int)gid,
1250                   sid_string_dbg(psid)));
1251
1252         return;
1253 }
1254
1255 bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
1256                      struct unixid *ids)
1257 {
1258         struct wbcDomainSid *wbc_sids = NULL;
1259         struct wbcUnixId *wbc_ids = NULL;
1260         uint32_t i, num_not_cached;
1261         wbcErr err;
1262         bool ret = false;
1263
1264         wbc_sids = talloc_array(talloc_tos(), struct wbcDomainSid, num_sids);
1265         if (wbc_sids == NULL) {
1266                 return false;
1267         }
1268
1269         num_not_cached = 0;
1270
1271         for (i=0; i<num_sids; i++) {
1272                 bool expired;
1273                 uint32_t rid;
1274
1275                 if (sid_peek_check_rid(&global_sid_Unix_Users,
1276                                        &sids[i], &rid)) {
1277                         ids[i].type = ID_TYPE_UID;
1278                         ids[i].id = rid;
1279                         continue;
1280                 }
1281                 if (sid_peek_check_rid(&global_sid_Unix_Groups,
1282                                        &sids[i], &rid)) {
1283                         ids[i].type = ID_TYPE_GID;
1284                         ids[i].id = rid;
1285                         continue;
1286                 }
1287                 if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
1288                     && !expired)
1289                 {
1290                         continue;
1291                 }
1292                 ids[i].type = ID_TYPE_NOT_SPECIFIED;
1293                 memcpy(&wbc_sids[num_not_cached], &sids[i],
1294                        ndr_size_dom_sid(&sids[i], 0));
1295                 num_not_cached += 1;
1296         }
1297         if (num_not_cached == 0) {
1298                 goto done;
1299         }
1300         wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, num_not_cached);
1301         if (wbc_ids == NULL) {
1302                 goto fail;
1303         }
1304         for (i=0; i<num_not_cached; i++) {
1305                 wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
1306         }
1307         err = wbcSidsToUnixIds(wbc_sids, num_not_cached, wbc_ids);
1308         if (!WBC_ERROR_IS_OK(err)) {
1309                 DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
1310                            wbcErrorString(err)));
1311         }
1312
1313         num_not_cached = 0;
1314
1315         for (i=0; i<num_sids; i++) {
1316                 if (ids[i].type == ID_TYPE_NOT_SPECIFIED) {
1317                         switch (wbc_ids[num_not_cached].type) {
1318                         case ID_TYPE_UID:
1319                                 ids[i].type = WBC_ID_TYPE_UID;
1320                                 ids[i].id = wbc_ids[num_not_cached].id.uid;
1321                                 break;
1322                         case ID_TYPE_GID:
1323                                 ids[i].type = WBC_ID_TYPE_GID;
1324                                 ids[i].id = wbc_ids[num_not_cached].id.gid;
1325                                 break;
1326                         default:
1327                                 /* The types match, and wbcUnixId -> id is a union anyway */
1328                                 ids[i].type = wbc_ids[num_not_cached].type;
1329                                 ids[i].id = wbc_ids[num_not_cached].id.gid;
1330                                 break;
1331                         }
1332                         num_not_cached += 1;
1333                 }
1334         }
1335
1336         for (i=0; i<num_sids; i++) {
1337                 if (ids[i].type != ID_TYPE_NOT_SPECIFIED) {
1338                         continue;
1339                 }
1340                 if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
1341                         ids[i].type = ID_TYPE_GID;
1342                         continue;
1343                 }
1344                 if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
1345                         ids[i].type = ID_TYPE_UID;
1346                         continue;
1347                 }
1348         }
1349 done:
1350         for (i=0; i<num_sids; i++) {
1351                 switch(ids[i].type) {
1352                 case WBC_ID_TYPE_GID:
1353                 case WBC_ID_TYPE_UID:
1354                 case WBC_ID_TYPE_BOTH:
1355                         if (ids[i].id == -1) {
1356                                 ids[i].type = ID_TYPE_NOT_SPECIFIED;
1357                         }
1358                         break;
1359                 case WBC_ID_TYPE_NOT_SPECIFIED:
1360                         break;
1361                 }
1362         }
1363
1364         ret = true;
1365 fail:
1366         TALLOC_FREE(wbc_ids);
1367         TALLOC_FREE(wbc_sids);
1368         return ret;
1369 }
1370
1371 /*****************************************************************
1372  *THE CANONICAL* convert SID to uid function.
1373 *****************************************************************/  
1374
1375 bool sid_to_uid(const struct dom_sid *psid, uid_t *puid)
1376 {
1377         bool expired = true;
1378         bool ret;
1379         uint32 rid;
1380
1381         /* Optimize for the Unix Users Domain
1382          * as the conversion is straightforward */
1383         if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1384                 uid_t uid = rid;
1385                 *puid = uid;
1386
1387                 /* return here, don't cache */
1388                 DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1389                         (unsigned int)*puid ));
1390                 return true;
1391         }
1392
1393         /* Check the winbindd cache directly. */
1394         ret = idmap_cache_find_sid2uid(psid, puid, &expired);
1395
1396         if (ret && !expired && (*puid == (uid_t)-1)) {
1397                 /*
1398                  * Negative cache entry, we already asked.
1399                  * do legacy.
1400                  */
1401                 return legacy_sid_to_uid(psid, puid);
1402         }
1403
1404         if (!ret || expired) {
1405                 /* Not in cache. Ask winbindd. */
1406                 if (!winbind_sid_to_uid(puid, psid)) {
1407                         DEBUG(5, ("winbind failed to find a uid for sid %s\n",
1408                                   sid_string_dbg(psid)));
1409                         /* winbind failed. do legacy */
1410                         return legacy_sid_to_uid(psid, puid);
1411                 }
1412         }
1413
1414         /* TODO: Here would be the place to allocate both a gid and a uid for
1415          * the SID in question */
1416
1417         DEBUG(10,("sid %s -> uid %u\n", sid_string_dbg(psid),
1418                 (unsigned int)*puid ));
1419
1420         return true;
1421 }
1422
1423 /*****************************************************************
1424  *THE CANONICAL* convert SID to gid function.
1425  Group mapping is used for gids that maps to Wellknown SIDs
1426 *****************************************************************/  
1427
1428 bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid)
1429 {
1430         bool expired = true;
1431         bool ret;
1432         uint32 rid;
1433
1434         /* Optimize for the Unix Groups Domain
1435          * as the conversion is straightforward */
1436         if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1437                 gid_t gid = rid;
1438                 *pgid = gid;
1439
1440                 /* return here, don't cache */
1441                 DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1442                         (unsigned int)*pgid ));
1443                 return true;
1444         }
1445
1446         /* Check the winbindd cache directly. */
1447         ret = idmap_cache_find_sid2gid(psid, pgid, &expired);
1448
1449         if (ret && !expired && (*pgid == (gid_t)-1)) {
1450                 /*
1451                  * Negative cache entry, we already asked.
1452                  * do legacy.
1453                  */
1454                 return legacy_sid_to_gid(psid, pgid);
1455         }
1456
1457         if (!ret || expired) {
1458                 /* Not in cache or negative. Ask winbindd. */
1459                 /* Ask winbindd if it can map this sid to a gid.
1460                  * (Idmap will check it is a valid SID and of the right type) */
1461
1462                 if ( !winbind_sid_to_gid(pgid, psid) ) {
1463
1464                         DEBUG(10,("winbind failed to find a gid for sid %s\n",
1465                                   sid_string_dbg(psid)));
1466                         /* winbind failed. do legacy */
1467                         return legacy_sid_to_gid(psid, pgid);
1468                 }
1469         }
1470
1471         DEBUG(10,("sid %s -> gid %u\n", sid_string_dbg(psid),
1472                   (unsigned int)*pgid ));
1473
1474         return true;
1475 }
1476
1477 /**
1478  * @brief This function gets the primary group SID mapping the primary
1479  *        GID of the user as obtained by an actual getpwnam() call.
1480  *        This is necessary to avoid issues with arbitrary group SIDs
1481  *        stored in passdb. We try as hard as we can to get the SID
1482  *        corresponding to the GID, including trying group mapping.
1483  *        If nothing else works, we will force "Domain Users" as the
1484  *        primary group.
1485  *        This is needed because we must always be able to lookup the
1486  *        primary group SID, so we cannot settle for an arbitrary SID.
1487  *
1488  *        This call can be expensive. Use with moderation.
1489  *        If you have a "samu" struct around use pdb_get_group_sid()
1490  *        instead as it does properly cache results.
1491  *
1492  * @param mem_ctx[in]     The memory context iused to allocate the result.
1493  * @param username[in]    The user's name
1494  * @param _pwd[in|out]    If available, pass in user's passwd struct.
1495  *                        It will contain a tallocated passwd if NULL was
1496  *                        passed in.
1497  * @param _group_sid[out] The user's Primary Group SID
1498  *
1499  * @return NTSTATUS error code.
1500  */
1501 NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
1502                                 const char *username,
1503                                 struct passwd **_pwd,
1504                                 struct dom_sid **_group_sid)
1505 {
1506         TALLOC_CTX *tmp_ctx;
1507         bool need_lookup_sid = false;
1508         struct dom_sid *group_sid;
1509         struct passwd *pwd = *_pwd;
1510
1511         tmp_ctx = talloc_new(mem_ctx);
1512         if (!tmp_ctx) {
1513                 return NT_STATUS_NO_MEMORY;
1514         }
1515
1516         if (!pwd) {
1517                 pwd = Get_Pwnam_alloc(mem_ctx, username);
1518                 if (!pwd) {
1519                         DEBUG(0, ("Failed to find a Unix account for %s",
1520                                   username));
1521                         TALLOC_FREE(tmp_ctx);
1522                         return NT_STATUS_NO_SUCH_USER;
1523                 }
1524         }
1525
1526         group_sid = talloc_zero(mem_ctx, struct dom_sid);
1527         if (!group_sid) {
1528                 TALLOC_FREE(tmp_ctx);
1529                 return NT_STATUS_NO_MEMORY;
1530         }
1531
1532         gid_to_sid(group_sid, pwd->pw_gid);
1533         if (!is_null_sid(group_sid)) {
1534                 struct dom_sid domain_sid;
1535                 uint32_t rid;
1536
1537                 /* We need a sid within our domain */
1538                 sid_copy(&domain_sid, group_sid);
1539                 sid_split_rid(&domain_sid, &rid);
1540                 if (dom_sid_equal(&domain_sid, get_global_sam_sid())) {
1541                         /*
1542                          * As shortcut for the expensive lookup_sid call
1543                          * compare the domain sid part
1544                          */
1545                         switch (rid) {
1546                         case DOMAIN_RID_ADMINS:
1547                         case DOMAIN_RID_USERS:
1548                                 goto done;
1549                         default:
1550                                 need_lookup_sid = true;
1551                                 break;
1552                         }
1553                 } else {
1554                         /* Try group mapping */
1555                         ZERO_STRUCTP(group_sid);
1556                         if (pdb_gid_to_sid(pwd->pw_gid, group_sid)) {
1557                                 need_lookup_sid = true;
1558                         }
1559                 }
1560         }
1561
1562         /* We must verify that this is a valid SID that resolves to a
1563          * group of the correct type */
1564         if (need_lookup_sid) {
1565                 enum lsa_SidType type = SID_NAME_UNKNOWN;
1566                 bool lookup_ret;
1567
1568                 DEBUG(10, ("do lookup_sid(%s) for group of user %s\n",
1569                            sid_string_dbg(group_sid), username));
1570
1571                 /* Now check that it's actually a domain group and
1572                  * not something else */
1573                 lookup_ret = lookup_sid(tmp_ctx, group_sid,
1574                                         NULL, NULL, &type);
1575
1576                 if (lookup_ret && (type == SID_NAME_DOM_GRP)) {
1577                         goto done;
1578                 }
1579
1580                 DEBUG(3, ("Primary group %s for user %s is"
1581                           " a %s and not a domain group\n",
1582                           sid_string_dbg(group_sid), username,
1583                           sid_type_lookup(type)));
1584         }
1585
1586         /* Everything else, failed.
1587          * Just set it to the 'Domain Users' RID of 513 which will
1588            always resolve to a name */
1589         DEBUG(3, ("Forcing Primary Group to 'Domain Users' for %s\n",
1590                   username));
1591
1592         sid_compose(group_sid, get_global_sam_sid(), DOMAIN_RID_USERS);
1593
1594 done:
1595         *_pwd = talloc_move(mem_ctx, &pwd);
1596         *_group_sid = talloc_move(mem_ctx, &group_sid);
1597         TALLOC_FREE(tmp_ctx);
1598         return NT_STATUS_OK;
1599 }
1600