diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2011-10-28 13:26:42 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2011-10-28 13:26:42 +0400 |
commit | 0c1d8aaaf1cfe49fdb18edba36c679b601c2c0e9 (patch) | |
tree | 5eb83b73b411f43e3a557c04ff398d5cc0dde7aa /winsup | |
parent | c85feb40a2c760ab12200c34eface647883ea39a (diff) |
* cygwin.din (getgrouplist): Export.
* grp.cc (get_groups): New static function to run the core functionality
of initgroups and getgrouplist.
(initgroups32): Call get_groups and just create supplementary group
list in cygheap. Rename name of first argument to "user". Add an
assertion to test for a NULL user name.
(initgroups): Rename name of first argument to "user".
(getgrouplist): New function.
* posix.sgml (std-bsd): Add getgrouplist.
* include/cygwin/grp.h (getgrouplist): Declare.
* include/cygwin/version.h: Bump API minor number.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 14 | ||||
-rw-r--r-- | winsup/cygwin/cygwin.din | 1 | ||||
-rw-r--r-- | winsup/cygwin/grp.cc | 83 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/grp.h | 4 | ||||
-rw-r--r-- | winsup/cygwin/include/cygwin/version.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/posix.sgml | 1 |
6 files changed, 86 insertions, 20 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index bf71c0d25..2ad220cb4 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,17 @@ +2011-10-28 Corinna Vinschen <corinna@vinschen.de> + + * cygwin.din (getgrouplist): Export. + * grp.cc (get_groups): New static function to run the core functionality + of initgroups and getgrouplist. + (initgroups32): Call get_groups and just create supplementary group + list in cygheap. Rename name of first argument to "user". Add an + assertion to test for a NULL user name. + (initgroups): Rename name of first argument to "user". + (getgrouplist): New function. + * posix.sgml (std-bsd): Add getgrouplist. + * include/cygwin/grp.h (getgrouplist): Declare. + * include/cygwin/version.h: Bump API minor number. + 2011-10-25 Christopher Faylor <me.cygwin2011@cgf.cx> * child_info.h (cchildren): New struct. diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index c8c66c48c..594edda9f 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -716,6 +716,7 @@ getgrnam SIGFE _getgrnam = getgrnam SIGFE _getgrnam32 = getgrnam32 SIGFE getgrnam_r SIGFE +getgrouplist SIGFE getgroups SIGFE _getgroups = getgroups SIGFE _getgroups32 = getgroups32 SIGFE diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index dac51ed0a..182732f75 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -13,6 +13,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" +#include <assert.h> #include <stdio.h> #include <stdlib.h> #include "cygerrno.h" @@ -419,40 +420,86 @@ getgroups (int gidsetsize, __gid16_t *grouplist) return ret; } -extern "C" int -initgroups32 (const char *name, __gid32_t gid) +/* Core functionality of initgroups and getgrouplist. */ +static int +get_groups (const char *user, gid_t gid, cygsidlist &gsids) { int ret = -1; cygheap->user.deimpersonate (); - struct passwd *pw = internal_getpwnam (name); + struct passwd *pw = internal_getpwnam (user); struct __group32 *gr = internal_getgrgid (gid); cygsid usersid, grpsid; if (!usersid.getfrompw (pw) || !grpsid.getfromgr (gr)) set_errno (EINVAL); - else + else if (get_server_groups (gsids, usersid, pw)) { - cygsidlist tmp_gsids (cygsidlist_auto, 12); - if (get_server_groups (tmp_gsids, usersid, pw)) - { - tmp_gsids += grpsid; - cygsidlist new_gsids (cygsidlist_alloc, tmp_gsids.count ()); - for (int i = 0; i < tmp_gsids.count (); i++) - new_gsids.sids[i] = tmp_gsids.sids[i]; - new_gsids.count (tmp_gsids.count ()); - cygheap->user.groups.update_supp (new_gsids); - ret = 0; - } + gsids += grpsid; + ret = 0; } cygheap->user.reimpersonate (); - syscall_printf ( "%d = initgroups (%s, %u)", ret, name, gid); return ret; } extern "C" int -initgroups (const char *name, __gid16_t gid) +initgroups32 (const char *user, __gid32_t gid) +{ + int ret; + + assert (user != NULL); + cygsidlist tmp_gsids (cygsidlist_auto, 12); + if (!(ret = get_groups (user, gid, tmp_gsids))) + { + cygsidlist new_gsids (cygsidlist_alloc, tmp_gsids.count ()); + for (int i = 0; i < tmp_gsids.count (); i++) + new_gsids.sids[i] = tmp_gsids.sids[i]; + new_gsids.count (tmp_gsids.count ()); + cygheap->user.groups.update_supp (new_gsids); + } + syscall_printf ( "%d = initgroups (%s, %u)", ret, user, gid); + return ret; +} + +extern "C" int +initgroups (const char *user, __gid16_t gid) { - return initgroups32 (name, gid16togid32(gid)); + return initgroups32 (user, gid16togid32(gid)); +} + +extern "C" int +getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups) +{ + int ret; + + /* Note that it's not defined if groups or ngroups may be NULL! + GLibc does not check the pointers on entry and just uses them. + FreeBSD calls assert for ngroups and allows a NULL groups if + *ngroups is 0. We follow FreeBSD's lead here, but always allow + a NULL groups pointer. */ + assert (user != NULL); + assert (ngroups != NULL); + + cygsidlist tmp_gsids (cygsidlist_auto, 12); + if (!(ret = get_groups (user, gid, tmp_gsids))) + { + int cnt = 0; + for (int i = 0; i < tmp_gsids.count (); i++) + { + struct __group32 *gr = internal_getgrsid (tmp_gsids.sids[i]); + if (gr) + { + if (groups && cnt < *ngroups) + groups[cnt] = gr->gr_gid; + ++cnt; + } + } + if (cnt > *ngroups) + ret = -1; + *ngroups = cnt; + } + syscall_printf ( "%d = getgrouplist (%s, %u, %p, %d)", + ret, user, gid, groups, *ngroups); + return ret; } /* setgroups32: standards? */ diff --git a/winsup/cygwin/include/cygwin/grp.h b/winsup/cygwin/include/cygwin/grp.h index 7dcae637d..b990b25ac 100644 --- a/winsup/cygwin/include/cygwin/grp.h +++ b/winsup/cygwin/include/cygwin/grp.h @@ -1,6 +1,6 @@ /* cygwin/grp.h - Copyright 2002 Red Hat Inc. + Copyright 2002, 2011 Red Hat Inc. Written by Corinna Vinschen <corinna@vinschen.de> This file is part of Cygwin. @@ -41,6 +41,8 @@ __gid32_t getgid32 (); __gid32_t getegid32 (); #endif +extern int getgrouplist (const char *, gid_t, gid_t *, int *); + #ifdef __cplusplus } #endif diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index 480b0ff47..27dccf27c 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -422,12 +422,13 @@ details. */ 251: RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND added. 252: CW_CVT_ENV_TO_WINENV added. 253: Export TIOCSCTTY, tcgetsid. + 254: Export getgrouplist. */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 253 +#define CYGWIN_VERSION_API_MINOR 254 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/posix.sgml b/winsup/cygwin/posix.sgml index 5c92f53f4..ef27fde32 100644 --- a/winsup/cygwin/posix.sgml +++ b/winsup/cygwin/posix.sgml @@ -989,6 +989,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para> gammaf gammaf_r getdtablesize + getgrouplist getifaddrs getpagesize getpeereid |