getgrouplist is available in uClibc since 0.9.30 (s. http://git.uclibc.org/uClibc/commit/libc/pwd_grp/pwd_grp.c?id=9385a9419d98aeb56fe54b7452d1310ef20cea95) check if it's available and provide a replacement if necessary --- config.h.in +++ config.h.in @@ -21,6 +21,9 @@ /* Define to 1 if you have the `getgrnam_r' function. */ #undef HAVE_GETGRNAM_R +/* Define to 1 if you have the `getgrouplist' function. */ +#undef HAVE_GETGROUPLIST + /* Define to 1 if getgrouplist() takes ints as arguments */ #undef HAVE_GETGROUPLIST_TAKES_INTS --- configure.ac +++ configure.ac @@ -34,7 +34,7 @@ dnl Prefer thread-safe functions, if available AC_CHECK_FUNCS([getgrgid_r getgrnam_r gethostbyname_r getpwnam_r getpwuid_r \ - openpty strcasestr getresuid getresgid setresuid setresgid ]) + openpty strcasestr getresuid getresgid setresuid setresgid getgrouplist ]) dnl We prefer ptsname_r(), but will settle for ptsname() if necessary AC_TRY_LINK([#ifndef _XOPEN_SOURCE --- configure +++ configure @@ -10655,7 +10655,7 @@ for ac_func in getgrgid_r getgrnam_r gethostbyname_r getpwnam_r getpwuid_r \ - openpty strcasestr getresuid getresgid setresuid setresgid + openpty strcasestr getresuid getresgid setresuid setresgid getgrouplist do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" --- shellinabox/launcher.c +++ shellinabox/launcher.c @@ -170,6 +170,47 @@ static int launcher = -1; static uid_t restricted; +#if !defined(HAVE_GETGROUPLIST) +/* + * define own getgrouplist + * based on the freebsd implementation (s. http://svnweb.freebsd.org/base/stable/9/lib/libc/gen/getgrouplist.c?revision=165903&view=markup) + * modified to support calls like getgrouplist(*, *, NULL, *) + */ +int +getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) +{ + const struct group *grp; + int i, maxgroups, ngroups; + + maxgroups = *grpcnt; + + if (groups) + groups[0] = agroup; + ngroups = 1; + + /* + * Scan the group file to find additional groups. + */ + setgrent(); + while ((grp = getgrent()) != NULL) { + if (grp->gr_gid == agroup) + continue; + for (i = 0; grp->gr_mem[i]; i++) { + if (strcmp(grp->gr_mem[i], uname) == 0) { + if (groups && ngroups < maxgroups) + groups[ngroups] = grp->gr_gid; + ngroups++; + break; + } + } + } + endgrent(); + + *grpcnt = ngroups; + return (ngroups > maxgroups) ? -1 : ngroups; +} +#endif + // MacOS X has a somewhat unusual definition of getgrouplist() which can // trigger a compile warning. #if defined(HAVE_GETGROUPLIST_TAKES_INTS)