diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 014d1255d..306e52e66 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,24 @@ +2006-12-12 Corinna Vinschen + + 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 * syscalls.cc (popen): Allow '[rw][bt]'. diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 0c54bad1a..f33feb546 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -182,14 +182,13 @@ public: void deimpersonate () { if (issetuid ()) - { - RevertToSelf (); - ImpersonateLoggedOnUser (hProcImpToken); - } + RevertToSelf (); } bool reimpersonate () { - return ImpersonateLoggedOnUser (issetuid () ? token () : hProcImpToken); + if (issetuid ()) + return ImpersonateLoggedOnUser (token ()); + return true; } bool has_impersonation_tokens () { return external_token != NO_IMPERSONATION diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 727163e08..8281f3676 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -771,17 +771,6 @@ dll_crt0_0 () 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"); } @@ -852,7 +841,7 @@ dll_crt0_1 (void *) /* Can be set only after environment has been initialized. */ if (wincap.has_security ()) - set_cygwin_privileges (hProcImpToken); + set_cygwin_privileges (hProcToken); if (!old_title && GetConsoleTitle (title_buf, TITLESIZE)) old_title = title_buf; diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index b94a28d0b..fcf231903 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -117,7 +117,8 @@ frok::child (void *) if (wincap.has_security ()) { - set_cygwin_privileges (hProcImpToken); + set_cygwin_privileges (hProcToken); + clear_procimptoken (); cygheap->user.reimpersonate (); } diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index 13d334a5d..fafef7587 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -367,7 +367,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) if (cygheap->user.issetuid ()) hToken = cygheap->user.token (); else - hToken = hProcImpToken; + hToken = hProcToken; if (hToken) { diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index c5a8f5ca3..d25e3c68b 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -2129,6 +2129,17 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping, HANDLE tok = cygheap->user.issetuid () ? cygheap->user.token () : 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)) __seterrno (); else if (!status) diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 9823ca2b4..dec066009 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -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); 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) { \ HANDLE _token = NULL, _dup_token = NULL; \ if (wincap.has_security ()) \ { \ _token = (cygheap->user.issetuid () && (_check)) \ - ? cygheap->user.token () : hProcImpToken; \ + ? cygheap->user.token () : hProcToken; \ if (!DuplicateTokenEx (_token, MAXIMUM_ALLOWED, NULL, \ SecurityImpersonation, TokenImpersonation, \ &_dup_token)) \ @@ -419,7 +419,10 @@ void set_cygwin_privileges (HANDLE token); #define pop_thread_privilege() \ if (_dup_token) \ { \ - ImpersonateLoggedOnUser (_token); \ + if (_token == hProcToken) \ + RevertToSelf (); \ + else \ + ImpersonateLoggedOnUser (_token); \ CloseHandle (_dup_token); \ } \ } diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 20696fa36..fc9bbe50e 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2418,9 +2418,7 @@ setegid32 (__gid32_t gid) cygheap->user.deimpersonate (); if (!SetTokenInformation (hProcToken, TokenPrimaryGroup, &gsid, sizeof gsid)) debug_printf ("SetTokenInformation(hProcToken, TokenPrimaryGroup), %E"); - if (!SetTokenInformation (hProcImpToken, TokenPrimaryGroup, &gsid, - sizeof gsid)) - debug_printf ("SetTokenInformation(hProcImpToken, TokenPrimaryGroup), %E"); + clear_procimptoken (); cygheap->user.reimpersonate (); return 0; } diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index b8519cfbc..5fd2117dd 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -115,11 +115,9 @@ internal_getlogin (cygheap_user &user) if (!SetTokenInformation (hProcToken, TokenPrimaryGroup, &gsid, sizeof gsid)) debug_printf ("SetTokenInformation(TokenPrimaryGroup), %E"); - if (!SetTokenInformation (hProcImpToken, TokenPrimaryGroup, - &gsid, sizeof gsid)) - debug_printf ("SetTokenInformation(TokenPrimaryGroup), %E"); else user.groups.pgsid = gsid; + clear_procimptoken (); } } else diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 9e9aea271..4174b510c 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -360,6 +360,16 @@ extern HANDLE hMainThread; extern HANDLE hMainProc; extern HANDLE hProcToken; extern HANDLE hProcImpToken; + +inline void clear_procimptoken () +{ + if (hProcImpToken) + { + CloseHandle (hProcImpToken); + hProcImpToken = NULL; + } +} + extern HANDLE hExeced; extern HMODULE cygwin_hmodule;