add another registry rpc (opnum 0x14). Have no idea what it's real name
[Samba.git] / source / lib / domain_namemap.c
blob988f5e5d65907eb5580efb4a9738f1f1fb6c947f
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"
50 extern int DEBUGLEVEL;
52 extern fstring global_myworkgroup;
53 extern DOM_SID global_member_sid;
54 extern fstring global_sam_name;
55 extern DOM_SID global_sam_sid;
56 extern DOM_SID global_sid_S_1_5_20;
58 /*******************************************************************
59 converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
60 ********************************************************************/
61 static uid_t pwdb_user_rid_to_uid(uint32 user_rid)
63 return ((user_rid & (~RID_TYPE_USER))- 1000)/RID_MULTIPLIER;
66 /*******************************************************************
67 converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
68 ********************************************************************/
69 static uint32 pwdb_group_rid_to_gid(uint32 group_rid)
71 return ((group_rid & (~RID_TYPE_GROUP))- 1000)/RID_MULTIPLIER;
74 /*******************************************************************
75 converts NT Alias RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
76 ********************************************************************/
77 static uint32 pwdb_alias_rid_to_gid(uint32 alias_rid)
79 return ((alias_rid & (~RID_TYPE_ALIAS))- 1000)/RID_MULTIPLIER;
82 /*******************************************************************
83 converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
84 ********************************************************************/
85 static uint32 pwdb_gid_to_group_rid(uint32 gid)
87 uint32 grp_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_GROUP);
88 return grp_rid;
91 /******************************************************************
92 converts UNIX gid to an NT Alias RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
93 ********************************************************************/
94 static uint32 pwdb_gid_to_alias_rid(uint32 gid)
96 uint32 alias_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_ALIAS);
97 return alias_rid;
100 /*******************************************************************
101 converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
102 ********************************************************************/
103 static uint32 pwdb_uid_to_user_rid(uint32 uid)
105 uint32 user_rid = ((((uid)*RID_MULTIPLIER) + 1000) | RID_TYPE_USER);
106 return user_rid;
109 /******************************************************************
110 converts SID + SID_NAME_USE type to a UNIX id. the Domain SID is,
111 and can only be, our own SID.
112 ********************************************************************/
113 static BOOL pwdb_sam_sid_to_unixid(DOM_SID *sid, uint8 type, uint32 *id)
115 DOM_SID tmp_sid;
116 uint32 rid;
118 sid_copy(&tmp_sid, sid);
119 sid_split_rid(&tmp_sid, &rid);
120 if (!sid_equal(&global_sam_sid, &tmp_sid))
122 return False;
125 switch (type)
127 case SID_NAME_USER:
129 *id = pwdb_user_rid_to_uid(rid);
130 return True;
132 case SID_NAME_ALIAS:
134 *id = pwdb_alias_rid_to_gid(rid);
135 return True;
137 case SID_NAME_DOM_GRP:
138 case SID_NAME_WKN_GRP:
140 *id = pwdb_group_rid_to_gid(rid);
141 return True;
144 return False;
147 /******************************************************************
148 converts UNIX gid + SID_NAME_USE type to a SID. the Domain SID is,
149 and can only be, our own SID.
150 ********************************************************************/
151 static BOOL pwdb_unixid_to_sam_sid(uint32 id, uint8 type, DOM_SID *sid)
153 sid_copy(sid, &global_sam_sid);
154 switch (type)
156 case SID_NAME_USER:
158 sid_append_rid(sid, pwdb_uid_to_user_rid(id));
159 return True;
161 case SID_NAME_ALIAS:
163 sid_append_rid(sid, pwdb_gid_to_alias_rid(id));
164 return True;
166 case SID_NAME_DOM_GRP:
167 case SID_NAME_WKN_GRP:
169 sid_append_rid(sid, pwdb_gid_to_group_rid(id));
170 return True;
173 return False;
176 /*******************************************************************
177 Decides if a RID is a well known RID.
178 ********************************************************************/
179 static BOOL pwdb_rid_is_well_known(uint32 rid)
181 return (rid < 1000);
184 /*******************************************************************
185 determines a rid's type. NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
186 ********************************************************************/
187 static uint32 pwdb_rid_type(uint32 rid)
189 /* lkcl i understand that NT attaches an enumeration to a RID
190 * such that it can be identified as either a user, group etc
191 * type: SID_ENUM_TYPE.
193 if (pwdb_rid_is_well_known(rid))
196 * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
197 * and DOMAIN_USER_RID_GUEST.
199 if (rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
201 return RID_TYPE_USER;
203 if (DOMAIN_GROUP_RID_ADMINS <= rid && rid <= DOMAIN_GROUP_RID_GUESTS)
205 return RID_TYPE_GROUP;
207 if (BUILTIN_ALIAS_RID_ADMINS <= rid && rid <= BUILTIN_ALIAS_RID_REPLICATOR)
209 return RID_TYPE_ALIAS;
212 return (rid & RID_TYPE_MASK);
215 /*******************************************************************
216 checks whether rid is a user rid. NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
217 ********************************************************************/
218 BOOL pwdb_rid_is_user(uint32 rid)
220 return pwdb_rid_type(rid) == RID_TYPE_USER;
223 /**************************************************************************
224 Groupname map functionality. The code loads a groupname map file and
225 (currently) loads it into a linked list. This is slow and memory
226 hungry, but can be changed into a more efficient storage format
227 if the demands on it become excessive.
228 ***************************************************************************/
230 typedef struct name_map
232 ubi_slNode next;
233 DOM_NAME_MAP grp;
235 } name_map_entry;
237 static ubi_slList groupname_map_list;
238 static ubi_slList aliasname_map_list;
239 static ubi_slList ntusrname_map_list;
241 static void delete_name_entry(name_map_entry *gmep)
243 if (gmep->grp.nt_name)
245 free(gmep->grp.nt_name);
247 if (gmep->grp.nt_domain)
249 free(gmep->grp.nt_domain);
251 if (gmep->grp.unix_name)
253 free(gmep->grp.unix_name);
255 free((char*)gmep);
258 /**************************************************************************
259 Delete all the entries in the name map list.
260 ***************************************************************************/
262 static void delete_map_list(ubi_slList *map_list)
264 name_map_entry *gmep;
266 while ((gmep = (name_map_entry *)ubi_slRemHead(map_list )) != NULL)
268 delete_name_entry(gmep);
273 /**************************************************************************
274 makes a group sid out of a domain sid and a _unix_ gid.
275 ***************************************************************************/
276 static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type)
278 int ret = False;
279 fstring sid_str;
281 if (!map_domain_name_to_sid(&grp->sid, &(grp->nt_domain)))
283 DEBUG(0,("make_mydomain_sid: unknown domain %s\n",
284 grp->nt_domain));
285 return False;
288 if (sid_equal(&grp->sid, &global_sid_S_1_5_20))
291 * only builtin aliases are recognised in S-1-5-20
293 DEBUG(10,("make_mydomain_sid: group %s in builtin domain\n",
294 grp->nt_name));
296 if (lookup_builtin_alias_name(grp->nt_name, "BUILTIN", &grp->sid, &grp->type) != 0x0)
298 DEBUG(0,("unix group %s mapped to an unrecognised BUILTIN domain name %s\n",
299 grp->unix_name, grp->nt_name));
300 return False;
302 ret = True;
304 else if (lookup_wk_user_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0)
306 if (type != DOM_MAP_USER)
308 DEBUG(0,("well-known NT user %s\\%s listed in wrong map file\n",
309 grp->nt_domain, grp->nt_name));
310 return False;
312 ret = True;
314 else if (lookup_wk_group_name(grp->nt_name, grp->nt_domain, &grp->sid, &grp->type) == 0x0)
316 if (type != DOM_MAP_DOMAIN)
318 DEBUG(0,("well-known NT group %s\\%s listed in wrong map file\n",
319 grp->nt_domain, grp->nt_name));
320 return False;
322 ret = True;
324 else
326 switch (type)
328 case DOM_MAP_USER:
330 grp->type = SID_NAME_USER;
331 break;
333 case DOM_MAP_DOMAIN:
335 grp->type = SID_NAME_DOM_GRP;
336 break;
338 case DOM_MAP_LOCAL:
340 grp->type = SID_NAME_ALIAS;
341 break;
345 ret = pwdb_unixid_to_sam_sid(grp->unix_id, grp->type, &grp->sid);
348 sid_to_string(sid_str, &grp->sid);
349 DEBUG(10,("nt name %s\\%s gid %d mapped to %s\n",
350 grp->nt_domain, grp->nt_name, grp->unix_id, sid_str));
351 return ret;
354 /**************************************************************************
355 makes a group sid out of an nt domain, nt group name or a unix group name.
356 ***************************************************************************/
357 static BOOL unix_name_to_nt_name_info(DOM_NAME_MAP *map, DOM_MAP_TYPE type)
360 * Attempt to get the unix gid_t for this name.
363 DEBUG(5,("unix_name_to_nt_name_info: unix_name:%s\n", map->unix_name));
365 if (type == DOM_MAP_USER)
367 const struct passwd *pwptr = Get_Pwnam(map->unix_name, False);
368 if (pwptr == NULL)
370 DEBUG(0,("unix_name_to_nt_name_info: Get_Pwnam for user %s\
371 failed. Error was %s.\n", map->unix_name, strerror(errno) ));
372 return False;
375 map->unix_id = (uint32)pwptr->pw_uid;
377 else
379 struct group *gptr = getgrnam(map->unix_name);
380 if (gptr == NULL)
382 DEBUG(0,("unix_name_to_nt_name_info: getgrnam for group %s\
383 failed. Error was %s.\n", map->unix_name, strerror(errno) ));
384 return False;
387 map->unix_id = (uint32)gptr->gr_gid;
390 DEBUG(5,("unix_name_to_nt_name_info: unix gid:%d\n", map->unix_id));
393 * Now map the name to an NT SID+RID.
396 if (map->nt_domain != NULL && !strequal(map->nt_domain, global_sam_name))
398 /* Must add client-call lookup code here, to
399 * resolve remote domain's sid and the group's rid,
400 * in that domain.
402 * NOTE: it is _incorrect_ to put code here that assumes
403 * we are responsible for lookups for foriegn domains' RIDs.
405 * for foriegn domains for which we are *NOT* the PDC, all
406 * we can be responsible for is the unix gid_t to which
407 * the foriegn SID+rid maps to, on this _local_ machine.
408 * we *CANNOT* make any short-cuts or assumptions about
409 * RIDs in a foriegn domain.
412 if (!map_domain_name_to_sid(&map->sid, &(map->nt_domain)))
414 DEBUG(0,("unix_name_to_nt_name_info: no known sid for %s\n",
415 map->nt_domain));
416 return False;
420 return make_mydomain_sid(map, type);
423 static BOOL make_name_entry(name_map_entry **new_ep,
424 char *nt_domain, char *nt_group, char *unix_group,
425 DOM_MAP_TYPE type)
428 * Create the list entry and add it onto the list.
431 DEBUG(5,("make_name_entry:%s,%s,%s\n", nt_domain, nt_group, unix_group));
433 (*new_ep) = (name_map_entry *)malloc(sizeof(name_map_entry));
434 if ((*new_ep) == NULL)
436 DEBUG(0,("make_name_entry: malloc fail for name_map_entry.\n"));
437 return False;
440 ZERO_STRUCTP(*new_ep);
442 (*new_ep)->grp.nt_name = strdup(nt_group );
443 (*new_ep)->grp.nt_domain = strdup(nt_domain );
444 (*new_ep)->grp.unix_name = strdup(unix_group);
446 if ((*new_ep)->grp.nt_name == NULL ||
447 (*new_ep)->grp.unix_name == NULL)
449 DEBUG(0,("make_name_entry: malloc fail for names in name_map_entry.\n"));
450 delete_name_entry((*new_ep));
451 return False;
455 * look up the group names, make the Group-SID and unix gid
458 if (!unix_name_to_nt_name_info(&(*new_ep)->grp, type))
460 delete_name_entry((*new_ep));
461 return False;
464 return True;
467 /**************************************************************************
468 Load a name map file. Sets last accessed timestamp.
469 ***************************************************************************/
470 static ubi_slList *load_name_map(DOM_MAP_TYPE type)
472 static time_t groupmap_file_last_modified = (time_t)0;
473 static time_t aliasmap_file_last_modified = (time_t)0;
474 static time_t ntusrmap_file_last_modified = (time_t)0;
475 static BOOL initialised_group = False;
476 static BOOL initialised_alias = False;
477 static BOOL initialised_ntusr = False;
478 char *groupname_map_file = lp_groupname_map();
479 char *aliasname_map_file = lp_aliasname_map();
480 char *ntusrname_map_file = lp_ntusrname_map();
482 FILE *fp;
483 char *s;
484 pstring buf;
485 name_map_entry *new_ep;
487 time_t *file_last_modified = NULL;
488 int *initialised = NULL;
489 char *map_file = NULL;
490 ubi_slList *map_list = NULL;
492 switch (type)
494 case DOM_MAP_DOMAIN:
496 file_last_modified = &groupmap_file_last_modified;
497 initialised = &initialised_group;
498 map_file = groupname_map_file;
499 map_list = &groupname_map_list;
501 break;
503 case DOM_MAP_LOCAL:
505 file_last_modified = &aliasmap_file_last_modified;
506 initialised = &initialised_alias;
507 map_file = aliasname_map_file;
508 map_list = &aliasname_map_list;
510 break;
512 case DOM_MAP_USER:
514 file_last_modified = &ntusrmap_file_last_modified;
515 initialised = &initialised_ntusr;
516 map_file = ntusrname_map_file;
517 map_list = &ntusrname_map_list;
519 break;
523 if (!(*initialised))
525 DEBUG(10,("initialising map %s\n", map_file));
526 ubi_slInitList(map_list);
527 (*initialised) = True;
530 if (!*map_file)
532 return map_list;
536 * Load the file.
539 fp = open_file_if_modified(map_file, "r", file_last_modified);
540 if (!fp)
542 return map_list;
546 * Throw away any previous list.
548 delete_map_list(map_list);
550 DEBUG(4,("load_name_map: Scanning name map %s\n",map_file));
552 while ((s = fgets_slash(buf, sizeof(buf), fp)) != NULL)
554 pstring unixname;
555 pstring nt_name;
556 fstring nt_domain;
557 fstring ntname;
558 char *p;
560 DEBUG(10,("Read line |%s|\n", s));
562 memset(nt_name, 0, sizeof(nt_name));
564 if (!*s || strchr("#;",*s))
565 continue;
567 if (!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
568 continue;
570 if (!next_token(&s,nt_name, "\t\n\r=", sizeof(nt_name)))
571 continue;
573 trim_string(unixname, " ", " ");
574 trim_string(nt_name, " ", " ");
576 if (!*nt_name)
577 continue;
579 if (!*unixname)
580 continue;
582 p = strchr(nt_name, '\\');
584 if (p == NULL)
586 memset(nt_domain, 0, sizeof(nt_domain));
587 fstrcpy(ntname, nt_name);
589 else
591 *p = 0;
592 p++;
593 fstrcpy(nt_domain, nt_name);
594 fstrcpy(ntname , p);
597 if (make_name_entry(&new_ep, nt_domain, ntname, unixname, type))
599 ubi_slAddTail(map_list, (ubi_slNode *)new_ep);
600 DEBUG(5,("unixname = %s, ntname = %s\\%s type = %d\n",
601 new_ep->grp.unix_name,
602 new_ep->grp.nt_domain,
603 new_ep->grp.nt_name,
604 new_ep->grp.type));
608 DEBUG(10,("load_name_map: Added %ld entries to name map.\n",
609 ubi_slCount(map_list)));
611 fclose(fp);
613 return map_list;
616 static void copy_grp_map_entry(DOM_NAME_MAP *grp, const DOM_NAME_MAP *from)
618 sid_copy(&grp->sid, &from->sid);
619 grp->unix_id = from->unix_id;
620 grp->nt_name = from->nt_name;
621 grp->nt_domain = from->nt_domain;
622 grp->unix_name = from->unix_name;
623 grp->type = from->type;
626 #if 0
627 /***********************************************************
628 Lookup unix name.
629 ************************************************************/
630 static BOOL map_unixname(DOM_MAP_TYPE type,
631 char *unixname, DOM_NAME_MAP *grp_info)
633 name_map_entry *gmep;
634 ubi_slList *map_list;
637 * Initialise and load if not already loaded.
639 map_list = load_name_map(type);
641 for (gmep = (name_map_entry *)ubi_slFirst(map_list);
642 gmep != NULL;
643 gmep = (name_map_entry *)ubi_slNext(gmep ))
645 if (strequal(gmep->grp.unix_name, unixname))
647 copy_grp_map_entry(grp_info, &gmep->grp);
648 DEBUG(7,("map_unixname: Mapping unix name %s to nt group %s.\n",
649 gmep->grp.unix_name, gmep->grp.nt_name ));
650 return True;
654 return False;
657 #endif
659 /***********************************************************
660 Lookup nt name.
661 ************************************************************/
662 static BOOL map_ntname(DOM_MAP_TYPE type, char *ntname, char *ntdomain,
663 DOM_NAME_MAP *grp_info)
665 name_map_entry *gmep;
666 ubi_slList *map_list;
669 * Initialise and load if not already loaded.
671 map_list = load_name_map(type);
673 for (gmep = (name_map_entry *)ubi_slFirst(map_list);
674 gmep != NULL;
675 gmep = (name_map_entry *)ubi_slNext(gmep ))
677 if (strequal(gmep->grp.nt_name , ntname) &&
678 strequal(gmep->grp.nt_domain, ntdomain))
680 copy_grp_map_entry(grp_info, &gmep->grp);
681 DEBUG(7,("map_ntname: Mapping unix name %s to nt name %s.\n",
682 gmep->grp.unix_name, gmep->grp.nt_name ));
683 return True;
687 return False;
691 /***********************************************************
692 Lookup by SID
693 ************************************************************/
694 static BOOL map_sid(DOM_MAP_TYPE type,
695 DOM_SID *psid, DOM_NAME_MAP *grp_info)
697 name_map_entry *gmep;
698 ubi_slList *map_list;
701 * Initialise and load if not already loaded.
703 map_list = load_name_map(type);
705 for (gmep = (name_map_entry *)ubi_slFirst(map_list);
706 gmep != NULL;
707 gmep = (name_map_entry *)ubi_slNext(gmep ))
709 if (sid_equal(&gmep->grp.sid, psid))
711 copy_grp_map_entry(grp_info, &gmep->grp);
712 DEBUG(7,("map_sid: Mapping unix name %s to nt name %s.\n",
713 gmep->grp.unix_name, gmep->grp.nt_name ));
714 return True;
718 return False;
721 /***********************************************************
722 Lookup by gid_t.
723 ************************************************************/
724 static BOOL map_unixid(DOM_MAP_TYPE type, uint32 unix_id, DOM_NAME_MAP *grp_info)
726 name_map_entry *gmep;
727 ubi_slList *map_list;
730 * Initialise and load if not already loaded.
732 map_list = load_name_map(type);
734 for (gmep = (name_map_entry *)ubi_slFirst(map_list);
735 gmep != NULL;
736 gmep = (name_map_entry *)ubi_slNext(gmep ))
738 fstring sid_str;
739 sid_to_string(sid_str, &gmep->grp.sid);
740 DEBUG(10,("map_unixid: enum entry unix group %s %d nt %s %s\n",
741 gmep->grp.unix_name, gmep->grp.unix_id, gmep->grp.nt_name, sid_str));
742 if (gmep->grp.unix_id == unix_id)
744 copy_grp_map_entry(grp_info, &gmep->grp);
745 DEBUG(7,("map_unixid: Mapping unix name %s to nt name %s type %d\n",
746 gmep->grp.unix_name, gmep->grp.nt_name, gmep->grp.type));
747 return True;
751 return False;
754 /***********************************************************
756 * Call four functions to resolve unix group ids and either
757 * local group SIDs or domain group SIDs listed in the local group
758 * or domain group map files.
760 * Note that it is *NOT* the responsibility of these functions to
761 * resolve entries that are not in the map files.
763 * Any SID can be in the map files (i.e from any Domain).
765 ***********************************************************/
767 #if 0
769 /***********************************************************
770 Lookup a UNIX Group entry by name.
771 ************************************************************/
772 BOOL map_unix_group_name(char *group_name, DOM_NAME_MAP *grp_info)
774 return map_unixname(DOM_MAP_DOMAIN, group_name, grp_info);
777 /***********************************************************
778 Lookup a UNIX Alias entry by name.
779 ************************************************************/
780 BOOL map_unix_alias_name(char *alias_name, DOM_NAME_MAP *grp_info)
782 return map_unixname(DOM_MAP_LOCAL, alias_name, grp_info);
785 /***********************************************************
786 Lookup an Alias name entry
787 ************************************************************/
788 BOOL map_nt_alias_name(char *ntalias_name, char *nt_domain, DOM_NAME_MAP *grp_info)
790 return map_ntname(DOM_MAP_LOCAL, ntalias_name, nt_domain, grp_info);
793 /***********************************************************
794 Lookup a Group entry
795 ************************************************************/
796 BOOL map_nt_group_name(char *ntgroup_name, char *nt_domain, DOM_NAME_MAP *grp_info)
798 return map_ntname(DOM_MAP_DOMAIN, ntgroup_name, nt_domain, grp_info);
801 #endif
803 /***********************************************************
804 Lookup a Username entry by name.
805 ************************************************************/
806 static BOOL map_nt_username(char *nt_name, char *nt_domain, DOM_NAME_MAP *grp_info)
808 return map_ntname(DOM_MAP_USER, nt_name, nt_domain, grp_info);
811 /***********************************************************
812 Lookup a Username entry by SID.
813 ************************************************************/
814 static BOOL map_username_sid(DOM_SID *sid, DOM_NAME_MAP *grp_info)
816 return map_sid(DOM_MAP_USER, sid, grp_info);
819 /***********************************************************
820 Lookup a Username SID entry by uid.
821 ************************************************************/
822 static BOOL map_username_uid(uid_t gid, DOM_NAME_MAP *grp_info)
824 return map_unixid(DOM_MAP_USER, (uint32)gid, grp_info);
827 /***********************************************************
828 Lookup an Alias SID entry by name.
829 ************************************************************/
830 BOOL map_alias_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info)
832 return map_sid(DOM_MAP_LOCAL, psid, grp_info);
835 /***********************************************************
836 Lookup a Group entry by sid.
837 ************************************************************/
838 BOOL map_group_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info)
840 return map_sid(DOM_MAP_DOMAIN, psid, grp_info);
843 /***********************************************************
844 Lookup an Alias SID entry by gid_t.
845 ************************************************************/
846 static BOOL map_alias_gid(gid_t gid, DOM_NAME_MAP *grp_info)
848 return map_unixid(DOM_MAP_LOCAL, (uint32)gid, grp_info);
851 /***********************************************************
852 Lookup a Group SID entry by gid_t.
853 ************************************************************/
854 static BOOL map_group_gid( gid_t gid, DOM_NAME_MAP *grp_info)
856 return map_unixid(DOM_MAP_DOMAIN, (uint32)gid, grp_info);
860 /************************************************************************
861 Routine to look up User details by UNIX name
862 *************************************************************************/
863 BOOL lookupsmbpwnam(const char *unix_usr_name, DOM_NAME_MAP *grp)
865 uid_t uid;
866 DEBUG(10,("lookupsmbpwnam: unix user name %s\n", unix_usr_name));
867 if (nametouid(unix_usr_name, &uid))
869 return lookupsmbpwuid(uid, grp);
871 else
873 return False;
877 /************************************************************************
878 Routine to look up a remote nt name
879 *************************************************************************/
880 static BOOL lookup_remote_ntname(const char *ntname, DOM_SID *sid, uint8 *type)
882 struct cli_state cli;
883 POLICY_HND lsa_pol;
884 fstring srv_name;
885 extern struct ntuser_creds *usr_creds;
886 struct ntuser_creds usr;
888 BOOL res3 = True;
889 BOOL res4 = True;
890 uint32 num_sids;
891 DOM_SID *sids;
892 uint8 *types;
893 char *names[1];
895 usr_creds = &usr;
897 ZERO_STRUCT(usr);
898 pwd_set_nullpwd(&usr.pwd);
900 DEBUG(5,("lookup_remote_ntname: %s\n", ntname));
902 if (!cli_connect_serverlist(&cli, lp_passwordserver()))
904 return False;
907 names[0] = ntname;
909 fstrcpy(srv_name, "\\\\");
910 fstrcat(srv_name, cli.desthost);
911 strupper(srv_name);
913 /* lookup domain controller; receive a policy handle */
914 res3 = res3 ? lsa_open_policy( srv_name,
915 &lsa_pol, True) : False;
917 /* send lsa lookup sids call */
918 res4 = res3 ? lsa_lookup_names( &lsa_pol,
919 1, names,
920 &sids, &types, &num_sids) : False;
922 res3 = res3 ? lsa_close(&lsa_pol) : False;
924 if (res4 && res3 && sids != NULL && types != NULL)
926 sid_copy(sid, &sids[0]);
927 *type = types[0];
929 else
931 res3 = False;
933 if (types != NULL)
935 free(types);
938 if (sids != NULL)
940 free(sids);
943 return res3 && res4;
946 /************************************************************************
947 Routine to look up a remote nt name
948 *************************************************************************/
949 static BOOL get_sid_and_type(const char *fullntname, uint8 expected_type,
950 DOM_NAME_MAP *gmep)
953 * check with the PDC to see if it owns the name. if so,
954 * the SID is resolved with the PDC database.
957 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
959 if (lookup_remote_ntname(fullntname, &gmep->sid, &gmep->type))
961 if (sid_front_equal(&gmep->sid, &global_member_sid) &&
962 strequal(gmep->nt_domain, global_myworkgroup) &&
963 gmep->type == expected_type)
965 return True;
967 return False;
972 * ... otherwise, it's one of ours. map the sid ourselves,
973 * which can only happen in our own SAM database.
976 if (!strequal(gmep->nt_domain, global_sam_name))
978 return False;
980 if (!pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid))
982 return False;
985 return True;
989 * used by lookup functions below
992 static fstring nt_name;
993 static fstring unix_name;
994 static fstring nt_domain;
996 /*************************************************************************
997 looks up a uid, returns User Information.
998 *************************************************************************/
999 BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep)
1001 DEBUG(10,("lookupsmbpwuid: unix uid %d\n", uid));
1002 if (map_username_uid(uid, gmep))
1004 return True;
1006 #if 0
1007 if (lp_server_role() != ROLE_DOMAIN_NONE)
1008 #endif
1010 gmep->nt_name = nt_name;
1011 gmep->unix_name = unix_name;
1012 gmep->nt_domain = nt_domain;
1014 gmep->unix_id = (uint32)uid;
1017 * ok, assume it's one of ours. then double-check it
1018 * if we are a member of a domain
1021 gmep->type = SID_NAME_USER;
1022 fstrcpy(gmep->nt_name, uidtoname(uid));
1023 fstrcpy(gmep->unix_name, gmep->nt_name);
1026 * here we should do a LsaLookupNames() call
1027 * to check the status of the name with the PDC.
1028 * if the PDC know nothing of the name, it's ours.
1031 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1033 #if 0
1034 lsa_lookup_names(global_myworkgroup, gmep->nt_name, &gmep->sid...);
1035 #endif
1039 * ok, it's one of ours.
1042 gmep->nt_domain = global_sam_name;
1043 pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid);
1045 return True;
1048 /* oops. */
1050 return False;
1053 /*************************************************************************
1054 looks up by NT name, returns User Information.
1055 *************************************************************************/
1056 BOOL lookupsmbpwntnam(const char *fullntname, DOM_NAME_MAP *gmep)
1058 DEBUG(10,("lookupsmbpwntnam: nt user name %s\n", fullntname));
1060 if (!split_domain_name(fullntname, nt_domain, nt_name))
1062 return False;
1065 if (map_nt_username(nt_name, nt_domain, gmep))
1067 return True;
1069 if (lp_server_role() != ROLE_DOMAIN_NONE)
1071 uid_t uid;
1072 gmep->nt_name = nt_name;
1073 gmep->unix_name = unix_name;
1074 gmep->nt_domain = nt_domain;
1077 * ok, it's one of ours. we therefore "create" an nt user named
1078 * after the unix user. this is the point where "appliance mode"
1079 * should get its teeth in, as unix users won't really exist,
1080 * they will only be numbers...
1083 gmep->type = SID_NAME_USER;
1084 fstrcpy(gmep->unix_name, gmep->nt_name);
1085 if (!nametouid(gmep->unix_name, &uid))
1087 return False;
1089 gmep->unix_id = (uint32)uid;
1091 return get_sid_and_type(fullntname, gmep->type, gmep);
1094 /* oops. */
1096 return False;
1099 /*************************************************************************
1100 looks up by RID, returns User Information.
1101 *************************************************************************/
1102 BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
1104 fstring sid_str;
1105 sid_to_string(sid_str, sid);
1106 DEBUG(10,("lookupsmbpwsid: nt sid %s\n", sid_str));
1108 if (map_username_sid(sid, gmep))
1110 return True;
1112 if (lp_server_role() != ROLE_DOMAIN_NONE)
1114 gmep->nt_name = nt_name;
1115 gmep->unix_name = unix_name;
1116 gmep->nt_domain = nt_domain;
1119 * here we should do a LsaLookupNames() call
1120 * to check the status of the name with the PDC.
1121 * if the PDC know nothing of the name, it's ours.
1124 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1126 #if 0
1127 if (lookup_remote_sid(global_myworkgroup, gmep->sid, gmep->nt_name, gmep->nt_domain...);
1128 #endif
1132 * ok, it's one of ours. we therefore "create" an nt user named
1133 * after the unix user. this is the point where "appliance mode"
1134 * should get its teeth in, as unix users won't really exist,
1135 * they will only be numbers...
1138 gmep->type = SID_NAME_USER;
1139 sid_copy(&gmep->sid, sid);
1140 if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
1142 return False;
1144 fstrcpy(gmep->nt_name, uidtoname((uid_t)gmep->unix_id));
1145 fstrcpy(gmep->unix_name, gmep->nt_name);
1146 gmep->nt_domain = global_sam_name;
1148 return True;
1151 /* oops. */
1153 return False;
1156 /************************************************************************
1157 Routine to look up group / alias / well-known group RID by UNIX name
1158 *************************************************************************/
1159 BOOL lookupsmbgrpnam(const char *unix_grp_name, DOM_NAME_MAP *grp)
1161 gid_t gid;
1162 DEBUG(10,("lookupsmbgrpnam: unix user group %s\n", unix_grp_name));
1163 if (nametogid(unix_grp_name, &gid))
1165 return lookupsmbgrpgid(gid, grp);
1167 else
1169 return False;
1173 /*************************************************************************
1174 looks up a SID, returns name map entry
1175 *************************************************************************/
1176 BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
1178 fstring sid_str;
1179 sid_to_string(sid_str, sid);
1180 DEBUG(10,("lookupsmbgrpsid: nt sid %s\n", sid_str));
1182 if (map_alias_sid(sid, gmep))
1184 return True;
1186 if (map_group_sid(sid, gmep))
1188 return True;
1190 if (lp_server_role() != ROLE_DOMAIN_NONE)
1192 gmep->nt_name = nt_name;
1193 gmep->unix_name = unix_name;
1194 gmep->nt_domain = nt_domain;
1197 * here we should do a LsaLookupNames() call
1198 * to check the status of the name with the PDC.
1199 * if the PDC know nothing of the name, it's ours.
1202 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1204 #if 0
1205 lsa_lookup_sids(global_myworkgroup, gmep->sid, gmep->nt_name, gmep->nt_domain...);
1206 #endif
1210 * ok, it's one of ours. we therefore "create" an nt group or
1211 * alias name named after the unix group. this is the point
1212 * where "appliance mode" should get its teeth in, as unix
1213 * groups won't really exist, they will only be numbers...
1216 /* name is not explicitly mapped
1217 * with map files or the PDC
1218 * so we are responsible for it...
1221 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1223 /* ... as a LOCAL group. */
1224 gmep->type = SID_NAME_ALIAS;
1226 else
1228 /* ... as a DOMAIN group. */
1229 gmep->type = SID_NAME_DOM_GRP;
1232 sid_copy(&gmep->sid, sid);
1233 if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
1235 return False;
1237 fstrcpy(gmep->nt_name, gidtoname((gid_t)gmep->unix_id));
1238 fstrcpy(gmep->unix_name, gmep->nt_name);
1239 gmep->nt_domain = global_sam_name;
1241 return True;
1244 /* oops */
1245 return False;
1248 /*************************************************************************
1249 looks up a gid, returns RID and type local, domain or well-known domain group
1250 *************************************************************************/
1251 BOOL lookupsmbgrpgid(gid_t gid, DOM_NAME_MAP *gmep)
1253 DEBUG(10,("lookupsmbgrpgid: unix gid %d\n", (int)gid));
1254 if (map_alias_gid(gid, gmep))
1256 return True;
1258 if (map_group_gid(gid, gmep))
1260 return True;
1262 if (lp_server_role() != ROLE_DOMAIN_NONE)
1264 gmep->nt_name = nt_name;
1265 gmep->unix_name = unix_name;
1266 gmep->nt_domain = nt_domain;
1268 gmep->unix_id = (uint32)gid;
1271 * here we should do a LsaLookupNames() call
1272 * to check the status of the name with the PDC.
1273 * if the PDC know nothing of the name, it's ours.
1276 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1278 #if 0
1279 if (lsa_lookup_names(global_myworkgroup, gmep->nt_name, &gmep->sid...);
1281 return True;
1283 #endif
1287 * ok, it's one of ours. we therefore "create" an nt group or
1288 * alias name named after the unix group. this is the point
1289 * where "appliance mode" should get its teeth in, as unix
1290 * groups won't really exist, they will only be numbers...
1293 /* name is not explicitly mapped
1294 * with map files or the PDC
1295 * so we are responsible for it...
1298 if (lp_server_role() == ROLE_DOMAIN_MEMBER)
1300 /* ... as a LOCAL group. */
1301 gmep->type = SID_NAME_ALIAS;
1303 else
1305 /* ... as a DOMAIN group. */
1306 gmep->type = SID_NAME_DOM_GRP;
1308 fstrcpy(gmep->nt_name, gidtoname(gid));
1309 fstrcpy(gmep->unix_name, gmep->nt_name);
1311 return get_sid_and_type(gmep->nt_name, gmep->type, gmep);
1314 /* oops */
1315 return False;