diff options
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/username.c | 130 | ||||
-rw-r--r-- | source3/lib/util.c | 50 |
2 files changed, 148 insertions, 32 deletions
diff --git a/source3/lib/username.c b/source3/lib/username.c index ad44c0c544..32e9eb3188 100644 --- a/source3/lib/username.c +++ b/source3/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/source3/lib/util.c b/source3/lib/util.c index aced56bc2f..0aef60082f 100644 --- a/source3/lib/util.c +++ b/source3/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; |