diff options
-rw-r--r-- | source/lib/replace.c | 2 | ||||
-rw-r--r-- | source/lib/system.c | 59 | ||||
-rw-r--r-- | source/smbd/uid.c | 8 |
3 files changed, 63 insertions, 6 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 */ diff --git a/source/smbd/uid.c b/source/smbd/uid.c index 8eb34e24063..09f8a4220a3 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -245,9 +245,9 @@ BOOL become_user(connection_struct *conn, uint16 vuid) if (!(conn && conn->ipc)) { /* groups stuff added by ih/wreu */ if (current_user.ngroups > 0) - if (setgroups(current_user.ngroups, + if (sys_setgroups(current_user.ngroups, current_user.groups)<0) { - DEBUG(0,("setgroups call failed!\n")); + DEBUG(0,("sys_setgroups call failed!\n")); } } #endif @@ -356,9 +356,9 @@ void unbecome_root(BOOL restore_dir) #ifdef HAVE_SETGROUPS if (current_user_saved.ngroups > 0) { - if (setgroups(current_user_saved.ngroups, + if (sys_setgroups(current_user_saved.ngroups, current_user_saved.groups)<0) - DEBUG(0,("ERROR: setgroups call failed!\n")); + DEBUG(0,("ERROR: sys_setgroups call failed!\n")); } #endif |