aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2019-02-22 18:31:03 +0100
committerCorinna Vinschen <corinna@vinschen.de>2019-02-22 21:58:51 +0100
commit649911fb40e45bc9a1ad8a3c28d90eec78c9cb7f (patch)
treeddccfde67116f5da5668ad38a495ddf883b46001
parent105fbdebdd3c65f96c7a95e1d5c527ce5790ac5e (diff)
downloadnewlib-649911fb40e45bc9a1ad8a3c28d90eec78c9cb7f.zip
newlib-649911fb40e45bc9a1ad8a3c28d90eec78c9cb7f.tar.gz
newlib-649911fb40e45bc9a1ad8a3c28d90eec78c9cb7f.tar.bz2
Cygwin: get_user_groups: fetch a user's group list from identification token
NetUserGetGroups and NetUserGetLocalGroups sometimes take a lot of time (up to more than 2 mins) for no apparent reason. Call s4uauth to generate an identification token for the user and fetch the group list from there. This is *much* faster. Keep the old code only for the sake of WOW64 on Vista and Windows 7, which don't implement MsV1_0S4ULogon. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/sec_auth.cc83
-rw-r--r--winsup/cygwin/wincap.cc10
-rw-r--r--winsup/cygwin/wincap.h2
3 files changed, 67 insertions, 28 deletions
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index 54182dd..459fe54 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -535,7 +535,6 @@ get_server_groups (cygsidlist &grp_list, PSID usersid,
{
WCHAR user[UNLEN + 1];
WCHAR domain[MAX_DOMAIN_NAME_LEN + 1];
- WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
DWORD ulen = UNLEN + 1;
DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
SID_NAME_USE use;
@@ -546,41 +545,73 @@ get_server_groups (cygsidlist &grp_list, PSID usersid,
return true;
}
- grp_list *= well_known_world_sid;
- grp_list *= well_known_authenticated_users_sid;
-
if (!LookupAccountSidW (NULL, usersid, user, &ulen, domain, &dlen, &use))
{
__seterrno ();
return false;
}
/* If the SID does NOT start with S-1-5-21, the domain is some builtin
- domain. The search for a logon server and fetching group accounts
- is moot. */
+ domain. We don't fetch a group list then. */
if (sid_id_auth (usersid) == 5 /* SECURITY_NT_AUTHORITY */
- && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE
- && get_logon_server (domain, server, DS_IS_FLAT_NAME))
+ && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE)
{
- if (check_account_disabled == CHK_DISABLED)
+ if (wincap.no_msv1_0_s4u_logon_in_wow64 ())
{
- 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)
+ WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
+
+ if (!get_logon_server (domain, server, DS_IS_FLAT_NAME))
+ return false;
+ 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;
+ }
}
+ grp_list *= well_known_world_sid;
+ grp_list *= well_known_authenticated_users_sid;
+ get_user_groups (server, grp_list, user, domain);
+ get_user_local_groups (domain, grp_list, user);
+ return true;
}
- get_user_groups (server, grp_list, user, domain);
- get_user_local_groups (domain, grp_list, user);
+
+ tmp_pathbuf tp;
+ HANDLE token;
+ NTSTATUS status;
+ PTOKEN_GROUPS groups;
+ ULONG size;
+
+ token = s4uauth (false, domain, user, status);
+ if (!token)
+ return false;
+
+ groups = (PTOKEN_GROUPS) tp.w_get ();
+ status = NtQueryInformationToken (token, TokenGroups, groups,
+ 2 * NT_MAX_PATH, &size);
+ if (NT_SUCCESS (status))
+ for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+ {
+ if (groups->Groups[pg].Attributes & SE_GROUP_USE_FOR_DENY_ONLY)
+ continue;
+ cygpsid grpsid = groups->Groups[pg].Sid;
+ if (sid_id_auth (grpsid) == 5 /* SECURITY_NT_AUTHORITY */
+ && sid_sub_auth (grpsid, 0) == SECURITY_NT_NON_UNIQUE)
+ grp_list += grpsid;
+ else
+ grp_list *= grpsid;
+ }
+ NtClose (token);
}
return true;
}
@@ -589,8 +620,6 @@ static bool
get_initgroups_sidlist (cygsidlist &grp_list, PSID usersid, PSID pgrpsid,
PTOKEN_GROUPS my_grps)
{
- grp_list *= well_known_world_sid;
- 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, CHK_DISABLED))
@@ -605,8 +634,6 @@ 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);
if (!get_server_groups (tmp_list, usersid, CHK_DISABLED))
return false;
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 132265c..7e381f4 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -39,6 +39,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
has_posix_unlink_semantics:false,
has_case_sensitive_dirs:false,
has_posix_rename_semantics:false,
+ no_msv1_0_s4u_logon_in_wow64:true,
},
};
@@ -63,6 +64,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_posix_unlink_semantics:false,
has_case_sensitive_dirs:false,
has_posix_rename_semantics:false,
+ no_msv1_0_s4u_logon_in_wow64:true,
},
};
@@ -87,6 +89,7 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_posix_unlink_semantics:false,
has_case_sensitive_dirs:false,
has_posix_rename_semantics:false,
+ no_msv1_0_s4u_logon_in_wow64:false,
},
};
@@ -111,6 +114,7 @@ wincaps wincap_10_1507 __attribute__((section (".cygwin_dll_common"), shared))
has_posix_unlink_semantics:false,
has_case_sensitive_dirs:false,
has_posix_rename_semantics:false,
+ no_msv1_0_s4u_logon_in_wow64:false,
},
};
@@ -135,6 +139,7 @@ wincaps wincap_10_1511 __attribute__((section (".cygwin_dll_common"), shared)) =
has_posix_unlink_semantics:false,
has_case_sensitive_dirs:false,
has_posix_rename_semantics:false,
+ no_msv1_0_s4u_logon_in_wow64:false,
},
};
@@ -159,6 +164,7 @@ wincaps wincap_10_1703 __attribute__((section (".cygwin_dll_common"), shared)) =
has_posix_unlink_semantics:false,
has_case_sensitive_dirs:false,
has_posix_rename_semantics:false,
+ no_msv1_0_s4u_logon_in_wow64:false,
},
};
@@ -183,6 +189,7 @@ wincaps wincap_10_1709 __attribute__((section (".cygwin_dll_common"), shared)) =
has_posix_unlink_semantics:true,
has_case_sensitive_dirs:false,
has_posix_rename_semantics:false,
+ no_msv1_0_s4u_logon_in_wow64:false,
},
};
@@ -207,6 +214,7 @@ wincaps wincap_10_1803 __attribute__((section (".cygwin_dll_common"), shared)) =
has_posix_unlink_semantics:true,
has_case_sensitive_dirs:true,
has_posix_rename_semantics:false,
+ no_msv1_0_s4u_logon_in_wow64:false,
},
};
@@ -231,6 +239,7 @@ wincaps wincap_10_1809 __attribute__((section (".cygwin_dll_common"), shared)) =
has_posix_unlink_semantics:true,
has_case_sensitive_dirs:true,
has_posix_rename_semantics:true,
+ no_msv1_0_s4u_logon_in_wow64:true,
},
};
@@ -303,6 +312,7 @@ wincapc::init ()
((wincaps *)caps)->needs_count_in_si_lpres2 = false;
((wincaps *)caps)->has_gaa_largeaddress_bug = false;
((wincaps *)caps)->has_broken_prefetchvm = false;
+ ((wincaps *)caps)->no_msv1_0_s4u_logon_in_wow64 = false;
}
__small_sprintf (osnam, "NT-%d.%d", version.dwMajorVersion,
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 75b7a9f..0e83f67 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -33,6 +33,7 @@ struct wincaps
unsigned has_posix_unlink_semantics : 1;
unsigned has_case_sensitive_dirs : 1;
unsigned has_posix_rename_semantics : 1;
+ unsigned no_msv1_0_s4u_logon_in_wow64 : 1;
};
};
@@ -87,6 +88,7 @@ public:
bool IMPLEMENT (has_posix_unlink_semantics)
bool IMPLEMENT (has_case_sensitive_dirs)
bool IMPLEMENT (has_posix_rename_semantics)
+ bool IMPLEMENT (no_msv1_0_s4u_logon_in_wow64)
void disable_case_sensitive_dirs ()
{