* 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.
This commit is contained in:
@@ -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;
|
||||
|
Reference in New Issue
Block a user