* 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:
parent
2ad518b5a0
commit
e0bdf94f32
|
@ -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>
|
||||
|
||||
* fhandler_disk_file.cc (fhandler_disk_file::fchmod): Handle S_IFSOCK
|
||||
|
|
|
@ -322,7 +322,9 @@ LoadDLLfuncEx (LsaRegisterLogonProcess, 12, secur32, 1)
|
|||
|
||||
LoadDLLfunc (CharToOemA, 8, user32)
|
||||
LoadDLLfunc (CloseClipboard, 0, user32)
|
||||
LoadDLLfunc (CloseDesktop, 4, user32)
|
||||
LoadDLLfunc (CloseWindowStation, 4, user32)
|
||||
LoadDLLfunc (CreateDesktopA, 24, user32)
|
||||
LoadDLLfunc (CreateWindowExA, 48, user32)
|
||||
LoadDLLfunc (CreateWindowStationA, 16, user32)
|
||||
LoadDLLfunc (DefWindowProcA, 16, user32)
|
||||
|
@ -349,6 +351,7 @@ LoadDLLfunc (RegisterClassA, 4, user32)
|
|||
LoadDLLfunc (RegisterClipboardFormatA, 4, user32)
|
||||
LoadDLLfunc (SendMessageA, 16, user32)
|
||||
LoadDLLfunc (SetClipboardData, 8, user32)
|
||||
LoadDLLfunc (SetThreadDesktop, 4, user32)
|
||||
LoadDLLfunc (SetProcessWindowStation, 4, user32)
|
||||
|
||||
LoadDLLfunc (accept, 12, ws2_32)
|
||||
|
|
|
@ -512,25 +512,49 @@ loop:
|
|||
if (mode == _P_OVERLAY)
|
||||
myself.set_acl();
|
||||
|
||||
/* allow the child to interact with our window station/desktop */
|
||||
HANDLE hwst, hdsk;
|
||||
SECURITY_INFORMATION dsi = DACL_SECURITY_INFORMATION;
|
||||
NTSTATUS status;
|
||||
char wstname[1024] = { '\0' };
|
||||
HWINSTA hwst_orig = NULL, hwst = NULL;
|
||||
HDESK hdsk_orig = NULL, hdsk = NULL;
|
||||
PSECURITY_ATTRIBUTES sa;
|
||||
DWORD n;
|
||||
char wstname[1024];
|
||||
char dskname[1024];
|
||||
|
||||
hwst = GetProcessWindowStation ();
|
||||
if ((status = NtSetSecurityObject (hwst, dsi, get_null_sd ())))
|
||||
system_printf ("NtSetSecurityObject, %lx", status);
|
||||
GetUserObjectInformation (hwst, UOI_NAME, wstname, 1024, &n);
|
||||
hdsk = GetThreadDesktop (GetCurrentThreadId ());
|
||||
if ((status = NtSetSecurityObject (hdsk, dsi, get_null_sd ())))
|
||||
system_printf ("NtSetSecurityObject, %lx", status);
|
||||
GetUserObjectInformation (hdsk, UOI_NAME, dskname, 1024, &n);
|
||||
strcat (wstname, "\\");
|
||||
strcat (wstname, dskname);
|
||||
si.lpDesktop = wstname;
|
||||
hwst_orig = GetProcessWindowStation ();
|
||||
hdsk_orig = GetThreadDesktop (GetCurrentThreadId ());
|
||||
GetUserObjectInformation (hwst_orig, UOI_NAME, wstname, 1024, &n);
|
||||
/* Prior to Vista it was possible to start a service with the
|
||||
"Interact with desktop" flag. This started the service in the
|
||||
interactive window station of the console. A big security
|
||||
risk, but we don't want to disable this behaviour for older
|
||||
OSes because it's still heavily used by some users. They have
|
||||
been warned. */
|
||||
if (!strcasematch (wstname, "WinSta0"))
|
||||
{
|
||||
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 (),
|
||||
runpath, /* image name - with full path */
|
||||
|
@ -543,6 +567,16 @@ loop:
|
|||
NULL,
|
||||
&si,
|
||||
&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
|
||||
|
|
Loading…
Reference in New Issue