* ldap.h: Remove index macros.

(class cyg_ldap): Remove members srch_msg and srch_entry.
	(cyg_ldap::get_string_attribute): Remove private method taking index
	argument.
	(cyg_ldap::get_num_attribute): Ditto.  Add method taking attribute name.
	(cyg_ldap::get_primary_gid): Adjust to aforementioned change.
	(cyg_ldap::get_unix_uid): Ditto.
	(cyg_ldap::get_unix_gid): Ditto.
	* ldap.cc: Throughout, use msg and entry in place of srch_msg and
	srch_entry.
	(std_user_attr): Add sAMAccountName and objectSid.
	(group_attr): Ditto.
	(cyg_ldap::close): Drop handling of srch_msg and srch_entry.
	(cyg_ldap::get_string_attribute): Move earlier in file.
	(cyg_ldap::get_num_attribute): Ditto.
	(cyg_ldap::enumerate_ad_accounts): Add comments for clarity.
	Use group_attr or user_attr rather than sid_attr to fetch all desired
	attributes for an account right away.
	(cyg_ldap::next_account): Store found SID in last_fetched_sid to
	skip calls to fetch_ad_account from fetch_account_from_windows.
	(cyg_ldap::get_string_attribute): Remove method taking index argument.
	(cyg_ldap::get_num_attribute): Ditto.
	* pwdgrp.h (class pg_ent): Fix formatting.  Add member dom.
	* passwd.cc (pg_ent::enumerate_ad): Store current flat domain name
	in dom.  Construct fetch_acc_t argument from LDAP attributes and
	call fetch_account_from_windows with that.
	* userinfo.h (enum fetch_user_arg_type_t): Rename FULL_grp_arg to
	FULL_acc_arg.  Change throughout.
	(struct fetch_acc_t): Rename from fetch_full_grp_t.  Change throughout.
	(struct fetch_user_arg_t): Rename full_grp to full_acc.  Change
	throughout.
This commit is contained in:
Corinna Vinschen 2015-02-24 20:52:57 +00:00
parent 59076540bc
commit ad8d295e7c
8 changed files with 144 additions and 102 deletions

View File

@ -1,3 +1,37 @@
2015-02-24 Corinna Vinschen <corinna@vinschen.de>
* ldap.h: Remove index macros.
(class cyg_ldap): Remove members srch_msg and srch_entry.
(cyg_ldap::get_string_attribute): Remove private method taking index
argument.
(cyg_ldap::get_num_attribute): Ditto. Add method taking attribute name.
(cyg_ldap::get_primary_gid): Adjust to aforementioned change.
(cyg_ldap::get_unix_uid): Ditto.
(cyg_ldap::get_unix_gid): Ditto.
* ldap.cc: Throughout, use msg and entry in place of srch_msg and
srch_entry.
(std_user_attr): Add sAMAccountName and objectSid.
(group_attr): Ditto.
(cyg_ldap::close): Drop handling of srch_msg and srch_entry.
(cyg_ldap::get_string_attribute): Move earlier in file.
(cyg_ldap::get_num_attribute): Ditto.
(cyg_ldap::enumerate_ad_accounts): Add comments for clarity.
Use group_attr or user_attr rather than sid_attr to fetch all desired
attributes for an account right away.
(cyg_ldap::next_account): Store found SID in last_fetched_sid to
skip calls to fetch_ad_account from fetch_account_from_windows.
(cyg_ldap::get_string_attribute): Remove method taking index argument.
(cyg_ldap::get_num_attribute): Ditto.
* pwdgrp.h (class pg_ent): Fix formatting. Add member dom.
* passwd.cc (pg_ent::enumerate_ad): Store current flat domain name
in dom. Construct fetch_acc_t argument from LDAP attributes and
call fetch_account_from_windows with that.
* userinfo.h (enum fetch_user_arg_type_t): Rename FULL_grp_arg to
FULL_acc_arg. Change throughout.
(struct fetch_acc_t): Rename from fetch_full_grp_t. Change throughout.
(struct fetch_user_arg_t): Rename full_grp to full_acc. Change
throughout.
2015-02-24 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_base): Add was_nonblocking status flag.

View File

@ -145,35 +145,35 @@ internal_getgrsid_cachedonly (cygpsid &sid)
for each group. This is quite a bit faster, especially in slower
environments. */
static struct group * __attribute__((used))
internal_getgrfull (fetch_full_grp_t &full_grp, cyg_ldap *pldap)
internal_getgrfull (fetch_acc_t &full_acc, cyg_ldap *pldap)
{
struct group *ret;
cygheap->pg.nss_init ();
/* Check caches first. */
if (cygheap->pg.nss_cygserver_caching ()
&& (ret = cygheap->pg.grp_cache.cygserver.find_group (full_grp.sid)))
&& (ret = cygheap->pg.grp_cache.cygserver.find_group (full_acc.sid)))
return ret;
if (cygheap->pg.nss_grp_files ()
&& (ret = cygheap->pg.grp_cache.file.find_group (full_grp.sid)))
&& (ret = cygheap->pg.grp_cache.file.find_group (full_acc.sid)))
return ret;
if (cygheap->pg.nss_grp_db ()
&& (ret = cygheap->pg.grp_cache.win.find_group (full_grp.sid)))
&& (ret = cygheap->pg.grp_cache.win.find_group (full_acc.sid)))
return ret;
/* Ask sources afterwards. */
if (cygheap->pg.nss_cygserver_caching ()
&& (ret = cygheap->pg.grp_cache.cygserver.add_group_from_cygserver
(full_grp.sid)))
(full_acc.sid)))
return ret;
if (cygheap->pg.nss_grp_files ())
{
cygheap->pg.grp_cache.file.check_file ();
if ((ret = cygheap->pg.grp_cache.file.add_group_from_file
(full_grp.sid)))
(full_acc.sid)))
return ret;
}
if (cygheap->pg.nss_grp_db ())
return cygheap->pg.grp_cache.win.add_group_from_windows (full_grp, pldap);
return cygheap->pg.grp_cache.win.add_group_from_windows (full_acc, pldap);
return NULL;
}
@ -647,14 +647,14 @@ internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap,
{
for (ULONG ncnt = 0; ncnt < scnt; ++ncnt)
{
fetch_full_grp_t full_grp =
fetch_acc_t full_acc =
{
.sid = sidp_buf[ncnt],
.name = &nlst[ncnt].Name,
.dom = &dlst->Domains[nlst[ncnt].DomainIndex].Name,
.acc_type = nlst[ncnt].Use
};
if ((grp = internal_getgrfull (full_grp, pldap)))
if ((grp = internal_getgrfull (full_acc, pldap)))
{
if (cnt < gidsetsize)
grouplist[cnt] = grp->gr_gid;

View File

@ -34,6 +34,8 @@ static PWCHAR rootdse_attr[] =
static const PCWSTR std_user_attr[] =
{
L"sAMAccountName",
L"objectSid",
L"primaryGroupID",
L"uidNumber",
L"cygwinUnixUid", /* TODO */
@ -55,7 +57,8 @@ static const PCWSTR std_user_attr[] =
static PWCHAR group_attr[] =
{
(PWCHAR) L"cn",
(PWCHAR) L"sAMAccountName",
(PWCHAR) L"objectSid",
(PWCHAR) L"gidNumber",
(PWCHAR) L"cygwinUnixGid", /* TODO */
NULL
@ -283,9 +286,9 @@ cyg_ldap::next_page_s ()
do
{
ret = ldap_get_next_page_s (lh, srch_id, NULL, CYG_LDAP_ENUM_PAGESIZE,
&total, &srch_msg);
&total, &msg);
}
while (ret == LDAP_SUCCESS && ldap_count_entries (lh, srch_msg) == 0);
while (ret == LDAP_SUCCESS && ldap_count_entries (lh, msg) == 0);
if (ret && ret != LDAP_NO_RESULTS_RETURNED)
debug_printf ("ldap_result() error 0x%02x", ret);
return ret;
@ -367,8 +370,6 @@ cyg_ldap::close ()
ldap_search_abandon_page (lh, srch_id);
if (lh)
ldap_unbind (lh);
if (srch_msg)
ldap_msgfree (srch_msg);
if (msg)
ldap_msgfree (msg);
if (val)
@ -380,10 +381,29 @@ cyg_ldap::close ()
val = NULL;
def_context = NULL;
srch_id = NULL;
srch_msg = srch_entry = NULL;
last_fetched_sid = NO_SID;
}
PWCHAR
cyg_ldap::get_string_attribute (PCWSTR name)
{
if (val)
ldap_value_freeW (val);
val = ldap_get_valuesW (lh, entry, (PWCHAR) name);
if (val)
return val[0];
return NULL;
}
uint32_t
cyg_ldap::get_num_attribute (PCWSTR name)
{
PWCHAR ret = get_string_attribute (name);
if (ret)
return (uint32_t) wcstoul (ret, NULL, 10);
return (uint32_t) -1;
}
#define ACCOUNT_FILTER_START L"(&(|(&(objectCategory=Person)" \
"(objectClass=User))" \
"(objectClass=Group))" \
@ -478,19 +498,26 @@ cyg_ldap::enumerate_ad_accounts (PCWSTR domain, bool group)
if (!group)
filter = L"(&(objectCategory=Person)"
"(objectClass=User)"
/* 512 == ADS_UF_NORMAL_ACCOUNT */
/* 512 == ADS_UF_NORMAL_ACCOUNT
Without checking this flag we'd enumerate undesired accounts
like, e.g., interdomain trusts. */
"(userAccountControl:" LDAP_MATCHING_RULE_BIT_AND ":=512)"
"(objectSid=*))";
else if (!domain)
/* From the local domain, we fetch well-known groups. */
filter = L"(&(objectClass=Group)"
"(objectSid=*))";
else
/* From foreign domains, we don't. */
filter = L"(&(objectClass=Group)"
/* 1 == BUILTIN_LOCAL_GROUP */
"(!(groupType:" LDAP_MATCHING_RULE_BIT_AND ":=1))"
"(objectSid=*))";
if (!user_attr)
cygheap->pg.init_ldap_user_attr ();
attr = group ? group_attr : user_attr;
srch_id = ldap_search_init_pageW (lh, def_context, LDAP_SCOPE_SUBTREE,
(PWCHAR) filter, sid_attr, 0, NULL, NULL,
(PWCHAR) filter, attr, 0, NULL, NULL,
INFINITE, CYG_LDAP_ENUM_PAGESIZE, NULL);
if (srch_id == NULL)
{
@ -507,25 +534,25 @@ cyg_ldap::next_account (cygsid &sid)
ULONG ret;
PLDAP_BERVAL *bval;
if (srch_entry)
if (entry)
{
if ((srch_entry = ldap_next_entry (lh, srch_entry))
&& (bval = ldap_get_values_lenW (lh, srch_entry, sid_attr[0])))
if ((entry = ldap_next_entry (lh, entry))
&& (bval = ldap_get_values_lenW (lh, entry, (PWCHAR) L"objectSid")))
{
sid = (PSID) bval[0]->bv_val;
last_fetched_sid = sid = (PSID) bval[0]->bv_val;
ldap_value_free_len (bval);
return NO_ERROR;
}
ldap_msgfree (srch_msg);
srch_msg = srch_entry = NULL;
ldap_msgfree (msg);
msg = entry = NULL;
}
ret = next_page ();
if (ret == NO_ERROR)
{
if ((srch_entry = ldap_first_entry (lh, srch_msg))
&& (bval = ldap_get_values_lenW (lh, srch_entry, sid_attr[0])))
if ((entry = ldap_first_entry (lh, msg))
&& (bval = ldap_get_values_lenW (lh, entry, (PWCHAR) L"objectSid")))
{
sid = (PSID) bval[0]->bv_val;
last_fetched_sid = sid = (PSID) bval[0]->bv_val;
ldap_value_free_len (bval);
return NO_ERROR;
}
@ -574,33 +601,7 @@ cyg_ldap::fetch_posix_offset_for_domain (PCWSTR domain)
debug_printf ("No entry for %W in def_context %W", filter, def_context);
return UINT32_MAX;
}
return get_num_attribute (0);
}
PWCHAR
cyg_ldap::get_string_attribute (PCWSTR name)
{
if (val)
ldap_value_freeW (val);
val = ldap_get_valuesW (lh, entry, (PWCHAR) name);
if (val)
return val[0];
return NULL;
}
PWCHAR
cyg_ldap::get_string_attribute (int idx)
{
return get_string_attribute (attr[idx]);
}
uint32_t
cyg_ldap::get_num_attribute (int idx)
{
PWCHAR ret = get_string_attribute (attr[idx]);
if (ret)
return (uint32_t) wcstoul (ret, NULL, 10);
return (uint32_t) -1;
return get_num_attribute (tdom_attr[0]);
}
#define UXID_FILTER_GRP L"(&(objectClass=Group)" \
@ -625,7 +626,7 @@ cyg_ldap::fetch_unix_sid_from_ad (uint32_t id, cygsid &sid, bool group)
if (search (def_context, LDAP_SCOPE_SUBTREE, filter, sid_attr) != 0)
return false;
if ((entry = ldap_first_entry (lh, msg))
&& (bval = ldap_get_values_lenW (lh, entry, sid_attr[0])))
&& (bval = ldap_get_values_lenW (lh, entry, (PWCHAR) L"objectSid")))
{
sid = (PSID) bval[0]->bv_val;
ldap_value_free_len (bval);
@ -664,7 +665,7 @@ cyg_ldap::fetch_unix_name_from_rfc2307 (uint32_t id, bool group)
debug_printf ("No entry for %W in def_context %W", filter, def_context);
return NULL;
}
return get_string_attribute (0);
return get_string_attribute (attr[0]);
}
uid_t

View File

@ -17,12 +17,6 @@ details. */
#include <ntldap.h>
#pragma pop_macro ("DECLSPEC_IMPORT")
#define LDAP_USER_PGRP_ATTR 0
#define LDAP_USER_UID_ATTR 1
#define LDAP_GROUP_NAME_ATTR 0
#define LDAP_GROUP_GID_ATTR 1
class cyg_ldap {
PLDAP lh;
PWCHAR def_context;
@ -31,7 +25,6 @@ class cyg_ldap {
PWCHAR *attr;
bool isAD;
PLDAPSearch srch_id;
PLDAPMessage srch_msg, srch_entry;
cygsid last_fetched_sid;
inline int map_ldaperr_to_errno (ULONG lerr);
@ -41,13 +34,11 @@ class cyg_ldap {
inline int next_page ();
bool fetch_unix_sid_from_ad (uint32_t id, cygsid &sid, bool group);
PWCHAR fetch_unix_name_from_rfc2307 (uint32_t id, bool group);
PWCHAR get_string_attribute (int idx);
uint32_t get_num_attribute (int idx);
public:
cyg_ldap () : lh (NULL), def_context (NULL), msg (NULL), entry (NULL),
val (NULL), isAD (false), srch_id (NULL), srch_msg (NULL),
srch_entry (NULL), last_fetched_sid (NO_SID)
val (NULL), isAD (false), srch_id (NULL),
last_fetched_sid (NO_SID)
{}
~cyg_ldap () { close (); }
@ -60,6 +51,8 @@ public:
operator PLDAP () const { return lh; }
int open (PCWSTR in_domain);
void close ();
PWCHAR get_string_attribute (PCWSTR name);
uint32_t get_num_attribute (PCWSTR name);
bool fetch_ad_account (PSID sid, bool group, PCWSTR domain = NULL);
int enumerate_ad_accounts (PCWSTR domain, bool group);
int next_account (cygsid &sid);
@ -67,11 +60,10 @@ public:
uid_t remap_uid (uid_t uid);
gid_t remap_gid (gid_t gid);
/* User only */
gid_t get_primary_gid () { return get_num_attribute (LDAP_USER_PGRP_ATTR); }
gid_t get_unix_uid () { return get_num_attribute (LDAP_USER_UID_ATTR); }
gid_t get_primary_gid () { return get_num_attribute (L"primaryGroupID"); }
gid_t get_unix_uid () { return get_num_attribute (L"uidNumber"); }
/* group only */
PWCHAR get_group_name ()
{ return get_string_attribute (LDAP_GROUP_NAME_ATTR); }
gid_t get_unix_gid () { return get_num_attribute (LDAP_GROUP_GID_ATTR); }
PWCHAR get_string_attribute (PCWSTR name);
{ return get_string_attribute (L"sAMAccountName"); }
gid_t get_unix_gid () { return get_num_attribute (L"gidNumber"); }
};

View File

@ -1,7 +1,7 @@
/* passwd.cc: getpwnam () and friends
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008,
2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
2009, 2010, 2011, 2012, 2013, 2014, 2015 Red Hat, Inc.
This file is part of Cygwin.
@ -600,6 +600,7 @@ pg_ent::enumerate_ad ()
if (!nss_db_enum_primary ()
|| cldap.enumerate_ad_accounts (NULL, group) != NO_ERROR)
continue;
RtlInitUnicodeString (&dom, cygheap->dom.primary_flat_name ());
}
else if ((td = cygheap->dom.trusted_domain (resume - 1)))
{
@ -616,6 +617,7 @@ pg_ent::enumerate_ad ()
|| cldap.enumerate_ad_accounts (td->DnsDomainName, group)
!= NO_ERROR)
continue;
RtlInitUnicodeString (&dom, td->NetbiosDomainName);
}
else
{
@ -628,9 +630,21 @@ pg_ent::enumerate_ad ()
int ret = cldap.next_account (sid);
if (ret == NO_ERROR)
{
fetch_acc_t full;
fetch_user_arg_t arg;
arg.type = SID_arg;
arg.sid = &sid;
UNICODE_STRING name;
arg.type = FULL_acc_arg;
arg.full_acc = &full;
full.sid = sid;
RtlInitUnicodeString (&name,
cldap.get_string_attribute (L"sAMAccountName"));
full.name = &name;
full.dom = &dom;
if (sid_sub_auth (sid, 0) == SECURITY_BUILTIN_DOMAIN_RID)
full.acc_type = SidTypeAlias;
else
full.acc_type = group ? SidTypeGroup : SidTypeUser;
char *line = pg.fetch_account_from_windows (arg, &cldap);
if (line)
return pg.add_account_post_fetch (line, false);

View File

@ -159,7 +159,7 @@ public:
{ return (struct group *) add_account_from_windows (name, pldap); }
struct group *add_group_from_windows (uint32_t id, cyg_ldap *pldap = NULL)
{ return (struct group *) add_account_from_windows (id, pldap); }
struct group *add_group_from_windows (fetch_full_grp_t &full_grp,
struct group *add_group_from_windows (fetch_acc_t &full_acc,
cyg_ldap *pldap = NULL);
struct group *find_group (cygpsid &sid);
struct group *find_group (const char *name);
@ -169,20 +169,21 @@ public:
class pg_ent
{
protected:
pwdgrp pg;
bool group;
pg_pwd pwd;
pg_grp grp;
NT_readline rl;
cyg_ldap cldap;
PCHAR buf;
ULONG cnt;
ULONG max;
ULONG_PTR resume;
int enums; /* ENUM_xxx values defined in sys/cygwin.h. */
PCWSTR enum_tdoms;
bool from_files;
bool from_db;
pwdgrp pg;
bool group;
pg_pwd pwd;
pg_grp grp;
NT_readline rl;
cyg_ldap cldap;
PCHAR buf;
ULONG cnt;
ULONG max;
ULONG_PTR resume;
int enums; /* ENUM_xxx values defined in sys/cygwin.h. */
PCWSTR enum_tdoms;
bool from_files;
bool from_db;
UNICODE_STRING dom;
enum {
rewound = 0,
from_cache,

View File

@ -1547,11 +1547,11 @@ pwdgrp::add_account_from_windows (uint32_t id, cyg_ldap *pldap)
/* Called from internal_getgrfull, in turn called from internal_getgroups. */
struct group *
pwdgrp::add_group_from_windows (fetch_full_grp_t &full_grp, cyg_ldap *pldap)
pwdgrp::add_group_from_windows (fetch_acc_t &full_acc, cyg_ldap *pldap)
{
fetch_user_arg_t arg;
arg.type = FULL_grp_arg;
arg.full_grp = &full_grp;
arg.type = FULL_acc_arg;
arg.full_acc = &full_acc;
char *line = fetch_account_from_windows (arg, pldap);
if (!line)
return NULL;
@ -1759,14 +1759,14 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
switch (arg.type)
{
case FULL_grp_arg:
case FULL_acc_arg:
{
sid = arg.full_grp->sid;
*wcpncpy (name, arg.full_grp->name->Buffer,
arg.full_grp->name->Length / sizeof (WCHAR)) = L'\0';
*wcpncpy (dom, arg.full_grp->dom->Buffer,
arg.full_grp->dom->Length / sizeof (WCHAR)) = L'\0';
acc_type = arg.full_grp->acc_type;
sid = arg.full_acc->sid;
*wcpncpy (name, arg.full_acc->name->Buffer,
arg.full_acc->name->Length / sizeof (WCHAR)) = L'\0';
*wcpncpy (dom, arg.full_acc->dom->Buffer,
arg.full_acc->dom->Length / sizeof (WCHAR)) = L'\0';
acc_type = arg.full_acc->acc_type;
ret = acc_type != SidTypeUnknown;
}
break;

View File

@ -14,12 +14,12 @@ enum fetch_user_arg_type_t {
SID_arg,
NAME_arg,
ID_arg,
FULL_grp_arg,
FULL_acc_arg,
};
#ifdef __INSIDE_CYGWIN__
struct fetch_full_grp_t {
struct fetch_acc_t {
cygpsid sid;
PUNICODE_STRING name;
PUNICODE_STRING dom;
@ -33,7 +33,7 @@ struct fetch_user_arg_t
cygpsid *sid;
const char *name;
uint32_t id;
fetch_full_grp_t *full_grp;
fetch_acc_t *full_acc;
};
/* Only used in fetch_account_from_file/line. */
size_t len;