[newlib-cygwin] Cygwin: seteuid: work with password-less user switch as well

Corinna Vinschen corinna@sourceware.org
Thu Jan 24 20:20:00 GMT 2019


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

commit 02373d8bec71abcd46421f0ce952ad4e8cfc1422
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Thu Jan 24 21:19:40 2019 +0100

    Cygwin: seteuid: work with password-less user switch as well
    
    The previous patch failed with password-less auth because in
    that case the return code from get_server_groups wasn't tested.
    Fix that.  Also make sure that get_server_groups does not
    check if the account is disabled or locked out when just fetching
    the group list for initgroups or getgrouplist.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/grp.cc      |  2 +-
 winsup/cygwin/sec_auth.cc | 50 +++++++++++++++++++++++++++++------------------
 winsup/cygwin/security.h  |  8 +++++++-
 3 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc
index ca35a4b..a126bff 100644
--- a/winsup/cygwin/grp.cc
+++ b/winsup/cygwin/grp.cc
@@ -738,7 +738,7 @@ get_groups (const char *user, gid_t gid, cygsidlist &gsids)
   struct group *grp = internal_getgrgid (gid, &cldap);
   cygsid usersid, grpsid;
   if (usersid.getfrompw (pw))
-    get_server_groups (gsids, usersid);
+    get_server_groups (gsids, usersid, NO_CHK_DISABLED);
   if (gid != ILLEGAL_GID && grpsid.getfromgr (grp))
     gsids += grpsid;
   cygheap->user.reimpersonate ();
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index 8fdfa3a..af92763 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -523,7 +523,8 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps)
 }
 
 bool
-get_server_groups (cygsidlist &grp_list, PSID usersid)
+get_server_groups (cygsidlist &grp_list, PSID usersid,
+		   acct_disabled_chk_t check_account_disabled)
 {
   WCHAR user[UNLEN + 1];
   WCHAR domain[MAX_DOMAIN_NAME_LEN + 1];
@@ -553,20 +554,23 @@ get_server_groups (cygsidlist &grp_list, PSID usersid)
       && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE
       && get_logon_server (domain, server, DS_IS_FLAT_NAME))
     {
-      NET_API_STATUS napi_stat;
-      USER_INFO_1 *ui1;
-      bool allow_user = false;
-
-      napi_stat = NetUserGetInfo (server, user, 1, (LPBYTE *) &ui1);
-      if (napi_stat == NERR_Success)
-	allow_user = !(ui1->usri1_flags & (UF_ACCOUNTDISABLE | UF_LOCKOUT));
-      if (ui1)
-	NetApiBufferFree (ui1);
-      if (!allow_user)
+      if (check_account_disabled == CHK_DISABLED)
 	{
-	  debug_printf ("User denied: %W\\%W", domain, user);
-	  set_errno (EACCES);
-	  return false;
+	  NET_API_STATUS napi_stat;
+	  USER_INFO_1 *ui1;
+	  bool allow_user = false;
+
+	  napi_stat = NetUserGetInfo (server, user, 1, (LPBYTE *) &ui1);
+	  if (napi_stat == NERR_Success)
+	    allow_user = !(ui1->usri1_flags & (UF_ACCOUNTDISABLE | UF_LOCKOUT));
+	  if (ui1)
+	    NetApiBufferFree (ui1);
+	  if (!allow_user)
+	    {
+	      debug_printf ("User denied: %W\\%W", domain, user);
+	      set_errno (EACCES);
+	      return false;
+	    }
 	}
       get_user_groups (server, grp_list, user, domain);
       get_user_local_groups (server, domain, grp_list, user);
@@ -582,7 +586,7 @@ get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
   grp_list *= well_known_authenticated_users_sid;
   if (well_known_system_sid != usersid)
     get_token_group_sidlist (grp_list, my_grps);
-  if (!get_server_groups (grp_list, usersid))
+  if (!get_server_groups (grp_list, usersid, CHK_DISABLED))
     return false;
 
   /* special_pgrp true if pgrpsid is not in normal groups */
@@ -590,17 +594,19 @@ get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
   return true;
 }
 
-static void
+static bool
 get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid,
 		       PTOKEN_GROUPS my_grps, user_groups &groups)
 {
   tmp_list *= well_known_world_sid;
   tmp_list *= well_known_authenticated_users_sid;
   get_token_group_sidlist (tmp_list, my_grps);
-  get_server_groups (tmp_list, usersid);
+  if (!get_server_groups (tmp_list, usersid, CHK_DISABLED))
+    return false;
   for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
     tmp_list += groups.sgsids.sids[gidx];
   tmp_list += groups.pgsid;
+  return true;
 }
 
 /* Fixed size TOKEN_PRIVILEGES list to reflect privileges given to the
@@ -953,7 +959,10 @@ create_token (cygsid &usersid, user_groups &new_groups)
 
   /* Create list of groups, the user is member in. */
   if (new_groups.issetgroups ())
-    get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups);
+    {
+      if (!get_setgroups_sidlist (tmp_gsids, usersid, my_tok_gsids, new_groups))
+	goto out;
+    }
   else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
 				    my_tok_gsids))
     goto out;
@@ -1089,7 +1098,10 @@ lsaauth (cygsid &usersid, user_groups &new_groups)
 
   /* Create list of groups, the user is member in. */
   if (new_groups.issetgroups ())
-    get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups);
+    {
+      if (!get_setgroups_sidlist (tmp_gsids, usersid, NULL, new_groups))
+	goto out;
+    }
   else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid,
 				    NULL))
     goto out;
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index 2f9d0ad..5104bb7 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -482,7 +482,13 @@ HANDLE lsaprivkeyauth (struct passwd *pw);
 /* Verify an existing token */
 bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
 /* Get groups of a user */
-bool get_server_groups (cygsidlist &grp_list, PSID usersid);
+enum acct_disabled_chk_t {
+  NO_CHK_DISABLED = 0,
+  CHK_DISABLED = 1
+};
+
+bool get_server_groups (cygsidlist &grp_list, PSID usersid,
+			acct_disabled_chk_t check_account_disabled);
 
 /* Extract U-domain\user field from passwd entry. */
 void extract_nt_dom_user (const struct passwd *pw, PWCHAR domain, PWCHAR user);



More information about the Cygwin-cvs mailing list