diff options
Diffstat (limited to 'source/lib')
-rw-r--r-- | source/lib/replace.c | 2 | ||||
-rw-r--r-- | source/lib/system.c | 59 |
2 files changed, 59 insertions, 2 deletions
diff --git a/source/lib/replace.c b/source/lib/replace.c index a768e9ce47a..632e80f5905 100644 --- a/source/lib/replace.c +++ b/source/lib/replace.c @@ -187,7 +187,7 @@ Corrections by richard.kettlewell@kewill.com } } endgrent(); - return(setgroups(i,grouplst)); + return(sys_setgroups(i,grouplst)); #endif /* HAVE_SETGROUPS */ } #endif /* HAVE_INITGROUPS */ diff --git a/source/lib/system.c b/source/lib/system.c index 9655abd9b9e..a42e80a1980 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -537,7 +537,8 @@ int sys_getgroups(int setlen, gid_t *gidset) return -1; } - if (setlen == 0) setlen = 1; + if (setlen == 0) + setlen = 1; if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) { DEBUG(0,("sys_getgroups: Malloc fail.\n")); @@ -558,3 +559,59 @@ int sys_getgroups(int setlen, gid_t *gidset) return ngroups; #endif /* HAVE_BROKEN_GETGROUPS */ } + +#ifdef HAVE_SETGROUPS + +/************************************************************************** + Wrapper for setgroups. Deals with broken (int) case. Automatically used + if we have broken getgroups. +****************************************************************************/ + +int sys_setgroups(int setlen, gid_t *gidset) +{ +#if !defined(HAVE_BROKEN_GETGROUPS) + return setgroups(setlen, gidset); +#else + + GID_T *group_list; + int i ; + + if (setlen == 0) + return 0 ; + +#ifdef NGROUPS_MAX + if (setlen > NGROUPS_MAX) { + errno = EINVAL; + return -1; + } +#endif + + /* + * Broken case. We need to allocate a + * GID_T array of size setlen. + */ + + if (setlen == 0) + setlen = 1; + + if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) { + DEBUG(0,("sys_setgroups: Malloc fail.\n")); + return -1; + } + + for(i = 0; i < setlen; i++) + group_list[i] = (GID_T) gidset[i]; + + if(setgroups(setlen, group_list) != 0) { + int saved_errno = errno; + free((char *)group_list); + errno = saved_errno; + return -1; + } + + free((char *)group_list); + return 0 ; +#endif /* HAVE_BROKEN_GETGROUPS */ +} + +#endif /* HAVE_SETGROUPS */ |