if we are adding a new sambaAccount, make sure that we add a
[Samba.git] / source / lib / domain_namemap.c
blob81b519a88d6342aca76d2f2cc1b086c0d3d640e4
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Groupname handling
5 Copyright (C) Jeremy Allison 1998.
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.
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.
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.
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...
33 format of the file is:
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 ....
42 if the DOMAIN_NAME\ component is left off, then your own domain is assumed.
49 #include "includes.h"
51 extern fstring global_myworkgroup;
52 extern DOM_SID global_member_sid;
53 extern fstring global_sam_name;
54 extern DOM_SID global_sam_sid;
55 extern DOM_SID global_sid_S_1_5_20;
57 /*******************************************************************
58 converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
59 ********************************************************************/
60 static uid_t pwdb_user_rid_to_uid(uint32 user_rid)
62 return ((user_rid & (~RID_TYPE_USER))- 1000)/RID_MULTIPLIER;
65 /*******************************************************************
66 converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
67 ********************************************************************/
68 static uint32 pwdb_group_rid_to_gid(uint32 group_rid)
70 return ((group_rid & (~RID_TYPE_GROUP))- 1000)/RID_MULTIPLIER;
73 /*******************************************************************
74 converts NT Alias RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
75 ********************************************************************/
76 static uint32 pwdb_alias_rid_to_gid(uint32 alias_rid)
78 return ((alias_rid & (~RID_TYPE_ALIAS))- 1000)/RID_MULTIPLIER;
81 /*******************************************************************
82 converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
83 ********************************************************************/
84 static uint32 pwdb_gid_to_group_rid(uint32 gid)
86 uint32 grp_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_GROUP);
87 return grp_rid;
90 /******************************************************************
91 converts UNIX gid to an NT Alias RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
92 ********************************************************************/
93 static uint32 pwdb_gid_to_alias_rid(uint32 gid)
95 uint32 alias_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_ALIAS);
96 return alias_rid;
99 /*******************************************************************
100 converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
101 ********************************************************************/
102 static uint32 pwdb_uid_to_user_rid(uint32 uid)
104 uint32 user_rid = ((((uid)*RID_MULTIPLIER) + 1000) | RID_TYPE_USER);
105 return user_rid;
108 /******************************************************************
109 converts SID + SID_NAME_USE type to a UNIX id. the Domain SID is,
110 and can only be, our own SID.
111 ********************************************************************/
112 static BOOL pwdb_sam_sid_to_unixid(DOM_SID *sid, uint8 type, uint32 *id)
114 DOM_SID tmp_sid;
115 uint32 rid;
117 sid_copy(&tmp_sid, sid);
118 sid_split_rid(&tmp_sid, &rid);
119 if (!sid_equal(&global_sam_sid, &tmp_sid))
121 return False;
124 switch (type)
126 case SID_NAME_USER:
128 *id = pwdb_user_rid_to_uid(rid);
129 return True;
131 case SID_NAME_ALIAS:
133 *id = pwdb_alias_rid_to_gid(rid);
134 return True;
136 case SID_NAME_DOM_GRP:
137 case SID_NAME_WKN_GRP:
139 *id = pwdb_group_rid_to_gid(rid);
140 return True;
143 return False;
146 /******************************************************************
147 converts UNIX gid + SID_NAME_USE type to a SID. the Domain SID is,
148 and can only be, our own SID.
149 ********************************************************************/
150 static BOOL pwdb_unixid_to_sam_sid(uint32 id, uint8 type, DOM_SID *sid)
152 sid_copy(sid, &global_sam_sid);
153 switch (type)
155 case SID_NAME_USER:
157 sid_append_rid(sid, pwdb_uid_to_user_rid(id));
158 return True;
160 case SID_NAME_ALIAS:
162 sid_append_rid(sid, pwdb_gid_to_alias_rid(id));
163 return True;
165 case SID_NAME_DOM_GRP:
166 case SID_NAME_WKN_GRP:
168 sid_append_rid(sid, pwdb_gid_to_group_rid(id));
169 return True;
172 return False;
175 /*******************************************************************
176 Decides if a RID is a well known RID.
177 ********************************************************************/
178 static BOOL pwdb_rid_is_well_known(uint32 rid)
180 return (rid < 1000);
183 /*******************************************************************
184 determines a rid's type. NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
185 ********************************************************************/
186 static uint32 pwdb_rid_type(uint32 rid)
188 /* lkcl i understand that NT attaches an enumeration to a RID
189 * such that it can be identified as either a user, group etc
190 * type: SID_ENUM_TYPE.
192 if (pwdb_rid_is_well_known(rid))
195 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
196 * and DOMAIN_USER_RID_GUEST.
198 if (rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
200 return RID_TYPE_USER;
202 if (DOMAIN_GROUP_RID_ADMINS <= rid && rid <= DOMAIN_GROUP_RID_GUESTS)
204 return RID_TYPE_GROUP;
206 if (BUILTIN_ALIAS_RID_ADMINS <= rid && rid <= BUILTIN_ALIAS_RID_REPLICATOR)
208 return RID_TYPE_ALIAS;
211 return (rid & RID_TYPE_MASK);
214 /*******************************************************************
215 checks whether rid is a user rid. NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
216 ********************************************************************/
217 BOOL pwdb_rid_is_user(uint32 rid)
219 return pwdb_rid_type(rid) == RID_TYPE_USER;
222 /**************************************************************************
223 Groupname map functionality. The code loads a groupname map file and
224 (currently) loads it into a linked list. This is slow and memory
225 hungry, but can be changed into a more efficient storage format
226 if the demands on it become excessive.
227 ***************************************************************************/
229 typedef struct name_map
231 ubi_slNode next;
232 DOM_NAME_MAP grp;
234 } name_map_entry;
236 static ubi_slList groupname_map_list;
237 static ubi_slList aliasname_map_list;
238 static ubi_slList ntusrname_map_list;
240 static void delete_name_entry(name_map_entry *gmep)
242 SAFE_FREE(gmep->grp.nt_name);
243 SAFE_FREE(gmep->grp.nt_domain);
244 SAFE_FREE(gmep->grp.unix_name);
245 SAFE_FREE(gmep);
248 /**************************************************************************
249 Delete all the entries in the name map list.
250 ***************************************************************************/
252 static void delete_map_list(ubi_slList *map_list)
254 name_map_entry *gmep;
256 while ((gmep = (name_map_entry *)ubi_slRemHead(map_list )) != NULL)
258 delete_name_entry(gmep);
263 /**************************************************************************
264 makes a group sid out of a domain sid and a _unix_ gid.
265 ***************************************************************************/
266 static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type)
268 int ret = False;
269 fstring sid_str;
271 if (!map_domain_name_to_sid(&grp->sid, &(grp->nt_domain)))
273 DEBUG(0,("make_mydomain_sid: unknown domain %s\n",
274 grp->nt_domain));
275 return False;
278 if (sid_equal(&grp->sid, &global_sid_S_1_5_20))
281 * only builtin aliases are recognised in S-1-5-20
283 DEBUG(10,("make_mydomain_sid: group %s in builtin domain\n",
284 grp->nt_name));
286 if (lookup_builtin_alias_name(grp->nt_name, "BUILTIN", &grp->sid, &grp->type) != 0x0)
288 DEBUG(0,("unix group %s mapped to an unrecognised BUILTIN domain name %s\n",
289 grp->unix_name, grp->nt_name));
290 return False;
292 ret = True;
294 else if (lookup_wk_user_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0)
296 if (type != DOM_MAP_USER)
298 DEBUG(0,("well-known NT user %s\\%s listed in wrong map file\n",
299 grp->nt_domain, grp->nt_name));
300 return False;
302 ret = True;
304 else if (lookup_wk_group_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0)
306 if (type != DOM_MAP_DOMAIN)
308 DEBUG(0,("well-known NT group %s\\%s listed in wrong map file\n",
309 grp->nt_domain, grp->nt_name));
310 return False;
312 ret = True;
314 else
316 switch (type)
318 case DOM_MAP_USER:
320 grp->type = SID_NAME_USER;
321 break;
323 case DOM_MAP_DOMAIN:
325 grp->type = SID_NAME_DOM_GRP;
326 break;
328 case DOM_MAP_LOCAL:
330 grp->type = SID_NAME_ALIAS;
331 break;
335 ret = pwdb_unixid_to_sam_sid(grp->unix_id, grp->type, &grp->sid);
338 sid_to_string(sid_str, &grp->sid);
339 DEBUG(10,("nt name %s\\%s gid %d mapped to %s\n",
340 grp->nt_domain, grp->nt_name, grp->unix_id, sid_str));
341 return ret;
344 /**************************************************************************
345 makes a group sid out of an nt domain, nt group name or a unix group name.
346 ***************************************************************************/
347 static BOOL unix_name_to_nt_name_info(DOM_NAME_MAP *map, DOM_MAP_TYPE type)
350 * Attempt to get the unix gid_t for this name.
353 DEBUG(5,("unix_name_to_nt_name_info: unix_name:%s\n", map->unix_name));
355 if (type == DOM_MAP_USER)
357 const struct passwd *pwptr = Get_Pwnam(map->unix_name, False);
358 if (pwptr == NULL)
360 DEBUG(0,("unix_name_to_nt_name_info: Get_Pwnam for user %s\
361 failed. Error was %s.\n", map->unix_name, strerror(errno) ));
362 return False;
365 map->unix_id = (uint32)pwptr->pw_uid;
367 else
369 struct group *gptr = getgrnam(map->unix_name);
370 if (gptr == NULL)
372 DEBUG(0,("unix_name_to_nt_name_info: getgrnam for group %s\
373 failed. Error was %s.\n", map->unix_name, strerror(errno) ));
374 return False;
377 map->unix_id = (uint32)gptr->gr_gid;
380 DEBUG(5,("unix_name_to_nt_name_info: unix gid:%d\n", map->unix_id));
383 * Now map the name to an NT SID+RID.
386 if (map->nt_domain != NULL && !strequal(map->nt_domain, global_sam_name))
388 /* Must add client-call lookup code here, to
389 * resolve remote domain's sid and the group's rid,
390 * in that domain.
392 * NOTE: it is _incorrect_ to put code here that assumes
393 * we are responsible for lookups for foriegn domains' RIDs.
395 * for foriegn domains for which we are *NOT* the PDC, all
396 * we can be responsible for is the unix gid_t to which
397 * the foriegn SID+rid maps to, on this _local_ machine.
398 * we *CANNOT* make any short-cuts or assumptions about
399 * RIDs in a foriegn domain.
402 if (!map_domain_name_to_sid(&map->sid, &(map->nt_domain)))
404 DEBUG(0,("unix_name_to_nt_name_info: no known sid for %s\n",
405 map->nt_domain));
406 return False;
410 return make_mydomain_sid(map, type);
413 static BOOL make_name_entry(name_map_entry **new_ep,
414 char *nt_domain, char *nt_group, char *unix_group,
415 DOM_MAP_TYPE type)
418 * Create the list entry and add it onto the list.
421 DEBUG(5,("make_name_entry:%s,%s,%s\n", nt_domain, nt_group, unix_group));
423 (*new_ep) = (name_map_entry *)malloc(sizeof(name_map_entry));
424 if ((*new_ep) == NULL)
426 DEBUG(0,("make_name_entry: malloc fail for name_map_entry.\n"));
427 return False;
430 ZERO_STRUCTP(*new_ep);
432 (*new_ep)->grp.nt_name = strdup(nt_group );
433 (*new_ep)->grp.nt_domain = strdup(nt_domain );
434 (*new_ep)->grp.unix_name = strdup(unix_group);
436 if ((*new_ep)->grp.nt_name == NULL ||
437 (*new_ep)->grp.unix_name == NULL)
439 DEBUG(0,("make_name_entry: malloc fail for names in name_map_entry.\n"));
440 delete_name_entry((*new_ep));
441 return False;
445 * look up the group names, make the Group-SID and unix gid
448 if (!unix_name_to_nt_name_info(&(*new_ep)->grp, type))
450 delete_name_entry((*new_ep));
451 return False;
454 return True;
457 /**************************************************************************
458 Load a name map file. Sets last accessed timestamp.
459 ***************************************************************************/
460 static ubi_slList *load_name_map(DOM_MAP_TYPE type)
462 static time_t groupmap_file_last_modified = (time_t)0;
463 static time_t aliasmap_file_last_modified = (time_t)0;
464 static time_t ntusrmap_file_last_modified = (time_t)0;
465 static BOOL initialised_group = False;
466 static BOOL initialised_alias = False;
467 static BOOL initialised_ntusr = False;
468 char *groupname_map_file = lp_groupname_map();
469 char *aliasname_map_file = lp_aliasname_map();
470 char *ntusrname_map_file = lp_ntusrname_map();
472 FILE *fp;
473 char *s;
474 pstring buf;
475 name_map_entry *new_ep;
477 time_t *file_last_modified = NULL;
478 int *initialised = NULL;
479 char *map_file = NULL;
480 ubi_slList *map_list = NULL;
482 switch (type)
484 case DOM_MAP_DOMAIN:
486 file_last_modified = &groupmap_file_last_modified;
487 initialised = &initialised_group;
488 map_file = groupname_map_file;
489 map_list = &groupname_map_list;
491 break;
493 case DOM_MAP_LOCAL:
495 file_last_modified = &aliasmap_file_last_modified;
496 initialised = &initialised_alias;
497 map_file = aliasname_map_file;
498 map_list = &aliasname_map_list;
500 break;
502 case DOM_MAP_USER:
504 file_last_modified = &ntusrmap_file_last_modified;
505 initialised = &initialised_ntusr;
506 map_file = ntusrname_map_file;
507 map_list = &ntusrname_map_list;
509 break;
513 if (!(*initialised))
515 DEBUG(10,("initialising map %s\n", map_file));
516 ubi_slInitList(map_list);
517 (*initialised) = True;
520 if (!*map_file)
522 return map_list;
526 * Load the file.
529 fp = open_file_if_modified(map_file, "r", file_last_modified);
530 if (!fp)
532 return map_list;
536 * Throw away any previous list.
538 delete_map_list(map_list);
540 DEBUG(4,("load_name_map: Scanning name map %s\n",map_file));
542 while ((s = fgets_slash(buf, sizeof(buf), fp)) != NULL)
544 pstring unixname;
545 pstring nt_name;
546 fstring nt_domain;
547 fstring ntname;
548 char *p;
550 DEBUG(10,("Read line |%s|\n", s));
552 memset(nt_name, 0, sizeof(nt_name));
554 if (!*s || strchr("#;",*s))
555 continue;
557 if (!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
558 continue;
560 if (!next_token(&s,nt_name, "\t\n\r=", sizeof(nt_name)))
561 continue;
563 trim_string(unixname, " ", " ");
564 trim_string(nt_name, " ", " ");
566 if (!*nt_name)
567 continue;
569 if (!*unixname)
570 continue;
572 p = strchr(nt_name, '\\');
574 if (p == NULL)
576 memset(nt_domain, 0, sizeof(nt_domain));
577 fstrcpy(ntname, nt_name);
579 else
581 *p = 0;
582 p++;
583 fstrcpy(nt_domain, nt_name);
584 fstrcpy(ntname , p);
587 if (make_name_entry(&new_ep, nt_domain, ntname, unixname, type))
589 ubi_slAddTail(map_list, (ubi_slNode *)new_ep);
590 DEBUG(5,("unixname = %s, ntname = %s\\%s type = %d\n",
591 new_ep->grp.unix_name,
592 new_ep->grp.nt_domain,
593 new_ep->grp.nt_name,
594 new_ep->grp.type));
598 DEBUG(10,("load_name_map: Added %ld entries to name map.\n",
599 ubi_slCount(map_list)));
601 fclose(fp);
603 return map_list;
606 static void copy_grp_map_entry(DOM_NAME_MAP *grp, const DOM_NAME_MAP *from)
608 sid_copy(&grp->sid, &from->sid);
609 grp->unix_id = from->unix_id;
610 grp->nt_name = from->nt_name;
611 grp->nt_domain = from->nt_domain;
612 grp->unix_name = from->unix_name;
613 grp->type = from->type;
616 #if 0
617 /***********************************************************
618 Lookup unix name.
619 ************************************************************/
620 static BOOL map_unixname(DOM_MAP_TYPE type,
621 char *unixname, DOM_NAME_MAP *grp_info)
623 name_map_entry *gmep;
624 ubi_slList *map_list;
627 * Initialise and load if not already loaded.
629 map_list = load_name_map(type);
631 for (gmep = (name_map_entry *)ubi_slFirst(map_list);
632 gmep != NULL;
633 gmep = (name_map_entry *)ubi_slNext(gmep ))
635 if (strequal(gmep->grp.unix_name, unixname))
637 copy_grp_map_entry(grp_info, &gmep->grp);
638 DEBUG(7,("map_unixname: Mapping unix name %s to nt group %s.\n",
639 gmep->grp.unix_name, gmep->grp.nt_name ));
640 return True;
644 return False;
647 #endif
649 /***********************************************************
650 Lookup nt name.
651 ************************************************************/
652 static BOOL map_ntname(DOM_MAP_TYPE type, char *ntname, char *ntdomain,
653 DOM_NAME_MAP *grp_info)
655 name_map_entry *gmep;
656 ubi_slList *map_list;
659 * Initialise and load if not already loaded.
661 map_list = load_name_map(type);
663 for (gmep = (name_map_entry *)ubi_slFirst(map_list);
664 gmep != NULL;
665 gmep = (name_map_entry *)ubi_slNext(gmep ))
667 if (strequal(gmep->grp.nt_name , ntname) &&
668 strequal(gmep->grp.nt_domain, ntdomain))
670 copy_grp_map_entry(grp_info, &gmep->grp);
671 DEBUG(7,("map_ntname: Mapping unix name %s to nt name %s.\n",
672 gmep->grp.unix_name, gmep->grp.nt_name ));
673 return True;
677 return False;
681 /***********************************************************
682 Lookup by SID
683 ************************************************************/
684 static BOOL map_sid(DOM_MAP_TYPE type,
685 DOM_SID *psid, DOM_NAME_MAP *grp_info)
687 name_map_entry *gmep;
688 ubi_slList *map_list;
691 * Initialise and load if not already loaded.
693 map_list = load_name_map(type);
695 for (gmep = (name_map_entry *)ubi_slFirst(map_list);
696 gmep != NULL;
697 gmep = (name_map_entry *)ubi_slNext(gmep ))
699 if (sid_equal(&gmep->grp.sid, psid))
701 copy_grp_map_entry(grp_info, &gmep->grp);
702 DEBUG(7,("map_sid: Mapping unix name %s to nt name %s.\n",
703 gmep->grp.unix_name, gmep->grp.nt_name ));
704 return True;
708 return False;
711 /***********************************************************
712 Lookup by gid_t.
713 ************************************************************/
714 static BOOL map_unixid(DOM_MAP_TYPE type, uint32 unix_id, DOM_NAME_MAP *grp_info)
716 name_map_entry *gmep;
717 ubi_slList *map_list;
720 * Initialise and load if not already loaded.
722 map_list = load_name_map(type);
724 for (gmep = (name_map_entry *)ubi_slFirst(map_list);
725 gmep != NULL;
726 gmep = (name_map_entry *)ubi_slNext(gmep ))
728 fstring sid_str;
729 sid_to_string(sid_str, &gmep->grp.sid);
730 DEBUG(10,("map_unixid: enum entry unix group %s %d nt %s %s\n",
731 gmep->grp.unix_name, gmep->grp.unix_id, gmep->grp.nt_name, sid_str));
732 if (gmep->grp.unix_id == unix_id)
734 copy_grp_map_entry(grp_info, &gmep->grp);
735 DEBUG(7,("map_unixid: Mapping unix name %s to nt name %s type %d\n",
736 gmep->grp.unix_name, gmep->grp.nt_name, gmep->grp.type));
737 return True;
741 return False;
744 /***********************************************************
746 * Call four functions to resolve unix group ids and either
747 * local group SIDs or domain group SIDs listed in the local group
748 * or domain group map files.
750 * Note that it is *NOT* the responsibility of these functions to
751 * resolve entries that are not in the map files.
753 * Any SID can be in the map files (i.e from any Domain).
755 ***********************************************************/
757 #if 0
759 /***********************************************************
760 Lookup a UNIX Group entry by name.
761 ************************************************************/
762 BOOL map_unix_group_name(char *group_name, DOM_NAME_MAP *grp_info)
764 return map_unixname(DOM_MAP_DOMAIN, group_name, grp_info);
767 /***********************************************************
768 Lookup a UNIX Alias entry by name.
769 ************************************************************/
770 BOOL map_unix_alias_name(char *alias_name, DOM_NAME_MAP *grp_info)
772 return map_unixname(DOM_MAP_LOCAL, alias_name, grp_info);
775 /***********************************************************
776 Lookup an Alias name entry
777 ************************************************************/
778 BOOL map_nt_alias_name(char *ntalias_name, char *nt_domain, DOM_NAME_MAP *grp_info)
780 return map_ntname(DOM_MAP_LOCAL, ntalias_name, nt_domain, grp_info);
783 /***********************************************************
784 Lookup a Group entry
785 ************************************************************/
786 BOOL map_nt_group_name(char *ntgroup_name, char *nt_domain, DOM_NAME_MAP *grp_info)
788 return map_ntname(DOM_MAP_DOMAIN, ntgroup_name, nt_domain, grp_info);
791 #endif
793 /***********************************************************
794 Lookup a Username entry by name.
795 ************************************************************/
796 static BOOL map_nt_username(char *nt_name, char *nt_domain, DOM_NAME_MAP *grp_info)
798 return map_ntname(DOM_MAP_USER, nt_name, nt_domain, grp_info);
801 /***********************************************************
802 Lookup a Username entry by SID.
803 ************************************************************/
804 static BOOL map_username_sid(DOM_SID *sid, DOM_NAME_MAP *grp_info)
806 return map_sid(DOM_MAP_USER, sid, grp_info);
809 /***********************************************************
810 Lookup a Username SID entry by uid.
811 ************************************************************/
812 static BOOL map_username_uid(uid_t gid, DOM_NAME_MAP *grp_info)
814 return map_unixid(DOM_MAP_USER, (uint32)gid, grp_info);
817 /***********************************************************
818 Lookup an Alias SID entry by name.
819 ************************************************************/
820 BOOL map_alias_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info)
822 return map_sid(DOM_MAP_LOCAL, psid, grp_info);
825 /***********************************************************
826 Lookup a Group entry by sid.
827 ************************************************************/
828 BOOL map_group_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info)
830 return map_sid(DOM_MAP_DOMAIN, psid, grp_info);
833 /***********************************************************
834 Lookup an Alias SID entry by gid_t.
835 ************************************************************/
836 static BOOL map_alias_gid(gid_t gid, DOM_NAME_MAP *grp_info)
838 return map_unixid(DOM_MAP_LOCAL, (uint32)gid, grp_info);
841 /***********************************************************
842 Lookup a Group SID entry by gid_t.
843 ************************************************************/
844 static BOOL map_group_gid( gid_t gid, DOM_NAME_MAP *grp_info)
846 return map_unixid(DOM_MAP_DOMAIN, (uint32)gid, grp_info);
850 /************************************************************************
851 Routine to look up User details by UNIX name
852 *************************************************************************/
853 BOOL lookupsmbpwnam(const char *unix_usr_name, DOM_NAME_MAP *grp)
855 uid_t uid;
856 DEBUG(10,("lookupsmbpwnam: unix user name %s\n", unix_usr_name));
857 if (nametouid(unix_usr_name, &uid))
859 return lookupsmbpwuid(uid, grp);
861 else
863 return False;
867 /************************************************************************
868 Routine to look up a remote nt name
869 *************************************************************************/
870 static BOOL lookup_remote_ntname(const char *ntname, DOM_SID *sid, uint8 *type)
872 struct cli_state cli;
873 POLICY_HND lsa_pol;
874 fstring srv_name;
875 extern struct ntuser_creds *usr_creds;
876 struct ntuser_creds usr;
878 BOOL res3 = True;
879 BOOL res4 = True;
880 uint32 num_sids;
881 DOM_SID *sids;
882 uint8 *types;
883 char *names[1];
885 usr_creds = &usr;
887 ZERO_STRUCT(usr);
888 pwd_set_nullpwd(&usr.pwd);
890 DEBUG(5,("lookup_remote_ntname: %s\n", ntname));
892 if (!cli_connect_serverlist(&cli, lp_passwordserver()))
894 return False;
897 names[0] = ntname;
899 fstrcpy(srv_name, "\\\\");
900 fstrcat(srv_name, cli.desthost);
901 strupper(srv_name);
903 /* lookup domain controller; receive a policy handle */
904 res3 = res3 ? lsa_open_policy( srv_name,
905 &lsa_pol, True) : False;
907 /* send lsa lookup sids call */
908 res4 = res3 ? lsa_lookup_names( &lsa_pol,
909 1, names,
910 &sids, &types, &num_sids) : False;
912 res3 = res3 ? lsa_close(&lsa_pol) : False;
914 if (res4 && res3 && sids != NULL && types != NULL)
916 sid_copy(sid, &sids[0]);
917 *type = types[0];
919 else
921 res3 = False;
923 SAFE_FREE(types);
924 SAFE_FREE(sids);
926 return res3 && res4;
929 /************************************************************************
930 Routine to look up a remote nt name
931 *************************************************************************/
932 static BOOL get_sid_and_type(const char *fullntname, uint8 expected_type,
933 DOM_NAME_MAP *gmep)
936 * check with the PDC to see if it owns the name. if so,
937 * the SID is resolved with the PDC database.
940 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
942 if (lookup_remote_ntname(fullntname, &gmep->sid, &gmep->type))
944 if (sid_front_equal(&gmep->sid, &global_member_sid) &&
945 strequal(gmep->nt_domain, global_myworkgroup) &&
946 gmep->type == expected_type)
948 return True;
950 return False;
955 * ... otherwise, it's one of ours. map the sid ourselves,
956 * which can only happen in our own SAM database.
959 if (!strequal(gmep->nt_domain, global_sam_name))
961 return False;
963 if (!pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid))
965 return False;
968 return True;
972 * used by lookup functions below
975 static fstring nt_name;
976 static fstring unix_name;
977 static fstring nt_domain;
979 /*************************************************************************
980 looks up a uid, returns User Information.
981 *************************************************************************/
982 BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep)
984 DEBUG(10,("lookupsmbpwuid: unix uid %d\n", uid));
985 if (map_username_uid(uid, gmep))
987 return True;
989 #if 0
990 if (lp_server_role() != ROLE_DOMAIN_NONE)
991 #endif
993 gmep->nt_name = nt_name;
994 gmep->unix_name = unix_name;
995 gmep->nt_domain = nt_domain;
997 gmep->unix_id = (uint32)uid;
1000 * ok, assume it's one of ours. then double-check it
1001 * if we are a member of a domain
1004 gmep->type = SID_NAME_USER;
1005 fstrcpy(gmep->nt_name, uidtoname(uid));
1006 fstrcpy(gmep->unix_name, gmep->nt_name);
1009 * here we should do a LsaLookupNames() call
1010 * to check the status of the name with the PDC.
1011 * if the PDC know nothing of the name, it's ours.
1014 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1016 #if 0
1017 lsa_lookup_names(global_myworkgroup, gmep->nt_name, &gmep->sid...);
1018 #endif
1022 * ok, it's one of ours.
1025 gmep->nt_domain = global_sam_name;
1026 pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid);
1028 return True;
1031 /* oops. */
1033 return False;
1036 /*************************************************************************
1037 looks up by NT name, returns User Information.
1038 *************************************************************************/
1039 BOOL lookupsmbpwntnam(const char *fullntname, DOM_NAME_MAP *gmep)
1041 DEBUG(10,("lookupsmbpwntnam: nt user name %s\n", fullntname));
1043 if (!split_domain_name(fullntname, nt_domain, nt_name))
1045 return False;
1048 if (map_nt_username(nt_name, nt_domain, gmep))
1050 return True;
1052 if (lp_server_role() != ROLE_DOMAIN_NONE)
1054 uid_t uid;
1055 gmep->nt_name = nt_name;
1056 gmep->unix_name = unix_name;
1057 gmep->nt_domain = nt_domain;
1060 * ok, it's one of ours. we therefore "create" an nt user named
1061 * after the unix user. this is the point where "appliance mode"
1062 * should get its teeth in, as unix users won't really exist,
1063 * they will only be numbers...
1066 gmep->type = SID_NAME_USER;
1067 fstrcpy(gmep->unix_name, gmep->nt_name);
1068 if (!nametouid(gmep->unix_name, &uid))
1070 return False;
1072 gmep->unix_id = (uint32)uid;
1074 return get_sid_and_type(fullntname, gmep->type, gmep);
1077 /* oops. */
1079 return False;
1082 /*************************************************************************
1083 looks up by RID, returns User Information.
1084 *************************************************************************/
1085 BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
1087 fstring sid_str;
1088 sid_to_string(sid_str, sid);
1089 DEBUG(10,("lookupsmbpwsid: nt sid %s\n", sid_str));
1091 if (map_username_sid(sid, gmep))
1093 return True;
1095 if (lp_server_role() != ROLE_DOMAIN_NONE)
1097 gmep->nt_name = nt_name;
1098 gmep->unix_name = unix_name;
1099 gmep->nt_domain = nt_domain;
1102 * here we should do a LsaLookupNames() call
1103 * to check the status of the name with the PDC.
1104 * if the PDC know nothing of the name, it's ours.
1107 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1109 #if 0
1110 if (lookup_remote_sid(global_myworkgroup, gmep->sid, gmep->nt_name, gmep->nt_domain...);
1111 #endif
1115 * ok, it's one of ours. we therefore "create" an nt user named
1116 * after the unix user. this is the point where "appliance mode"
1117 * should get its teeth in, as unix users won't really exist,
1118 * they will only be numbers...
1121 gmep->type = SID_NAME_USER;
1122 sid_copy(&gmep->sid, sid);
1123 if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
1125 return False;
1127 fstrcpy(gmep->nt_name, uidtoname((uid_t)gmep->unix_id));
1128 fstrcpy(gmep->unix_name, gmep->nt_name);
1129 gmep->nt_domain = global_sam_name;
1131 return True;
1134 /* oops. */
1136 return False;
1139 /************************************************************************
1140 Routine to look up group / alias / well-known group RID by UNIX name
1141 *************************************************************************/
1142 BOOL lookupsmbgrpnam(const char *unix_grp_name, DOM_NAME_MAP *grp)
1144 gid_t gid;
1145 DEBUG(10,("lookupsmbgrpnam: unix user group %s\n", unix_grp_name));
1146 if (nametogid(unix_grp_name, &gid))
1148 return lookupsmbgrpgid(gid, grp);
1150 else
1152 return False;
1156 /*************************************************************************
1157 looks up a SID, returns name map entry
1158 *************************************************************************/
1159 BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
1161 fstring sid_str;
1162 sid_to_string(sid_str, sid);
1163 DEBUG(10,("lookupsmbgrpsid: nt sid %s\n", sid_str));
1165 if (map_alias_sid(sid, gmep))
1167 return True;
1169 if (map_group_sid(sid, gmep))
1171 return True;
1173 if (lp_server_role() != ROLE_DOMAIN_NONE)
1175 gmep->nt_name = nt_name;
1176 gmep->unix_name = unix_name;
1177 gmep->nt_domain = nt_domain;
1180 * here we should do a LsaLookupNames() call
1181 * to check the status of the name with the PDC.
1182 * if the PDC know nothing of the name, it's ours.
1185 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1187 #if 0
1188 lsa_lookup_sids(global_myworkgroup, gmep->sid, gmep->nt_name, gmep->nt_domain...);
1189 #endif
1193 * ok, it's one of ours. we therefore "create" an nt group or
1194 * alias name named after the unix group. this is the point
1195 * where "appliance mode" should get its teeth in, as unix
1196 * groups won't really exist, they will only be numbers...
1199 /* name is not explicitly mapped
1200 * with map files or the PDC
1201 * so we are responsible for it...
1204 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1206 /* ... as a LOCAL group. */
1207 gmep->type = SID_NAME_ALIAS;
1209 else
1211 /* ... as a DOMAIN group. */
1212 gmep->type = SID_NAME_DOM_GRP;
1215 sid_copy(&gmep->sid, sid);
1216 if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
1218 return False;
1220 fstrcpy(gmep->nt_name, gidtoname((gid_t)gmep->unix_id));
1221 fstrcpy(gmep->unix_name, gmep->nt_name);
1222 gmep->nt_domain = global_sam_name;
1224 return True;
1227 /* oops */
1228 return False;
1231 /*************************************************************************
1232 looks up a gid, returns RID and type local, domain or well-known domain group
1233 *************************************************************************/
1234 BOOL lookupsmbgrpgid(gid_t gid, DOM_NAME_MAP *gmep)
1236 DEBUG(10,("lookupsmbgrpgid: unix gid %d\n", (int)gid));
1237 if (map_alias_gid(gid, gmep))
1239 return True;
1241 if (map_group_gid(gid, gmep))
1243 return True;
1245 if (lp_server_role() != ROLE_DOMAIN_NONE)
1247 gmep->nt_name = nt_name;
1248 gmep->unix_name = unix_name;
1249 gmep->nt_domain = nt_domain;
1251 gmep->unix_id = (uint32)gid;
1254 * here we should do a LsaLookupNames() call
1255 * to check the status of the name with the PDC.
1256 * if the PDC know nothing of the name, it's ours.
1259 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1261 #if 0
1262 if (lsa_lookup_names(global_myworkgroup, gmep->nt_name, &gmep->sid...);
1264 return True;
1266 #endif
1270 * ok, it's one of ours. we therefore "create" an nt group or
1271 * alias name named after the unix group. this is the point
1272 * where "appliance mode" should get its teeth in, as unix
1273 * groups won't really exist, they will only be numbers...
1276 /* name is not explicitly mapped
1277 * with map files or the PDC
1278 * so we are responsible for it...
1281 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1283 /* ... as a LOCAL group. */
1284 gmep->type = SID_NAME_ALIAS;
1286 else
1288 /* ... as a DOMAIN group. */
1289 gmep->type = SID_NAME_DOM_GRP;
1291 fstrcpy(gmep->nt_name, gidtoname(gid));
1292 fstrcpy(gmep->unix_name, gmep->nt_name);
1294 return get_sid_and_type(gmep->nt_name, gmep->type, gmep);
1297 /* oops */
1298 return False;