2 Unix SMB/Netbios implementation.
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.
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)
42 if the DOMAIN_NAME\ component is left off, then your own domain is assumed.
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
);
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
);
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
);
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
)
118 sid_copy(&tmp_sid
, sid
);
119 sid_split_rid(&tmp_sid
, &rid
);
120 if (!sid_equal(&global_sam_sid
, &tmp_sid
))
129 *id
= pwdb_user_rid_to_uid(rid
);
134 *id
= pwdb_alias_rid_to_gid(rid
);
137 case SID_NAME_DOM_GRP
:
138 case SID_NAME_WKN_GRP
:
140 *id
= pwdb_group_rid_to_gid(rid
);
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
);
158 sid_append_rid(sid
, pwdb_uid_to_user_rid(id
));
163 sid_append_rid(sid
, pwdb_gid_to_alias_rid(id
));
166 case SID_NAME_DOM_GRP
:
167 case SID_NAME_WKN_GRP
:
169 sid_append_rid(sid
, pwdb_gid_to_group_rid(id
));
176 /*******************************************************************
177 Decides if a RID is a well known RID.
178 ********************************************************************/
179 static BOOL
pwdb_rid_is_well_known(uint32 rid
)
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
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
);
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
)
281 if (!map_domain_name_to_sid(&grp
->sid
, &(grp
->nt_domain
)))
283 DEBUG(0,("make_mydomain_sid: unknown domain %s\n",
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",
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
));
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
));
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
));
330 grp
->type
= SID_NAME_USER
;
335 grp
->type
= SID_NAME_DOM_GRP
;
340 grp
->type
= SID_NAME_ALIAS
;
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
));
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
);
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
) ));
375 map
->unix_id
= (uint32
)pwptr
->pw_uid
;
379 struct group
*gptr
= getgrnam(map
->unix_name
);
382 DEBUG(0,("unix_name_to_nt_name_info: getgrnam for group %s\
383 failed. Error was %s.\n", map
->unix_name
, strerror(errno
) ));
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,
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",
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
,
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"));
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
));
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
));
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();
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
;
496 file_last_modified
= &groupmap_file_last_modified
;
497 initialised
= &initialised_group
;
498 map_file
= groupname_map_file
;
499 map_list
= &groupname_map_list
;
505 file_last_modified
= &aliasmap_file_last_modified
;
506 initialised
= &initialised_alias
;
507 map_file
= aliasname_map_file
;
508 map_list
= &aliasname_map_list
;
514 file_last_modified
= &ntusrmap_file_last_modified
;
515 initialised
= &initialised_ntusr
;
516 map_file
= ntusrname_map_file
;
517 map_list
= &ntusrname_map_list
;
525 DEBUG(10,("initialising map %s\n", map_file
));
526 ubi_slInitList(map_list
);
527 (*initialised
) = True
;
539 fp
= open_file_if_modified(map_file
, "r", file_last_modified
);
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
)
560 DEBUG(10,("Read line |%s|\n", s
));
562 memset(nt_name
, 0, sizeof(nt_name
));
564 if (!*s
|| strchr("#;",*s
))
567 if (!next_token(&s
,unixname
, "\t\n\r=", sizeof(unixname
)))
570 if (!next_token(&s
,nt_name
, "\t\n\r=", sizeof(nt_name
)))
573 trim_string(unixname
, " ", " ");
574 trim_string(nt_name
, " ", " ");
582 p
= strchr(nt_name
, '\\');
586 memset(nt_domain
, 0, sizeof(nt_domain
));
587 fstrcpy(ntname
, nt_name
);
593 fstrcpy(nt_domain
, nt_name
);
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
,
608 DEBUG(10,("load_name_map: Added %ld entries to name map.\n",
609 ubi_slCount(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
;
627 /***********************************************************
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
);
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
));
659 /***********************************************************
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
);
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
));
691 /***********************************************************
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
);
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
));
721 /***********************************************************
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
);
736 gmep
= (name_map_entry
*)ubi_slNext(gmep
))
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
));
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 ***********************************************************/
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 /***********************************************************
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
);
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
)
866 DEBUG(10,("lookupsmbpwnam: unix user name %s\n", unix_usr_name
));
867 if (nametouid(unix_usr_name
, &uid
))
869 return lookupsmbpwuid(uid
, grp
);
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
;
885 extern struct ntuser_creds
*usr_creds
;
886 struct ntuser_creds usr
;
898 pwd_set_nullpwd(&usr
.pwd
);
900 DEBUG(5,("lookup_remote_ntname: %s\n", ntname
));
902 if (!cli_connect_serverlist(&cli
, lp_passwordserver()))
909 fstrcpy(srv_name
, "\\\\");
910 fstrcat(srv_name
, cli
.desthost
);
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
,
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]);
946 /************************************************************************
947 Routine to look up a remote nt name
948 *************************************************************************/
949 static BOOL
get_sid_and_type(const char *fullntname
, uint8 expected_type
,
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
)
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
))
980 if (!pwdb_unixid_to_sam_sid(gmep
->unix_id
, gmep
->type
, &gmep
->sid
))
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
))
1007 if (lp_server_role() != ROLE_DOMAIN_NONE
)
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
)
1034 lsa_lookup_names(global_myworkgroup
, gmep
->nt_name
, &gmep
->sid
...);
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
);
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
))
1065 if (map_nt_username(nt_name
, nt_domain
, gmep
))
1069 if (lp_server_role() != ROLE_DOMAIN_NONE
)
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
))
1089 gmep
->unix_id
= (uint32
)uid
;
1091 return get_sid_and_type(fullntname
, gmep
->type
, gmep
);
1099 /*************************************************************************
1100 looks up by RID, returns User Information.
1101 *************************************************************************/
1102 BOOL
lookupsmbpwsid(DOM_SID
*sid
, DOM_NAME_MAP
*gmep
)
1105 sid_to_string(sid_str
, sid
);
1106 DEBUG(10,("lookupsmbpwsid: nt sid %s\n", sid_str
));
1108 if (map_username_sid(sid
, gmep
))
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
)
1127 if (lookup_remote_sid(global_myworkgroup
, gmep
->sid
, gmep
->nt_name
, gmep
->nt_domain
...);
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
))
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
;
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
)
1162 DEBUG(10,("lookupsmbgrpnam: unix user group %s\n", unix_grp_name
));
1163 if (nametogid(unix_grp_name
, &gid
))
1165 return lookupsmbgrpgid(gid
, grp
);
1173 /*************************************************************************
1174 looks up a SID, returns name map entry
1175 *************************************************************************/
1176 BOOL
lookupsmbgrpsid(DOM_SID
*sid
, DOM_NAME_MAP
*gmep
)
1179 sid_to_string(sid_str
, sid
);
1180 DEBUG(10,("lookupsmbgrpsid: nt sid %s\n", sid_str
));
1182 if (map_alias_sid(sid
, gmep
))
1186 if (map_group_sid(sid
, gmep
))
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
)
1205 lsa_lookup_sids(global_myworkgroup
, gmep
->sid
, gmep
->nt_name
, gmep
->nt_domain
...);
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
;
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
))
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
;
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
))
1258 if (map_group_gid(gid
, gmep
))
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
)
1279 if (lsa_lookup_names(global_myworkgroup
, gmep
->nt_name
, &gmep
->sid
...);
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
;
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
);