diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2002-11-14 19:19:39 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2002-11-14 19:19:39 +0000 |
commit | 4ce377c9d46006e1dfa02deba260ee86224517b5 (patch) | |
tree | 71ff520ea725606a38ea78b3823aed3c163e9c16 | |
parent | 69920bb5bd131f0d334b4eefc47fee7c5fec98a2 (diff) | |
download | cygnal-4ce377c9d46006e1dfa02deba260ee86224517b5.tar.gz cygnal-4ce377c9d46006e1dfa02deba260ee86224517b5.tar.bz2 cygnal-4ce377c9d46006e1dfa02deba260ee86224517b5.zip |
* grp.cc (getgroups32): Revert previous patch. Use impersonation
token if process is in impersonated state.
* sec_helper.cc (is_grp_member): Rewrite. Call getgroups32 only
for current user. Scan passwd and group info otherwise.
-rw-r--r-- | winsup/cygwin/ChangeLog | 7 | ||||
-rw-r--r-- | winsup/cygwin/grp.cc | 15 | ||||
-rw-r--r-- | winsup/cygwin/sec_helper.cc | 57 |
3 files changed, 62 insertions, 17 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index da0dfbbbd..e2f573e43 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2002-11-14 Corinna Vinschen <corinna@vinschen.de> + + * grp.cc (getgroups32): Revert previous patch. Use impersonation + token if process is in impersonated state. + * sec_helper.cc (is_grp_member): Rewrite. Call getgroups32 only + for current user. Scan passwd and group info otherwise. + 2002-11-14 Christopher Faylor <cgf@redhat.com> * fhandler_console.cc (fhandler_console::write): Allow characters >= diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index 648d5a3da..083b9db75 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -341,9 +341,15 @@ getgroups32 (int gidsetsize, __gid32_t *grouplist, __gid32_t gid, if (group_state <= initializing) read_etc_group (); - if (allow_ntsec && - strcasematch (username, cygheap->user.name ()) && - OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken)) + if (allow_ntsec) + { + /* If impersonated, use impersonation token. */ + if (cygheap->user.issetuid ()) + hToken = cygheap->user.token; + else if (!OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken)) + hToken = NULL; + } + if (hToken) { if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size) || GetLastError () == ERROR_INSUFFICIENT_BUFFER) @@ -375,7 +381,8 @@ getgroups32 (int gidsetsize, __gid32_t *grouplist, __gid32_t gid, } else debug_printf ("%d = GetTokenInformation(NULL) %E", size); - CloseHandle (hToken); + if (hToken != cygheap->user.token) + CloseHandle (hToken); if (cnt) return cnt; } diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc index 3b5e162cd..42570ecef 100644 --- a/winsup/cygwin/sec_helper.cc +++ b/winsup/cygwin/sec_helper.cc @@ -183,19 +183,50 @@ BOOL is_grp_member (__uid32_t uid, __gid32_t gid) { extern int getgroups32 (int, __gid32_t *, __gid32_t, const char *); - BOOL grp_member = TRUE; - - struct passwd *pw = getpwuid32 (uid); - __gid32_t grps[NGROUPS_MAX]; - int cnt = getgroups32 (NGROUPS_MAX, grps, - pw ? pw->pw_gid : myself->gid, - pw ? pw->pw_name : cygheap->user.name ()); - int i; - for (i = 0; i < cnt; ++i) - if (grps[i] == gid) - break; - grp_member = (i < cnt); - return grp_member; + struct passwd *pw; + struct __group32 *gr; + int idx; + + /* Evaluate current user info by examining the info given in cygheap and + the current access token if ntsec is on. */ + if (uid == myself->uid) + { + /* If gid == primary group of current user, return immediately. */ + if (gid == myself->gid) + return TRUE; + /* Calling getgroups32 only makes sense when reading the access token. */ + if (allow_ntsec) + { + __gid32_t grps[NGROUPS_MAX]; + int cnt = getgroups32 (NGROUPS_MAX, grps, myself->gid, + cygheap->user.name ()); + for (idx = 0; idx < cnt; ++idx) + if (grps[idx] == gid) + return TRUE; + return FALSE; + } + } + + /* Otherwise try getting info from examining passwd and group files. */ + for (int idx = 0; (pw = internal_getpwent (idx)); ++idx) + if ((__uid32_t) pw->pw_uid == uid) + { + /* If gid == primary group of uid, return immediately. */ + if ((__gid32_t) pw->pw_gid == gid) + return TRUE; + /* Otherwise search for supplementary user list of this group. */ + for (idx = 0; (gr = internal_getgrent (idx)); ++idx) + if ((__gid32_t) gr->gr_gid == gid) + { + if (gr->gr_mem) + for (idx = 0; gr->gr_mem[idx]; ++idx) + if (strcasematch (cygheap->user.name (), gr->gr_mem[idx])) + return TRUE; + return FALSE; + } + return FALSE; + } + return FALSE; } #if 0 // unused |