summaryrefslogtreecommitdiff
path: root/source3/lib/util_smbd.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2004-10-09 01:44:05 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:52:55 -0500
commit4792a8de3057dc9a6e6be43f618407ddb036484e (patch)
tree37459f627eea15c1cff1cf4e97f0a20636931221 /source3/lib/util_smbd.c
parent3d502114809854a49fab0ff6c14cb6a51a07ab85 (diff)
downloadsamba-4792a8de3057dc9a6e6be43f618407ddb036484e.tar.gz
samba-4792a8de3057dc9a6e6be43f618407ddb036484e.tar.bz2
samba-4792a8de3057dc9a6e6be43f618407ddb036484e.zip
r2868: Well, I'm not quite sure what I'm doing back in Samba 3.0, but anyway...
I've been grumbling about under-efficient calls in SAMR, and finally got around to fixing some of them. We now call sys_getgroups() (which in turn calls initgroups(), until glibc 3.4 is released) to figure out a user's group membership. This is far, far more efficient than scanning all the groups looking for a match, and is still the 'posix way', just using an effiecient call. The seperate issue of 'who is in this group' remains, but this one has been biting some people. I need to talk to VL about how best to exersise nasty corner cases, but my initial tests hold strong. (The code is also much simpiler than before, which has to count for something :-) Andrew Bartlett (This used to be commit dc19f161698dab5b71d61fa2bacc7e7b8da5fbba)
Diffstat (limited to 'source3/lib/util_smbd.c')
-rw-r--r--source3/lib/util_smbd.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/source3/lib/util_smbd.c b/source3/lib/util_smbd.c
index 071f20b416..36c3104e55 100644
--- a/source3/lib/util_smbd.c
+++ b/source3/lib/util_smbd.c
@@ -37,29 +37,58 @@
NOTE! uses become_root() to gain correct priviages on systems
that lack a native getgroups() call (uses initgroups and getgroups)
*/
-int getgroups_user(const char *user, gid_t **groups)
+BOOL getgroups_user(const char *user, gid_t **ret_groups, int *ngroups)
{
struct passwd *pwd;
int ngrp, max_grp;
+ gid_t *temp_groups;
+ gid_t *groups;
+ int i;
pwd = getpwnam_alloc(user);
- if (!pwd) return -1;
+ if (!pwd) return False;
max_grp = groups_max();
- (*groups) = (gid_t *)malloc(sizeof(gid_t) * max_grp);
- if (! *groups) {
+ temp_groups = (gid_t *)malloc(sizeof(gid_t) * max_grp);
+ if (! temp_groups) {
passwd_free(&pwd);
- errno = ENOMEM;
- return -1;
+ return False;
}
- ngrp = sys_getgrouplist(user, pwd->pw_gid, *groups, &max_grp);
- if (ngrp <= 0) {
- passwd_free(&pwd);
- free(*groups);
- return ngrp;
+ if (sys_getgrouplist(user, pwd->pw_gid, temp_groups, &max_grp) == -1) {
+
+ gid_t *groups_tmp;
+
+ groups_tmp = Realloc(temp_groups, sizeof(gid_t) * max_grp);
+
+ if (!groups_tmp) {
+ SAFE_FREE(temp_groups);
+ return False;
+ }
+ temp_groups = groups_tmp;
+
+ if (sys_getgrouplist(user, pwd->pw_gid, temp_groups, &max_grp) == -1) {
+ DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
+ passwd_free(&pwd);
+ SAFE_FREE(temp_groups);
+ return False;
+ }
}
+
+ ngrp = 0;
+ groups = NULL;
+
+ /* Add in primary group first */
+ add_gid_to_array_unique(pwd->pw_gid, &groups, &ngrp);
passwd_free(&pwd);
- return ngrp;
+
+ for (i=0; i<max_grp; i++)
+ add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
+
+ *ngroups = ngrp;
+ *ret_groups = groups;
+ SAFE_FREE(temp_groups);
+ return True;
}
+