diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2005-04-16 15:21:47 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2005-04-16 15:21:47 +0000 |
commit | 68a3f0d34af960ecb1da72ce70819189a3b6dd29 (patch) | |
tree | b06e50bb18f618e2fccf7f3e8073662f1929a28d /winsup/cygwin/grp.cc | |
parent | 00c05edcf1457ce2b6a03892c095ced9e4d15465 (diff) | |
download | newlib-68a3f0d34af960ecb1da72ce70819189a3b6dd29.zip newlib-68a3f0d34af960ecb1da72ce70819189a3b6dd29.tar.gz newlib-68a3f0d34af960ecb1da72ce70819189a3b6dd29.tar.bz2 |
* security.h (cygsidlist::addfromgr): Allow duplicate entries.
(get_server_groups): Declare new function.
* security.cc (is_group_member): Simplify.
(get_server_groups): New function.
(get_initgroups_sidlist): Call get_server_groups.
(verify_token): Allow token when supplementary sids are not in
/etc/group but are in the token.
Streamline the code.
* grp.cc (initgroups32): New implementation.
(getgroups32): Handle case where the supplementary groups are set.
Diffstat (limited to 'winsup/cygwin/grp.cc')
-rw-r--r-- | winsup/cygwin/grp.cc | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index ae3c27a..c82a59f 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -344,14 +344,32 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) __gid32_t gid; const char *username; - if (allow_ntsec) + if (!srchsid && cygheap->user.groups.issetgroups ()) { - /* If impersonated, use impersonation token. */ - if (cygheap->user.issetuid ()) - hToken = cygheap->user.token (); - else - hToken = hProcImpToken; + cygsid sid; + for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx) + if (sid.getfromgr (gr)) + for (int pg = 0; pg < cygheap->user.groups.sgsids.count; ++pg) + if (sid == cygheap->user.groups.sgsids.sids[pg] && + sid != well_known_world_sid) + { + if (cnt < gidsetsize) + grouplist[cnt] = gr->gr_gid; + ++cnt; + if (gidsetsize && cnt > gidsetsize) + goto error; + break; + } + return cnt; } + + + /* If impersonated, use impersonation token. */ + if (cygheap->user.issetuid ()) + hToken = cygheap->user.token (); + else + hToken = hProcImpToken; + if (hToken) { if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size) @@ -450,9 +468,32 @@ getgroups (int gidsetsize, __gid16_t *grouplist) extern "C" int initgroups32 (const char *name, __gid32_t gid) { + int ret; if (wincap.has_security ()) - cygheap->user.groups.clear_supp (); - syscall_printf ( "0 = initgroups (%s, %u)", name, gid); + { + ret = -1; + struct passwd *pw = internal_getpwnam (name); + struct __group32 *gr = internal_getgrgid (gid); + cygsid usersid, grpsid; + if (!usersid.getfrompw (pw) || !grpsid.getfromgr (gr)) + { + set_errno (EINVAL); + goto out; + } + cygsidlist tmp_gsids (cygsidlist_auto, 12); + if (!get_server_groups (tmp_gsids, usersid, pw)) + goto out; + 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; + + out: + syscall_printf ( "%d = initgroups (%s, %u)", ret, name, gid); return 0; } |