summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2007-08-17 19:58:57 +0000
committerCorinna Vinschen <corinna@vinschen.de>2007-08-17 19:58:57 +0000
commite0bdf94f32f1efb60720d10c9b49308bab406f01 (patch)
tree44e0607d762652e981b916d6f0bf96541280024f
parent2ad518b5a0606b115a4aa9786603b388c74a255a (diff)
downloadcygnal-e0bdf94f32f1efb60720d10c9b49308bab406f01.tar.gz
cygnal-e0bdf94f32f1efb60720d10c9b49308bab406f01.tar.bz2
cygnal-e0bdf94f32f1efb60720d10c9b49308bab406f01.zip
* 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.
-rw-r--r--winsup/cygwin/ChangeLog10
-rw-r--r--winsup/cygwin/autoload.cc3
-rw-r--r--winsup/cygwin/spawn.cc70
3 files changed, 65 insertions, 18 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a6198ced9..a3585494b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 09e645a72..c89333401 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -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)
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 6a658e92e..48895312f 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -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