summaryrefslogtreecommitdiff
path: root/source3/lib/username.c
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/username.c
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/username.c')
-rw-r--r--source3/lib/username.c130
1 files changed, 113 insertions, 17 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;
}
-