diff options
author | Christian Ambach <christian.ambach@de.ibm.com> | 2011-03-14 08:08:58 -0400 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2011-06-14 12:56:22 +0200 |
commit | cde942d2672bd81d0534c0260ebb1a3b41dc50f1 (patch) | |
tree | f4cb0eccc09a36477787163c34c0c8934fda71e2 /source3/lib | |
parent | 1804c7c22e322f680779c47a1593a0a526025587 (diff) | |
download | samba-cde942d2672bd81d0534c0260ebb1a3b41dc50f1.tar.gz |
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
(cherry picked from commit ed46dfc4f16e230645fae5f3b3b21c462694c30a)
Fix bug #8012 (Use getgrset() instead of initgroups() + getgroups() when
getgrouplist() is not defined).
(cherry picked from commit 64be11d41292fd2e9f6c13855fa6041b9290ce0c)
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 b22d15fb8a9..5b285b48734 100644 --- a/source3/lib/system_smbd.c +++ b/source3/lib/system_smbd.c @@ -27,6 +27,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 @@ -112,7 +162,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) { @@ -130,10 +181,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) { |