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: DS_FORCE_REDISCOVERY lookup slows ssh logon


On 6/7/2013 11:55 PM, Daniel Colascione wrote:
> (By the way: how on earth does logon eventually succeed if group enumeration
> fails? I'm using the stored-password authentication method, and when sshd
> eventually connects, my user (according to whoami.exe /priv) is a member of the
> groups I expect.)

Ah, I found http://cygwin.com/ml/cygwin/2009-06/msg00828.html. sshd is just
getting a truncated group list from initgroups while checking ~/.ssh
permissions, which still happens to work fine in my case, the logon delay aside.

Changing openssh to call setgroups only after calling seteuid might help (so
we'd retrieve the group list in the context of our new user), but because
get_groups calls deimpersonate before talking to the server, that wouldn't
actually work.

What about something like this?

Index: sec_auth.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/sec_auth.cc,v
retrieving revision 1.47
diff -u -r1.47 sec_auth.cc
--- sec_auth.cc	23 Apr 2013 09:44:33 -0000	1.47
+++ sec_auth.cc	8 Jun 2013 08:31:16 -0000
@@ -246,7 +246,8 @@

 static bool
 get_user_groups (WCHAR *logonserver, cygsidlist &grp_list,
-		 PWCHAR user, PWCHAR domain)
+		 PWCHAR user, PWCHAR domain,
+		 struct passwd *pw)
 {
   WCHAR dgroup[MAX_DOMAIN_NAME_LEN + GNLEN + 2];
   LPGROUP_USERS_INFO_0 buf;
@@ -256,6 +257,33 @@
   /* Look only on logonserver */
   ret = NetUserGetGroups (logonserver, user, 0, (LPBYTE *) &buf,
 			  MAX_PREFERRED_LENGTH, &cnt, &tot);
+
+  if (ret == ERROR_ACCESS_DENIED)
+    {
+      /* If we can't list the user's groups as ourselves, try
+	 impersonating the user and trying again.  If the user is a
+	 domain account and we're just a privileged local account, the
+	 user might have more access than we do. Only try
+	 lsaprivkeyauth because other methods for creating user tokens
+	 don't give us network credentials anyway.
+      */
+
+      HANDLE user_token = lsaprivkeyauth (pw);
+
+      if (user_token)
+	{
+	  if (ImpersonateLoggedOnUser (user_token))
+	    {
+	      ret = NetUserGetGroups (logonserver, user, 0, (LPBYTE *) &buf,
+				      MAX_PREFERRED_LENGTH, &cnt, &tot);
+
+	      RevertToSelf ();
+	    }
+
+	  CloseHandle (user_token);
+	}
+    }
+
   if (ret)
     {
       __seterrno_from_win_error (ret);
@@ -292,7 +320,8 @@

 static bool
 get_user_local_groups (PWCHAR logonserver, PWCHAR domain,
-		       cygsidlist &grp_list, PWCHAR user)
+		       cygsidlist &grp_list, PWCHAR user,
+		       struct passwd *pw)
 {
   LPLOCALGROUP_INFO_0 buf;
   DWORD cnt, tot;
@@ -301,6 +330,29 @@
   ret = NetUserGetLocalGroups (logonserver, user, 0, LG_INCLUDE_INDIRECT,
 			       (LPBYTE *) &buf, MAX_PREFERRED_LENGTH,
 			       &cnt, &tot);
+
+  if (ret == ERROR_ACCESS_DENIED)
+    {
+      /* See the ERROR_ACCESS_DENIED comment in get_user_groups */
+
+      HANDLE user_token = lsaprivkeyauth (pw);
+
+      if (user_token)
+	{
+	  if (ImpersonateLoggedOnUser (user_token))
+	    {
+	      ret = NetUserGetLocalGroups (
+		logonserver, user, 0, LG_INCLUDE_INDIRECT,
+		(LPBYTE *) &buf, MAX_PREFERRED_LENGTH,
+		&cnt, &tot);
+
+	      RevertToSelf ();
+	    }
+
+	  CloseHandle (user_token);
+	}
+    }
+
   if (ret)
     {
       __seterrno_from_win_error (ret);
@@ -482,10 +534,10 @@
       return false;
     }
   if (get_logon_server (domain, server, false)
-      && !get_user_groups (server, grp_list, user, domain)
+      && !get_user_groups (server, grp_list, user, domain, pw)
       && get_logon_server (domain, server, true))
-    get_user_groups (server, grp_list, user, domain);
-  get_user_local_groups (server, domain, grp_list, user);
+    get_user_groups (server, grp_list, user, domain, pw);
+  get_user_local_groups (server, domain, grp_list, user, pw);
   get_unix_group_sidlist (pw, grp_list);
   return true;
 }




Attachment: signature.asc
Description: OpenPGP digital signature


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