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