summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-10-13 01:59:14 +0000
committerJeremy Allison <jra@samba.org>2000-10-13 01:59:14 +0000
commit330d678fbad70fabd9712c56ad15bd215f950255 (patch)
treedf834b65049fb3c675119cf6acfefa167cb96376 /source3/lib
parenta7f8d8b6362f4c2970fee63130963734528bcb6e (diff)
downloadsamba-330d678fbad70fabd9712c56ad15bd215f950255.tar.gz
samba-330d678fbad70fabd9712c56ad15bd215f950255.tar.bz2
samba-330d678fbad70fabd9712c56ad15bd215f950255.zip
Fix to allow smbd to call winbindd if it is running for all group enumeration,
falling back to the UNIX calls on error. This should fix all problems with smbd enumerating all users in all groups in all trusted domains via winbindd. Also changed GETDC to query 1C name rather than 1b name as only the PDC registers 1b. Jeremy. (This used to be commit 5b0038a2afd8abbd6fd4a58f5477a40d1926d498)
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;