Partially revert change from 2005-04-03, always running under an

impersonation token, which collides with Vista UAC.
	* cygheap.h (deimpersonate): revert to self instead of impersonating
	hProcImpToken.
	(reimpersonate): Only impersonate if setuid.
	* dcrt0.cc (dll_crt0_0): Don't initialize hProcImpToken here.
	(dll_crt0_1): Set privileges on hProcToken.
	* fork.cc (frok::child): Set privileges on hProcToken.  Close handle to
	hProcImpToken.
	* grp.cc (internal_getgroups): Use hProcToken instead of hProcImpToken.
	* security.cc (check_access): Create hProcImpToken on demand here.
	* security.h (set_process_privilege): Set privileges on hProcToken.
	(_push_thread_privilege): Use hProcToken instead of hProcImpToken.
	(pop_thread_privilege): If not setuid'ed, revert to self.
	* syscalls.cc (setegid32): Drop setting primary group on hProcImpToken.
	Close handle to hProcImpToken.
	* uinfo.cc (internal_getlogin): Ditto.
	* winsup.h (clear_procimptoken): New inline function.
This commit is contained in:
Corinna Vinschen 2006-12-12 16:27:32 +00:00
parent 815122d842
commit 5684cfebba
10 changed files with 58 additions and 28 deletions

View File

@ -1,3 +1,24 @@
2006-12-12 Corinna Vinschen <corinna@vinschen.de>
Partially revert change from 2005-04-03, always running under an
impersonation token, which collides with Vista UAC.
* cygheap.h (deimpersonate): revert to self instead of impersonating
hProcImpToken.
(reimpersonate): Only impersonate if setuid.
* dcrt0.cc (dll_crt0_0): Don't initialize hProcImpToken here.
(dll_crt0_1): Set privileges on hProcToken.
* fork.cc (frok::child): Set privileges on hProcToken. Close handle to
hProcImpToken.
* grp.cc (internal_getgroups): Use hProcToken instead of hProcImpToken.
* security.cc (check_access): Create hProcImpToken on demand here.
* security.h (set_process_privilege): Set privileges on hProcToken.
(_push_thread_privilege): Use hProcToken instead of hProcImpToken.
(pop_thread_privilege): If not setuid'ed, revert to self.
* syscalls.cc (setegid32): Drop setting primary group on hProcImpToken.
Close handle to hProcImpToken.
* uinfo.cc (internal_getlogin): Ditto.
* winsup.h (clear_procimptoken): New inline function.
2006-12-12 Christopher Faylor <me@cgf.cx> 2006-12-12 Christopher Faylor <me@cgf.cx>
* syscalls.cc (popen): Allow '[rw][bt]'. * syscalls.cc (popen): Allow '[rw][bt]'.

View File

@ -182,14 +182,13 @@ public:
void deimpersonate () void deimpersonate ()
{ {
if (issetuid ()) if (issetuid ())
{ RevertToSelf ();
RevertToSelf ();
ImpersonateLoggedOnUser (hProcImpToken);
}
} }
bool reimpersonate () bool reimpersonate ()
{ {
return ImpersonateLoggedOnUser (issetuid () ? token () : hProcImpToken); if (issetuid ())
return ImpersonateLoggedOnUser (token ());
return true;
} }
bool has_impersonation_tokens () bool has_impersonation_tokens ()
{ return external_token != NO_IMPERSONATION { return external_token != NO_IMPERSONATION

View File

@ -771,17 +771,6 @@ dll_crt0_0 ()
cygheap->cwd.init (); cygheap->cwd.init ();
/* Late duplicate simplifies tweaking the process token in uinfo.cc. */
if (wincap.has_security ()
&& !DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenImpersonation,
&hProcImpToken))
#ifdef DEBUGGING
system_printf ("DuplicateTokenEx failed, %E");
#else
;
#endif
debug_printf ("finished dll_crt0_0 initialization"); debug_printf ("finished dll_crt0_0 initialization");
} }
@ -852,7 +841,7 @@ dll_crt0_1 (void *)
/* Can be set only after environment has been initialized. */ /* Can be set only after environment has been initialized. */
if (wincap.has_security ()) if (wincap.has_security ())
set_cygwin_privileges (hProcImpToken); set_cygwin_privileges (hProcToken);
if (!old_title && GetConsoleTitle (title_buf, TITLESIZE)) if (!old_title && GetConsoleTitle (title_buf, TITLESIZE))
old_title = title_buf; old_title = title_buf;

View File

@ -117,7 +117,8 @@ frok::child (void *)
if (wincap.has_security ()) if (wincap.has_security ())
{ {
set_cygwin_privileges (hProcImpToken); set_cygwin_privileges (hProcToken);
clear_procimptoken ();
cygheap->user.reimpersonate (); cygheap->user.reimpersonate ();
} }

View File

@ -367,7 +367,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
if (cygheap->user.issetuid ()) if (cygheap->user.issetuid ())
hToken = cygheap->user.token (); hToken = cygheap->user.token ();
else else
hToken = hProcImpToken; hToken = hProcToken;
if (hToken) if (hToken)
{ {

View File

@ -2129,6 +2129,17 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping,
HANDLE tok = cygheap->user.issetuid () ? cygheap->user.token () HANDLE tok = cygheap->user.issetuid () ? cygheap->user.token ()
: hProcImpToken; : hProcImpToken;
if (!tok && !DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenImpersonation,
&hProcImpToken))
#ifdef DEBUGGING
system_printf ("DuplicateTokenEx failed, %E");
#else
syscall_printf ("DuplicateTokenEx failed, %E");
#endif
else
tok = hProcImpToken;
if (!AccessCheck (sd, tok, desired, &mapping, pset, &plen, &granted, &status)) if (!AccessCheck (sd, tok, desired, &mapping, pset, &plen, &granted, &status))
__seterrno (); __seterrno ();
else if (!status) else if (!status)

View File

@ -396,14 +396,14 @@ bool get_logon_server (const char * domain, char * server, WCHAR *wserver,
int set_privilege (HANDLE token, enum cygpriv_idx privilege, bool enable); int set_privilege (HANDLE token, enum cygpriv_idx privilege, bool enable);
void set_cygwin_privileges (HANDLE token); void set_cygwin_privileges (HANDLE token);
#define set_process_privilege(p,v) set_privilege (hProcImpToken, (p), (v)) #define set_process_privilege(p,v) set_privilege (hProcToken, (p), (v))
#define _push_thread_privilege(_priv, _val, _check) { \ #define _push_thread_privilege(_priv, _val, _check) { \
HANDLE _token = NULL, _dup_token = NULL; \ HANDLE _token = NULL, _dup_token = NULL; \
if (wincap.has_security ()) \ if (wincap.has_security ()) \
{ \ { \
_token = (cygheap->user.issetuid () && (_check)) \ _token = (cygheap->user.issetuid () && (_check)) \
? cygheap->user.token () : hProcImpToken; \ ? cygheap->user.token () : hProcToken; \
if (!DuplicateTokenEx (_token, MAXIMUM_ALLOWED, NULL, \ if (!DuplicateTokenEx (_token, MAXIMUM_ALLOWED, NULL, \
SecurityImpersonation, TokenImpersonation, \ SecurityImpersonation, TokenImpersonation, \
&_dup_token)) \ &_dup_token)) \
@ -419,7 +419,10 @@ void set_cygwin_privileges (HANDLE token);
#define pop_thread_privilege() \ #define pop_thread_privilege() \
if (_dup_token) \ if (_dup_token) \
{ \ { \
ImpersonateLoggedOnUser (_token); \ if (_token == hProcToken) \
RevertToSelf (); \
else \
ImpersonateLoggedOnUser (_token); \
CloseHandle (_dup_token); \ CloseHandle (_dup_token); \
} \ } \
} }

View File

@ -2418,9 +2418,7 @@ setegid32 (__gid32_t gid)
cygheap->user.deimpersonate (); cygheap->user.deimpersonate ();
if (!SetTokenInformation (hProcToken, TokenPrimaryGroup, &gsid, sizeof gsid)) if (!SetTokenInformation (hProcToken, TokenPrimaryGroup, &gsid, sizeof gsid))
debug_printf ("SetTokenInformation(hProcToken, TokenPrimaryGroup), %E"); debug_printf ("SetTokenInformation(hProcToken, TokenPrimaryGroup), %E");
if (!SetTokenInformation (hProcImpToken, TokenPrimaryGroup, &gsid, clear_procimptoken ();
sizeof gsid))
debug_printf ("SetTokenInformation(hProcImpToken, TokenPrimaryGroup), %E");
cygheap->user.reimpersonate (); cygheap->user.reimpersonate ();
return 0; return 0;
} }

View File

@ -115,11 +115,9 @@ internal_getlogin (cygheap_user &user)
if (!SetTokenInformation (hProcToken, TokenPrimaryGroup, if (!SetTokenInformation (hProcToken, TokenPrimaryGroup,
&gsid, sizeof gsid)) &gsid, sizeof gsid))
debug_printf ("SetTokenInformation(TokenPrimaryGroup), %E"); debug_printf ("SetTokenInformation(TokenPrimaryGroup), %E");
if (!SetTokenInformation (hProcImpToken, TokenPrimaryGroup,
&gsid, sizeof gsid))
debug_printf ("SetTokenInformation(TokenPrimaryGroup), %E");
else else
user.groups.pgsid = gsid; user.groups.pgsid = gsid;
clear_procimptoken ();
} }
} }
else else

View File

@ -360,6 +360,16 @@ extern HANDLE hMainThread;
extern HANDLE hMainProc; extern HANDLE hMainProc;
extern HANDLE hProcToken; extern HANDLE hProcToken;
extern HANDLE hProcImpToken; extern HANDLE hProcImpToken;
inline void clear_procimptoken ()
{
if (hProcImpToken)
{
CloseHandle (hProcImpToken);
hProcImpToken = NULL;
}
}
extern HANDLE hExeced; extern HANDLE hExeced;
extern HMODULE cygwin_hmodule; extern HMODULE cygwin_hmodule;