This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch] Allow to disable root privileges with CYGWIN=noroot


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]