summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorChristian Ambach <christian.ambach@de.ibm.com>2011-03-14 08:08:58 -0400
committerVolker Lendecke <vlendec@samba.org>2011-03-19 10:09:38 +0100
commited46dfc4f16e230645fae5f3b3b21c462694c30a (patch)
tree30abbeaf2e146efb9125bcf7716d74a6ed5db283 /source3/lib
parent98e4ef09f4ee9ecbf4e7d6411cfc658f908eda2e (diff)
downloadsamba-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.c59
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) {