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