Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog7
-rw-r--r--winsup/cygwin/grp.cc15
-rw-r--r--winsup/cygwin/sec_helper.cc57
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