[newlib-cygwin] Cygwin: s4uauth: allow to be called for identification only

Corinna Vinschen corinna@sourceware.org
Fri Feb 22 22:34:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=105fbdebdd3c65f96c7a95e1d5c527ce5790ac5e

commit 105fbdebdd3c65f96c7a95e1d5c527ce5790ac5e
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Fri Feb 22 18:27:38 2019 +0100

    Cygwin: s4uauth: allow to be called for identification only
    
    s4uath was only callable to create an impersonation token so
    far.  Rework the function to allow creating an identification
    token for informational purposes even from untrusted processes.
    
    Take domainname and username instead of a passwd pointer to be
    more multi-purpose.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/autoload.cc |  1 +
 winsup/cygwin/sec_auth.cc | 34 ++++++++++++++++++++--------------
 winsup/cygwin/security.h  |  2 +-
 winsup/cygwin/syscalls.cc |  6 +++++-
 4 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 73367df..056fac7 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -642,6 +642,7 @@ LoadDLLfunc (NetUserGetLocalGroups, 32, netapi32)
 
 LoadDLLfunc (CoTaskMemFree, 4, ole32)
 
+LoadDLLfunc (LsaConnectUntrusted, 4, secur32)
 LoadDLLfunc (LsaDeregisterLogonProcess, 4, secur32)
 LoadDLLfunc (LsaFreeReturnBuffer, 4, secur32)
 LoadDLLfunc (LsaLogonUser, 56, secur32)
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index 3a08671..54182dd 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -22,7 +22,6 @@ details. */
 #include "tls_pbuf.h"
 #include <lm.h>
 #include <iptypes.h>
-#include <wininet.h>
 #include <userenv.h>
 #define SECURITY_WIN32
 #include <secext.h>
@@ -1421,7 +1420,7 @@ out:
 */
 
 /* In Mingw-w64, MsV1_0S4ULogon and MSV1_0_S4U_LOGON are only defined
-   in ddk/ntifs.h.  We can't inlcude this. */
+   in ddk/ntifs.h.  We can't include this. */
 
 #define MsV1_0S4ULogon ((MSV1_0_LOGON_SUBMIT_TYPE) 12)
 
@@ -1433,15 +1432,18 @@ typedef struct _MSV1_0_S4U_LOGON
   UNICODE_STRING DomainName;
 } MSV1_0_S4U_LOGON, *PMSV1_0_S4U_LOGON;
 
+/* Missing in Mingw-w64 */
+#define KERB_S4U_LOGON_FLAG_IDENTITY 0x08
+
+/* If logon is true we need an impersonation token.  Otherwise we just
+   need an identification token, e. g. to fetch the group list. */
 HANDLE
-s4uauth (struct passwd *pw, NTSTATUS &ret_status)
+s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status)
 {
   LSA_STRING name;
   HANDLE lsa_hdl = NULL;
   LSA_OPERATIONAL_MODE sec_mode;
   NTSTATUS status, sub_status;
-  WCHAR domain[MAX_DOMAIN_NAME_LEN + 1];
-  WCHAR user[UNLEN + 1];
   bool try_kerb_auth;
   ULONG package_id, size;
   struct {
@@ -1460,19 +1462,23 @@ s4uauth (struct passwd *pw, NTSTATUS &ret_status)
 
   push_self_privilege (SE_TCB_PRIVILEGE, true);
 
-  /* Register as logon process. */
-  RtlInitAnsiString (&name, "Cygwin");
-  status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode);
+  if (logon)
+    {
+      /* Register as logon process. */
+      RtlInitAnsiString (&name, "Cygwin");
+      status = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode);
+    }
+  else
+    status = LsaConnectUntrusted (&lsa_hdl);
   if (status != STATUS_SUCCESS)
     {
-      debug_printf ("LsaRegisterLogonProcess: %y", status);
+      debug_printf ("%s: %y", logon ? "LsaRegisterLogonProcess"
+				    : "LsaConnectUntrusted", status);
       __seterrno_from_nt_status (status);
       goto out;
     }
 
-  /* Fetch user and domain name and check if this is a domain user.
-     If so, try Kerberos first. */
-  extract_nt_dom_user (pw, domain, user);
+  /* Check if this is a domain user.  If so, try Kerberos first. */
   try_kerb_auth = cygheap->dom.member_machine ()
 		  && wcscasecmp (domain, cygheap->dom.account_flat_name ());
   /* Create origin. */
@@ -1523,7 +1529,7 @@ s4uauth (struct passwd *pw, NTSTATUS &ret_status)
       RtlSecureZeroMemory (authinf, authinf_size);
       s4u_logon = (KERB_S4U_LOGON *) authinf;
       s4u_logon->MessageType = KerbS4ULogon;
-      s4u_logon->Flags = 0;
+      s4u_logon->Flags = logon ? 0 : KERB_S4U_LOGON_FLAG_IDENTITY;
       /* Append user to login info */
       RtlInitEmptyUnicodeString (&s4u_logon->ClientUpn,
 				 (PWCHAR) (s4u_logon + 1),
@@ -1615,7 +1621,7 @@ out:
   if (profile)
     LsaFreeReturnBuffer (profile);
 
-  if (token)
+  if (token && logon)
     {
       /* Convert to primary token.  Strictly speaking this is only
 	 required on Vista/2008.  CreateProcessAsUser also takes
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index cabb91d..483a527 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -480,7 +480,7 @@ HANDLE lsaauth (cygsid &, user_groups &);
 /* LSA private key storage authentication, same as when using service logons. */
 HANDLE lsaprivkeyauth (struct passwd *pw);
 /* Kerberos or MsV1 S4U logon. */
-HANDLE s4uauth (struct passwd *pw, NTSTATUS &ret_status);
+HANDLE s4uauth (bool logon, PCWSTR domain, PCWSTR user, NTSTATUS &ret_status);
 /* Verify an existing token */
 bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
 /* Get groups of a user */
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index c3a9244..f4e8bcf 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -37,6 +37,7 @@ details. */
 #include <sys/wait.h>
 #include <dirent.h>
 #include <ntsecapi.h>
+#include <iptypes.h>
 #include "ntdll.h"
 
 #undef fstat
@@ -3565,9 +3566,12 @@ seteuid32 (uid_t uid)
       if (!new_token)
 	{
 	  NTSTATUS status;
+	  WCHAR domain[MAX_DOMAIN_NAME_LEN + 1];
+	  WCHAR user[UNLEN + 1];
 
 	  debug_printf ("lsaprivkeyauth failed, try s4uauth.");
-	  if (!(new_token = s4uauth (pw_new, status)))
+	  extract_nt_dom_user (pw_new, domain, user);
+	  if (!(new_token = s4uauth (true, domain, user, status)))
 	    {
 	      if (status != STATUS_INVALID_PARAMETER)
 		{



More information about the Cygwin-cvs mailing list