Skip to content

Commit 09097de

Browse files
rgliddendscho
authored andcommitted
msys2-runtime: restore fast path for current user primary group
Commit a5bcfe6 removed an optimization that fetches the default group from the current user token, as it is sometimes not accurate such as when groups like the builtin Administrators group is the primary group. However, removing this optimization causes extremely poor performance when connected to some Active Directory environments. Restored this optimization as the default behaviour, and added a `group: db-accurate` option to `nsswitch.conf` that can be used to disable the optimization in cases where accurate group information is required. This fixes git-for-windows/git#4459 Signed-off-by: Richard Glidden <[email protected]>
1 parent efae895 commit 09097de

File tree

4 files changed

+46
-8
lines changed

4 files changed

+46
-8
lines changed

winsup/cygwin/include/sys/cygwin.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ enum
219219
enum
220220
{
221221
NSS_SRC_FILES = 1,
222-
NSS_SRC_DB = 2
222+
NSS_SRC_DB = 2,
223+
NSS_SRC_DB_ACCURATE = 4
223224
};
224225

225226
/* Enumeration source constants for CW_SETENT called from mkpasswd/mkgroup. */

winsup/cygwin/local_includes/cygheap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ class cygheap_pwdgrp
405405
inline int nss_pwd_src () const { return pwd_src; } /* CW_GETNSS_PWD_SRC */
406406
inline bool nss_grp_files () const { return !!(grp_src & NSS_SRC_FILES); }
407407
inline bool nss_grp_db () const { return !!(grp_src & NSS_SRC_DB); }
408+
inline bool nss_grp_db_accurate () const { return !!(grp_src & NSS_SRC_DB_ACCURATE); }
408409
inline int nss_grp_src () const { return grp_src; } /* CW_GETNSS_GRP_SRC */
409410
inline bool nss_cygserver_caching () const { return caching; }
410411
inline void nss_disable_cygserver_caching () { caching = false; }

winsup/cygwin/uinfo.cc

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,11 @@ cygheap_pwdgrp::nss_init_line (const char *line)
637637
*src |= NSS_SRC_DB;
638638
c += 2;
639639
}
640+
else if (NSS_CMP ("db-accurate"))
641+
{
642+
*src |= NSS_SRC_DB | NSS_SRC_DB_ACCURATE;
643+
c += 11;
644+
}
640645
else
641646
{
642647
c += strcspn (c, " \t");
@@ -1952,6 +1957,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
19521957
gid_t gid = ILLEGAL_GID;
19531958
bool is_domain_account = true;
19541959
PCWSTR domain = NULL;
1960+
bool get_default_group_from_current_user_token = false;
19551961
char *shell = NULL;
19561962
char *home = NULL;
19571963
char *gecos = NULL;
@@ -2466,19 +2472,31 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
24662472
uid = posix_offset + sid_sub_auth_rid (sid);
24672473
if (!is_group () && acc_type == SidTypeUser)
24682474
{
2469-
/* Default primary group. Make the educated guess that the user
2470-
is in group "Domain Users" or "None". */
2471-
gid = posix_offset + DOMAIN_GROUP_RID_USERS;
2475+
/* Default primary group. If the sid is the current user, and
2476+
we are not configured for accurate mode, fetch
2477+
the default group from the current user token, otherwise make
2478+
the educated guess that the user is in group "Domain Users"
2479+
or "None". */
2480+
if (!cygheap->pg.nss_grp_db_accurate() && sid == cygheap->user.sid ())
2481+
{
2482+
get_default_group_from_current_user_token = true;
2483+
gid = posix_offset
2484+
+ sid_sub_auth_rid (cygheap->user.groups.pgsid);
2485+
}
2486+
else
2487+
gid = posix_offset + DOMAIN_GROUP_RID_USERS;
24722488
}
24732489

24742490
if (is_domain_account)
24752491
{
24762492
/* Skip this when creating group entries and for non-users. */
24772493
if (is_group() || acc_type != SidTypeUser)
24782494
break;
2479-
/* Fetch primary group from AD and overwrite the one we
2480-
just guessed above. */
2481-
if (cldap->fetch_ad_account (sid, false, domain))
2495+
/* For the current user we got correctly cased username and
2496+
the primary group via process token. For any other user
2497+
we fetch it from AD and overwrite it. */
2498+
if (!get_default_group_from_current_user_token
2499+
&& cldap->fetch_ad_account (sid, false, domain))
24822500
{
24832501
if ((val = cldap->get_account_name ()))
24842502
wcscpy (name, val);

winsup/doc/ntsec.xml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,16 @@ The two lines starting with the keywords <literal>passwd:</literal> and
930930
information from. <literal>files</literal> means, fetch the information
931931
from the corresponding file in the /etc directory. <literal>db</literal>
932932
means, fetch the information from the Windows account databases, the SAM
933-
for local accounts, Active Directory for domain account. Examples:
933+
for local accounts, Active Directory for domain account. For the current
934+
user, the default group is obtained from the current user token to avoid
935+
additional lookups to the group database. <literal>db-accurate</literal>
936+
is only valid on <literal>group:</literal> line, and performs the same
937+
lookups as the <literal>db</literal> option, but disables using the
938+
current user token to retrieve the default group as this optimization
939+
is not accurate in all cases. For example, if you run a native process
940+
with the primary group set to the Administrators builtin group, the
941+
<literal>db</literal> option will return a non-existent group as primary
942+
group. Examples:
934943
</para>
935944

936945
<screen>
@@ -949,6 +958,15 @@ Read passwd entries only from /etc/passwd.
949958
Read group entries only from SAM/AD.
950959
</para>
951960

961+
<screen>
962+
group: db-accurate
963+
</screen>
964+
965+
<para>
966+
Read group entries only from SAM/AD. Force the use of the group database
967+
for the current user.
968+
</para>
969+
952970
<screen>
953971
group: files # db
954972
</screen>

0 commit comments

Comments
 (0)