From ed46dfc4f16e230645fae5f3b3b21c462694c30a Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Mon, 14 Mar 2011 08:08:58 -0400 Subject: 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 Autobuild-User: Volker Lendecke Autobuild-Date: Sat Mar 19 10:09:38 CET 2011 on sn-devel-104 --- source3/configure.in | 1 + source3/lib/system_smbd.c | 59 +++++++++++++++++++++++++++++++++++++++++++++-- source3/wscript | 2 +- 3 files changed, 59 insertions(+), 3 deletions(-) (limited to 'source3') diff --git a/source3/configure.in b/source3/configure.in index 74df9d4836..6033b0b13b 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1070,6 +1070,7 @@ AC_CHECK_FUNCS(fdatasync,,[AC_CHECK_LIB_EXT(rt, LIBS, fdatasync)]) AC_CHECK_FUNCS(setsid glob strpbrk crypt16 getauthuid) AC_CHECK_FUNCS(sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent) AC_CHECK_FUNCS(initgroups select rdchk getgrnam getgrent pathconf) +AC_CHECK_FUNCS(getgrset) AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf stat64 fstat64) AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt lseek64 ftruncate64 posix_fallocate posix_fallocate64) AC_CHECK_FUNCS(fallocate fallocate64) 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) { @@ -130,11 +181,15 @@ 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) { diff --git a/source3/wscript b/source3/wscript index 9fcf173065..e8bd62598b 100644 --- a/source3/wscript +++ b/source3/wscript @@ -269,7 +269,7 @@ _fork __fork fremoveea fremovexattr fseek64 fseeko64 fsetea fsetproplist fsetxattr _fstat __fstat fstat64 _fstat64 __fstat64 fsync ftell64 ftello64 ftruncate64 futimens futimes __fxstat getauthuid getcwd _getcwd __getcwd getdents __getdents getdents64 getdirentries -getgrent getgrnam getgrouplist getmntent getpagesize +getgrent getgrnam getgrouplist getgrset getmntent getpagesize getproplist get_proplist_entry getpwanam getpwent_r getrlimit gettext glob grantpt hstrerror initgroups innetgr inotify_init lgetea lgetxattr listea listxattr llistea llistxattr -- cgit