OSDN Git Service

* autoload.cc (CloseDesktop): Define.
authorcorinna <corinna>
Fri, 17 Aug 2007 19:58:55 +0000 (19:58 +0000)
committercorinna <corinna>
Fri, 17 Aug 2007 19:58:55 +0000 (19:58 +0000)
(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.

winsup/cygwin/ChangeLog
winsup/cygwin/autoload.cc
winsup/cygwin/spawn.cc

index a6198ce..a358549 100644 (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>
 
        * fhandler_disk_file.cc (fhandler_disk_file::fchmod): Handle S_IFSOCK
index 09e645a..c893334 100644 (file)
@@ -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)
index 6a658e9..4889531 100644 (file)
@@ -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