public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Daniel Colascione <dancol@dancol.org>
To: cygwin@cygwin.com
Subject: Re: DS_FORCE_REDISCOVERY  lookup slows ssh logon
Date: Sat, 08 Jun 2013 08:32:00 -0000	[thread overview]
Message-ID: <51B2EC44.30102@dancol.org> (raw)
In-Reply-To: <51B2D55B.3020904@dancol.org>

[-- Attachment #1: Type: text/plain, Size: 3965 bytes --]

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 #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

  reply	other threads:[~2013-06-08  8:32 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-08  6:55 Daniel Colascione
2013-06-08  8:32 ` Daniel Colascione [this message]
2013-06-08 18:47   ` Corinna Vinschen
2013-06-08 19:02     ` Corinna Vinschen
2013-06-11  7:44       ` Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51B2EC44.30102@dancol.org \
    --to=dancol@dancol.org \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).