From 9a735eb7e25d8bf6c5be7775d89436034ea6be8a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Jun 1998 03:08:23 +0000 Subject: ipc.c: map_username is now a BOOL function. reply.c: map_username is now a BOOL function. server.c: Added capability to do map_username on service names when looking for a home directory. That's what the original code would do. lib/rpc/server/srv_util.c: Changed domain_ to builtin_ for BUILTIN aliases. username.c: Work in progress on groupname map parameter. Jeremy (This used to be commit fa95fae5eed95aff64f0a01825477610a101bbc7) --- source3/include/proto.h | 3 +- source3/lib/username.c | 203 ++++++++++++++++++++++++++++++++++++++---- source3/rpc_server/srv_util.c | 52 +++++------ source3/smbd/ipc.c | 4 +- source3/smbd/reply.c | 6 +- source3/smbd/server.c | 70 +++++++++------ 6 files changed, 263 insertions(+), 75 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 7dd4918028..9381aacf84 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1939,9 +1939,10 @@ void unbecome_root(BOOL restore_dir); /*The following definitions come from username.c */ char *get_home_dir(char *user); -void map_username(char *user); +BOOL map_username(char *user); struct passwd *Get_Pwnam(char *user,BOOL allow_change); BOOL user_in_list(char *user,char *list); +void load_groupname_map(void); /*The following definitions come from util.c */ diff --git a/source3/lib/username.c b/source3/lib/username.c index d5ecfe9166..101f2fc4eb 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -21,6 +21,7 @@ #include "includes.h" extern int DEBUGLEVEL; +extern DOM_SID global_machine_sid; /* internal functions */ static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (char *), int N); @@ -48,20 +49,22 @@ any incoming or new username - in order to canonicalize the name. This is being done to de-couple the case conversions from the user mapping function. Previously, the map_username was being called every time Get_Pwnam was called. +Returns True if username was changed, false otherwise. ********************************************************************/ -void map_username(char *user) +BOOL map_username(char *user) { static BOOL initialised=False; static fstring last_from,last_to; FILE *f; - char *s; char *mapfile = lp_username_map(); + char *s; + pstring buf; - if (!*user) return; + if (!*user) + return False; - if (!*mapfile) { - return; - } + if (!*mapfile) + return False; if (!initialised) { *last_from = *last_to = 0; @@ -69,38 +72,43 @@ void map_username(char *user) } if (strequal(user,last_to)) - return; + return False; if (strequal(user,last_from)) { DEBUG(3,("Mapped user %s to %s\n",user,last_to)); fstrcpy(user,last_to); - return; + return True; } f = fopen(mapfile,"r"); if (!f) { DEBUG(0,("can't open username map %s\n",mapfile)); - return; + return False; } DEBUG(4,("Scanning username map %s\n",mapfile)); - for (; (s=fgets_slash(NULL,80,f)); free(s)) { + while((s=fgets_slash(buf,sizeof(buf),f))!=NULL) { char *unixname = s; char *dosname = strchr(unixname,'='); BOOL return_if_mapped = False; - if (!dosname) continue; + if (!dosname) + continue; + *dosname++ = 0; - while (isspace(*unixname)) unixname++; + while (isspace(*unixname)) + unixname++; if ('!' == *unixname) { return_if_mapped = True; unixname++; - while (*unixname && isspace(*unixname)) unixname++; + while (*unixname && isspace(*unixname)) + unixname++; } - if (!*unixname || strchr("#;",*unixname)) continue; + if (!*unixname || strchr("#;",*unixname)) + continue; { int l = strlen(unixname); @@ -116,14 +124,23 @@ void map_username(char *user) sscanf(unixname,"%s",user); fstrcpy(last_to,user); if(return_if_mapped) { - free(s); fclose(f); - return; + return True; } } } fclose(f); + + /* + * Username wasn't mapped. Setup the last_from and last_to + * as an optimization so that we don't scan the file again + * for the same user. + */ + fstrcpy(last_from,user); + fstrcpy(last_to,user); + + return False; } /**************************************************************************** @@ -335,3 +352,157 @@ static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(c } return(NULL); } + +#if 0 +/* JRATEST - under construction. */ +/************************************************************************** + Groupname map functionality. The code loads a groupname map file and + (currently) loads it into a linked list. This is slow and memory + hungry, but can be changed into a more efficient storage format + if the demands on it become excessive. +***************************************************************************/ + +typedef struct groupname_map { + ubi_slNode next; + + char *windows_name; + DOM_SID windows_sid; + char *unix_name; + gid_t unix_gid; +} groupname_map_entry; + +static ubi_slList groupname_map_list; + +/************************************************************************** + Delete all the entries in the groupname map list. +***************************************************************************/ + +static void delete_groupname_map_list(void) +{ + groupname_map_entry *gmep; + + while((gmep = (groupname_map_entry *)ubi_slRemHead( groupname_map_list )) != NULL) { + if(gmep->windows_name) + free(gmep->windows_name); + if(gmep->unix_name) + free(gmep->unix_name); + free((char *)gmep); + } +} + +/************************************************************************** + Load a groupname map file. Sets last accessed timestamp. +***************************************************************************/ + +void load_groupname_map(void) +{ + static time_t groupmap_file_last_modified = (time_t)0; + static BOOL initialized = False; + char *groupname_map_file = lp_groupname_map(); + struct stat st; + FILE *fp; + char *s; + pstring buf; + + if(!initialized) { + ubi_slInsert( &groupname_map_list ); + initialized = True; + } + + if (!*groupname_map_file) + return; + + if(stat(groupname_map_file, &st) != 0) { + DEBUG(0, ("load_groupname_map: Unable to stat file %s. Error was %s\n", + groupname_map_file, strerror(errno) )); + return; + } + + /* + * Check if file has changed. + */ + if( st.st_mtime <= groupmap_file_last_modified) + return; + + groupmap_file_last_modified = st.st_mtime; + + /* + * Load the file. + */ + + fp = fopen(groupname_map_file,"r"); + if (!fp) { + DEBUG(0,("load_groupname_map: can't open groupname map %s. Error was %s\n", + mapfile, strerror(errno))); + return; + } + + /* + * Throw away any previous list. + */ + delete_groupname_map_list(); + + DEBUG(4,("load_groupname_map: Scanning groupname map %s\n",groupname_map_file)); + + while((s=fgets_slash(buf,sizeof(buf),fp))!=NULL) { + pstring unixname; + pstring windows_name; + struct group *gptr; + DOM_SID tmp_sid; + + DEBUG(10,("load_groupname_map: Read line |%s|\n", s); + + if (!*s || strchr("#;",*s)) + continue; + + if(!next_token(&s,unixname, "\t\n\r=")) + continue; + + if(!next_token(&s,windows_name, "\t\n\r=")) + continue; + + trim_string(unixname, " ", " "); + trim_string(windows_name, " ", " "); + + if (!*dosname) + continue; + + if(!*unixname) + continue; + + /* + * Attempt to get the unix gid_t for this name. + */ + + DEBUG(5,("load_groupname_map: Attempting to find unix group %s.\n", + unixname )); + + if((gptr = (struct group *)getgrnam(unixname)) == NULL) { + DEBUG(0,("load_groupname_map: getgrnam for group %s failed.\ +Error was %s.\n", unixname, strerror(errno) )); + continue; + } + + /* + * Now map to an NT SID. + */ + + if(!lookup_wellknown_sid_from_name(windows_name, &tmp_sid)) { + /* + * It's not a well known name, convert the UNIX gid_t + * to a rid within this domain SID. + */ + tmp_sid = global_machine_sid; + tmp_sid.sub_auths[tmp_sid.num_auths++] = + pdb_gid_to_group_rid((gid_t)gptr->gr_gid); + } + + /* + * Create the list entry and add it onto the list. + */ + + } + + fclose(fp); +} +#endif /* JRATEST */ diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index 1ccd14c813..e05a964c9f 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -43,21 +43,23 @@ extern int DEBUGLEVEL; -/* array lookup of well-known RID aliases. the purpose of these escapes me.. */ -/* XXXX this structure should not have the well-known RID groups added to it, - i.e the DOMAIN_GROUP_RID_ADMIN/USER/GUEST. */ -rid_name domain_alias_rids[] = +/* + * A list of the rids of well known BUILTIN and Domain users + * and groups. + */ + +rid_name builtin_alias_rids[] = { - { BUILTIN_ALIAS_RID_ADMINS , "admins" }, - { BUILTIN_ALIAS_RID_USERS , "users" }, - { BUILTIN_ALIAS_RID_GUESTS , "guests" }, - { BUILTIN_ALIAS_RID_POWER_USERS , "power_users" }, - - { BUILTIN_ALIAS_RID_ACCOUNT_OPS , "account_ops" }, - { BUILTIN_ALIAS_RID_SYSTEM_OPS , "system_ops" }, - { BUILTIN_ALIAS_RID_PRINT_OPS , "print_ops" }, - { BUILTIN_ALIAS_RID_BACKUP_OPS , "backup_ops" }, - { BUILTIN_ALIAS_RID_REPLICATOR , "replicator" }, + { BUILTIN_ALIAS_RID_ADMINS , "Administrators" }, + { BUILTIN_ALIAS_RID_USERS , "Users" }, + { BUILTIN_ALIAS_RID_GUESTS , "Guests" }, + { BUILTIN_ALIAS_RID_POWER_USERS , "Power Users" }, + + { BUILTIN_ALIAS_RID_ACCOUNT_OPS , "Account Operators" }, + { BUILTIN_ALIAS_RID_SYSTEM_OPS , "System Operators" }, + { BUILTIN_ALIAS_RID_PRINT_OPS , "Print Operators" }, + { BUILTIN_ALIAS_RID_BACKUP_OPS , "Backup Operators" }, + { BUILTIN_ALIAS_RID_REPLICATOR , "Replicator" }, { 0 , NULL } }; @@ -72,9 +74,9 @@ rid_name domain_user_rids[] = /* array lookup of well-known Domain RID groups. */ rid_name domain_group_rids[] = { - { DOMAIN_GROUP_RID_ADMINS , "domain admins" }, - { DOMAIN_GROUP_RID_USERS , "domain users" }, - { DOMAIN_GROUP_RID_GUESTS , "domain guests" }, + { DOMAIN_GROUP_RID_ADMINS , "Domain Admins" }, + { DOMAIN_GROUP_RID_USERS , "Domain Users" }, + { DOMAIN_GROUP_RID_GUESTS , "Domain Guests" }, { 0 , NULL } }; @@ -119,11 +121,11 @@ int make_dom_gids(char *gids_str, DOM_GID **ppgids) attr = "7"; /* default value for attribute is 7 */ /* look up the RID string and see if we can turn it into a rid number */ - for (i = 0; domain_alias_rids[i].name != NULL; i++) + for (i = 0; builtin_alias_rids[i].name != NULL; i++) { - if (strequal(domain_alias_rids[i].name, s2)) + if (strequal(builtin_alias_rids[i].name, s2)) { - rid = domain_alias_rids[i].rid; + rid = builtin_alias_rids[i].rid; break; } } @@ -373,14 +375,14 @@ uint32 lookup_alias_name(uint32 rid, char *alias_name, uint32 *type) DEBUG(5,("lookup_alias_name: rid: %d", rid)); - while (domain_alias_rids[i].rid != rid && domain_alias_rids[i].rid != 0) + while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0) { i++; } - if (domain_alias_rids[i].rid != 0) + if (builtin_alias_rids[i].rid != 0) { - fstrcpy(alias_name, domain_alias_rids[i].name); + fstrcpy(alias_name, builtin_alias_rids[i].name); DEBUG(5,(" = %s\n", alias_name)); return 0x0; } @@ -459,8 +461,8 @@ uint32 lookup_alias_rid(char *alias_name, uint32 *rid) do /* find, if it exists, a alias rid for the alias name*/ { i++; - (*rid) = domain_alias_rids[i].rid; - als_name = domain_alias_rids[i].name; + (*rid) = builtin_alias_rids[i].rid; + als_name = builtin_alias_rids[i].name; } while (als_name != NULL && !strequal(als_name, alias_name)); diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index f92e376575..9c48951e35 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -1637,7 +1637,7 @@ static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data, * function. */ - map_username(user); + (void)map_username(user); /* * Do any UNIX username case mangling. @@ -1725,7 +1725,7 @@ static BOOL api_SamOEMChangePassword(int cnum,uint16 vuid, char *param,char *dat * function. */ - map_username(user); + (void)map_username(user); /* * Do any UNIX username case mangling. diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c9b0c6852d..a9db0b3840 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -237,7 +237,7 @@ int reply_tcon(char *inbuf,char *outbuf, int dum_size, int dum_buffsize) * function. */ - map_username(user); + (void)map_username(user); /* * Do any UNIX username case mangling. @@ -317,7 +317,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) * function. */ - map_username(user); + (void)map_username(user); /* * Do any UNIX username case mangling. @@ -628,7 +628,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) * function. */ - map_username(user); + (void)map_username(user); /* * Do any UNIX username case mangling. diff --git a/source3/smbd/server.c b/source3/smbd/server.c index ba7a0a18f1..25ec11abaa 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -2340,16 +2340,28 @@ int find_service(char *service) if (iService < 0) { char *phome_dir = get_home_dir(service); + + if(!phome_dir) + { + /* + * Try mapping the servicename, it may + * be a Windows to unix mapped user name. + */ + if(map_username(service)) + phome_dir = get_home_dir(service); + } + DEBUG(3,("checking for home directory %s gave %s\n",service, - phome_dir?phome_dir:"(NULL)")); + phome_dir?phome_dir:"(NULL)")); + if (phome_dir) { - int iHomeService; - if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0) - { - lp_add_home(service,iHomeService,phome_dir); - iService = lp_servicenumber(service); - } + int iHomeService; + if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0) + { + lp_add_home(service,iHomeService,phome_dir); + iService = lp_servicenumber(service); + } } } @@ -2380,34 +2392,36 @@ int find_service(char *service) /* just possibly it's a default service? */ if (iService < 0) + { + char *pdefservice = lp_defaultservice(); + if (pdefservice && *pdefservice && !strequal(pdefservice,service)) { - char *pdefservice = lp_defaultservice(); - if (pdefservice && *pdefservice && !strequal(pdefservice,service)) { - /* - * We need to do a local copy here as lp_defaultservice() - * returns one of the rotating lp_string buffers that - * could get overwritten by the recursive find_service() call - * below. Fix from Josef Hinteregger . - */ - pstring defservice; - pstrcpy(defservice, pdefservice); - iService = find_service(defservice); - if (iService >= 0) { - string_sub(service,"_","/"); - iService = lp_add_service(service,iService); - } + /* + * We need to do a local copy here as lp_defaultservice() + * returns one of the rotating lp_string buffers that + * could get overwritten by the recursive find_service() call + * below. Fix from Josef Hinteregger . + */ + pstring defservice; + pstrcpy(defservice, pdefservice); + iService = find_service(defservice); + if (iService >= 0) + { + string_sub(service,"_","/"); + iService = lp_add_service(service,iService); } } + } if (iService >= 0) - if (!VALID_SNUM(iService)) - { - DEBUG(0,("Invalid snum %d for %s\n",iService,service)); - iService = -1; - } + if (!VALID_SNUM(iService)) + { + DEBUG(0,("Invalid snum %d for %s\n",iService,service)); + iService = -1; + } if (iService < 0) - DEBUG(3,("find_service() failed to find service %s\n", service)); + DEBUG(3,("find_service() failed to find service %s\n", service)); return (iService); } -- cgit