diff options
-rw-r--r-- | source/include/proto.h | 29 | ||||
-rw-r--r-- | source/lib/username.c | 130 | ||||
-rw-r--r-- | source/lib/util.c | 50 | ||||
-rw-r--r-- | source/libsmb/namequery.c | 2 | ||||
-rw-r--r-- | source/nsswitch/wb_client.c | 247 | ||||
-rw-r--r-- | source/smbd/groupname.c | 10 | ||||
-rw-r--r-- | source/smbd/service.c | 16 | ||||
-rw-r--r-- | source/smbd/uid.c | 226 |
8 files changed, 457 insertions, 253 deletions
diff --git a/source/include/proto.h b/source/include/proto.h index b68209434f0..e3d574de21d 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -151,6 +151,7 @@ void mdfour(unsigned char *out, unsigned char *in, int n); /*The following definitions come from lib/messages.c */ void ping_message(int msg_type, pid_t src, void *buf, size_t len); +void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len); BOOL message_init(void); BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len); void message_dispatch(void); @@ -317,6 +318,7 @@ char *ufc_crypt(char *key,char *salt); char *get_user_home_dir(char *user); BOOL map_username(char *user); struct passwd *Get_Pwnam(char *user,BOOL allow_change); +BOOL user_in_group_list(char *user,char *gname); BOOL user_in_list(char *user,char *list); struct passwd *smb_getpwnam(char *user, BOOL allow_change); @@ -358,8 +360,8 @@ struct hostent *Get_Hostbyname(const char *name); BOOL process_exists(pid_t pid); char *uidtoname(uid_t uid); char *gidtoname(gid_t gid); -uid_t nametouid(const char *name); -gid_t nametogid(const char *name); +uid_t nametouid(char *name); +gid_t nametogid(char *name); void smb_panic(char *why); char *readdirname(DIR *p); BOOL is_in_path(char *name, name_compare_entry *namelist); @@ -1299,12 +1301,16 @@ void expire_workgroups_and_servers(time_t t); BOOL winbind_lookup_name(char *name, DOM_SID *sid, enum SID_NAME_USE *name_type); BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type); -BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type); -BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type); -DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid); -DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid); -BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype); -BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype); +BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid); +BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid); +BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid); +BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid); +int winbind_initgroups(char *user, gid_t gid); +int winbind_getgroups(char *user, int size, gid_t *list); +BOOL winbind_uidtoname(fstring name, uid_t uid); +BOOL winbind_gidtoname(fstring name, gid_t gid); +BOOL winbind_nametouid(uid_t *puid, char *name); +BOOL winbind_nametogid(gid_t *pgid, char *gname); /*The following definitions come from nsswitch/wb_common.c */ @@ -3648,7 +3654,6 @@ user_struct *get_valid_user_struct(uint16 vuid); void invalidate_vuid(uint16 vuid); char *validated_username(uint16 vuid); char *validated_domain(uint16 vuid); -BOOL initialize_groups(char *user, uid_t uid, gid_t gid); NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups); uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, char *domain,BOOL guest); @@ -3843,6 +3848,12 @@ BOOL become_authenticated_pipe_user(pipes_struct *p); BOOL unbecome_authenticated_pipe_user(pipes_struct *p); void become_root(void); void unbecome_root(void); +BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type); +BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type); +DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid); +DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid); +BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype); +BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype); #endif /*The following definitions come from smbd/unix_acls.c */ diff --git a/source/lib/username.c b/source/lib/username.c index ad44c0c5444..32e9eb31885 100644 --- a/source/lib/username.c +++ b/source/lib/username.c @@ -260,29 +260,109 @@ static BOOL user_in_netgroup_list(char *user,char *ngname) } /**************************************************************************** - Check if a user is in a UNIX user list. + Check if a user is in a winbind group. +****************************************************************************/ + +static BOOL user_in_winbind_group_list(char *user,char *gname, BOOL *winbind_answered) +{ + int num_groups; + int i; + gid_t *groups = NULL; + gid_t gid; + DOM_SID g_sid; + enum SID_NAME_USE name_type; + BOOL ret = False; + + *winbind_answered = False; + + /* + * Get the gid's that this user belongs to. + */ + + if ((num_groups = winbind_getgroups(user, 0, NULL)) == -1) + return False; + + if (num_groups == 0) { + *winbind_answered = True; + return False; + } + + if ((groups = (gid_t *)malloc(sizeof(gid_t) * num_groups )) == NULL) { + DEBUG(0,("user_in_winbind_group_list: malloc fail.\n")); + goto err; + } + + if ((num_groups = winbind_getgroups(user, num_groups, groups)) == -1) { + DEBUG(0,("user_in_winbind_group_list: second winbind_getgroups call \ +failed with error %s\n", strerror(errno) )); + goto err; + } + + /* + * Now we have the gid list for this user - convert the gname + * to a gid_t via winbind and do the comparison. + */ + + if (!winbind_nametogid(gname, &gid)) { + DEBUG(0,("user_in_winbind_group_list: winbind_lookup_name for group %s failed.\n", + gname )); + goto err; + } + + for (i = 0; i < num_groups; i++) { + if (gid == groups[i]) { + ret = True; + break; + } + } + + *winbind_answered = True; + safe_free(groups); + return ret; + + err: + + *winbind_answered = False; + safe_free(groups); + return False; +} + +/**************************************************************************** + Check if a user is in a UNIX group. ****************************************************************************/ -static BOOL user_in_group_list(char *user,char *gname) +static BOOL user_in_unix_group_list(char *user,char *gname) { struct group *gptr; char **member; struct passwd *pass = Get_Pwnam(user,False); - if (pass) { - gptr = getgrgid(pass->pw_gid); - if (gptr && strequal(gptr->gr_name,gname)) - return True; - } - - if ((gptr = (struct group *)getgrnam(gname)) == NULL) - return False; - - member = gptr->gr_mem; - while (member && *member) { - if (strequal(*member,user)) { - return(True); - } + DEBUG(10,("user_in_unix_group_list: checking user %s in group %s\n", user, gname)); + + /* + * We need to check the users primary group as this + * group is implicit and often not listed in the group database. + */ + + if (pass) { + gptr = getgrgid(pass->pw_gid); + if (gptr && strequal(gptr->gr_name,gname)) { + DEBUG(10,("user_in_unix_group_list: group %s is primary group.\n", gname )); + return True; + } + } + + if ((gptr = (struct group *)getgrnam(gname)) == NULL) { + DEBUG(10,("user_in_unix_group_list: no such group %s\n", gname )); + return False; + } + + member = gptr->gr_mem; + while (member && *member) { + DEBUG(10,("user_in_unix_group_list: checking user %s against member %s\n", user, *member )); + if (strequal(*member,user)) { + return(True); + } member++; } @@ -290,6 +370,21 @@ static BOOL user_in_group_list(char *user,char *gname) } /**************************************************************************** + Check if a user is in a group list. Ask winbind first, then use UNIX. +****************************************************************************/ + +BOOL user_in_group_list(char *user,char *gname) +{ + BOOL winbind_answered = False; + BOOL ret = user_in_winbind_group_list(user, gname, &winbind_answered); + + if (winbind_answered) + return ret; + + return user_in_unix_group_list(user, gname); +} + +/**************************************************************************** Check if a user is in a user list - can check combinations of UNIX and netgroup lists. ****************************************************************************/ @@ -299,6 +394,8 @@ BOOL user_in_list(char *user,char *list) pstring tok; char *p=list; + DEBUG(10,("user_in_list: checking user %s in list %s\n", user, list)); + while (next_token(&p,tok,LIST_SEP, sizeof(tok))) { /* * Check raw username. @@ -447,4 +544,3 @@ struct passwd *smb_getpwnam(char *user, BOOL allow_change) return NULL; } - diff --git a/source/lib/util.c b/source/lib/util.c index aced56bc2f7..0aef60082f3 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -1099,60 +1099,80 @@ BOOL process_exists(pid_t pid) /******************************************************************* -turn a uid into a user name + Convert a uid into a user name. ********************************************************************/ + char *uidtoname(uid_t uid) { - static char name[40]; - struct passwd *pass = sys_getpwuid(uid); - if (pass) return(pass->pw_name); - slprintf(name, sizeof(name) - 1, "%d",(int)uid); - return(name); + static fstring name; + struct passwd *pass; + + if (winbind_uidtoname(name, uid)) + return name; + + pass = sys_getpwuid(uid); + if (pass) return(pass->pw_name); + slprintf(name, sizeof(name) - 1, "%d",(int)uid); + return(name); } /******************************************************************* -turn a gid into a group name + Convert a gid into a group name. ********************************************************************/ char *gidtoname(gid_t gid) { - static char name[40]; - struct group *grp = getgrgid(gid); + static fstring name; + struct group *grp; + + if (winbind_gidtoname(name, gid)) + return name; + + grp = getgrgid(gid); if (grp) return(grp->gr_name); slprintf(name,sizeof(name) - 1, "%d",(int)gid); return(name); } /******************************************************************* -turn a user name into a uid + Convert a user name into a uid. If winbindd is present uses this. ********************************************************************/ -uid_t nametouid(const char *name) + +uid_t nametouid(char *name) { struct passwd *pass; char *p; uid_t u; - u = strtol(name, &p, 0); + u = (uid_t)strtol(name, &p, 0); if (p != name) return u; + if (winbind_nametouid(&u, name)) + return u; + pass = sys_getpwnam(name); if (pass) return(pass->pw_uid); return (uid_t)-1; } /******************************************************************* -turn a group name into a gid + Convert a name to a gid_t if possible. Return -1 if not a group. If winbindd + is present does a shortcut lookup... ********************************************************************/ -gid_t nametogid(const char *name) + +gid_t nametogid(char *name) { struct group *grp; char *p; gid_t g; - g = strtol(name, &p, 0); + g = (gid_t)strtol(name, &p, 0); if (p != name) return g; + if (winbind_nametogid(&g, name)) + return g; + grp = getgrnam(name); if (grp) return(grp->gr_gid); return (gid_t)-1; diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c index 41924d4631e..52ff6287c42 100644 --- a/source/libsmb/namequery.c +++ b/source/libsmb/namequery.c @@ -891,7 +891,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd dgram->header.packet_offset = 0; make_nmb_name(&dgram->source_name,srcname,0); - make_nmb_name(&dgram->dest_name,domain,0x1B); + make_nmb_name(&dgram->dest_name,domain,0x1C); ptr = &dgram->data[0]; diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c index 436bbc7bcc3..d2762674aac 100644 --- a/source/nsswitch/wb_client.c +++ b/source/nsswitch/wb_client.c @@ -58,27 +58,8 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_N struct winbindd_request request; struct winbindd_response response; enum nss_status result; - DOM_SID tmp_sid; - uint32 rid; fstring sid_str; - if (!name_type) - return False; - - /* Check if this is our own sid. This should perhaps be done by - winbind? For the moment handle it here. */ - - if (sid->num_auths == 5) { - sid_copy(&tmp_sid, sid); - sid_split_rid(&tmp_sid, &rid); - - if (sid_equal(&global_sam_sid, &tmp_sid)) { - - return map_domain_sid_to_name(&tmp_sid, dom_name) && - local_lookup_rid(rid, name, name_type); - } - } - /* Initialise request */ ZERO_STRUCT(request); @@ -103,7 +84,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_N /* Call winbindd to convert SID to uid */ -static BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid) +BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid) { struct winbindd_request request; struct winbindd_response response; @@ -136,7 +117,7 @@ static BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid) /* Call winbindd to convert uid to sid */ -static BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid) +BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid) { struct winbindd_request request; struct winbindd_response response; @@ -169,7 +150,7 @@ static BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid) /* Call winbindd to convert SID to gid */ -static BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid) +BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid) { struct winbindd_request request; struct winbindd_response response; @@ -202,7 +183,7 @@ static BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid) /* Call winbindd to convert gid to sid */ -static BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) +BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) { struct winbindd_request request; struct winbindd_response response; @@ -361,208 +342,82 @@ int winbind_getgroups(char *user, int size, gid_t *list) return result; } -/***************************************************************** - *THE CANONICAL* convert name to SID function. - Tries winbind first - then uses local lookup. -*****************************************************************/ +/********************************************************************************** + Utility function. Convert a uid_t to a name if possible. +**********************************************************************************/ -BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) +BOOL winbind_uidtoname(fstring name, uid_t uid) { - extern pstring global_myname; - fstring sid; - - if (!winbind_lookup_name(name, psid, name_type)) { - BOOL ret; - - DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name )); - - ret = local_lookup_name(global_myname, name, psid, name_type); - if (ret) - DEBUG(10,("lookup_name : (local) %s -> SID %s (type %u)\n", - name, sid_to_string(sid,psid), - (unsigned int)*name_type )); - else - DEBUG(10,("lookup name : (local) %s failed.\n", - name )); - return ret; - } - - DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n", - name, sid_to_string(sid,psid), (unsigned int)*name_type )); - return True; -} - -/***************************************************************** - *THE CANONICAL* convert SID to name function. - Tries winbind first - then uses local lookup. -*****************************************************************/ + DOM_SID sid; + fstring dom_name; + enum SID_NAME_USE name_type; -BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) -{ - if (!winbind_lookup_sid(sid, dom_name, name, name_type)) { - fstring sid_str; - DOM_SID tmp_sid; - uint32 rid; + if (!winbind_uid_to_sid(&sid, uid)) + return False; + if (!winbind_lookup_sid(&sid, dom_name, name, &name_type)) + return False; - DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) )); + if (name_type != SID_NAME_USER) + return False; - sid_copy(&tmp_sid, sid); - sid_split_rid(&tmp_sid, &rid); - return map_domain_sid_to_name(&tmp_sid, dom_name) && - lookup_known_rid(&tmp_sid, rid, name, name_type); - } return True; } -/***************************************************************** - *THE CANONICAL* convert uid_t to SID function. - Tries winbind first - then uses local lookup. - Returns SID pointer. -*****************************************************************/ +/********************************************************************************** + Utility function. Convert a gid_t to a name if possible. +**********************************************************************************/ -DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) +BOOL winbind_gidtoname(fstring name, gid_t gid) { - fstring sid; - - if (!winbind_uid_to_sid(psid, uid)) { - DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid )); - - return local_uid_to_sid(psid, uid); - } - - DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", - (unsigned int)uid, sid_to_string(sid, psid) )); - - return psid; -} - -/***************************************************************** - *THE CANONICAL* convert gid_t to SID function. - Tries winbind first - then uses local lookup. - Returns SID pointer. -*****************************************************************/ - -DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) -{ - fstring sid; - - if (!winbind_gid_to_sid(psid, gid)) { - DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid )); - - return local_gid_to_sid(psid, gid); - } - - DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", - (unsigned int)gid, sid_to_string(sid,psid) )); - - return psid; -} - -/***************************************************************** - *THE CANONICAL* convert SID to uid function. - Tries winbind first - then uses local lookup. - Returns True if this name is a user sid and the conversion - was done correctly, False if not. -*****************************************************************/ - -BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) -{ - fstring dom_name, name, sid_str; + DOM_SID sid; + fstring dom_name; enum SID_NAME_USE name_type; - *sidtype = SID_NAME_UNKNOWN; - - /* - * First we must look up the name and decide if this is a user sid. - */ - - if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { - DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", - sid_to_string(sid_str, psid) )); - - return local_sid_to_uid(puid, psid, sidtype); - } - - /* - * Ensure this is a user sid. - */ - - if (name_type != SID_NAME_USER) { - DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n", - (unsigned int)name_type )); + if (!winbind_gid_to_sid(&sid, gid)) return False; - } - - *sidtype = SID_NAME_USER; - - /* - * Get the uid for this SID. - */ - - if (!winbind_sid_to_uid(puid, psid)) { - DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", - sid_to_string(sid_str, psid) )); + if (!winbind_lookup_sid(&sid, dom_name, name, &name_type)) return False; - } - DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", - sid_to_string(sid_str, psid), - (unsigned int)*puid )); + if (name_type != SID_NAME_USER) + return False; return True; } -/***************************************************************** - *THE CANONICAL* convert SID to gid function. - Tries winbind first - then uses local lookup. - Returns True if this name is a user sid and the conversion - was done correctly, False if not. -*****************************************************************/ +/********************************************************************************** + Utility function. Convert a name to a uid_t if possible. +**********************************************************************************/ -BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) +BOOL winbind_nametouid(uid_t *puid, char *name) { - fstring dom_name, name, sid_str; + DOM_SID sid; enum SID_NAME_USE name_type; - *sidtype = SID_NAME_UNKNOWN; - - /* - * First we must look up the name and decide if this is a group sid. - */ + if (!winbind_lookup_name(name, &sid, &name_type)) { + return False; + } - if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", - sid_to_string(sid_str, psid) )); - - return local_sid_to_gid(pgid, psid, sidtype); - } - - /* - * Ensure this is a group sid. - */ + if (name_type != SID_NAME_USER) + return False; - if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { - DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a know group (%u)\n", - (unsigned int)name_type )); + return winbind_sid_to_uid(puid, &sid); +} - return local_sid_to_gid(pgid, psid, sidtype); - } +/********************************************************************************** + Utility function. Convert a name to a gid_t if possible. +**********************************************************************************/ - *sidtype = name_type; +BOOL winbind_nametogid(gid_t *pgid, char *gname) +{ + DOM_SID g_sid; + enum SID_NAME_USE name_type; - /* - * Get the gid for this SID. - */ + if (!winbind_lookup_name(gname, &g_sid, &name_type)) { + return False; + } - if (!winbind_sid_to_gid(pgid, psid)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", - sid_to_string(sid_str, psid) )); + if (name_type != SID_NAME_DOM_GRP) return False; - } - - DEBUG(10,("gid_to_uid: winbindd %s -> %u\n", - sid_to_string(sid_str, psid), - (unsigned int)*pgid )); - return True; + return winbind_sid_to_gid(pgid, &g_sid); } diff --git a/source/smbd/groupname.c b/source/smbd/groupname.c index f0b11e1b366..d53fa56a44f 100644 --- a/source/smbd/groupname.c +++ b/source/smbd/groupname.c @@ -119,7 +119,7 @@ void load_groupname_map(void) for (i=0; lines[i]; i++) { pstring unixname; pstring windows_name; - struct group *gptr; + gid_t gid; DOM_SID tmp_sid; char *s = lines[i]; @@ -150,8 +150,8 @@ void load_groupname_map(void) * Attempt to get the unix gid_t for this name. */ - if((gptr = (struct group *)getgrnam(unixname)) == NULL) { - DEBUG(0,("load_groupname_map: getgrnam for group %s failed.\ + if ((gid = nametogid(unixname)) == (gid_t)-1) + DEBUG(0,("load_groupname_map: nametogid for group %s failed.\ Error was %s.\n", unixname, strerror(errno) )); continue; } @@ -167,7 +167,7 @@ Error was %s.\n", unixname, strerror(errno) )); */ tmp_sid = global_sam_sid; tmp_sid.sub_auths[tmp_sid.num_auths++] = - pdb_gid_to_group_rid((gid_t)gptr->gr_gid); + pdb_gid_to_group_rid(gid); } /* @@ -180,7 +180,7 @@ Error was %s.\n", unixname, strerror(errno) )); return; } - new_ep->unix_gid = gptr->gr_gid; + new_ep->unix_gid = gid; new_ep->windows_sid = tmp_sid; new_ep->windows_name = strdup( windows_name ); new_ep->unix_name = strdup( unixname ); diff --git a/source/smbd/service.c b/source/smbd/service.c index 6d075627438..b86f3beadda 100644 --- a/source/smbd/service.c +++ b/source/smbd/service.c @@ -401,7 +401,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int */ if (*lp_force_group(snum)) { - struct group *gptr; + gid_t gid; pstring gname; pstring tmp_gname; BOOL user_must_be_member = False; @@ -416,9 +416,9 @@ connection_struct *make_connection(char *service,char *user,char *password, int } /* default service may be a group name */ pstring_sub(gname,"%S",service); - gptr = (struct group *)getgrnam(gname); + gid = nametogid(gname); - if (gptr) { + if (gid != (gid_t)-1) { /* * If the user has been forced and the forced group starts * with a '+', then we only set the group to be the forced @@ -426,16 +426,12 @@ connection_struct *make_connection(char *service,char *user,char *password, int * Otherwise, the meaning of the '+' would be ignored. */ if (conn->force_user && user_must_be_member) { - int i; - for (i = 0; gptr->gr_mem[i] != NULL; i++) { - if (strcmp(user,gptr->gr_mem[i]) == 0) { - conn->gid = gptr->gr_gid; + if (user_in_group_list( user, gname )) { + conn->gid = gid; DEBUG(3,("Forced group %s for member %s\n",gname,user)); - break; - } } } else { - conn->gid = gptr->gr_gid; + conn->gid = gid; DEBUG(3,("Forced group %s\n",gname)); } } else { diff --git a/source/smbd/uid.c b/source/smbd/uid.c index b28f056a301..fb83e724b8b 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -257,4 +257,230 @@ void unbecome_root(void) pop_sec_ctx(); } +/***************************************************************** + *THE CANONICAL* convert name to SID function. + Tries winbind first - then uses local lookup. +*****************************************************************/ + +BOOL lookup_name(char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) +{ + extern pstring global_myname; + fstring sid; + + if (!winbind_lookup_name(name, psid, name_type)) { + BOOL ret; + + DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name )); + + ret = local_lookup_name(global_myname, name, psid, name_type); + if (ret) + DEBUG(10,("lookup_name : (local) %s -> SID %s (type %u)\n", + name, sid_to_string(sid,psid), + (unsigned int)*name_type )); + else + DEBUG(10,("lookup name : (local) %s failed.\n", + name )); + return ret; + } + + DEBUG(10,("lookup_name (winbindd): %s -> SID %s (type %u)\n", + name, sid_to_string(sid,psid), (unsigned int)*name_type )); + return True; +} + +/***************************************************************** + *THE CANONICAL* convert SID to name function. + Tries winbind first - then uses local lookup. +*****************************************************************/ + +BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) +{ + if (!name_type) + return False; + + /* Check if this is our own sid. This should perhaps be done by + winbind? For the moment handle it here. */ + + if (sid->num_auths == 5) { + DOM_SID tmp_sid; + uint32 rid; + + sid_copy(&tmp_sid, sid); + sid_split_rid(&tmp_sid, &rid); + + if (sid_equal(&global_sam_sid, &tmp_sid)) { + + return map_domain_sid_to_name(&tmp_sid, dom_name) && + local_lookup_rid(rid, name, name_type); + } + } + + if (!winbind_lookup_sid(sid, dom_name, name, name_type)) { + fstring sid_str; + DOM_SID tmp_sid; + uint32 rid; + + DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) )); + + sid_copy(&tmp_sid, sid); + sid_split_rid(&tmp_sid, &rid); + return map_domain_sid_to_name(&tmp_sid, dom_name) && + lookup_known_rid(&tmp_sid, rid, name, name_type); + } + return True; +} + +/***************************************************************** + *THE CANONICAL* convert uid_t to SID function. + Tries winbind first - then uses local lookup. + Returns SID pointer. +*****************************************************************/ + +DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) +{ + fstring sid; + + if (!winbind_uid_to_sid(psid, uid)) { + DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid )); + + return local_uid_to_sid(psid, uid); + } + + DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", + (unsigned int)uid, sid_to_string(sid, psid) )); + + return psid; +} + +/***************************************************************** + *THE CANONICAL* convert gid_t to SID function. + Tries winbind first - then uses local lookup. + Returns SID pointer. +*****************************************************************/ + +DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) +{ + fstring sid; + + if (!winbind_gid_to_sid(psid, gid)) { + DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid )); + + return local_gid_to_sid(psid, gid); + } + + DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", + (unsigned int)gid, sid_to_string(sid,psid) )); + + return psid; +} + +/***************************************************************** + *THE CANONICAL* convert SID to uid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) +{ + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; + + *sidtype = SID_NAME_UNKNOWN; + + /* + * First we must look up the name and decide if this is a user sid. + */ + + if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { + DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", + sid_to_string(sid_str, psid) )); + + return local_sid_to_uid(puid, psid, sidtype); + } + + /* + * Ensure this is a user sid. + */ + + if (name_type != SID_NAME_USER) { + DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n", + (unsigned int)name_type )); + return False; + } + + *sidtype = SID_NAME_USER; + + /* + * Get the uid for this SID. + */ + + if (!winbind_sid_to_uid(puid, psid)) { + DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + return False; + } + + DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", + sid_to_string(sid_str, psid), + (unsigned int)*puid )); + + return True; +} + +/***************************************************************** + *THE CANONICAL* convert SID to gid function. + Tries winbind first - then uses local lookup. + Returns True if this name is a user sid and the conversion + was done correctly, False if not. +*****************************************************************/ + +BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) +{ + fstring dom_name, name, sid_str; + enum SID_NAME_USE name_type; + + *sidtype = SID_NAME_UNKNOWN; + + /* + * First we must look up the name and decide if this is a group sid. + */ + + if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", + sid_to_string(sid_str, psid) )); + + return local_sid_to_gid(pgid, psid, sidtype); + } + + /* + * Ensure this is a group sid. + */ + + if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { + DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a know group (%u)\n", + (unsigned int)name_type )); + + return local_sid_to_gid(pgid, psid, sidtype); + } + + *sidtype = name_type; + + /* + * Get the gid for this SID. + */ + + if (!winbind_sid_to_gid(pgid, psid)) { + DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", + sid_to_string(sid_str, psid) )); + return False; + } + + DEBUG(10,("gid_to_uid: winbindd %s -> %u\n", + sid_to_string(sid_str, psid), + (unsigned int)*pgid )); + + return True; +} + #undef OLD_NTDOMAIN |