Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2019-02-23 19:22:44 +0300
committerCorinna Vinschen <corinna@vinschen.de>2019-02-23 19:22:44 +0300
commit322ab51659dbac7ff6b5a6aa5bfb3099a7e11681 (patch)
tree56608881d297befb036001930a6f6c1076c8b635
parent649911fb40e45bc9a1ad8a3c28d90eec78c9cb7f (diff)
Cygwin: user profile: fetch roaming profile path via LDAP
Commit 649911fb40e45bc9a1ad8a3c28d90eec78c9cb7f avoids the calls to NetUserGetGroups and NetUserGetLocalGroups since these can take a lot of time. The same problem potentially occurs when loading the user profile. The code fetches the roaming profile path calling NetUserGetInfo, which also can be rather slow. To avoid this problem, fetch the profile patch using LDAP. Also, don't bail out early if the user's registry hive already exists. This may result in outdated information. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/ldap.cc1
-rw-r--r--winsup/cygwin/ldap.h2
-rw-r--r--winsup/cygwin/sec_auth.cc66
3 files changed, 48 insertions, 21 deletions
diff --git a/winsup/cygwin/ldap.cc b/winsup/cygwin/ldap.cc
index dcd4fc461..01e892f03 100644
--- a/winsup/cygwin/ldap.cc
+++ b/winsup/cygwin/ldap.cc
@@ -36,6 +36,7 @@ static const PCWSTR std_user_attr[] =
L"objectSid",
L"primaryGroupID",
L"uidNumber",
+ L"profilePath",
L"cygwinUnixUid", /* TODO */
/* windows scheme */
L"displayName",
diff --git a/winsup/cygwin/ldap.h b/winsup/cygwin/ldap.h
index 4c2437a6f..d51f18cbb 100644
--- a/winsup/cygwin/ldap.h
+++ b/winsup/cygwin/ldap.h
@@ -63,4 +63,6 @@ public:
PWCHAR get_account_name ()
{ return get_string_attribute (L"sAMAccountName"); }
gid_t get_unix_gid () { return get_num_attribute (L"gidNumber"); }
+ PWCHAR get_profile_path ()
+ { return get_string_attribute (L"profilePath"); }
};
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index 459fe5420..c96011d6d 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -231,23 +231,12 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid)
WCHAR domain[DNLEN + 1];
WCHAR username[UNLEN + 1];
WCHAR sid[128];
- HKEY hkey;
WCHAR userpath[MAX_PATH];
PROFILEINFOW pi;
- WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
- NET_API_STATUS nas = NERR_UserNotFound;
- PUSER_INFO_3 ui;
extract_nt_dom_user (pw, domain, username);
usersid.string (sid);
- debug_printf ("user: <%W> <%W>", username, sid);
- /* Check if user hive is already loaded. */
- if (!RegOpenKeyExW (HKEY_USERS, sid, 0, KEY_READ, &hkey))
- {
- debug_printf ("User registry hive for %W already exists", username);
- RegCloseKey (hkey);
- return NULL;
- }
+ debug_printf ("user: <%W> <%W> <%W>", username, domain, sid);
/* Check if the local profile dir has already been created. */
if (!get_user_profile_directory (sid, userpath, MAX_PATH))
{
@@ -264,21 +253,56 @@ load_user_profile (HANDLE token, struct passwd *pw, cygpsid &usersid)
pi.dwSize = sizeof pi;
pi.dwFlags = PI_NOUI;
pi.lpUserName = username;
- /* Check if user has a roaming profile and fill in lpProfilePath, if so. */
- if (get_logon_server (domain, server, DS_IS_FLAT_NAME))
+ /* Check if user has a roaming profile and fill in lpProfilePath, if so.
+ Call NetUserGetInfo only for local machine accounts, use LDAP otherwise. */
+ if (!wcscasecmp (domain, cygheap->dom.account_flat_name ()))
{
- nas = NetUserGetInfo (server, username, 3, (PBYTE *) &ui);
- if (NetUserGetInfo (server, username, 3, (PBYTE *) &ui) != NERR_Success)
+ NET_API_STATUS nas;
+ PUSER_INFO_3 ui;
+
+ nas = NetUserGetInfo (NULL, username, 3, (PBYTE *) &ui);
+ if (nas != NERR_Success)
debug_printf ("NetUserGetInfo, %u", nas);
- else if (ui->usri3_profile && *ui->usri3_profile)
- pi.lpProfilePath = ui->usri3_profile;
+ else
+ {
+ if (ui->usri3_profile && *ui->usri3_profile)
+ pi.lpProfilePath = ui->usri3_profile;
+ NetApiBufferFree (ui);
+ }
+ }
+ else
+ {
+ cyg_ldap cldap;
+ PWCHAR dnsdomain = NULL;
+
+ if (!wcscasecmp (domain, cygheap->dom.primary_flat_name ()))
+ dnsdomain = wcsdup (cygheap->dom.primary_dns_name ());
+ else
+ {
+ PDS_DOMAIN_TRUSTSW td = NULL;
+
+ for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx)
+ if (!wcscasecmp (domain, td->NetbiosDomainName))
+ {
+ dnsdomain = wcsdup (td->DnsDomainName);
+ break;
+ }
+ }
+ if (cldap.fetch_ad_account (usersid, false, dnsdomain))
+ {
+ PWCHAR val = cldap.get_profile_path ();
+ if (val && *val)
+ {
+ wcsncpy (userpath, val, MAX_PATH - 1);
+ userpath[MAX_PATH - 1] = L'\0';
+ pi.lpProfilePath = userpath;
+ }
+ }
+ free (dnsdomain);
}
if (!LoadUserProfileW (token, &pi))
debug_printf ("LoadUserProfileW, %E");
- /* Free buffer created by NetUserGetInfo */
- if (nas == NERR_Success)
- NetApiBufferFree (ui);
return pi.hProfile;
}