summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/username.c130
-rw-r--r--source3/lib/util.c50
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;