* autoload.cc (CloseDesktop): Define.

(CreateDesktopA): Define.
	(SetThreadDesktop): Define.
	* spawn.cc (spawn_guts): When starting a process under another user
	account, don't open up permissions on current window station and
	desktop.  Instead, if not in interactive session, create a new per-user
	window station plus default desktop and use that for the child process.
This commit is contained in:
Corinna Vinschen 2007-08-17 19:58:57 +00:00
parent 2ad518b5a0
commit e0bdf94f32
3 changed files with 64 additions and 17 deletions

View File

@ -1,3 +1,13 @@
2007-08-17 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (CloseDesktop): Define.
(CreateDesktopA): Define.
(SetThreadDesktop): Define.
* spawn.cc (spawn_guts): When starting a process under another user
account, don't open up permissions on current window station and
desktop. Instead, if not in interactive session, create a new per-user
window station plus default desktop and use that for the child process.
2007-08-16 Corinna Vinschen <corinna@vinschen.de> 2007-08-16 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Handle S_IFSOCK * fhandler_disk_file.cc (fhandler_disk_file::fchmod): Handle S_IFSOCK

View File

@ -322,7 +322,9 @@ LoadDLLfuncEx (LsaRegisterLogonProcess, 12, secur32, 1)
LoadDLLfunc (CharToOemA, 8, user32) LoadDLLfunc (CharToOemA, 8, user32)
LoadDLLfunc (CloseClipboard, 0, user32) LoadDLLfunc (CloseClipboard, 0, user32)
LoadDLLfunc (CloseDesktop, 4, user32)
LoadDLLfunc (CloseWindowStation, 4, user32) LoadDLLfunc (CloseWindowStation, 4, user32)
LoadDLLfunc (CreateDesktopA, 24, user32)
LoadDLLfunc (CreateWindowExA, 48, user32) LoadDLLfunc (CreateWindowExA, 48, user32)
LoadDLLfunc (CreateWindowStationA, 16, user32) LoadDLLfunc (CreateWindowStationA, 16, user32)
LoadDLLfunc (DefWindowProcA, 16, user32) LoadDLLfunc (DefWindowProcA, 16, user32)
@ -349,6 +351,7 @@ LoadDLLfunc (RegisterClassA, 4, user32)
LoadDLLfunc (RegisterClipboardFormatA, 4, user32) LoadDLLfunc (RegisterClipboardFormatA, 4, user32)
LoadDLLfunc (SendMessageA, 16, user32) LoadDLLfunc (SendMessageA, 16, user32)
LoadDLLfunc (SetClipboardData, 8, user32) LoadDLLfunc (SetClipboardData, 8, user32)
LoadDLLfunc (SetThreadDesktop, 4, user32)
LoadDLLfunc (SetProcessWindowStation, 4, user32) LoadDLLfunc (SetProcessWindowStation, 4, user32)
LoadDLLfunc (accept, 12, ws2_32) LoadDLLfunc (accept, 12, ws2_32)

View File

@ -512,25 +512,49 @@ loop:
if (mode == _P_OVERLAY) if (mode == _P_OVERLAY)
myself.set_acl(); myself.set_acl();
/* allow the child to interact with our window station/desktop */ char wstname[1024] = { '\0' };
HANDLE hwst, hdsk; HWINSTA hwst_orig = NULL, hwst = NULL;
SECURITY_INFORMATION dsi = DACL_SECURITY_INFORMATION; HDESK hdsk_orig = NULL, hdsk = NULL;
NTSTATUS status; PSECURITY_ATTRIBUTES sa;
DWORD n; DWORD n;
char wstname[1024];
char dskname[1024];
hwst = GetProcessWindowStation (); hwst_orig = GetProcessWindowStation ();
if ((status = NtSetSecurityObject (hwst, dsi, get_null_sd ()))) hdsk_orig = GetThreadDesktop (GetCurrentThreadId ());
system_printf ("NtSetSecurityObject, %lx", status); GetUserObjectInformation (hwst_orig, UOI_NAME, wstname, 1024, &n);
GetUserObjectInformation (hwst, UOI_NAME, wstname, 1024, &n); /* Prior to Vista it was possible to start a service with the
hdsk = GetThreadDesktop (GetCurrentThreadId ()); "Interact with desktop" flag. This started the service in the
if ((status = NtSetSecurityObject (hdsk, dsi, get_null_sd ()))) interactive window station of the console. A big security
system_printf ("NtSetSecurityObject, %lx", status); risk, but we don't want to disable this behaviour for older
GetUserObjectInformation (hdsk, UOI_NAME, dskname, 1024, &n); OSes because it's still heavily used by some users. They have
strcat (wstname, "\\"); been warned. */
strcat (wstname, dskname); if (!strcasematch (wstname, "WinSta0"))
si.lpDesktop = wstname; {
char sid[128];
sa = sec_user ((PSECURITY_ATTRIBUTES) alloca (1024),
cygheap->user.sid ());
/* We're create a window station per user, not per logon session.
First of all we might not have a valid logon session for
the user (logon by create_token), and second, it doesn't
make sense in terms of security to create a new window
station for every logon of the same user. It just fills up
the system with window stations for no good reason. */
hwst = CreateWindowStationA (cygheap->user.get_windows_id (sid), 0,
GENERIC_READ | GENERIC_WRITE, sa);
if (!hwst)
system_printf ("CreateWindowStation failed, %E");
else if (!SetProcessWindowStation (hwst))
system_printf ("SetProcessWindowStation failed, %E");
else if (!(hdsk = CreateDesktopA ("Default", NULL, NULL, 0,
GENERIC_ALL, sa)))
system_printf ("CreateDesktop failed, %E");
else
{
stpcpy (stpcpy (wstname, sid), "\\Default");
si.lpDesktop = wstname;
debug_printf ("Desktop: %s", si.lpDesktop);
}
}
rc = CreateProcessAsUser (cygheap->user.primary_token (), rc = CreateProcessAsUser (cygheap->user.primary_token (),
runpath, /* image name - with full path */ runpath, /* image name - with full path */
@ -543,6 +567,16 @@ loop:
NULL, NULL,
&si, &si,
&pi); &pi);
if (hwst)
{
SetProcessWindowStation (hwst_orig);
CloseWindowStation (hwst);
}
if (hdsk)
{
SetThreadDesktop (hdsk_orig);
CloseDesktop (hdsk);
}
} }
/* Restore impersonation. In case of _P_OVERLAY this isn't /* Restore impersonation. In case of _P_OVERLAY this isn't