This is the mail archive of the cygwin 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: 'su' no longer working?


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Igor Peshansky on 1/9/2006 6:04 AM:
> 
> Right, that's pretty much what I was asking for above.  Eric, if it helps,
> I can look into submitting the patch later this week, though I haven't
> looked at the coreutils code in a while, so it might take some time to
> understand the specifics.

I've already been playing some with a cygwin-specific patch.  Using the
tips at http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-setuid, I have
already gotten a working implementation that will switch user context on
NT machines with a password.  But I still want to get passwordless
switching working where possible.  The patch should apply to src/su.c
provided in the 5.93-2 source tarball from setup.exe, as a starting point
for your hacking.

Speaking of which, I noticed that in my attached patch (work in progress),
I got a failure return for PrivilegeCheck on my NT machine when run as
SYSTEM, even though my understanding is that on NT, SYSTEM has the
privileges of passwordless context switching.  Any ideas what I might need
to fix to make this check more robust, short of just trying a setuid() to
see if it will succeed without first doing the
cygwin_logon_user()/cygwin_set_impersonation_token() check?

- --
Life is short - so eat dessert first!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFDwnJ084KuGfSFAYARAjqvAJ4mqjQwCTfjohU8t0exVnFikS7E7ACdHn0D
YLfFxh7W1dpGd54uET6K3vg=
=SC+D
-----END PGP SIGNATURE-----
Index: src/su.c
===================================================================
RCS file: /sources/coreutils/coreutils/src/su.c,v
retrieving revision 1.89
diff -u -r1.89 su.c
--- src/su.c	23 Aug 2005 15:09:13 -0000	1.89
+++ src/su.c	7 Jan 2006 00:27:55 -0000
@@ -1,5 +1,5 @@
 /* su for GNU.  Run a shell with substitute user and group IDs.
-   Copyright (C) 1992-2005 Free Software Foundation, Inc.
+   Copyright (C) 1992-2006 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -112,6 +112,13 @@
 
 #include "error.h"
 
+#if __CYGWIN__
+# include <windows.h>
+# include <sys/cygwin.h>
+/* Use the following define to determine the Windows version */
+# define is_winnt        (GetVersion() < 0x80000000)
+#endif
+
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "su"
 
@@ -261,6 +268,47 @@
 
   if (getuid () == 0 || !correct || correct[0] == '\0')
     return true;
+#if __CYGWIN__
+  /* On cygwin, any process with enough privilege can do passwordless
+     authentication.  http://cygwin.com/ml/cygwin/2006-01/msg00289.html
+     shows how to grant these privileges to an arbitrary account,
+     although this should only be done to trusted users.  */
+  {
+    PRIVILEGE_SET *pset = xmalloc (2 * sizeof (DWORD)
+                                   + 3 * sizeof (LUID_AND_ATTRIBUTES));
+    bool ok = true;
+    BOOL privileged;
+    HANDLE process;
+    HANDLE access;
+
+    pset->PrivilegeCount = 3;
+    pset->Control = PRIVILEGE_SET_ALL_NECESSARY;
+    if (LookupPrivilegeValue (NULL, SE_CREATE_TOKEN_NAME,
+                              &pset->Privilege[0].Luid) == 0)
+      ok = false;
+    pset->Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
+    if (LookupPrivilegeValue (NULL, SE_ASSIGNPRIMARYTOKEN_NAME,
+                              &pset->Privilege[1].Luid) == 0)
+      ok = false;
+    pset->Privilege[1].Attributes = SE_PRIVILEGE_ENABLED;
+    if (LookupPrivilegeValue (NULL, SE_INCREASE_QUOTA_NAME,
+                              &pset->Privilege[2].Luid) == 0)
+      ok = false;
+    pset->Privilege[2].Attributes = SE_PRIVILEGE_ENABLED;
+
+    process = GetCurrentProcess ();
+    if (OpenProcessToken (process, TOKEN_QUERY, &access) == 0)
+      ok = false;
+    if (PrivilegeCheck (access, pset, &privileged) == 0)
+      ok = false;
+
+    CloseHandle (process);
+    CloseHandle (access);
+    free (pset);
+    if (ok && privileged)
+      return true;
+  }
+#endif /* __CYGWIN__ */
 
   unencrypted = getpass (_("Password:"));
   if (!unencrypted)
@@ -268,6 +316,25 @@
       error (0, 0, _("getpass: cannot open /dev/tty"));
       return false;
     }
+#if __CYGWIN__
+  /* Windows NT class machines don't store password in pw->pw_passwd, but
+     do support setuid if we use the cygwin password test.
+     See http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-setuid.  */
+  if (is_winnt)
+    {
+      HANDLE token;
+      /* Try to get the access token from NT. */
+      token = cygwin_logon_user (pw, unencrypted);
+      if (token == INVALID_HANDLE_VALUE)
+         return false;
+      /* Inform Cygwin about the new impersonation token.
+         Cygwin is able now, to switch to that user context by
+         setuid or seteuid calls. */
+      cygwin_set_impersonation_token (token);
+      encrypted = correct;
+    }
+  else
+#endif /* __CYGWIN__ */
   encrypted = crypt (unencrypted, correct);
   memset (unencrypted, 0, strlen (unencrypted));
   return STREQ (encrypted, correct);

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

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