diff options
author | Christian Ambach <christian.ambach@de.ibm.com> | 2011-03-14 08:08:58 -0400 |
---|---|---|
committer | Volker Lendecke <vlendec@samba.org> | 2011-03-19 10:09:38 +0100 |
commit | ed46dfc4f16e230645fae5f3b3b21c462694c30a (patch) | |
tree | 30abbeaf2e146efb9125bcf7716d74a6ed5db283 /source3/lib | |
parent | 98e4ef09f4ee9ecbf4e7d6411cfc658f908eda2e (diff) | |
download | samba-ed46dfc4f16e230645fae5f3b3b21c462694c30a.tar.gz samba-ed46dfc4f16e230645fae5f3b3b21c462694c30a.tar.bz2 samba-ed46dfc4f16e230645fae5f3b3b21c462694c30a.zip |
s3: use getgrset() when it is available
When getgrouplist() is not defined, use getgrset() if it is defined
instead of using the initgroups() + getgroups() combo
Major contributions from Yannick Bergeron <yaberger@ca.ibm.com>
Autobuild-User: Volker Lendecke <vlendec@samba.org>
Autobuild-Date: Sat Mar 19 10:09:38 CET 2011 on sn-devel-104
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/system_smbd.c | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/source3/lib/system_smbd.c b/source3/lib/system_smbd.c index 3bb2c4240b..12538c4434 100644 --- a/source3/lib/system_smbd.c +++ b/source3/lib/system_smbd.c @@ -28,6 +28,56 @@ #ifndef HAVE_GETGROUPLIST +#ifdef HAVE_GETGRSET +static int getgrouplist_getgrset(const char *user, gid_t gid, gid_t *groups, + int *grpcnt) +{ + char *grplist; + char *grp; + gid_t temp_gid; + int num_gids = 1; + int ret = 0; + long l; + + grplist = getgrset(user); + + DEBUG(10, ("getgrset returned %s\n", grplist)); + + if (grplist == NULL) { + return -1; + } + + if (*grpcnt > 0) { + groups[0] = gid; + } + + while ((grp = strsep(&grplist, ",")) != NULL) { + l = strtol(grp, NULL, 10); + temp_gid = (gid_t) l; + if (temp_gid == gid) { + continue; + } + + if (num_gids + 1 > *grpcnt) { + num_gids++; + continue; + } + groups[num_gids++] = temp_gid; + } + free(grplist); + + if (num_gids > *grpcnt) { + ret = -1; + } + *grpcnt = num_gids; + + DEBUG(10, ("Found %d groups for user %s\n", *grpcnt, user)); + + return ret; +} + +#else /* HAVE_GETGRSET */ + /* This is a *much* faster way of getting the list of groups for a user without changing the current supplementary group list. The old @@ -113,7 +163,8 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, free(gids_saved); return ret; } -#endif +#endif /* HAVE_GETGRSET */ +#endif /* HAVE_GETGROUPLIST */ static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt) { @@ -131,10 +182,14 @@ static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grp #ifdef HAVE_GETGROUPLIST retval = getgrouplist(user, gid, groups, grpcnt); #else +#ifdef HAVE_GETGRSET + retval = getgrouplist_getgrset(user, gid, groups, grpcnt); +#else become_root(); retval = getgrouplist_internals(user, gid, groups, grpcnt); unbecome_root(); -#endif +#endif /* HAVE_GETGRSET */ +#endif /* HAVE_GETGROUPLIST */ /* allow winbindd lookups, but only if they were not already disabled */ if (!winbind_env) { |