3de5b6078554f3bd623d548d414c81c51532c35e
[samba.git] / source / lib / domain_namemap.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Groupname handling
5    Copyright (C) Jeremy Allison 1998.
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 /* 
23  * UNIX gid and Local or Domain SID resolution.  This module resolves
24  * only those entries in the map files, it is *NOT* responsible for
25  * resolving UNIX groups not listed: that is an entirely different
26  * matter, altogether...
27  */
28
29 /*
30  *
31  *
32
33  format of the file is:
34
35  unixname       NT Group name
36  unixname       Domain Admins (well-known Domain Group)
37  unixname       DOMAIN_NAME\NT Group name
38  unixname       OTHER_DOMAIN_NAME\NT Group name
39  unixname       DOMAIN_NAME\Domain Admins (well-known Domain Group)
40  ....
41
42  if the DOMAIN_NAME\ component is left off, then your own domain is assumed.
43
44  *
45  *
46  */
47
48
49 #include "includes.h"
50 extern int DEBUGLEVEL;
51
52 extern fstring global_sam_name;
53 extern DOM_SID global_sam_sid;
54 extern DOM_SID global_sid_S_1_5_20;
55
56 /*******************************************************************
57  converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
58  ********************************************************************/
59 static uid_t pwdb_user_rid_to_uid(uint32 user_rid)
60 {
61         return ((user_rid & (~RID_TYPE_USER))- 1000)/RID_MULTIPLIER;
62 }
63
64 /*******************************************************************
65  converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
66  ********************************************************************/
67 static uint32 pwdb_group_rid_to_gid(uint32 group_rid)
68 {
69         return ((group_rid & (~RID_TYPE_GROUP))- 1000)/RID_MULTIPLIER;
70 }
71
72 /*******************************************************************
73  converts NT Alias RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
74  ********************************************************************/
75 static uint32 pwdb_alias_rid_to_gid(uint32 alias_rid)
76 {
77         return ((alias_rid & (~RID_TYPE_ALIAS))- 1000)/RID_MULTIPLIER;
78 }
79
80 /*******************************************************************
81  converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
82  ********************************************************************/
83 static uint32 pwdb_gid_to_group_rid(uint32 gid)
84 {
85         uint32 grp_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_GROUP);
86         return grp_rid;
87 }
88
89 /******************************************************************
90  converts UNIX gid to an NT Alias RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
91  ********************************************************************/
92 static uint32 pwdb_gid_to_alias_rid(uint32 gid)
93 {
94         uint32 alias_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_ALIAS);
95         return alias_rid;
96 }
97
98 /*******************************************************************
99  converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
100  ********************************************************************/
101 static uint32 pwdb_uid_to_user_rid(uint32 uid)
102 {
103         uint32 user_rid = ((((uid)*RID_MULTIPLIER) + 1000) | RID_TYPE_USER);
104         return user_rid;
105 }
106
107 /******************************************************************
108  converts SID + SID_NAME_USE type to a UNIX id.  the Domain SID is,
109  and can only be, our own SID.
110  ********************************************************************/
111 static BOOL pwdb_sam_sid_to_unixid(DOM_SID *sid, uint8 type, uint32 *id)
112 {
113         DOM_SID tmp_sid;
114         uint32 rid;
115
116         sid_copy(&tmp_sid, sid);
117         sid_split_rid(&tmp_sid, &rid);
118         if (!sid_equal(&global_sam_sid, &tmp_sid))
119         {
120                 return False;
121         }
122
123         switch (type)
124         {
125                 case SID_NAME_USER:
126                 {
127                         *id = pwdb_user_rid_to_uid(rid);
128                         return True;
129                 }
130                 case SID_NAME_ALIAS:
131                 {
132                         *id = pwdb_alias_rid_to_gid(rid);
133                         return True;
134                 }
135                 case SID_NAME_DOM_GRP:
136                 case SID_NAME_WKN_GRP:
137                 {
138                         *id = pwdb_group_rid_to_gid(rid);
139                         return True;
140                 }
141         }
142         return False;
143 }
144
145 /******************************************************************
146  converts UNIX gid + SID_NAME_USE type to a SID.  the Domain SID is,
147  and can only be, our own SID.
148  ********************************************************************/
149 static BOOL pwdb_unixid_to_sam_sid(uint32 id, uint8 type, DOM_SID *sid)
150 {
151         sid_copy(sid, &global_sam_sid);
152         switch (type)
153         {
154                 case SID_NAME_USER:
155                 {
156                         sid_append_rid(sid, pwdb_uid_to_user_rid(id));
157                         return True;
158                 }
159                 case SID_NAME_ALIAS:
160                 {
161                         sid_append_rid(sid, pwdb_gid_to_alias_rid(id));
162                         return True;
163                 }
164                 case SID_NAME_DOM_GRP:
165                 case SID_NAME_WKN_GRP:
166                 {
167                         sid_append_rid(sid, pwdb_gid_to_group_rid(id));
168                         return True;
169                 }
170         }
171         return False;
172 }
173
174 /*******************************************************************
175  Decides if a RID is a well known RID.
176  ********************************************************************/
177 static BOOL pwdb_rid_is_well_known(uint32 rid)
178 {
179         return (rid < 1000);
180 }
181
182 /*******************************************************************
183  determines a rid's type.  NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
184  ********************************************************************/
185 static uint32 pwdb_rid_type(uint32 rid)
186 {
187         /* lkcl i understand that NT attaches an enumeration to a RID
188          * such that it can be identified as either a user, group etc
189          * type: SID_ENUM_TYPE.
190          */
191         if (pwdb_rid_is_well_known(rid))
192         {
193                 /*
194                  * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
195                  * and DOMAIN_USER_RID_GUEST.
196                  */
197                 if (rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
198                 {
199                         return RID_TYPE_USER;
200                 }
201                 if (DOMAIN_GROUP_RID_ADMINS <= rid && rid <= DOMAIN_GROUP_RID_GUESTS)
202                 {
203                         return RID_TYPE_GROUP;
204                 }
205                 if (BUILTIN_ALIAS_RID_ADMINS <= rid && rid <= BUILTIN_ALIAS_RID_REPLICATOR)
206                 {
207                         return RID_TYPE_ALIAS;
208                 }
209         }
210         return (rid & RID_TYPE_MASK);
211 }
212
213 /*******************************************************************
214  checks whether rid is a user rid.  NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
215  ********************************************************************/
216 BOOL pwdb_rid_is_user(uint32 rid)
217 {
218         return pwdb_rid_type(rid) == RID_TYPE_USER;
219 }
220
221 /**************************************************************************
222  Groupname map functionality. The code loads a groupname map file and
223  (currently) loads it into a linked list. This is slow and memory
224  hungry, but can be changed into a more efficient storage format
225  if the demands on it become excessive.
226 ***************************************************************************/
227
228 typedef struct name_map
229 {
230         ubi_slNode next;
231         DOM_NAME_MAP grp;
232
233 } name_map_entry;
234
235 static ubi_slList groupname_map_list;
236 static ubi_slList aliasname_map_list;
237 static ubi_slList ntusrname_map_list;
238
239 static void delete_name_entry(name_map_entry *gmep)
240 {
241         if (gmep->grp.nt_name)
242         {
243                 free(gmep->grp.nt_name);
244         }
245         if (gmep->grp.nt_domain)
246         {
247                 free(gmep->grp.nt_domain);
248         }
249         if (gmep->grp.unix_name)
250         {
251                 free(gmep->grp.unix_name);
252         }
253         free((char*)gmep);
254 }
255
256 /**************************************************************************
257  Delete all the entries in the name map list.
258 ***************************************************************************/
259
260 static void delete_map_list(ubi_slList *map_list)
261 {
262         name_map_entry *gmep;
263
264         while ((gmep = (name_map_entry *)ubi_slRemHead(map_list )) != NULL)
265         {
266                 delete_name_entry(gmep);
267         }
268 }
269
270
271 /**************************************************************************
272  makes a group sid out of a domain sid and a _unix_ gid.
273 ***************************************************************************/
274 static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type)
275 {
276         DEBUG(10,("make_mydomain_sid\n"));
277
278         if (!map_domain_name_to_sid(&grp->sid, &(grp->nt_domain)))
279         {
280                 DEBUG(0,("make_mydomain_sid: unknown domain %s\n",
281                           grp->nt_domain));
282                 return False;
283         }
284
285         if (sid_equal(&grp->sid, &global_sid_S_1_5_20))
286         {
287                 /*
288                  * only builtin aliases are recognised in S-1-5-20
289                  */
290
291                 if (!lookup_builtin_alias_name(grp->nt_name, "BUILTIN", &grp->sid, &grp->type))
292                 {
293                         DEBUG(0,("unix group %s mapped to an unrecognised BUILTIN domain name %s\n",
294                                   grp->unix_name, grp->nt_name));
295                         return False;
296                 }
297                 return True;
298         }
299         else if (lookup_wk_user_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0)
300         {
301                 if (type != DOM_MAP_USER)
302                 {
303                         DEBUG(0,("well-known NT user %s\%s listed in wrong map file\n",
304                                   grp->nt_domain, grp->nt_name));
305                         return False;
306                 }
307                 return True;
308         }
309         else if (lookup_wk_group_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0)
310         {
311                 if (type != DOM_MAP_DOMAIN)
312                 {
313                         DEBUG(0,("well-known NT group %s\%s listed in wrong map file\n",
314                                   grp->nt_domain, grp->nt_name));
315                         return False;
316                 }
317                 return True;
318         }
319         else
320         {
321                 BOOL ret;
322                 fstring sid_str;
323                 switch (type)
324                 {
325                         case DOM_MAP_USER:
326                         {
327                                 grp->type = SID_NAME_USER;
328                                 break;
329                         }
330                         case DOM_MAP_DOMAIN:
331                         {
332                                 grp->type = SID_NAME_DOM_GRP;
333                                 break;
334                         }
335                         case DOM_MAP_LOCAL:
336                         {
337                                 grp->type = SID_NAME_ALIAS;
338                                 break;
339                         }
340                 }
341
342                 ret = pwdb_unixid_to_sam_sid(grp->unix_id, grp->type, &grp->sid);
343                 sid_to_string(sid_str, &grp->sid);
344                 DEBUG(10,("nt name %s gid %d mapped to %s\n",
345                            grp->nt_name, grp->unix_id, sid_str));
346                 return ret;
347         }
348
349         return False;
350 }
351
352 /**************************************************************************
353  makes a group sid out of an nt domain, nt group name or a unix group name.
354 ***************************************************************************/
355 static BOOL unix_name_to_group_info(DOM_NAME_MAP *grp, DOM_MAP_TYPE type)
356 {
357         struct group *gptr = NULL;
358
359         /*
360          * Attempt to get the unix gid_t for this name.
361          */
362
363         DEBUG(5,("unix_name_to_group_info: unix_name:%s\n", grp->unix_name));
364
365         gptr = (struct group *)getgrnam(grp->unix_name);
366         if (gptr == NULL)
367         {
368                 DEBUG(0,("unix_name_to_group_info: getgrnam for group %s\
369 failed. Error was %s.\n", grp->unix_name, strerror(errno) ));
370                 return False;
371         }
372
373         grp->unix_id = (uint32)gptr->gr_gid;
374
375         DEBUG(5,("unix_name_to_group_info: unix gid:%d\n", grp->unix_id));
376
377         /*
378          * Now map the name to an NT SID+RID.
379          */
380
381         if (grp->nt_domain != NULL && !strequal(grp->nt_domain, global_sam_name))
382         {
383                 /* Must add client-call lookup code here, to 
384                  * resolve remote domain's sid and the group's rid,
385                  * in that domain.
386                  *
387                  * NOTE: it is _incorrect_ to put code here that assumes
388                  * we are responsible for lookups for foriegn domains' RIDs.
389                  *
390                  * for foriegn domains for which we are *NOT* the PDC, all
391                  * we can be responsible for is the unix gid_t to which
392                  * the foriegn SID+rid maps to, on this _local_ machine.  
393                  * we *CANNOT* make any short-cuts or assumptions about
394                  * RIDs in a foriegn domain.
395                  */
396
397                 if (!map_domain_name_to_sid(&grp->sid, &(grp->nt_domain)))
398                 {
399                         DEBUG(0,("unix_name_to_group_info: no known sid for %s\n",
400                                   grp->nt_domain));
401                         return False;
402                 }
403         }
404
405         return make_mydomain_sid(grp, type);
406 }
407
408 static BOOL make_name_entry(name_map_entry **new_ep,
409                 char *nt_domain, char *nt_group, char *unix_group,
410                 DOM_MAP_TYPE type)
411 {
412         /*
413          * Create the list entry and add it onto the list.
414          */
415
416         DEBUG(5,("make_name_entry:%s,%s,%s\n", nt_domain, nt_group, unix_group));
417
418         (*new_ep) = (name_map_entry *)malloc(sizeof(name_map_entry));
419         if ((*new_ep) == NULL)
420         {
421                 DEBUG(0,("make_name_entry: malloc fail for name_map_entry.\n"));
422                 return False;
423         } 
424
425         ZERO_STRUCTP(*new_ep);
426
427         (*new_ep)->grp.nt_name   = strdup(nt_group  );
428         (*new_ep)->grp.nt_domain = strdup(nt_domain );
429         (*new_ep)->grp.unix_name = strdup(unix_group);
430
431         if ((*new_ep)->grp.nt_name   == NULL ||
432             (*new_ep)->grp.unix_name == NULL)
433         {
434                 DEBUG(0,("make_name_entry: malloc fail for names in name_map_entry.\n"));
435                 delete_name_entry((*new_ep));
436                 return False;
437         }
438
439         /*
440          * look up the group names, make the Group-SID and unix gid
441          */
442  
443         if (!unix_name_to_group_info(&(*new_ep)->grp, type))
444         {
445                 delete_name_entry((*new_ep));
446                 return False;
447         }
448
449         return True;
450 }
451
452 /**************************************************************************
453  Load a name map file. Sets last accessed timestamp.
454 ***************************************************************************/
455 static ubi_slList *load_name_map(DOM_MAP_TYPE type)
456 {
457         static time_t groupmap_file_last_modified = (time_t)0;
458         static time_t aliasmap_file_last_modified = (time_t)0;
459         static time_t ntusrmap_file_last_modified  = (time_t)0;
460         static BOOL initialised_group = False;
461         static BOOL initialised_alias = False;
462         static BOOL initialised_ntusr  = False;
463         char *groupname_map_file = lp_groupname_map();
464         char *aliasname_map_file = lp_aliasname_map();
465         char *ntusrname_map_file = lp_ntusrname_map();
466
467         SMB_STRUCT_STAT st;
468         FILE *fp;
469         char *s;
470         pstring buf;
471         name_map_entry *new_ep;
472
473         time_t *file_last_modified = NULL;
474         int    *initialised = NULL;
475         char   *map_file = NULL;
476         ubi_slList *map_list = NULL;
477
478         switch (type)
479         {
480                 case DOM_MAP_DOMAIN:
481                 {
482                         file_last_modified = &groupmap_file_last_modified;
483                         initialised        = &initialised_group;
484                         map_file           = groupname_map_file;
485                         map_list           = &groupname_map_list;
486
487                         break;
488                 }
489                 case DOM_MAP_LOCAL:
490                 {
491                         file_last_modified = &aliasmap_file_last_modified;
492                         initialised        = &initialised_alias;
493                         map_file           = aliasname_map_file;
494                         map_list           = &aliasname_map_list;
495
496                         break;
497                 }
498                 case DOM_MAP_USER:
499                 {
500                         file_last_modified = &ntusrmap_file_last_modified;
501                         initialised        = &initialised_ntusr;
502                         map_file           = ntusrname_map_file;
503                         map_list           = &ntusrname_map_list;
504
505                         break;
506                 }
507         }
508
509         if (!(*initialised))
510         {
511                 DEBUG(10,("initialising map %s\n", map_file));
512                 ubi_slInitList(map_list);
513                 (*initialised) = True;
514         }
515
516         if (!*map_file)
517         {
518                 return map_list;
519         }
520
521         if (sys_stat(map_file, &st) != 0)
522         {
523                 DEBUG(0, ("load_name_map: Unable to stat file %s. Error was %s\n",
524                            map_file, strerror(errno) ));
525                 return map_list;
526         }
527
528         /*
529          * Check if file has changed.
530          */
531         if (st.st_mtime <= (*file_last_modified))
532         {
533                 return map_list;
534         }
535
536         (*file_last_modified) = st.st_mtime;
537
538         /*
539          * Load the file.
540          */
541
542         fp = fopen(map_file,"r");
543         if (!fp)
544         {
545                 DEBUG(0,("load_name_map: can't open name map %s. Error was %s\n",
546                           map_file, strerror(errno)));
547                 return map_list;
548         }
549
550         /*
551          * Throw away any previous list.
552          */
553         delete_map_list(map_list);
554
555         DEBUG(4,("load_name_map: Scanning name map %s\n",map_file));
556
557         while ((s = fgets_slash(buf, sizeof(buf), fp)) != NULL)
558         {
559                 pstring unixname;
560                 pstring nt_name;
561                 fstring nt_domain;
562                 fstring nt_group;
563                 char *p;
564
565                 DEBUG(10,("Read line |%s|\n", s));
566
567                 memset(nt_name, 0, sizeof(nt_name));
568
569                 if (!*s || strchr("#;",*s))
570                         continue;
571
572                 if (!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
573                         continue;
574
575                 if (!next_token(&s,nt_name, "\t\n\r=", sizeof(nt_name)))
576                         continue;
577
578                 trim_string(unixname, " ", " ");
579                 trim_string(nt_name, " ", " ");
580
581                 if (!*nt_name)
582                         continue;
583
584                 if (!*unixname)
585                         continue;
586
587                 DEBUG(5,("unixname = %s, ntname = %s.\n",
588                           unixname, nt_name));
589
590                 p = strchr(nt_name, '\\');
591
592                 if (p == NULL)
593                 {
594                         memset(nt_domain, 0, sizeof(nt_domain));
595                         fstrcpy(nt_group, nt_name);
596                 }
597                 else
598                 {
599                         *p = 0;
600                         p++;
601                         fstrcpy(nt_domain, nt_name);
602                         fstrcpy(nt_group , p);
603                 }
604
605                 if (make_name_entry(&new_ep, nt_domain, nt_name, unixname, type))
606                 {
607                         ubi_slAddTail(map_list, (ubi_slNode *)new_ep);
608                 }
609         }
610
611         DEBUG(10,("load_name_map: Added %ld entries to name map.\n",
612                    ubi_slCount(map_list)));
613
614         fclose(fp);
615
616         return map_list;
617 }
618
619 static void copy_grp_map_entry(DOM_NAME_MAP *grp, const DOM_NAME_MAP *from)
620 {
621         sid_copy(&grp->sid, &from->sid);
622         grp->unix_id   = from->unix_id;
623         grp->nt_name   = from->nt_name;
624         grp->nt_domain = from->nt_domain;
625         grp->unix_name = from->unix_name;
626         grp->type      = from->type;
627 }
628
629 #if 0
630 /***********************************************************
631  Lookup unix name.
632 ************************************************************/
633 static BOOL map_unixname(DOM_MAP_TYPE type,
634                 char *unixname, DOM_NAME_MAP *grp_info)
635 {
636         name_map_entry *gmep;
637         ubi_slList *map_list;
638
639         /*
640          * Initialise and load if not already loaded.
641          */
642         map_list = load_name_map(type);
643
644         for (gmep = (name_map_entry *)ubi_slFirst(map_list);
645              gmep != NULL;
646              gmep = (name_map_entry *)ubi_slNext(gmep ))
647         {
648                 if (strequal(gmep->grp.unix_name, unixname))
649                 {
650                         copy_grp_map_entry(grp_info, &gmep->grp);
651                         DEBUG(7,("map_unixname: Mapping unix group %s to nt group %s.\n",
652                                gmep->grp.unix_name, gmep->grp.nt_name ));
653                         return True;
654                 }
655         }
656
657         return False;
658 }
659
660 #endif
661
662 /***********************************************************
663  Lookup nt name.
664 ************************************************************/
665 static BOOL map_ntname(DOM_MAP_TYPE type, char *ntname, char *ntdomain,
666                                 DOM_NAME_MAP *grp_info)
667 {
668         name_map_entry *gmep;
669         ubi_slList *map_list;
670
671         /*
672          * Initialise and load if not already loaded.
673          */
674         map_list = load_name_map(type);
675
676         for (gmep = (name_map_entry *)ubi_slFirst(map_list);
677              gmep != NULL;
678              gmep = (name_map_entry *)ubi_slNext(gmep ))
679         {
680                 if (strequal(gmep->grp.nt_name  , ntname) &&
681                     strequal(gmep->grp.nt_domain, ntdomain))
682                 {
683                         copy_grp_map_entry(grp_info, &gmep->grp);
684                         DEBUG(7,("map_ntname: Mapping unix group %s to nt group %s.\n",
685                                gmep->grp.unix_name, gmep->grp.nt_name ));
686                         return True;
687                 }
688         }
689
690         return False;
691 }
692
693
694 /***********************************************************
695  Lookup by SID
696 ************************************************************/
697 static BOOL map_sid(DOM_MAP_TYPE type,
698                 DOM_SID *psid, DOM_NAME_MAP *grp_info)
699 {
700         name_map_entry *gmep;
701         ubi_slList *map_list;
702
703         /*
704          * Initialise and load if not already loaded.
705          */
706         map_list = load_name_map(type);
707
708         for (gmep = (name_map_entry *)ubi_slFirst(map_list);
709              gmep != NULL;
710              gmep = (name_map_entry *)ubi_slNext(gmep ))
711         {
712                 if (sid_equal(&gmep->grp.sid, psid))
713                 {
714                         copy_grp_map_entry(grp_info, &gmep->grp);
715                         DEBUG(7,("map_sid: Mapping unix group %s to nt group %s.\n",
716                                gmep->grp.unix_name, gmep->grp.nt_name ));
717                         return True;
718                 }
719         }
720
721         return False;
722 }
723
724 /***********************************************************
725  Lookup by gid_t.
726 ************************************************************/
727 static BOOL map_unixid(DOM_MAP_TYPE type, uint32 unix_id, DOM_NAME_MAP *grp_info)
728 {
729         name_map_entry *gmep;
730         ubi_slList *map_list;
731
732         /*
733          * Initialise and load if not already loaded.
734          */
735         map_list = load_name_map(type);
736
737         for (gmep = (name_map_entry *)ubi_slFirst(map_list);
738              gmep != NULL;
739              gmep = (name_map_entry *)ubi_slNext(gmep ))
740         {
741                 fstring sid_str;
742                 sid_to_string(sid_str, &gmep->grp.sid);
743                 DEBUG(10,("map_unixid: enum entry unix group %s %d nt %s %s\n",
744                                gmep->grp.unix_name, gmep->grp.unix_id, gmep->grp.nt_name, sid_str));
745                 if (gmep->grp.unix_id == unix_id)
746                 {
747                         copy_grp_map_entry(grp_info, &gmep->grp);
748                         DEBUG(7,("map_unixid: Mapping unix group %s to nt group %s type %d\n",
749                                gmep->grp.unix_name, gmep->grp.nt_name, gmep->grp.type));
750                         return True;
751                 }
752         }
753
754         return False;
755 }
756
757 /***********************************************************
758  *
759  * Call four functions to resolve unix group ids and either
760  * local group SIDs or domain group SIDs listed in the local group
761  * or domain group map files.
762  *
763  * Note that it is *NOT* the responsibility of these functions to
764  * resolve entries that are not in the map files.
765  *
766  * Any SID can be in the map files (i.e from any Domain).
767  *
768  ***********************************************************/
769
770 #if 0
771
772 /***********************************************************
773  Lookup a UNIX Group entry by name.
774 ************************************************************/
775 BOOL map_unix_group_name(char *group_name, DOM_NAME_MAP *grp_info)
776 {
777         return map_unixname(DOM_MAP_DOMAIN, group_name, grp_info);
778 }
779
780 /***********************************************************
781  Lookup a UNIX Alias entry by name.
782 ************************************************************/
783 BOOL map_unix_alias_name(char *alias_name, DOM_NAME_MAP *grp_info)
784 {
785         return map_unixname(DOM_MAP_LOCAL, alias_name, grp_info);
786 }
787
788 /***********************************************************
789  Lookup an Alias name entry 
790 ************************************************************/
791 BOOL map_nt_alias_name(char *ntalias_name, char *nt_domain, DOM_NAME_MAP *grp_info)
792 {
793         return map_ntname(DOM_MAP_LOCAL, ntalias_name, nt_domain, grp_info);
794 }
795
796 /***********************************************************
797  Lookup a Group entry
798 ************************************************************/
799 BOOL map_nt_group_name(char *ntgroup_name, char *nt_domain, DOM_NAME_MAP *grp_info)
800 {
801         return map_ntname(DOM_MAP_DOMAIN, ntgroup_name, nt_domain, grp_info);
802 }
803
804 #endif
805
806 /***********************************************************
807  Lookup a Username entry by name.
808 ************************************************************/
809 static BOOL map_nt_username(char *nt_name, char *nt_domain, DOM_NAME_MAP *grp_info)
810 {
811         return map_ntname(DOM_MAP_USER, nt_name, nt_domain, grp_info);
812 }
813
814 /***********************************************************
815  Lookup a Username entry by SID.
816 ************************************************************/
817 static BOOL map_username_sid(DOM_SID *sid, DOM_NAME_MAP *grp_info)
818 {
819         return map_sid(DOM_MAP_USER, sid, grp_info);
820 }
821
822 /***********************************************************
823  Lookup a Username SID entry by uid.
824 ************************************************************/
825 static BOOL map_username_uid(uid_t gid, DOM_NAME_MAP *grp_info)
826 {
827         return map_unixid(DOM_MAP_USER, (uint32)gid, grp_info);
828 }
829
830 /***********************************************************
831  Lookup an Alias SID entry by name.
832 ************************************************************/
833 BOOL map_alias_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info)
834 {
835         return map_sid(DOM_MAP_LOCAL, psid, grp_info);
836 }
837
838 /***********************************************************
839  Lookup a Group entry by sid.
840 ************************************************************/
841 BOOL map_group_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info)
842 {
843         return map_sid(DOM_MAP_DOMAIN, psid, grp_info);
844 }
845
846 /***********************************************************
847  Lookup an Alias SID entry by gid_t.
848 ************************************************************/
849 static BOOL map_alias_gid(gid_t gid, DOM_NAME_MAP *grp_info)
850 {
851         return map_unixid(DOM_MAP_LOCAL, (uint32)gid, grp_info);
852 }
853
854 /***********************************************************
855  Lookup a Group SID entry by gid_t.
856 ************************************************************/
857 static BOOL map_group_gid( gid_t gid, DOM_NAME_MAP *grp_info)
858 {
859         return map_unixid(DOM_MAP_DOMAIN, (uint32)gid, grp_info);
860 }
861
862
863 /************************************************************************
864  Routine to look up User details by UNIX name
865 *************************************************************************/
866 BOOL lookupsmbpwnam(const char *unix_usr_name, DOM_NAME_MAP *grp)
867 {
868         uid_t uid;
869         DEBUG(10,("lookupsmbpwnam: unix user name %s\n", unix_usr_name));
870         if (nametouid(unix_usr_name, &uid))
871         {
872                 return lookupsmbpwuid(uid, grp);
873         }
874         else
875         {
876                 return False;
877         }
878 }
879
880 /*
881  * used by lookup functions below
882  */
883
884 static fstring nt_name;
885 static fstring unix_name;
886 static fstring nt_domain;
887
888 /*************************************************************************
889  looks up a uid, returns User Information.  
890 *************************************************************************/
891 BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep)
892 {
893         DEBUG(10,("lookupsmbpwuid: unix uid %d\n", uid));
894         if (map_username_uid(uid, gmep))
895         {
896                 return True;
897         }
898         if (lp_server_role() != ROLE_DOMAIN_NONE)
899         {
900                 gmep->nt_name   = nt_name;
901                 gmep->unix_name = unix_name;
902
903                 gmep->unix_id = (uint32)uid;
904
905                 /*
906                  * here we should do a LsaLookupNames() call
907                  * to check the status of the name with the PDC.
908                  * if the PDC know nothing of the name, it's ours.
909                  */
910
911                 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
912                 {
913 #if 0
914                         do_lsa_lookup_names(global_myworkgroup, gmep->nt_name, &gmep->sid...);
915 #endif
916                 }
917
918                 gmep->type = SID_NAME_USER;
919                 fstrcpy(gmep->nt_name, uidtoname(uid));
920                 fstrcpy(gmep->unix_name, gmep->nt_name);
921                 gmep->nt_domain = global_sam_name;
922                 pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid);
923
924                 return True;
925         }
926
927         /* oops. */
928
929         return False;
930 }
931
932 /*************************************************************************
933  looks up by NT name, returns User Information.  
934 *************************************************************************/
935 BOOL lookupsmbpwntnam(char *fullntname, DOM_NAME_MAP *gmep)
936 {
937         DEBUG(10,("lookupsmbpwntnam: nt user name %s\n", fullntname));
938
939         if (!split_domain_name(fullntname, nt_name, nt_domain))
940         {
941                 return False;
942         }
943
944         if (map_nt_username(nt_name, nt_domain, gmep))
945         {
946                 return True;
947         }
948         if (lp_server_role() != ROLE_DOMAIN_NONE)
949         {
950                 uid_t uid;
951                 gmep->nt_name   = nt_name;
952                 gmep->unix_name = unix_name;
953                 gmep->nt_domain = nt_domain;
954
955                 /*
956                  * here we should do a LsaLookupNames() call
957                  * to check the status of the name with the PDC.
958                  * if the PDC know nothing of the name, it's ours.
959                  */
960
961                 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
962                 {
963 #if 0
964                         do_lsa_lookup_names(global_myworkgroup, gmep->nt_name, gmep->nt_domain, &gmep->sid...);
965 #endif
966                 }
967
968                 gmep->type = SID_NAME_USER;
969                 fstrcpy(gmep->unix_name, gmep->nt_name);
970                 if (!nametouid(gmep->unix_name, &uid))
971                 {
972                         return False;
973                 }
974                 gmep->unix_id = (uint32)uid;
975                 if (!pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid))
976                 {
977                         return False;
978                 }
979
980                 return True;
981         }
982
983         /* oops. */
984
985         return False;
986 }
987
988 /*************************************************************************
989  looks up by RID, returns User Information.  
990 *************************************************************************/
991 BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
992 {
993         fstring sid_str;
994         sid_to_string(sid_str, sid);
995         DEBUG(10,("lookupsmbpwsid: nt sid %s\n", sid_str));
996
997         if (map_username_sid(sid, gmep))
998         {
999                 return True;
1000         }
1001         if (lp_server_role() != ROLE_DOMAIN_NONE)
1002         {
1003                 gmep->nt_name   = nt_name;
1004                 gmep->unix_name = unix_name;
1005                 gmep->nt_domain = nt_domain;
1006
1007                 /*
1008                  * here we should do a LsaLookupNames() call
1009                  * to check the status of the name with the PDC.
1010                  * if the PDC know nothing of the name, it's ours.
1011                  */
1012
1013                 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1014                 {
1015 #if 0
1016                         do_lsa_lookup_sids(global_myworkgroup, gmep->sid, gmep->nt_name, gmep->nt_domain...);
1017 #endif
1018                 }
1019
1020                 gmep->type = SID_NAME_USER;
1021                 sid_copy(&gmep->sid, sid);
1022                 if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
1023                 {
1024                         return False;
1025                 }
1026                 fstrcpy(gmep->nt_name, uidtoname((uid_t)gmep->unix_id));
1027                 fstrcpy(gmep->unix_name, gmep->nt_name);
1028                 gmep->nt_domain = global_sam_name;
1029
1030                 return True;
1031         }
1032
1033         /* oops. */
1034
1035         return False;
1036 }
1037
1038 /************************************************************************
1039  Routine to look up group / alias / well-known group RID by UNIX name
1040 *************************************************************************/
1041 BOOL lookupsmbgrpnam(const char *unix_grp_name, DOM_NAME_MAP *grp)
1042 {
1043         gid_t gid;
1044         DEBUG(10,("lookupsmbgrpnam: unix user group %s\n", unix_grp_name));
1045         if (nametogid(unix_grp_name, &gid))
1046         {
1047                 return lookupsmbgrpgid(gid, grp);
1048         }
1049         else
1050         {
1051                 return False;
1052         }
1053 }
1054
1055 /*************************************************************************
1056  looks up a SID, returns name map entry
1057 *************************************************************************/
1058 BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
1059 {
1060         fstring sid_str;
1061         sid_to_string(sid_str, sid);
1062         DEBUG(10,("lookupsmbgrpsid: nt sid %s\n", sid_str));
1063
1064         if (map_alias_sid(sid, gmep))
1065         {
1066                 return True;
1067         }
1068         if (map_group_sid(sid, gmep))
1069         {
1070                 return True;
1071         }
1072         if (lp_server_role() != ROLE_DOMAIN_NONE)
1073         {
1074                 gmep->nt_name   = nt_name;
1075                 gmep->unix_name = unix_name;
1076                 gmep->nt_domain = nt_domain;
1077
1078                 /*
1079                  * here we should do a LsaLookupNames() call
1080                  * to check the status of the name with the PDC.
1081                  * if the PDC know nothing of the name, it's ours.
1082                  */
1083
1084                 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1085                 {
1086 #if 0
1087                         do_lsa_lookup_sids(global_myworkgroup, gmep->sid, gmep->nt_name, gmep->nt_domain...);
1088 #endif
1089                 }
1090
1091                 /* name is not explicitly mapped
1092                  * with map files or the PDC
1093                  * so we are responsible for it...
1094                  */
1095
1096                 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1097                 {
1098                         /* ... as a LOCAL group. */
1099                         gmep->type = SID_NAME_ALIAS;
1100                 }
1101                 else
1102                 {
1103                         /* ... as a DOMAIN group. */
1104                         gmep->type = SID_NAME_DOM_GRP;
1105                 }
1106
1107                 sid_copy(&gmep->sid, sid);
1108                 if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
1109                 {
1110                         return False;
1111                 }
1112                 fstrcpy(gmep->nt_name, gidtoname((gid_t)gmep->unix_id));
1113                 fstrcpy(gmep->unix_name, gmep->nt_name);
1114                 gmep->nt_domain = global_sam_name;
1115
1116                 return True;
1117         }
1118
1119         /* oops */
1120         return False;
1121 }
1122
1123 /*************************************************************************
1124  looks up a gid, returns RID and type local, domain or well-known domain group
1125 *************************************************************************/
1126 BOOL lookupsmbgrpgid(gid_t gid, DOM_NAME_MAP *gmep)
1127 {
1128         DEBUG(10,("lookupsmbgrpgid: unix gid %d\n", (int)gid));
1129         if (map_alias_gid(gid, gmep))
1130         {
1131                 return True;
1132         }
1133         if (map_group_gid(gid, gmep))
1134         {
1135                 return True;
1136         }
1137         if (lp_server_role() != ROLE_DOMAIN_NONE)
1138         {
1139                 gmep->nt_name   = nt_name;
1140                 gmep->unix_name = unix_name;
1141
1142                 gmep->unix_id = (uint32)gid;
1143
1144                 /*
1145                  * here we should do a LsaLookupNames() call
1146                  * to check the status of the name with the PDC.
1147                  * if the PDC know nothing of the name, it's ours.
1148                  */
1149
1150                 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1151                 {
1152 #if 0
1153                         do_lsa_lookup_names(global_myworkgroup, gmep->nt_name, &gmep->sid...);
1154                         {
1155                                 return True;
1156                         }
1157 #endif
1158                 }
1159
1160                 /* name is not explicitly mapped
1161                  * with map files or the PDC
1162                  * so we are responsible for it...
1163                  */
1164
1165                 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1166                 {
1167                         /* ... as a LOCAL group. */
1168                         gmep->type = SID_NAME_ALIAS;
1169                 }
1170                 else
1171                 {
1172                         /* ... as a DOMAIN group. */
1173                         gmep->type = SID_NAME_DOM_GRP;
1174                 }
1175                 fstrcpy(gmep->nt_name, gidtoname(gid));
1176                 fstrcpy(gmep->unix_name, gmep->nt_name);
1177                 gmep->nt_domain = global_sam_name;
1178                 pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid);
1179
1180                 return True;
1181         }
1182
1183         /* oops */
1184         return False;
1185 }
1186