r17554: Cleanup
[sfrench/samba-autobuild/.git] / source / 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 2 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, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 /*****************************************************************
26  Dissect a user-provided name into domain, name, sid and type.
27
28  If an explicit domain name was given in the form domain\user, it
29  has to try that. If no explicit domain name was given, we have
30  to do guesswork.
31 *****************************************************************/  
32
33 BOOL lookup_name(TALLOC_CTX *mem_ctx,
34                  const char *full_name, int flags,
35                  const char **ret_domain, const char **ret_name,
36                  DOM_SID *ret_sid, enum SID_NAME_USE *ret_type)
37 {
38         char *p;
39         const char *tmp;
40         const char *domain = NULL;
41         const char *name = NULL;
42         uint32 rid;
43         DOM_SID sid;
44         enum SID_NAME_USE type;
45         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
46         struct group *grp;
47
48         if (tmp_ctx == NULL) {
49                 DEBUG(0, ("talloc_new failed\n"));
50                 return False;
51         }
52
53         p = strchr_m(full_name, '\\');
54
55         if (p != NULL) {
56                 domain = talloc_strndup(tmp_ctx, full_name,
57                                         PTR_DIFF(p, full_name));
58                 name = talloc_strdup(tmp_ctx, p+1);
59         } else {
60                 domain = talloc_strdup(tmp_ctx, "");
61                 name = talloc_strdup(tmp_ctx, full_name);
62         }
63
64         DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n", 
65                 full_name, domain, name));
66
67         if ((domain == NULL) || (name == NULL)) {
68                 DEBUG(0, ("talloc failed\n"));
69                 TALLOC_FREE(tmp_ctx);
70                 return False;
71         }
72
73         if (strequal(domain, get_global_sam_name())) {
74
75                 /* It's our own domain, lookup the name in passdb */
76                 if (lookup_global_sam_name(name, flags, &rid, &type)) {
77                         sid_copy(&sid, get_global_sam_sid());
78                         sid_append_rid(&sid, rid);
79                         goto ok;
80                 }
81                 TALLOC_FREE(tmp_ctx);
82                 return False;
83         }
84
85         if (strequal(domain, builtin_domain_name())) {
86
87                 /* Explicit request for a name in BUILTIN */
88                 if (lookup_builtin_name(name, &rid)) {
89                         sid_copy(&sid, &global_sid_Builtin);
90                         sid_append_rid(&sid, rid);
91                         type = SID_NAME_ALIAS;
92                         goto ok;
93                 }
94                 TALLOC_FREE(tmp_ctx);
95                 return False;
96         }
97
98         /* Try the explicit winbind lookup first, don't let it guess the
99          * domain yet at this point yet. This comes later. */
100
101         if ((domain[0] != '\0') &&
102             (winbind_lookup_name(domain, name, &sid, &type))) {
103                         goto ok;
104         }
105
106         if (strequal(domain, unix_users_domain_name())) {
107                 if (lookup_unix_user_name(name, &sid)) {
108                         type = SID_NAME_USER;
109                         goto ok;
110                 }
111                 TALLOC_FREE(tmp_ctx);
112                 return False;
113         }
114
115         if (strequal(domain, unix_groups_domain_name())) {
116                 if (lookup_unix_group_name(name, &sid)) {
117                         type = SID_NAME_DOM_GRP;
118                         goto ok;
119                 }
120                 TALLOC_FREE(tmp_ctx);
121                 return False;
122         }
123
124         if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
125                 TALLOC_FREE(tmp_ctx);
126                 return False;
127         }
128
129         /*
130          * Nasty hack necessary for too common scenarios:
131          *
132          * For 'valid users = +users' we know "users" is most probably not
133          * BUILTIN\users but the unix group users. This hack requires the
134          * admin to explicitly qualify BUILTIN if BUILTIN\users is meant.
135          *
136          * Please note that LOOKUP_NAME_GROUP can not be requested via for
137          * example lsa_lookupnames, it only comes into this routine via
138          * the expansion of group names coming in from smb.conf
139          */
140
141         if ((flags & LOOKUP_NAME_GROUP) && ((grp = getgrnam(name)) != NULL)) {
142
143                 GROUP_MAP map;
144
145                 if (pdb_getgrgid(&map, grp->gr_gid)) {
146                         /* The hack gets worse. Handle the case where we have
147                          * 'force group = +unixgroup' but "unixgroup" has a
148                          * group mapping */
149
150                         if (sid_check_is_in_builtin(&map.sid)) {
151                                 domain = talloc_strdup(
152                                         tmp_ctx, builtin_domain_name());
153                         } else {
154                                 domain = talloc_strdup(
155                                         tmp_ctx, get_global_sam_name());
156                         }
157
158                         sid_copy(&sid, &map.sid);
159                         type = map.sid_name_use;
160                         goto ok;
161                 }
162
163                 /* If we are using the smbpasswd backend, we need to use the
164                  * algorithmic mapping for the unix group we find. This is
165                  * necessary because when creating the NT token from the unix
166                  * gid list we got from initgroups() we use gid_to_sid() that
167                  * uses algorithmic mapping if pdb_rid_algorithm() is true. */
168
169                 if (pdb_rid_algorithm() &&
170                     (grp->gr_gid < max_algorithmic_gid())) {
171                         domain = talloc_strdup(tmp_ctx, get_global_sam_name());
172                         sid_compose(&sid, get_global_sam_sid(),
173                                     pdb_gid_to_group_rid(grp->gr_gid));
174                         type = SID_NAME_DOM_GRP;
175                         goto ok;
176                 }
177                 
178                 if (lookup_unix_group_name(name, &sid)) {
179                         domain = talloc_strdup(tmp_ctx,
180                                                unix_groups_domain_name());
181                         type = SID_NAME_DOM_GRP;
182                         goto ok;
183                 }
184         }
185
186         /* Now the guesswork begins, we haven't been given an explicit
187          * domain. Try the sequence as documented on
188          * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
189          * November 27, 2005 */
190
191         /* 1. well-known names */
192
193         if (lookup_wellknown_name(tmp_ctx, name, &sid, &domain)) {
194                 type = SID_NAME_WKN_GRP;
195                 goto ok;
196         }
197
198         /* 2. Builtin domain as such */
199
200         if (strequal(name, builtin_domain_name())) {
201                 /* Swap domain and name */
202                 tmp = name; name = domain; domain = tmp;
203                 sid_copy(&sid, &global_sid_Builtin);
204                 type = SID_NAME_DOMAIN;
205                 goto ok;
206         }
207
208         /* 3. Account domain */
209
210         if (strequal(name, get_global_sam_name())) {
211                 if (!secrets_fetch_domain_sid(name, &sid)) {
212                         DEBUG(3, ("Could not fetch my SID\n"));
213                         TALLOC_FREE(tmp_ctx);
214                         return False;
215                 }
216                 /* Swap domain and name */
217                 tmp = name; name = domain; domain = tmp;
218                 type = SID_NAME_DOMAIN;
219                 goto ok;
220         }
221
222         /* 4. Primary domain */
223
224         if (!IS_DC && strequal(name, lp_workgroup())) {
225                 if (!secrets_fetch_domain_sid(name, &sid)) {
226                         DEBUG(3, ("Could not fetch the domain SID\n"));
227                         TALLOC_FREE(tmp_ctx);
228                         return False;
229                 }
230                 /* Swap domain and name */
231                 tmp = name; name = domain; domain = tmp;
232                 type = SID_NAME_DOMAIN;
233                 goto ok;
234         }
235
236         /* 5. Trusted domains as such, to me it looks as if members don't do
237               this, tested an XP workstation in a NT domain -- vl */
238
239         if (IS_DC && (secrets_fetch_trusted_domain_password(name, NULL,
240                                                             &sid, NULL))) {
241                 /* Swap domain and name */
242                 tmp = name; name = domain; domain = tmp;
243                 type = SID_NAME_DOMAIN;
244                 goto ok;
245         }
246
247         /* 6. Builtin aliases */        
248
249         if (lookup_builtin_name(name, &rid)) {
250                 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
251                 sid_copy(&sid, &global_sid_Builtin);
252                 sid_append_rid(&sid, rid);
253                 type = SID_NAME_ALIAS;
254                 goto ok;
255         }
256
257         /* 7. Local systems' SAM (DCs don't have a local SAM) */
258         /* 8. Primary SAM (On members, this is the domain) */
259
260         /* Both cases are done by looking at our passdb */
261
262         if (lookup_global_sam_name(name, flags, &rid, &type)) {
263                 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
264                 sid_copy(&sid, get_global_sam_sid());
265                 sid_append_rid(&sid, rid);
266                 goto ok;
267         }
268
269         /* Now our local possibilities are exhausted. */
270
271         if (!(flags & LOOKUP_NAME_REMOTE)) {
272                 TALLOC_FREE(tmp_ctx);
273                 return False;
274         }
275
276         /* If we are not a DC, we have to ask in our primary domain. Let
277          * winbind do that. */
278
279         if (!IS_DC &&
280             (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
281                 domain = talloc_strdup(tmp_ctx, lp_workgroup());
282                 goto ok;
283         }
284
285         /* 9. Trusted domains */
286
287         /* If we're a DC we have to ask all trusted DC's. Winbind does not do
288          * that (yet), but give it a chance. */
289
290         if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
291                 DOM_SID dom_sid;
292                 uint32 tmp_rid;
293                 enum SID_NAME_USE domain_type;
294                 
295                 if (type == SID_NAME_DOMAIN) {
296                         /* Swap name and type */
297                         tmp = name; name = domain; domain = tmp;
298                         goto ok;
299                 }
300
301                 /* Here we have to cope with a little deficiency in the
302                  * winbind API: We have to ask it again for the name of the
303                  * domain it figured out itself. Maybe fix that later... */
304
305                 sid_copy(&dom_sid, &sid);
306                 sid_split_rid(&dom_sid, &tmp_rid);
307
308                 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
309                                         &domain_type) ||
310                     (domain_type != SID_NAME_DOMAIN)) {
311                         DEBUG(2, ("winbind could not find the domain's name "
312                                   "it just looked up for us\n"));
313                         TALLOC_FREE(tmp_ctx);
314                         return False;
315                 }
316                 goto ok;
317         }
318
319         /* 10. Don't translate */
320
321         /* 11. Ok, windows would end here. Samba has two more options:
322                Unmapped users and unmapped groups */
323
324         if (lookup_unix_user_name(name, &sid)) {
325                 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
326                 type = SID_NAME_USER;
327                 goto ok;
328         }
329
330         if (lookup_unix_group_name(name, &sid)) {
331                 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
332                 type = SID_NAME_DOM_GRP;
333                 goto ok;
334         }
335
336         /*
337          * Ok, all possibilities tried. Fail.
338          */
339
340         TALLOC_FREE(tmp_ctx);
341         return False;
342
343  ok:
344         if ((domain == NULL) || (name == NULL)) {
345                 DEBUG(0, ("talloc failed\n"));
346                 TALLOC_FREE(tmp_ctx);
347                 return False;
348         }
349
350         /*
351          * Hand over the results to the talloc context we've been given.
352          */
353
354         if ((ret_name != NULL) &&
355             !(*ret_name = talloc_strdup(mem_ctx, name))) {
356                 DEBUG(0, ("talloc failed\n"));
357                 TALLOC_FREE(tmp_ctx);
358                 return False;
359         }
360
361         if (ret_domain != NULL) {
362                 char *tmp_dom;
363                 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
364                         DEBUG(0, ("talloc failed\n"));
365                         TALLOC_FREE(tmp_ctx);
366                         return False;
367                 }
368                 strupper_m(tmp_dom);
369                 *ret_domain = tmp_dom;
370         }
371
372         if (ret_sid != NULL) {
373                 sid_copy(ret_sid, &sid);
374         }
375
376         if (ret_type != NULL) {
377                 *ret_type = type;
378         }
379
380         TALLOC_FREE(tmp_ctx);
381         return True;
382 }
383
384 /************************************************************************
385  Names from smb.conf can be unqualified. eg. valid users = foo
386  These names should never map to a remote name. Try global_sam_name()\foo,
387  and then "Unix Users"\foo (or "Unix Groups"\foo).
388 ************************************************************************/
389
390 BOOL lookup_name_smbconf(TALLOC_CTX *mem_ctx,
391                  const char *full_name, int flags,
392                  const char **ret_domain, const char **ret_name,
393                  DOM_SID *ret_sid, enum SID_NAME_USE *ret_type)
394 {
395         char *qualified_name;
396         const char *p;
397
398         /* NB. No winbindd_separator here as lookup_name needs \\' */
399         if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
400
401                 /* The name is already qualified with a domain. */
402
403                 if (*lp_winbind_separator() != '\\') {
404                         char *tmp;
405
406                         /* lookup_name() needs '\\' as a separator */
407
408                         tmp = talloc_strdup(mem_ctx, full_name);
409                         if (!tmp) {
410                                 return False;
411                         }
412                         tmp[p - full_name] = '\\';
413                         full_name = tmp;
414                 }
415
416                 return lookup_name(mem_ctx, full_name, flags,
417                                 ret_domain, ret_name,
418                                 ret_sid, ret_type);
419         }
420
421         /* Try with our own SAM name. */
422         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
423                                 get_global_sam_name(),
424                                 full_name );
425         if (!qualified_name) {
426                 return False;
427         }
428
429         if (lookup_name(mem_ctx, qualified_name, flags,
430                                 ret_domain, ret_name,
431                                 ret_sid, ret_type)) {
432                 return True;
433         }
434         
435         /* Finally try with "Unix Users" or "Unix Group" */
436         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
437                                 flags & LOOKUP_NAME_GROUP ?
438                                         unix_groups_domain_name() :
439                                         unix_users_domain_name(),
440                                 full_name );
441         if (!qualified_name) {
442                 return False;
443         }
444
445         return lookup_name(mem_ctx, qualified_name, flags,
446                                 ret_domain, ret_name,
447                                 ret_sid, ret_type);
448 }
449
450 static BOOL wb_lookup_rids(TALLOC_CTX *mem_ctx,
451                            const DOM_SID *domain_sid,
452                            int num_rids, uint32 *rids,
453                            const char **domain_name,
454                            const char **names, enum SID_NAME_USE *types)
455 {
456         int i;
457         const char **my_names;
458         enum SID_NAME_USE *my_types;
459         TALLOC_CTX *tmp_ctx;
460
461         if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
462                 return False;
463         }
464
465         if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
466                                  domain_name, &my_names, &my_types)) {
467                 for (i=0; i<num_rids; i++) {
468                         types[i] = SID_NAME_UNKNOWN;
469                 }
470                 return True;
471         }
472
473         /*
474          * winbind_lookup_rids allocates its own array. We've been given the
475          * array, so copy it over
476          */
477
478         for (i=0; i<num_rids; i++) {
479                 if (my_names[i] == NULL) {
480                         TALLOC_FREE(tmp_ctx);
481                         return False;
482                 }
483                 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
484                         TALLOC_FREE(tmp_ctx);
485                         return False;
486                 }
487                 types[i] = my_types[i];
488         }
489         TALLOC_FREE(tmp_ctx);
490         return True;
491 }
492
493 static BOOL lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
494                         int num_rids, uint32_t *rids,
495                         const char **domain_name,
496                         const char ***names, enum SID_NAME_USE **types)
497 {
498         int i;
499
500         *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids);
501         *types = TALLOC_ARRAY(mem_ctx, enum SID_NAME_USE, num_rids);
502
503         if ((*names == NULL) || (*types == NULL)) {
504                 return False;
505         }
506
507         if (sid_check_is_domain(domain_sid)) {
508                 NTSTATUS result;
509
510                 if (*domain_name == NULL) {
511                         *domain_name = talloc_strdup(
512                                 mem_ctx, get_global_sam_name());
513                 }
514
515                 if (*domain_name == NULL) {
516                         return False;
517                 }
518
519                 become_root();
520                 result = pdb_lookup_rids(domain_sid, num_rids, rids,
521                                          *names, *types);
522                 unbecome_root();
523
524                 return (NT_STATUS_IS_OK(result) ||
525                         NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
526                         NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
527         }
528
529         if (sid_check_is_builtin(domain_sid)) {
530
531                 if (*domain_name == NULL) {
532                         *domain_name = talloc_strdup(
533                                 mem_ctx, builtin_domain_name());
534                 }
535
536                 if (*domain_name == NULL) {
537                         return False;
538                 }
539
540                 for (i=0; i<num_rids; i++) {
541                         if (lookup_builtin_rid(*names, rids[i],
542                                                &(*names)[i])) {
543                                 if ((*names)[i] == NULL) {
544                                         return False;
545                                 }
546                                 (*types)[i] = SID_NAME_ALIAS;
547                         } else {
548                                 (*types)[i] = SID_NAME_UNKNOWN;
549                         }
550                 }
551                 return True;
552         }
553
554         if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
555                 for (i=0; i<num_rids; i++) {
556                         DOM_SID sid;
557                         sid_copy(&sid, domain_sid);
558                         sid_append_rid(&sid, rids[i]);
559                         if (lookup_wellknown_sid(mem_ctx, &sid,
560                                                  domain_name, &(*names)[i])) {
561                                 if ((*names)[i] == NULL) {
562                                         return False;
563                                 }
564                                 (*types)[i] = SID_NAME_WKN_GRP;
565                         } else {
566                                 (*types)[i] = SID_NAME_UNKNOWN;
567                         }
568                 }
569                 return True;
570         }
571
572         if (sid_check_is_unix_users(domain_sid)) {
573                 if (*domain_name == NULL) {
574                         *domain_name = talloc_strdup(
575                                 mem_ctx, unix_users_domain_name());
576                 }
577                 for (i=0; i<num_rids; i++) {
578                         (*names)[i] = talloc_strdup(
579                                 (*names), uidtoname(rids[i]));
580                         (*types)[i] = SID_NAME_USER;
581                 }
582                 return True;
583         }
584
585         if (sid_check_is_unix_groups(domain_sid)) {
586                 if (*domain_name == NULL) {
587                         *domain_name = talloc_strdup(
588                                 mem_ctx, unix_groups_domain_name());
589                 }
590                 for (i=0; i<num_rids; i++) {
591                         (*names)[i] = talloc_strdup(
592                                 (*names), gidtoname(rids[i]));
593                         (*types)[i] = SID_NAME_DOM_GRP;
594                 }
595                 return True;
596         }
597
598         return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
599                               domain_name, *names, *types);
600 }
601
602 /*
603  * Is the SID a domain as such? If yes, lookup its name.
604  */
605
606 static BOOL lookup_as_domain(const DOM_SID *sid, TALLOC_CTX *mem_ctx,
607                              const char **name)
608 {
609         const char *tmp;
610         enum SID_NAME_USE type;
611
612         if (sid_check_is_domain(sid)) {
613                 *name = talloc_strdup(mem_ctx, get_global_sam_name());
614                 return True;
615         }
616
617         if (sid_check_is_builtin(sid)) {
618                 *name = talloc_strdup(mem_ctx, builtin_domain_name());
619                 return True;
620         }
621
622         if (sid_check_is_wellknown_domain(sid, &tmp)) {
623                 *name = talloc_strdup(mem_ctx, tmp);
624                 return True;
625         }
626
627         if (sid->num_auths != 4) {
628                 /* This can't be a domain */
629                 return False;
630         }
631
632         if (IS_DC) {
633                 uint32 i, num_domains;
634                 struct trustdom_info **domains;
635
636                 /* This is relatively expensive, but it happens only on DCs
637                  * and for SIDs that have 4 sub-authorities and thus look like
638                  * domains */
639
640                 if (!NT_STATUS_IS_OK(secrets_trusted_domains(mem_ctx,
641                                                              &num_domains,
642                                                              &domains))) {
643                         return False;
644                 }
645
646                 for (i=0; i<num_domains; i++) {
647                         if (sid_equal(sid, &domains[i]->sid)) {
648                                 *name = talloc_strdup(mem_ctx,
649                                                       domains[i]->name);
650                                 return True;
651                         }
652                 }
653                 return False;
654         }
655
656         if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
657             (type == SID_NAME_DOMAIN)) {
658                 *name = tmp;
659                 return True;
660         }
661
662         return False;
663 }
664
665 /*
666  * This tries to implement the rather weird rules for the lsa_lookup level
667  * parameter.
668  *
669  * This is as close as we can get to what W2k3 does. With this we survive the
670  * RPC-LSALOOKUP samba4 test as of 2006-01-08. NT4 as a PDC is a bit more
671  * different, but I assume that's just being too liberal. For example, W2k3
672  * replies to everything else but the levels 1-6 with INVALID_PARAMETER
673  * whereas NT4 does the same as level 1 (I think). I did not fully test that
674  * with NT4, this is what w2k3 does.
675  *
676  * Level 1: Ask everywhere
677  * Level 2: Ask domain and trusted domains, no builtin and wkn
678  * Level 3: Only ask domain
679  * Level 4: W2k3ad: Only ask AD trusts
680  * Level 5: Don't lookup anything
681  * Level 6: Like 4
682  */
683
684 static BOOL check_dom_sid_to_level(const DOM_SID *sid, int level)
685 {
686         int ret = False;
687
688         switch(level) {
689         case 1:
690                 ret = True;
691                 break;
692         case 2:
693                 ret = (!sid_check_is_builtin(sid) &&
694                        !sid_check_is_wellknown_domain(sid, NULL));
695                 break;
696         case 3:
697         case 4:
698         case 6:
699                 ret = sid_check_is_domain(sid);
700                 break;
701         case 5:
702                 ret = False;
703                 break;
704         }
705
706         DEBUG(10, ("%s SID %s in level %d\n",
707                    ret ? "Accepting" : "Rejecting",
708                    sid_string_static(sid), level));
709         return ret;
710 }
711
712 /*
713  * Lookup a bunch of SIDs. This is modeled after lsa_lookup_sids with
714  * references to domains, it is explicitly made for this.
715  *
716  * This attempts to be as efficient as possible: It collects all SIDs
717  * belonging to a domain and hands them in bulk to the appropriate lookup
718  * function. In particular pdb_lookup_rids with ldapsam_trusted benefits
719  * *hugely* from this. Winbind is going to be extended with a lookup_rids
720  * interface as well, so on a DC we can do a bulk lsa_lookuprids to the
721  * appropriate DC.
722  */
723
724 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
725                      const DOM_SID **sids, int level,
726                      struct lsa_dom_info **ret_domains,
727                      struct lsa_name_info **ret_names)
728 {
729         TALLOC_CTX *tmp_ctx;
730         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
731         struct lsa_name_info *name_infos;
732         struct lsa_dom_info *dom_infos;
733
734         int i, j;
735
736         if (!(tmp_ctx = talloc_new(mem_ctx))) {
737                 DEBUG(0, ("talloc_new failed\n"));
738                 return NT_STATUS_NO_MEMORY;
739         }
740
741         name_infos = TALLOC_ARRAY(mem_ctx, struct lsa_name_info, num_sids);
742         dom_infos = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_dom_info,
743                                       MAX_REF_DOMAINS);
744         if ((name_infos == NULL) || (dom_infos == NULL)) {
745                 result = NT_STATUS_NO_MEMORY;
746                 goto fail;
747         }
748
749         /* First build up the data structures:
750          * 
751          * dom_infos is a list of domains referenced in the list of
752          * SIDs. Later we will walk the list of domains and look up the RIDs
753          * in bulk.
754          *
755          * name_infos is a shadow-copy of the SIDs array to collect the real
756          * data.
757          *
758          * dom_info->idxs is an index into the name_infos array. The
759          * difficulty we have here is that we need to keep the SIDs the client
760          * asked for in the same order for the reply
761          */
762
763         for (i=0; i<num_sids; i++) {
764                 DOM_SID sid;
765                 uint32 rid;
766                 const char *domain_name = NULL;
767
768                 sid_copy(&sid, sids[i]);
769                 name_infos[i].type = SID_NAME_USE_NONE;
770
771                 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
772                         /* We can't push that through the normal lookup
773                          * process, as this would reference illegal
774                          * domains.
775                          *
776                          * For example S-1-5-32 would end up referencing
777                          * domain S-1-5- with RID 32 which is clearly wrong.
778                          */
779                         if (domain_name == NULL) {
780                                 result = NT_STATUS_NO_MEMORY;
781                                 goto fail;
782                         }
783                                 
784                         name_infos[i].rid = 0;
785                         name_infos[i].type = SID_NAME_DOMAIN;
786                         name_infos[i].name = NULL;
787
788                         if (sid_check_is_builtin(&sid)) {
789                                 /* Yes, W2k3 returns "BUILTIN" both as domain
790                                  * and name here */
791                                 name_infos[i].name = talloc_strdup(
792                                         name_infos, builtin_domain_name());
793                                 if (name_infos[i].name == NULL) {
794                                         result = NT_STATUS_NO_MEMORY;
795                                         goto fail;
796                                 }
797                         }
798                 } else {
799                         /* This is a normal SID with rid component */
800                         if (!sid_split_rid(&sid, &rid)) {
801                                 result = NT_STATUS_INVALID_PARAMETER;
802                                 goto fail;
803                         }
804                 }
805
806                 if (!check_dom_sid_to_level(&sid, level)) {
807                         name_infos[i].rid = 0;
808                         name_infos[i].type = SID_NAME_UNKNOWN;
809                         name_infos[i].name = NULL;
810                         continue;
811                 }
812
813                 for (j=0; j<MAX_REF_DOMAINS; j++) {
814                         if (!dom_infos[j].valid) {
815                                 break;
816                         }
817                         if (sid_equal(&sid, &dom_infos[j].sid)) {
818                                 break;
819                         }
820                 }
821
822                 if (j == MAX_REF_DOMAINS) {
823                         /* TODO: What's the right error message here? */
824                         result = NT_STATUS_NONE_MAPPED;
825                         goto fail;
826                 }
827
828                 if (!dom_infos[j].valid) {
829                         /* We found a domain not yet referenced, create a new
830                          * ref. */
831                         dom_infos[j].valid = True;
832                         sid_copy(&dom_infos[j].sid, &sid);
833
834                         if (domain_name != NULL) {
835                                 /* This name was being found above in the case
836                                  * when we found a domain SID */
837                                 dom_infos[j].name =
838                                         talloc_strdup(dom_infos, domain_name);
839                                 if (dom_infos[j].name == NULL) {
840                                         result = NT_STATUS_NO_MEMORY;
841                                         goto fail;
842                                 }
843                         } else {
844                                 /* lookup_rids will take care of this */
845                                 dom_infos[j].name = NULL;
846                         }
847                 }
848
849                 name_infos[i].dom_idx = j;
850
851                 if (name_infos[i].type == SID_NAME_USE_NONE) {
852                         name_infos[i].rid = rid;
853
854                         ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
855                                      &dom_infos[j].num_idxs);
856
857                         if (dom_infos[j].idxs == NULL) {
858                                 result = NT_STATUS_NO_MEMORY;
859                                 goto fail;
860                         }
861                 }
862         }
863
864         /* Iterate over the domains found */
865
866         for (i=0; i<MAX_REF_DOMAINS; i++) {
867                 uint32_t *rids;
868                 const char *domain_name = NULL;
869                 const char **names;
870                 enum SID_NAME_USE *types;
871                 struct lsa_dom_info *dom = &dom_infos[i];
872
873                 if (!dom->valid) {
874                         /* No domains left, we're done */
875                         break;
876                 }
877
878                 if (!(rids = TALLOC_ARRAY(tmp_ctx, uint32, dom->num_idxs))) {
879                         result = NT_STATUS_NO_MEMORY;
880                         goto fail;
881                 }
882
883                 for (j=0; j<dom->num_idxs; j++) {
884                         rids[j] = name_infos[dom->idxs[j]].rid;
885                 }
886
887                 if (!lookup_rids(tmp_ctx, &dom->sid,
888                                  dom->num_idxs, rids, &domain_name,
889                                  &names, &types)) {
890                         result = NT_STATUS_NO_MEMORY;
891                         goto fail;
892                 }
893
894                 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
895                         result = NT_STATUS_NO_MEMORY;
896                         goto fail;
897                 }
898                         
899                 for (j=0; j<dom->num_idxs; j++) {
900                         int idx = dom->idxs[j];
901                         name_infos[idx].type = types[j];
902                         if (types[j] != SID_NAME_UNKNOWN) {
903                                 name_infos[idx].name =
904                                         talloc_strdup(name_infos, names[j]);
905                                 if (name_infos[idx].name == NULL) {
906                                         result = NT_STATUS_NO_MEMORY;
907                                         goto fail;
908                                 }
909                         } else {
910                                 name_infos[idx].name = NULL;
911                         }
912                 }
913         }
914
915         *ret_domains = dom_infos;
916         *ret_names = name_infos;
917         return NT_STATUS_OK;
918
919  fail:
920         TALLOC_FREE(dom_infos);
921         TALLOC_FREE(name_infos);
922         TALLOC_FREE(tmp_ctx);
923         return result;
924 }
925
926 /*****************************************************************
927  *THE CANONICAL* convert SID to name function.
928 *****************************************************************/  
929
930 BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
931                 const char **ret_domain, const char **ret_name,
932                 enum SID_NAME_USE *ret_type)
933 {
934         struct lsa_dom_info *domain;
935         struct lsa_name_info *name;
936         TALLOC_CTX *tmp_ctx;
937         BOOL ret = False;
938
939         if (!(tmp_ctx = talloc_new(mem_ctx))) {
940                 DEBUG(0, ("talloc_new failed\n"));
941                 return False;
942         }
943
944         if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
945                                          &domain, &name))) {
946                 goto done;
947         }
948
949         if (name->type == SID_NAME_UNKNOWN) {
950                 goto done;
951         }
952
953         if ((ret_domain != NULL) &&
954             !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
955                 goto done;
956         }
957
958         if ((ret_name != NULL) && 
959             !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
960                 goto done;
961         }
962
963         if (ret_type != NULL) {
964                 *ret_type = name->type;
965         }
966
967         ret = True;
968
969  done:
970         if (ret) {
971                 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n",
972                            sid_string_static(sid), domain->name,
973                            name->name, name->type));
974         } else {
975                 DEBUG(10, ("failed to lookup sid %s\n",
976                            sid_string_static(sid)));
977         }
978         TALLOC_FREE(tmp_ctx);
979         return ret;
980 }
981
982 /*****************************************************************
983  Id mapping cache.  This is to avoid Winbind mappings already
984  seen by smbd to be queried too frequently, keeping winbindd
985  busy, and blocking smbd while winbindd is busy with other
986  stuff. Written by Michael Steffens <michael.steffens@hp.com>,
987  modified to use linked lists by jra.
988 *****************************************************************/  
989
990 #define MAX_UID_SID_CACHE_SIZE 100
991 #define TURNOVER_UID_SID_CACHE_SIZE 10
992 #define MAX_GID_SID_CACHE_SIZE 100
993 #define TURNOVER_GID_SID_CACHE_SIZE 10
994
995 static size_t n_uid_sid_cache = 0;
996 static size_t n_gid_sid_cache = 0;
997
998 static struct uid_sid_cache {
999         struct uid_sid_cache *next, *prev;
1000         uid_t uid;
1001         DOM_SID sid;
1002         enum SID_NAME_USE sidtype;
1003 } *uid_sid_cache_head;
1004
1005 static struct gid_sid_cache {
1006         struct gid_sid_cache *next, *prev;
1007         gid_t gid;
1008         DOM_SID sid;
1009         enum SID_NAME_USE sidtype;
1010 } *gid_sid_cache_head;
1011
1012 /*****************************************************************
1013   Find a SID given a uid.
1014 *****************************************************************/  
1015
1016 static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
1017 {
1018         struct uid_sid_cache *pc;
1019
1020         for (pc = uid_sid_cache_head; pc; pc = pc->next) {
1021                 if (pc->uid == uid) {
1022                         *psid = pc->sid;
1023                         DEBUG(3,("fetch sid from uid cache %u -> %s\n",
1024                                  (unsigned int)uid, sid_string_static(psid)));
1025                         DLIST_PROMOTE(uid_sid_cache_head, pc);
1026                         return True;
1027                 }
1028         }
1029         return False;
1030 }
1031
1032 /*****************************************************************
1033   Find a uid given a SID.
1034 *****************************************************************/  
1035
1036 static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
1037 {
1038         struct uid_sid_cache *pc;
1039
1040         for (pc = uid_sid_cache_head; pc; pc = pc->next) {
1041                 if (sid_compare(&pc->sid, psid) == 0) {
1042                         *puid = pc->uid;
1043                         DEBUG(3,("fetch uid from cache %u -> %s\n",
1044                                  (unsigned int)*puid, sid_string_static(psid)));
1045                         DLIST_PROMOTE(uid_sid_cache_head, pc);
1046                         return True;
1047                 }
1048         }
1049         return False;
1050 }
1051
1052 /*****************************************************************
1053  Store uid to SID mapping in cache.
1054 *****************************************************************/  
1055
1056 void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
1057 {
1058         struct uid_sid_cache *pc;
1059
1060         if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) {
1061                 /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */
1062                 struct uid_sid_cache *pc_next;
1063                 size_t i;
1064
1065                 for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next)
1066                         ;
1067                 for(; pc; pc = pc_next) {
1068                         pc_next = pc->next;
1069                         DLIST_REMOVE(uid_sid_cache_head,pc);
1070                         SAFE_FREE(pc);
1071                         n_uid_sid_cache--;
1072                 }
1073         }
1074
1075         pc = SMB_MALLOC_P(struct uid_sid_cache);
1076         if (!pc)
1077                 return;
1078         pc->uid = uid;
1079         sid_copy(&pc->sid, psid);
1080         DLIST_ADD(uid_sid_cache_head, pc);
1081         n_uid_sid_cache++;
1082 }
1083
1084 /*****************************************************************
1085   Find a SID given a gid.
1086 *****************************************************************/  
1087
1088 static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
1089 {
1090         struct gid_sid_cache *pc;
1091
1092         for (pc = gid_sid_cache_head; pc; pc = pc->next) {
1093                 if (pc->gid == gid) {
1094                         *psid = pc->sid;
1095                         DEBUG(3,("fetch sid from gid cache %u -> %s\n",
1096                                  (unsigned int)gid, sid_string_static(psid)));
1097                         DLIST_PROMOTE(gid_sid_cache_head, pc);
1098                         return True;
1099                 }
1100         }
1101         return False;
1102 }
1103
1104 /*****************************************************************
1105   Find a gid given a SID.
1106 *****************************************************************/  
1107
1108 static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
1109 {
1110         struct gid_sid_cache *pc;
1111
1112         for (pc = gid_sid_cache_head; pc; pc = pc->next) {
1113                 if (sid_compare(&pc->sid, psid) == 0) {
1114                         *pgid = pc->gid;
1115                         DEBUG(3,("fetch gid from cache %u -> %s\n",
1116                                  (unsigned int)*pgid, sid_string_static(psid)));
1117                         DLIST_PROMOTE(gid_sid_cache_head, pc);
1118                         return True;
1119                 }
1120         }
1121         return False;
1122 }
1123
1124 /*****************************************************************
1125  Store gid to SID mapping in cache.
1126 *****************************************************************/  
1127
1128 void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
1129 {
1130         struct gid_sid_cache *pc;
1131
1132         if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) {
1133                 /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */
1134                 struct gid_sid_cache *pc_next;
1135                 size_t i;
1136
1137                 for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next)
1138                         ;
1139                 for(; pc; pc = pc_next) {
1140                         pc_next = pc->next;
1141                         DLIST_REMOVE(gid_sid_cache_head,pc);
1142                         SAFE_FREE(pc);
1143                         n_gid_sid_cache--;
1144                 }
1145         }
1146
1147         pc = SMB_MALLOC_P(struct gid_sid_cache);
1148         if (!pc)
1149                 return;
1150         pc->gid = gid;
1151         sid_copy(&pc->sid, psid);
1152         DLIST_ADD(gid_sid_cache_head, pc);
1153
1154         DEBUG(3,("store_gid_sid_cache: gid %u in cache -> %s\n", (unsigned int)gid,
1155                 sid_string_static(psid)));
1156
1157         n_gid_sid_cache++;
1158 }
1159
1160 /*****************************************************************
1161  *THE CANONICAL* convert uid_t to SID function.
1162 *****************************************************************/  
1163
1164 void uid_to_sid(DOM_SID *psid, uid_t uid)
1165 {
1166         uid_t low, high;
1167         uint32 rid;
1168
1169         ZERO_STRUCTP(psid);
1170
1171         if (fetch_sid_from_uid_cache(psid, uid))
1172                 return;
1173
1174         if (lp_idmap_uid(&low, &high) && (uid >= low) && (uid <= high) &&
1175             winbind_uid_to_sid(psid, uid)) {
1176
1177                 DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
1178                           (unsigned int)uid, sid_string_static(psid)));
1179                 goto done;
1180         }
1181
1182         if (pdb_uid_to_rid(uid, &rid)) {
1183                 /* This is a mapped user */
1184                 sid_copy(psid, get_global_sam_sid());
1185                 sid_append_rid(psid, rid);
1186                 goto done;
1187         }
1188
1189         if (pdb_rid_algorithm() && (uid < max_algorithmic_uid())) {
1190                 sid_copy(psid, get_global_sam_sid());
1191                 sid_append_rid(psid, algorithmic_pdb_uid_to_user_rid(uid));
1192                 goto done;
1193         } else {
1194                 uid_to_unix_users_sid(uid, psid);
1195                 goto done;
1196         }
1197
1198  done:
1199         DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid,
1200                   sid_string_static(psid)));
1201
1202         store_uid_sid_cache(psid, uid);
1203         return;
1204 }
1205
1206 /*****************************************************************
1207  *THE CANONICAL* convert gid_t to SID function.
1208 *****************************************************************/  
1209
1210 void gid_to_sid(DOM_SID *psid, gid_t gid)
1211 {
1212         gid_t low, high;
1213
1214         ZERO_STRUCTP(psid);
1215
1216         if (fetch_sid_from_gid_cache(psid, gid))
1217                 return;
1218
1219         if (lp_idmap_gid(&low, &high) && (gid >= low) && (gid <= high) &&
1220             winbind_gid_to_sid(psid, gid)) {
1221
1222                 DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
1223                           (unsigned int)gid, sid_string_static(psid)));
1224                 goto done;
1225         }
1226
1227         if (pdb_gid_to_sid(gid, psid)) {
1228                 /* This is a mapped group */
1229                 goto done;
1230         }
1231
1232         if (pdb_rid_algorithm() && (gid < max_algorithmic_gid())) {
1233                 sid_copy(psid, get_global_sam_sid());
1234                 sid_append_rid(psid, pdb_gid_to_group_rid(gid));
1235                 goto done;
1236         } else {
1237                 sid_copy(psid, &global_sid_Unix_Groups);
1238                 sid_append_rid(psid, gid);
1239                 goto done;
1240         }
1241
1242  done:
1243         DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid,
1244                   sid_string_static(psid)));
1245
1246         store_gid_sid_cache(psid, gid);
1247         return;
1248 }
1249
1250 /*****************************************************************
1251  *THE CANONICAL* convert SID to uid function.
1252 *****************************************************************/  
1253
1254 BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid)
1255 {
1256         enum SID_NAME_USE type;
1257         uint32 rid;
1258         gid_t gid;
1259
1260         if (fetch_uid_from_cache(puid, psid))
1261                 return True;
1262
1263         if (fetch_gid_from_cache(&gid, psid)) {
1264                 return False;
1265         }
1266
1267         if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
1268                 uid_t uid = rid;
1269                 *puid = uid;
1270                 goto done;
1271         }
1272
1273         if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
1274                 union unid_t id;
1275
1276                 if (pdb_sid_to_id(psid, &id, &type)) {
1277                         if (type != SID_NAME_USER) {
1278                                 DEBUG(5, ("sid %s is a %s, expected a user\n",
1279                                           sid_string_static(psid),
1280                                           sid_type_lookup(type)));
1281                                 return False;
1282                         }
1283                         *puid = id.uid;
1284                         goto done;
1285                 }
1286                 if (pdb_rid_algorithm() &&
1287                     algorithmic_pdb_rid_is_user(rid)) {
1288                         *puid = algorithmic_pdb_user_rid_to_uid(rid);
1289                         goto done;
1290                 }
1291
1292                 /* This was ours, but it was neither mapped nor
1293                  * algorithmic. Fail */
1294                 return False;
1295         }
1296
1297         if (winbind_lookup_sid(NULL, psid, NULL, NULL, &type)) {
1298
1299                 if (type != SID_NAME_USER) {
1300                         DEBUG(10, ("sid_to_uid: sid %s is a %s\n",
1301                                    sid_string_static(psid),
1302                                    sid_type_lookup(type)));
1303                         return False;
1304                 }
1305
1306                 if (!winbind_sid_to_uid(puid, psid)) {
1307                         DEBUG(5, ("sid_to_uid: winbind failed to allocate a "
1308                                   "new uid for sid %s\n",
1309                                   sid_string_static(psid)));
1310                         return False;
1311                 }
1312                 goto done;
1313         }
1314
1315         /* TODO: Here would be the place to allocate both a gid and a uid for
1316          * the SID in question */
1317
1318         return False;
1319
1320  done:
1321         DEBUG(10,("sid_to_uid: %s -> %u\n", sid_string_static(psid),
1322                 (unsigned int)*puid ));
1323
1324         store_uid_sid_cache(psid, *puid);
1325         return True;
1326 }
1327
1328 /*****************************************************************
1329  *THE CANONICAL* convert SID to gid function.
1330  Group mapping is used for gids that maps to Wellknown SIDs
1331 *****************************************************************/  
1332
1333 BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid)
1334 {
1335         uint32 rid;
1336         GROUP_MAP map;
1337         union unid_t id;
1338         enum SID_NAME_USE type;
1339         uid_t uid;
1340
1341         if (fetch_gid_from_cache(pgid, psid))
1342                 return True;
1343
1344         if (fetch_uid_from_cache(&uid, psid))
1345                 return False;
1346
1347         if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
1348                 gid_t gid = rid;
1349                 *pgid = gid;
1350                 goto done;
1351         }
1352
1353         if ((sid_check_is_in_builtin(psid) ||
1354              sid_check_is_in_wellknown_domain(psid))) {
1355                 if (pdb_getgrsid(&map, *psid)) {
1356                         *pgid = map.gid;
1357                         goto done;
1358                 }
1359                 return False;
1360         }
1361
1362         if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
1363                 if (pdb_sid_to_id(psid, &id, &type)) {
1364                         if ((type != SID_NAME_DOM_GRP) &&
1365                             (type != SID_NAME_ALIAS)) {
1366                                 DEBUG(5, ("sid %s is a %s, expected a group\n",
1367                                           sid_string_static(psid),
1368                                           sid_type_lookup(type)));
1369                                 return False;
1370                         }
1371                         *pgid = id.gid;
1372                         goto done;
1373                 }
1374                 if (pdb_rid_algorithm() &&
1375                     !algorithmic_pdb_rid_is_user(rid)) {
1376                         /* This must be a group, presented as alias */
1377                         *pgid = pdb_group_rid_to_gid(rid);
1378                         goto done;
1379                 }
1380                 /* This was ours, but it was neither mapped nor
1381                  * algorithmic. Fail. */
1382                 return False;
1383         }
1384         
1385         if (!winbind_lookup_sid(NULL, psid, NULL, NULL, &type)) {
1386                 DEBUG(11,("sid_to_gid: no one knows the SID %s (tried local, "
1387                           "then winbind)\n", sid_string_static(psid)));
1388                 
1389                 return False;
1390         }
1391
1392         /* winbindd knows it; Ensure this is a group sid */
1393
1394         if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
1395             (type != SID_NAME_WKN_GRP)) {
1396                 DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is "
1397                           "a %s\n", sid_type_lookup(type)));
1398                 return False;
1399         }
1400         
1401         /* winbindd knows it and it is a type of group; sid_to_gid must succeed
1402            or we are dead in the water */
1403
1404         if ( !winbind_sid_to_gid(pgid, psid) ) {
1405                 DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid "
1406                           "for sid %s\n", sid_string_static(psid)));
1407                 return False;
1408         }
1409
1410  done:
1411         DEBUG(10,("sid_to_gid: %s -> %u\n", sid_string_static(psid),
1412                   (unsigned int)*pgid ));
1413
1414         store_gid_sid_cache(psid, *pgid);
1415         
1416         return True;
1417 }
1418