4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-31 19:40:33 +08:00

* 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:
Corinna Vinschen 2015-02-12 16:55:38 +00:00
parent 54ade28dfa
commit b49934db7f
5 changed files with 206 additions and 107 deletions

View File

@ -1,3 +1,35 @@
2015-02-12 Corinna Vinschen <corinna@vinschen.de>
* 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 <corinna@vinschen.de> 2015-02-11 Corinna Vinschen <corinna@vinschen.de>
* flock.cc (fhandler_base::lock): Convert accidental system_printf to * flock.cc (fhandler_base::lock): Convert accidental system_printf to

View File

@ -470,18 +470,18 @@ public:
inline bool nss_cygserver_caching () const { return caching; } inline bool nss_cygserver_caching () const { return caching; }
inline void nss_disable_cygserver_caching () { caching = false; } inline void nss_disable_cygserver_caching () { caching = false; }
char *get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR name, char *get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR dnsdomain,
bool fq); PCWSTR name, bool fq);
char *get_home (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom, char *get_home (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom,
PCWSTR name, bool fq); PCWSTR name, bool fq);
char *get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR name, char *get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR dnsdomain,
bool fq); PCWSTR name, bool fq);
char *get_shell (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom, char *get_shell (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom,
PCWSTR name, bool fq); PCWSTR name, bool fq);
char *get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR name, char *get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, PCWSTR dnsdomain,
bool fq); PCWSTR name, bool fq);
char *get_gecos (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom, char *get_gecos (struct _USER_INFO_3 *ui, cygpsid &sid, PCWSTR dom,
PCWSTR name, bool fq); PCWSTR name, bool fq);

View File

@ -1,6 +1,6 @@
/* ldap.cc: Helper functions for ldap access to Active Directory. /* 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. This file is part of Cygwin.
@ -312,11 +312,11 @@ cyg_ldap::next_page ()
int int
cyg_ldap::open (PCWSTR domain) cyg_ldap::open (PCWSTR domain)
{ {
int ret = 0; int ret = NO_ERROR;
/* Already open? */ /* Already open? */
if (lh) if (lh)
return 0; return NO_ERROR;
if ((ret = connect (domain)) != NO_ERROR) if ((ret = connect (domain)) != NO_ERROR)
goto err; goto err;
@ -351,7 +351,7 @@ cyg_ldap::open (PCWSTR domain)
val = NULL; val = NULL;
ldap_msgfree (msg); ldap_msgfree (msg);
msg = entry = NULL; msg = entry = NULL;
return 0; return NO_ERROR;
err: err:
close (); close ();
return ret; return ret;
@ -378,17 +378,24 @@ cyg_ldap::close ()
rootdse = NULL; rootdse = NULL;
srch_id = NULL; srch_id = NULL;
srch_msg = srch_entry = NULL; srch_msg = srch_entry = NULL;
last_fetched_sid = NO_SID;
} }
bool bool
cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain) 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); LONG len = (LONG) RtlLengthSid (sid);
PBYTE s = (PBYTE) sid; PBYTE s = (PBYTE) sid;
static WCHAR hex_wchars[] = L"0123456789abcdef"; static WCHAR hex_wchars[] = L"0123456789abcdef";
tmp_pathbuf tp; tmp_pathbuf tp;
if (last_fetched_sid == sid)
return true;
if (open (NULL) != NO_ERROR)
return false;
if (msg) if (msg)
{ {
ldap_msgfree (msg); ldap_msgfree (msg);
@ -426,6 +433,11 @@ cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain)
r = wcpcpy (r, domain); r = wcpcpy (r, domain);
} }
} }
else
{
/* rootdse is only valid after open. */
rdse = rootdse;
}
if (!user_attr) if (!user_attr)
cygheap->pg.init_ldap_user_attr (); cygheap->pg.init_ldap_user_attr ();
attr = group ? group_attr : 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); debug_printf ("No entry for %W in rootdse %W", filter, rdse);
return false; return false;
} }
last_fetched_sid = sid;
return true; return true;
} }

View File

@ -1,6 +1,6 @@
/* ldap.h. /* ldap.h.
Copyright 2014 Red Hat, Inc. Copyright 2014, 2015 Red Hat, Inc.
This file is part of Cygwin. This file is part of Cygwin.
@ -32,6 +32,7 @@ class cyg_ldap {
bool isAD; bool isAD;
PLDAPSearch srch_id; PLDAPSearch srch_id;
PLDAPMessage srch_msg, srch_entry; PLDAPMessage srch_msg, srch_entry;
cygsid last_fetched_sid;
inline int map_ldaperr_to_errno (ULONG lerr); inline int map_ldaperr_to_errno (ULONG lerr);
inline int wait (cygthread *thr); inline int wait (cygthread *thr);
@ -45,7 +46,8 @@ class cyg_ldap {
public: public:
cyg_ldap () : lh (NULL), rootdse (NULL), msg (NULL), entry (NULL), val (NULL), 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 (); } ~cyg_ldap () { close (); }
@ -54,6 +56,7 @@ public:
ULONG search_s (PWCHAR base, PWCHAR filter, PWCHAR *attrs); ULONG search_s (PWCHAR base, PWCHAR filter, PWCHAR *attrs);
ULONG next_page_s (); ULONG next_page_s ();
bool is_open () const { return !!lh; }
operator PLDAP () const { return lh; } operator PLDAP () const { return lh; }
int open (PCWSTR in_domain); int open (PCWSTR in_domain);
void close (); void close ();

View File

@ -604,12 +604,14 @@ cygheap_pwdgrp::init ()
grp_src = (NSS_SRC_FILES | NSS_SRC_DB); grp_src = (NSS_SRC_FILES | NSS_SRC_DB);
prefix = NSS_PFX_AUTO; prefix = NSS_PFX_AUTO;
separator[0] = L'+'; separator[0] = L'+';
#if 0
home_scheme[0].method = NSS_SCHEME_CYGWIN; home_scheme[0].method = NSS_SCHEME_CYGWIN;
home_scheme[1].method = NSS_SCHEME_DESC; home_scheme[1].method = NSS_SCHEME_DESC;
shell_scheme[0].method = NSS_SCHEME_CYGWIN; shell_scheme[0].method = NSS_SCHEME_CYGWIN;
shell_scheme[1].method = NSS_SCHEME_DESC; shell_scheme[1].method = NSS_SCHEME_DESC;
gecos_scheme[0].method = NSS_SCHEME_CYGWIN; gecos_scheme[0].method = NSS_SCHEME_CYGWIN;
gecos_scheme[1].method = NSS_SCHEME_DESC; gecos_scheme[1].method = NSS_SCHEME_DESC;
#endif
enums = (ENUM_CACHE | ENUM_BUILTIN); enums = (ENUM_CACHE | ENUM_BUILTIN);
enum_tdoms = NULL; enum_tdoms = NULL;
caching = true; /* INTERNAL ONLY */ caching = true; /* INTERNAL ONLY */
@ -815,20 +817,24 @@ cygheap_pwdgrp::nss_init_line (const char *line)
} }
static char * 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; PCWSTR home_from_db = NULL;
char *home = NULL; char *home = NULL;
if (pldap) if (pldap)
{ {
if (pldap->fetch_ad_account (sid, false, dnsdomain))
{
#if 0 #if 0
/* Disable preferring homeDrive for now. The drive letter may not /* Disable preferring homeDrive for now. The drive letter may not
be available when it's needed. */ be available when it's needed. */
home_from_db = pldap->get_string_attribute (L"homeDrive"); home_from_db = pldap->get_string_attribute (L"homeDrive");
if (!home_from_db || !*home_from_db) if (!home_from_db || !*home_from_db)
#endif #endif
home_from_db = pldap->get_string_attribute (L"homeDirectory"); home_from_db = pldap->get_string_attribute (L"homeDirectory");
}
} }
else if (ui) else if (ui)
{ {
@ -902,8 +908,8 @@ fetch_from_description (PCWSTR desc, PCWSTR search, size_t len)
} }
static char * static char *
fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, fetch_from_path (cyg_ldap *pldap, PUSER_INFO_3 ui, cygpsid &sid, PCWSTR str,
PCWSTR str, PCWSTR dom, PCWSTR name, bool full_qualified) PCWSTR dom, PCWSTR dnsdomain, PCWSTR name, bool full_qualified)
{ {
tmp_pathbuf tp; tmp_pathbuf tp;
PWCHAR wpath = tp.w_get (); 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); w = wcpncpy (w, dom, we - w);
break; break;
case L'H': case L'H':
home = fetch_windows_home (pldap, ui, sid); home = fetch_windows_home (pldap, ui, sid, dnsdomain);
if (home) if (home)
{ {
/* Drop one leading slash to accommodate home being an /* 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 * char *
cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, 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; PWCHAR val;
char *home = NULL; char *home = NULL;
@ -977,35 +983,49 @@ cygheap_pwdgrp::get_home (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
case NSS_SCHEME_FALLBACK: case NSS_SCHEME_FALLBACK:
return NULL; return NULL;
case NSS_SCHEME_WINDOWS: 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; break;
case NSS_SCHEME_CYGWIN: case NSS_SCHEME_CYGWIN:
val = pldap->get_string_attribute (L"cygwinHome"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val); val = pldap->get_string_attribute (L"cygwinHome");
if (val && *val)
sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val);
}
break; break;
case NSS_SCHEME_UNIX: case NSS_SCHEME_UNIX:
val = pldap->get_string_attribute (L"unixHomeDirectory"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val); val = pldap->get_string_attribute (L"unixHomeDirectory");
if (val && *val)
sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val);
}
break; break;
case NSS_SCHEME_DESC: case NSS_SCHEME_DESC:
val = pldap->get_string_attribute (L"description"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
home = fetch_from_description (val, L"home=\"", 6); val = pldap->get_string_attribute (L"description");
if (val && *val)
home = fetch_from_description (val, L"home=\"", 6);
}
break; break;
case NSS_SCHEME_PATH: case NSS_SCHEME_PATH:
home = fetch_from_path (pldap, NULL, sid, home_scheme[idx].attrib, home = fetch_from_path (pldap, NULL, sid, home_scheme[idx].attrib,
dom, name, full_qualified); dom, dnsdomain, name, full_qualified);
break; break;
case NSS_SCHEME_FREEATTR: case NSS_SCHEME_FREEATTR:
val = pldap->get_string_attribute (home_scheme[idx].attrib); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val)
{ {
if (isdrive (val) || *val == '\\') val = pldap->get_string_attribute (home_scheme[idx].attrib);
home = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, val); if (val && *val)
else {
sys_wcstombs_alloc (&home, HEAP_NOTHEAP, 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; break;
} }
@ -1026,7 +1046,7 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
case NSS_SCHEME_FALLBACK: case NSS_SCHEME_FALLBACK:
return NULL; return NULL;
case NSS_SCHEME_WINDOWS: case NSS_SCHEME_WINDOWS:
home = fetch_windows_home (NULL, ui, sid); home = fetch_windows_home (NULL, ui, sid, NULL);
break; break;
case NSS_SCHEME_CYGWIN: case NSS_SCHEME_CYGWIN:
case NSS_SCHEME_UNIX: case NSS_SCHEME_UNIX:
@ -1037,7 +1057,7 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
break; break;
case NSS_SCHEME_PATH: case NSS_SCHEME_PATH:
home = fetch_from_path (NULL, ui, sid, home_scheme[idx].attrib, home = fetch_from_path (NULL, ui, sid, home_scheme[idx].attrib,
dom, name, full_qualified); dom, NULL, name, full_qualified);
break; break;
} }
} }
@ -1046,7 +1066,7 @@ cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
char * char *
cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, 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; PWCHAR val;
char *shell = NULL; char *shell = NULL;
@ -1060,32 +1080,45 @@ cygheap_pwdgrp::get_shell (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
case NSS_SCHEME_WINDOWS: case NSS_SCHEME_WINDOWS:
break; break;
case NSS_SCHEME_CYGWIN: case NSS_SCHEME_CYGWIN:
val = pldap->get_string_attribute (L"cygwinShell"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val); val = pldap->get_string_attribute (L"cygwinShell");
if (val && *val)
sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val);
}
break; break;
case NSS_SCHEME_UNIX: case NSS_SCHEME_UNIX:
val = pldap->get_string_attribute (L"loginShell"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val); val = pldap->get_string_attribute (L"loginShell");
if (val && *val)
sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val);
}
break; break;
case NSS_SCHEME_DESC: case NSS_SCHEME_DESC:
val = pldap->get_string_attribute (L"description"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
shell = fetch_from_description (val, L"shell=\"", 7); val = pldap->get_string_attribute (L"description");
if (val && *val)
shell = fetch_from_description (val, L"shell=\"", 7);
}
break; break;
case NSS_SCHEME_PATH: case NSS_SCHEME_PATH:
shell = fetch_from_path (pldap, NULL, sid, shell_scheme[idx].attrib, shell = fetch_from_path (pldap, NULL, sid, shell_scheme[idx].attrib,
dom, name, full_qualified); dom, dnsdomain, name, full_qualified);
break; break;
case NSS_SCHEME_FREEATTR: case NSS_SCHEME_FREEATTR:
val = pldap->get_string_attribute (shell_scheme[idx].attrib); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val)
{ {
if (isdrive (val) || *val == '\\') val = pldap->get_string_attribute (shell_scheme[idx].attrib);
shell = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, val); if (val && *val)
else {
sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, 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; break;
} }
@ -1115,7 +1148,7 @@ cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
break; break;
case NSS_SCHEME_PATH: case NSS_SCHEME_PATH:
shell = fetch_from_path (NULL, ui, sid, shell_scheme[idx].attrib, shell = fetch_from_path (NULL, ui, sid, shell_scheme[idx].attrib,
dom, name, full_qualified); dom, NULL, name, full_qualified);
break; break;
} }
} }
@ -1133,7 +1166,7 @@ colon_to_semicolon (char *str)
char * char *
cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom, 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; PWCHAR val;
char *gecos = NULL; char *gecos = NULL;
@ -1145,34 +1178,49 @@ cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, cygpsid &sid, PCWSTR dom,
case NSS_SCHEME_FALLBACK: case NSS_SCHEME_FALLBACK:
return NULL; return NULL;
case NSS_SCHEME_WINDOWS: case NSS_SCHEME_WINDOWS:
val = pldap->get_string_attribute (L"displayName"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); val = pldap->get_string_attribute (L"displayName");
if (val && *val)
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
}
break; break;
case NSS_SCHEME_CYGWIN: case NSS_SCHEME_CYGWIN:
val = pldap->get_string_attribute (L"cygwinGecos"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); val = pldap->get_string_attribute (L"cygwinGecos");
if (val && *val)
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
}
break; break;
case NSS_SCHEME_UNIX: case NSS_SCHEME_UNIX:
val = pldap->get_string_attribute (L"gecos"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); val = pldap->get_string_attribute (L"gecos");
if (val && *val)
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
}
break; break;
case NSS_SCHEME_DESC: case NSS_SCHEME_DESC:
val = pldap->get_string_attribute (L"description"); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
gecos = fetch_from_description (val, L"gecos=\"", 7); val = pldap->get_string_attribute (L"description");
if (val && *val)
gecos = fetch_from_description (val, L"gecos=\"", 7);
}
break; break;
case NSS_SCHEME_PATH: case NSS_SCHEME_PATH:
gecos = fetch_from_path (pldap, NULL, sid, gecos = fetch_from_path (pldap, NULL, sid,
gecos_scheme[idx].attrib + 1, gecos_scheme[idx].attrib + 1,
dom, name, full_qualified); dom, dnsdomain, name, full_qualified);
break; break;
case NSS_SCHEME_FREEATTR: case NSS_SCHEME_FREEATTR:
val = pldap->get_string_attribute (gecos_scheme[idx].attrib); if (pldap->fetch_ad_account (sid, false, dnsdomain))
if (val && *val) {
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val); val = pldap->get_string_attribute (gecos_scheme[idx].attrib);
if (val && *val)
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
}
break; break;
} }
} }
@ -1206,7 +1254,7 @@ cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, cygpsid &sid, PCWSTR dom,
break; break;
case NSS_SCHEME_PATH: case NSS_SCHEME_PATH:
gecos = fetch_from_path (NULL, ui, sid, gecos_scheme[idx].attrib + 1, gecos = fetch_from_path (NULL, ui, sid, gecos_scheme[idx].attrib + 1,
dom, name, full_qualified); dom, NULL, name, full_qualified);
break; break;
} }
} }
@ -1676,6 +1724,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
gid_t gid = ILLEGAL_GID; gid_t gid = ILLEGAL_GID;
bool is_domain_account = true; bool is_domain_account = true;
PCWSTR domain = NULL; PCWSTR domain = NULL;
bool is_current_user = false;
char *shell = NULL; char *shell = NULL;
char *home = NULL; char *home = NULL;
char *gecos = 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. */ DC for some weird reason. Use LDAP instead. */
PWCHAR val; PWCHAR val;
if (cldap->open (NULL) == NO_ERROR if (cldap->fetch_ad_account (sid, true)
&& cldap->fetch_ad_account (sid, is_group ())
&& (val = cldap->get_group_name ())) && (val = cldap->get_group_name ()))
{ {
wcpcpy (name, val); 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" the educated guess that the user is in group "Domain Users"
or "None". */ or "None". */
if (sid == cygheap->user.sid ()) 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 else
gid = posix_offset + DOMAIN_GROUP_RID_USERS; gid = posix_offset + DOMAIN_GROUP_RID_USERS;
} }
if (is_domain_account) 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. */ /* On AD machines, use LDAP to fetch domain account infos. */
if (cygheap->dom.primary_dns_name ()) if (cygheap->dom.primary_dns_name ())
{ {
if (cldap->open (NULL) != NO_ERROR) /* For the current user we got the primary group from the
break; user token. For any other user we fetch it from AD. */
if (cldap->fetch_ad_account (sid, is_group (), domain)) 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) id_val = cldap->get_unix_uid ();
gid = posix_offset + id_val; if (id_val != ILLEGAL_UID
if (!is_group ()) && cygheap->ugid_cache.get_uid (id_val)
{ == ILLEGAL_UID)
home = cygheap->pg.get_home (cldap, sid, dom, name, cygheap->ugid_cache.add_uid (id_val, uid);
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);
}
} }
} }
/* If primary_dns_name() is empty, we're likely running under an /* 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 NT4 domain, so we can't use LDAP. For user accounts fall back
to NetUserGetInfo. This isn't overly fast, but keep in mind to NetUserGetInfo. This isn't overly fast, but keep in mind
that NT4 domains are mostly replaced by AD these days. */ 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]; WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
NET_API_STATUS nas; NET_API_STATUS nas;