* 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.
This commit is contained in:
Corinna Vinschen 2011-10-28 09:26:42 +00:00
parent c85feb40a2
commit 0c1d8aaaf1
6 changed files with 86 additions and 20 deletions

View file

@ -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.

View file

@ -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

View file

@ -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)
{
return initgroups32 (name, gid16togid32(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 (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? */

View file

@ -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

View file

@ -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

View file

@ -989,6 +989,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
gammaf
gammaf_r
getdtablesize
getgrouplist
getifaddrs
getpagesize
getpeereid