From b49934db7f440e099f628d7ccc3376902bb8800d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 12 Feb 2015 16:55:38 +0000 Subject: [PATCH] * cygheap.h (cygheap_pwdgrp::get_home): Add dnsdomain parameter to declaration in ldap-related method. (cygheap_pwdgrp::get_shell): Ditto. (cygheap_pwdgrp::get_gecos): Ditto. * ldap.cc (cyg_ldap::open): Use NO_ERROR instead of 0. (cyg_ldap::close): Reset last_fetched_sid. (cyg_ldap::fetch_ad_account): Return immediately if sid is the same as last_fetched_sid. Open LDAP connection from here. Move initialization of rdse after open call. Set last_fetched_sid if LDAP call was successful. * ldap.h (class cyg_ldap): Add member last_fetched_sid. (cyg_ldap::cyg_ldap): Initialize last_fetched_sid. (cyg_ldap::is_open): New inline method. * uinfo.cc (cygheap_pwdgrp::init): Drop initialization of db_home, db_shell and db_gecos with "cygwin desc", thus only using the fallback by default. (fetch_windows_home): Add parameter dnsdomain. Call cyg_ldap::fetch_ad_account if required. (fetch_from_path): Add parameter dnsdomain. Call fetch_windows_home accordingly. (cygheap_pwdgrp::get_home): Accomodate call to fetch_windows_home. Add dnsdomain parameter in ldap-related method. Call cyg_ldap::fetch_ad_account if required. (cygheap_pwdgrp::get_shell): Ditto. (cygheap_pwdgrp::get_gecos): Ditto. (pwdgrp::fetch_account_from_windows): Drop cyg_ldap::open call prior to cyg_ldap::fetch_ad_account call. Set is_current_user to true if we're handling the current user account. Make sure to perform the LDAP calls only for users, and only if required. --- winsup/cygwin/ChangeLog | 32 ++++++ winsup/cygwin/cygheap.h | 12 +- winsup/cygwin/ldap.cc | 23 +++- winsup/cygwin/ldap.h | 7 +- winsup/cygwin/uinfo.cc | 239 ++++++++++++++++++++++++---------------- 5 files changed, 206 insertions(+), 107 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 5dd666ff8..e3969cc2f 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,35 @@ +2015-02-12 Corinna Vinschen + + * cygheap.h (cygheap_pwdgrp::get_home): Add dnsdomain parameter to + declaration in ldap-related method. + (cygheap_pwdgrp::get_shell): Ditto. + (cygheap_pwdgrp::get_gecos): Ditto. + * ldap.cc (cyg_ldap::open): Use NO_ERROR instead of 0. + (cyg_ldap::close): Reset last_fetched_sid. + (cyg_ldap::fetch_ad_account): Return immediately if sid is the same as + last_fetched_sid. Open LDAP connection from here. Move initialization + of rdse after open call. Set last_fetched_sid if LDAP call was + successful. + * ldap.h (class cyg_ldap): Add member last_fetched_sid. + (cyg_ldap::cyg_ldap): Initialize last_fetched_sid. + (cyg_ldap::is_open): New inline method. + * uinfo.cc (cygheap_pwdgrp::init): Drop initialization of db_home, + db_shell and db_gecos with "cygwin desc", thus only using the fallback + by default. + (fetch_windows_home): Add parameter dnsdomain. Call + cyg_ldap::fetch_ad_account if required. + (fetch_from_path): Add parameter dnsdomain. Call fetch_windows_home + accordingly. + (cygheap_pwdgrp::get_home): Accomodate call to fetch_windows_home. + Add dnsdomain parameter in ldap-related method. Call + cyg_ldap::fetch_ad_account if required. + (cygheap_pwdgrp::get_shell): Ditto. + (cygheap_pwdgrp::get_gecos): Ditto. + (pwdgrp::fetch_account_from_windows): Drop cyg_ldap::open call prior to + cyg_ldap::fetch_ad_account call. Set is_current_user to true if we're + handling the current user account. Make sure to perform the LDAP calls + only for users, and only if required. + 2015-02-11 Corinna Vinschen * flock.cc (fhandler_base::lock): Convert accidental system_printf to diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 4b7f66896..6fb7a063b 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -470,18 +470,18 @@ public: inline bool nss_cygserver_caching () const { return caching; } inline void nss_disable_cygserver_caching () { caching = false; } - char *get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR name, - bool fq); + char *get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR dnsdomain, + PCWSTR name, bool fq); char *get_home (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom, PCWSTR name, bool fq); - char *get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR name, - bool fq); + char *get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR dnsdomain, + PCWSTR name, bool fq); char *get_shell (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom, PCWSTR name, bool fq); - char *get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR name, - bool fq); + char *get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR dnsdomain, + PCWSTR name, bool fq); char *get_gecos (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom, PCWSTR name, bool fq); diff --git a/winsup/cygwin/ldap.cc b/winsup/cygwin/ldap.cc index 9daf89b6d..c72274a70 100644 --- a/winsup/cygwin/ldap.cc +++ b/winsup/cygwin/ldap.cc @@ -1,6 +1,6 @@ /* ldap.cc: Helper functions for ldap access to Active Directory. - Copyright 2014 Red Hat, Inc. + Copyright 2014, 2015 Red Hat, Inc. This file is part of Cygwin. @@ -312,11 +312,11 @@ cyg_ldap::next_page () int cyg_ldap::open (PCWSTR domain) { - int ret = 0; + int ret = NO_ERROR; /* Already open? */ if (lh) - return 0; + return NO_ERROR; if ((ret = connect (domain)) != NO_ERROR) goto err; @@ -351,7 +351,7 @@ cyg_ldap::open (PCWSTR domain) val = NULL; ldap_msgfree (msg); msg = entry = NULL; - return 0; + return NO_ERROR; err: close (); return ret; @@ -378,17 +378,24 @@ cyg_ldap::close () rootdse = NULL; srch_id = NULL; srch_msg = srch_entry = NULL; + last_fetched_sid = NO_SID; } bool cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain) { - WCHAR filter[140], *f, *rdse = rootdse; + WCHAR filter[140], *f, *rdse = NULL; LONG len = (LONG) RtlLengthSid (sid); PBYTE s = (PBYTE) sid; static WCHAR hex_wchars[] = L"0123456789abcdef"; tmp_pathbuf tp; + if (last_fetched_sid == sid) + return true; + + if (open (NULL) != NO_ERROR) + return false; + if (msg) { ldap_msgfree (msg); @@ -426,6 +433,11 @@ cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain) r = wcpcpy (r, domain); } } + else + { + /* rootdse is only valid after open. */ + rdse = rootdse; + } if (!user_attr) cygheap->pg.init_ldap_user_attr (); attr = group ? group_attr : user_attr; @@ -436,6 +448,7 @@ cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain) debug_printf ("No entry for %W in rootdse %W", filter, rdse); return false; } + last_fetched_sid = sid; return true; } diff --git a/winsup/cygwin/ldap.h b/winsup/cygwin/ldap.h index d3c28fcbd..4a85ece20 100644 --- a/winsup/cygwin/ldap.h +++ b/winsup/cygwin/ldap.h @@ -1,6 +1,6 @@ /* ldap.h. - Copyright 2014 Red Hat, Inc. + Copyright 2014, 2015 Red Hat, Inc. This file is part of Cygwin. @@ -32,6 +32,7 @@ class cyg_ldap { bool isAD; PLDAPSearch srch_id; PLDAPMessage srch_msg, srch_entry; + cygsid last_fetched_sid; inline int map_ldaperr_to_errno (ULONG lerr); inline int wait (cygthread *thr); @@ -45,7 +46,8 @@ class cyg_ldap { public: cyg_ldap () : lh (NULL), rootdse (NULL), msg (NULL), entry (NULL), val (NULL), - isAD (false), srch_id (NULL), srch_msg (NULL), srch_entry (NULL) + isAD (false), srch_id (NULL), srch_msg (NULL), + srch_entry (NULL), last_fetched_sid (NO_SID) {} ~cyg_ldap () { close (); } @@ -54,6 +56,7 @@ public: ULONG search_s (PWCHAR base, PWCHAR filter, PWCHAR *attrs); ULONG next_page_s (); + bool is_open () const { return !!lh; } operator PLDAP () const { return lh; } int open (PCWSTR in_domain); void close (); diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index f1fb99d01..894276de2 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -604,12 +604,14 @@ cygheap_pwdgrp::init () grp_src = (NSS_SRC_FILES | NSS_SRC_DB); prefix = NSS_PFX_AUTO; separator[0] = L'+'; +#if 0 home_scheme[0].method = NSS_SCHEME_CYGWIN; home_scheme[1].method = NSS_SCHEME_DESC; shell_scheme[0].method = NSS_SCHEME_CYGWIN; shell_scheme[1].method = NSS_SCHEME_DESC; gecos_scheme[0].method = NSS_SCHEME_CYGWIN; gecos_scheme[1].method = NSS_SCHEME_DESC; +#endif enums = (ENUM_CACHE | ENUM_BUILTIN); enum_tdoms = NULL; caching = true; /* INTERNAL ONLY */ @@ -815,20 +817,24 @@ cygheap_pwdgrp::nss_init_line (const char *line) } static char * -fetch_windows_home (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid) +fetch_windows_home (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, + PCWSTR dnsdomain) { PCWSTR home_from_db = NULL; char *home = NULL; if (pldap) { + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { #if 0 - /* Disable preferring homeDrive for now. The drive letter may not - be available when it's needed. */ - home_from_db = pldap->get_string_attribute (L"homeDrive"); - if (!home_from_db || !*home_from_db) + /* Disable preferring homeDrive for now. The drive letter may not + be available when it's needed. */ + home_from_db = pldap->get_string_attribute (L"homeDrive"); + if (!home_from_db || !*home_from_db) #endif - home_from_db = pldap->get_string_attribute (L"homeDirectory"); + home_from_db = pldap->get_string_attribute (L"homeDirectory"); + } } else if (ui) { @@ -902,8 +908,8 @@ fetch_from_description (PCWSTR desc, PCWSTR search, size_t len) } static char * -fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, - PCWSTR str, PCWSTR dom, PCWSTR name, bool full_qualified) +fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, PCWSTR str, + PCWSTR dom, PCWSTR dnsdomain, PCWSTR name, bool full_qualified) { tmp_pathbuf tp; PWCHAR wpath = tp.w_get (); @@ -936,7 +942,7 @@ fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, w = wcpncpy (w, dom, we - w); break; case L'H': - home = fetch_windows_home (pldap, ui, sid); + home = fetch_windows_home (pldap, ui, sid, dnsdomain); if (home) { /* Drop one leading slash to accommodate home being an @@ -965,7 +971,7 @@ fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, char * cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, - PCWSTR name, bool full_qualified) + PCWSTR dnsdomain, PCWSTR name, bool full_qualified) { PWCHAR val; char *home = NULL; @@ -977,35 +983,49 @@ cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, case NSS_SCHEME_FALLBACK: return NULL; case NSS_SCHEME_WINDOWS: - home = fetch_windows_home (pldap, NULL, sid); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + home = fetch_windows_home (pldap, NULL, sid, dnsdomain); break; case NSS_SCHEME_CYGWIN: - val = pldap->get_string_attribute (L"cygwinHome"); - if (val && *val) - sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"cygwinHome"); + if (val && *val) + sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val); + } break; case NSS_SCHEME_UNIX: - val = pldap->get_string_attribute (L"unixHomeDirectory"); - if (val && *val) - sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"unixHomeDirectory"); + if (val && *val) + sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val); + } break; case NSS_SCHEME_DESC: - val = pldap->get_string_attribute (L"description"); - if (val && *val) - home = fetch_from_description (val, L"home=\"", 6); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"description"); + if (val && *val) + home = fetch_from_description (val, L"home=\"", 6); + } break; case NSS_SCHEME_PATH: home = fetch_from_path (pldap, NULL, sid, home_scheme[idx].attrib, - dom, name, full_qualified); + dom, dnsdomain, name, full_qualified); break; case NSS_SCHEME_FREEATTR: - val = pldap->get_string_attribute (home_scheme[idx].attrib); - if (val && *val) + if (pldap->fetch_ad_account (sid, false, dnsdomain)) { - if (isdrive (val) || *val == '\\') - home = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, val); - else - sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val); + val = pldap->get_string_attribute (home_scheme[idx].attrib); + if (val && *val) + { + if (isdrive (val) || *val == '\\') + home = (char *) + cygwin_create_path (CCP_WIN_W_TO_POSIX, val); + else + sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val); + } } break; } @@ -1026,7 +1046,7 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom, case NSS_SCHEME_FALLBACK: return NULL; case NSS_SCHEME_WINDOWS: - home = fetch_windows_home (NULL, ui, sid); + home = fetch_windows_home (NULL, ui, sid, NULL); break; case NSS_SCHEME_CYGWIN: case NSS_SCHEME_UNIX: @@ -1037,7 +1057,7 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom, break; case NSS_SCHEME_PATH: home = fetch_from_path (NULL, ui, sid, home_scheme[idx].attrib, - dom, name, full_qualified); + dom, NULL, name, full_qualified); break; } } @@ -1046,7 +1066,7 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom, char * cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, - PCWSTR name, bool full_qualified) + PCWSTR dnsdomain, PCWSTR name, bool full_qualified) { PWCHAR val; char *shell = NULL; @@ -1060,32 +1080,45 @@ cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, case NSS_SCHEME_WINDOWS: break; case NSS_SCHEME_CYGWIN: - val = pldap->get_string_attribute (L"cygwinShell"); - if (val && *val) - sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"cygwinShell"); + if (val && *val) + sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val); + } break; case NSS_SCHEME_UNIX: - val = pldap->get_string_attribute (L"loginShell"); - if (val && *val) - sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"loginShell"); + if (val && *val) + sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val); + } break; case NSS_SCHEME_DESC: - val = pldap->get_string_attribute (L"description"); - if (val && *val) - shell = fetch_from_description (val, L"shell=\"", 7); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"description"); + if (val && *val) + shell = fetch_from_description (val, L"shell=\"", 7); + } break; case NSS_SCHEME_PATH: shell = fetch_from_path (pldap, NULL, sid, shell_scheme[idx].attrib, - dom, name, full_qualified); + dom, dnsdomain, name, full_qualified); break; case NSS_SCHEME_FREEATTR: - val = pldap->get_string_attribute (shell_scheme[idx].attrib); - if (val && *val) + if (pldap->fetch_ad_account (sid, false, dnsdomain)) { - if (isdrive (val) || *val == '\\') - shell = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, val); - else - sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val); + val = pldap->get_string_attribute (shell_scheme[idx].attrib); + if (val && *val) + { + if (isdrive (val) || *val == '\\') + shell = (char *) + cygwin_create_path (CCP_WIN_W_TO_POSIX, val); + else + sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val); + } } break; } @@ -1115,7 +1148,7 @@ cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom, break; case NSS_SCHEME_PATH: shell = fetch_from_path (NULL, ui, sid, shell_scheme[idx].attrib, - dom, name, full_qualified); + dom, NULL, name, full_qualified); break; } } @@ -1133,7 +1166,7 @@ colon_to_semicolon (char *str) char * cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, - PCWSTR name, bool full_qualified) + PCWSTR dnsdomain, PCWSTR name, bool full_qualified) { PWCHAR val; char *gecos = NULL; @@ -1145,34 +1178,49 @@ cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, case NSS_SCHEME_FALLBACK: return NULL; case NSS_SCHEME_WINDOWS: - val = pldap->get_string_attribute (L"displayName"); - if (val && *val) - sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"displayName"); + if (val && *val) + sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); + } break; case NSS_SCHEME_CYGWIN: - val = pldap->get_string_attribute (L"cygwinGecos"); - if (val && *val) - sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"cygwinGecos"); + if (val && *val) + sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); + } break; case NSS_SCHEME_UNIX: - val = pldap->get_string_attribute (L"gecos"); - if (val && *val) - sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"gecos"); + if (val && *val) + sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); + } break; case NSS_SCHEME_DESC: - val = pldap->get_string_attribute (L"description"); - if (val && *val) - gecos = fetch_from_description (val, L"gecos=\"", 7); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (L"description"); + if (val && *val) + gecos = fetch_from_description (val, L"gecos=\"", 7); + } break; case NSS_SCHEME_PATH: gecos = fetch_from_path (pldap, NULL, sid, gecos_scheme[idx].attrib + 1, - dom, name, full_qualified); + dom, dnsdomain, name, full_qualified); break; case NSS_SCHEME_FREEATTR: - val = pldap->get_string_attribute (gecos_scheme[idx].attrib); - if (val && *val) - sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); + if (pldap->fetch_ad_account (sid, false, dnsdomain)) + { + val = pldap->get_string_attribute (gecos_scheme[idx].attrib); + if (val && *val) + sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); + } break; } } @@ -1206,7 +1254,7 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom, break; case NSS_SCHEME_PATH: gecos = fetch_from_path (NULL, ui, sid, gecos_scheme[idx].attrib + 1, - dom, name, full_qualified); + dom, NULL, name, full_qualified); break; } } @@ -1676,6 +1724,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) gid_t gid = ILLEGAL_GID; bool is_domain_account = true; PCWSTR domain = NULL; + bool is_current_user = false; char *shell = NULL; char *home = NULL; char *gecos = NULL; @@ -1708,8 +1757,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) DC for some weird reason. Use LDAP instead. */ PWCHAR val; - if (cldap->open (NULL) == NO_ERROR - && cldap->fetch_ad_account (sid, is_group ()) + if (cldap->fetch_ad_account (sid, true) && (val = cldap->get_group_name ())) { wcpcpy (name, val); @@ -2069,49 +2117,52 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap) the educated guess that the user is in group "Domain Users" or "None". */ if (sid == cygheap->user.sid ()) - gid = posix_offset - + sid_sub_auth_rid (cygheap->user.groups.pgsid); + { + is_current_user = true; + gid = posix_offset + + sid_sub_auth_rid (cygheap->user.groups.pgsid); + } else gid = posix_offset + DOMAIN_GROUP_RID_USERS; } if (is_domain_account) { + /* Skip this when creating group entries and for non-users. */ + if (is_group() || acc_type != SidTypeUser) + break; /* On AD machines, use LDAP to fetch domain account infos. */ if (cygheap->dom.primary_dns_name ()) { - if (cldap->open (NULL) != NO_ERROR) - break; - if (cldap->fetch_ad_account (sid, is_group (), domain)) + /* For the current user we got the primary group from the + user token. For any other user we fetch it from AD. */ + if (!is_current_user + && cldap->fetch_ad_account (sid, false, domain) + && (id_val = cldap->get_primary_gid ()) != ILLEGAL_GID) + gid = posix_offset + id_val; + home = cygheap->pg.get_home (cldap, sid, dom, domain, + name, fully_qualified_name); + shell = cygheap->pg.get_shell (cldap, sid, dom, domain, + name, + fully_qualified_name); + gecos = cygheap->pg.get_gecos (cldap, sid, dom, domain, + name, fully_qualified_name); + /* Check and, if necessary, add unix<->windows id mapping + on the fly, unless we're called from getpwent. */ + if (!pldap && cldap->is_open ()) { - if ((id_val = cldap->get_primary_gid ()) != ILLEGAL_GID) - gid = posix_offset + id_val; - if (!is_group ()) - { - home = cygheap->pg.get_home (cldap, sid, dom, name, - fully_qualified_name); - shell = cygheap->pg.get_shell (cldap, sid, dom, name, - fully_qualified_name); - gecos = cygheap->pg.get_gecos (cldap, sid, dom, name, - fully_qualified_name); - } - /* Check and, if necessary, add unix<->windows id mapping - on the fly, unless we're called from getpwent. */ - if (!pldap) - { - id_val = cldap->get_unix_uid (); - if (id_val != ILLEGAL_UID - && cygheap->ugid_cache.get_uid (id_val) - == ILLEGAL_UID) - cygheap->ugid_cache.add_uid (id_val, uid); - } + id_val = cldap->get_unix_uid (); + if (id_val != ILLEGAL_UID + && cygheap->ugid_cache.get_uid (id_val) + == ILLEGAL_UID) + cygheap->ugid_cache.add_uid (id_val, uid); } } /* If primary_dns_name() is empty, we're likely running under an NT4 domain, so we can't use LDAP. For user accounts fall back to NetUserGetInfo. This isn't overly fast, but keep in mind that NT4 domains are mostly replaced by AD these days. */ - else if (!is_group () && acc_type == SidTypeUser) + else { WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3]; NET_API_STATUS nas; -- 2.43.5