On Oct 4 14:30, Corinna Vinschen wrote: > [...] > Patch attached. For simplicity I just applied the patch to the w32api > winbase.h header file which defines CreateRestrictedToken and > IsTokenRestricted. > > > Thanks, > Corinna > > > * autoload.cc (IsTokenRestricted): Define. > * syscalls.cc (seteuid32): Create special case for restricted > external tokens to switch to a restricted token for the current > user.
New patch attached. I made the test a bit more foolproof, hopefully. And a restricted token does not require to load the user's registry hive, nor should Cygwin try to enable the backup/restore permissions in the new token. That spoils the idea of a restricted token a bit... Corinna Index: autoload.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/autoload.cc,v retrieving revision 1.165 diff -u -p -r1.165 autoload.cc --- autoload.cc 22 Sep 2009 14:27:57 -0000 1.165 +++ autoload.cc 4 Oct 2009 12:54:15 -0000 @@ -422,6 +422,8 @@ LoadDLLfuncEx (GetSystemDEPPolicy, 0, ke LoadDLLfuncEx (GetProcessDEPPolicy, 12, kernel32, 1) LoadDLLfuncEx (SetProcessDEPPolicy, 4, kernel32, 1) +LoadDLLfunc (IsTokenRestricted, 4, advapi32) + LoadDLLfunc (SHGetDesktopFolder, 4, shell32) LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1) Index: syscalls.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v retrieving revision 1.540 diff -u -p -r1.540 syscalls.cc --- syscalls.cc 4 Oct 2009 11:32:07 -0000 1.540 +++ syscalls.cc 4 Oct 2009 12:54:17 -0000 @@ -2664,7 +2664,31 @@ seteuid32 (__uid32_t uid) debug_printf ("uid: %u myself->uid: %u myself->gid: %u", uid, myself->uid, myself->gid); - if (uid == myself->uid && !cygheap->user.groups.ischanged) + /* Same uid as we're just running under is usually a no-op. + + Except we have an external token which is a restricted token. Or, + the external token is NULL, but the current impersonation token is + a restricted token. This allows to restrict user rights temporarily + like this: + + cygwin_set_impersonation_token (restricted_token); + setuid (getuid ()); + [...do stuff with restricted rights...] + cygwin_set_impersonation_token (INVALID_HANDLE_VALUE); + setuid (getuid ()); + + Note that using the current uid is a requirement! Starting with Windows + Vista, we have restricted tokens galore (UAC), so this is really just + a special case to restict your own processes to lesser rights. */ + bool request_restricted_uid_switch = + uid == myself->uid + && ( (cygheap->user.external_token != NO_IMPERSONATION + && IsTokenRestricted (cygheap->user.external_token)) + || (cygheap->user.external_token == NO_IMPERSONATION + && cygheap->user.issetuid () + && IsTokenRestricted (cygheap->user.curr_primary_token))); + if (uid == myself->uid && !cygheap->user.groups.ischanged + && !request_restricted_uid_switch) { debug_printf ("Nothing happens"); return 0; @@ -2686,6 +2710,21 @@ seteuid32 (__uid32_t uid) cygheap->user.deimpersonate (); /* Verify if the process token is suitable. */ + /* First of all, skip all checks if a switch to a restricted token has been + requested, or if trying to switch back from it. */ + if (request_restricted_uid_switch) + { + if (cygheap->user.external_token != NO_IMPERSONATION) + { + debug_printf ("Switch to restricted token"); + new_token = cygheap->user.external_token; + } + else + { + debug_printf ("Switch back from restricted token"); + new_token = hProcToken; + } + } /* TODO, CV 2008-11-25: The check against saved_sid is a kludge and a shortcut. We must check if it's really feasible in the long run. The reason to add this shortcut is this: sshd switches back to the @@ -2763,9 +2802,12 @@ seteuid32 (__uid32_t uid) if (new_token != hProcToken) { - /* Avoid having HKCU use default user */ - WCHAR name[128]; - load_registry_hive (usersid.string (name)); + if (!request_restricted_uid_switch) + { + /* Avoid having HKCU use default user */ + WCHAR name[128]; + load_registry_hive (usersid.string (name)); + } /* Try setting owner to same value as user. */ if (!SetTokenInformation (new_token, TokenOwner, @@ -2805,7 +2847,8 @@ seteuid32 (__uid32_t uid) cygheap->user.curr_primary_token = NO_IMPERSONATION; return -1; } - set_cygwin_privileges (cygheap->user.curr_imp_token); + if (!request_restricted_uid_switch) + set_cygwin_privileges (cygheap->user.curr_imp_token); } if (!cygheap->user.reimpersonate ()) { -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat