* cygheap.h (class cygheap_domain_info): Remove lowest_tdo_posix_offset.

* ldap.cc (cyg_ldap::fetch_posix_offset_for_domain): Return UINT32_MAX
	in case of error.
	* security.h (PRIMARY_POSIX_OFFSET): Define.
	(NOACCESS_POSIX_OFFSET): Define.
	(UNUSABLE_POSIX_OFFSET): Define.
	* uinfo.cc (cygheap_domain_info::init): Drop initializing
	lowest_tdo_posix_offset.
	(pwdgrp::fetch_account_from_file): Set PosixOffset to either
	UNUSABLE_POSIX_OFFSET or NOACCESS_POSIX_OFFSET in case we don't get a
	sensible offset from AD.  Explain why.  Drop setting ch
	lowest_tdo_posix_offset.
	(pwdgrp::fetch_account_from_windows): Replace constant 0x100000 with
	PRIMARY_POSIX_OFFSET throughout.
This commit is contained in:
Corinna Vinschen 2014-07-29 08:53:13 +00:00
parent ca6a65aa64
commit 898e26c82f
5 changed files with 49 additions and 20 deletions

View File

@ -1,3 +1,20 @@
2014-07-29 Corinna Vinschen <corinna@vinschen.de>
* cygheap.h (class cygheap_domain_info): Remove lowest_tdo_posix_offset.
* ldap.cc (cyg_ldap::fetch_posix_offset_for_domain): Return UINT32_MAX
in case of error.
* security.h (PRIMARY_POSIX_OFFSET): Define.
(NOACCESS_POSIX_OFFSET): Define.
(UNUSABLE_POSIX_OFFSET): Define.
* uinfo.cc (cygheap_domain_info::init): Drop initializing
lowest_tdo_posix_offset.
(pwdgrp::fetch_account_from_file): Set PosixOffset to either
UNUSABLE_POSIX_OFFSET or NOACCESS_POSIX_OFFSET in case we don't get a
sensible offset from AD. Explain why. Drop setting ch
lowest_tdo_posix_offset.
(pwdgrp::fetch_account_from_windows): Replace constant 0x100000 with
PRIMARY_POSIX_OFFSET throughout.
2014-07-24 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::send_internal): Fix value of

View File

@ -371,8 +371,6 @@ class cygheap_domain_info
PWCHAR rfc2307_domain_buf;
public:
ULONG lowest_tdo_posix_offset;
bool init ();
inline PCWSTR primary_flat_name () const { return pdom_name; }

View File

@ -471,6 +471,8 @@ cyg_ldap::next_account (cygsid &sid)
return ret;
}
/* Return UINT32_MAX on error to allow differing between not being able
to fetch a value and a real 0 offset. */
uint32_t
cyg_ldap::fetch_posix_offset_for_domain (PCWSTR domain)
{
@ -491,11 +493,11 @@ cyg_ldap::fetch_posix_offset_for_domain (PCWSTR domain)
__small_swprintf (filter, L"(&(objectClass=trustedDomain)(%W=%W))",
wcschr (domain, L'.') ? L"name" : L"flatName", domain);
if (search (rootdse, filter, attr = tdom_attr) != 0)
return 0;
return UINT32_MAX;
if (!(entry = ldap_first_entry (lh, msg)))
{
debug_printf ("No entry for %W in rootdse %W", filter, rootdse);
return 0;
return UINT32_MAX;
}
return get_num_attribute (0);
}

View File

@ -24,6 +24,16 @@ void uinfo_init ();
#define ILLEGAL_UID ((uid_t)-1)
#define ILLEGAL_GID ((gid_t)-1)
/* Offset for accounts in the primary domain of the machine. */
#define PRIMARY_POSIX_OFFSET (0x00100000)
/* Fake POSIX offsets used in scenarios in which the account has no permission
to fetch the POSIX offset, or when the admins have set the offset to an
unreasonable low value. The values are chosen in the hope that they won't
collide with "real" offsets. */
#define NOACCESS_POSIX_OFFSET (0xfe500000)
#define UNUSABLE_POSIX_OFFSET (0xfea00000)
/* For UNIX accounts not mapped to Windows accounts via winbind, Samba returns
SIDs of the form S-1-22-x-y, with x == 1 for users and x == 2 for groups,
and y == UNIX uid/gid. NFS returns no SIDs at all, but the plain UNIX

View File

@ -815,9 +815,6 @@ cygheap_domain_info::init ()
lsa_close_policy (lsa);
if (cygheap->dom.member_machine ())
{
/* For a domain member machine fetch all trusted domain info.
Start out with UNIX_POSIX_OFFSET. */
lowest_tdo_posix_offset = UNIX_POSIX_OFFSET;
ret = DsEnumerateDomainTrustsW (NULL, DS_DOMAIN_DIRECT_INBOUND
| DS_DOMAIN_DIRECT_OUTBOUND
| DS_DOMAIN_IN_FOREST,
@ -1138,24 +1135,29 @@ pwdgrp::fetch_account_from_file (fetch_user_arg_t &arg)
static ULONG
fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, cyg_ldap *cldap)
{
uint32_t id_val = 0;
uint32_t id_val = UINT32_MAX;
if (!td->PosixOffset && !(td->Flags & DS_DOMAIN_PRIMARY) && td->DomainSid)
{
if (cldap->open (NULL) == NO_ERROR)
id_val = cldap->fetch_posix_offset_for_domain (td->DnsDomainName);
if (!id_val)
if (id_val < PRIMARY_POSIX_OFFSET)
{
/* If the offset is less than the primay domain offset, we're bound
to suffer collisions with system and local accounts. Move offset
to a fixed replacement fake offset. This may result in collisions
between other domains all of which were moved to this replacement
offset, but we can't fix all problems caused by careless admins. */
id_val = UNUSABLE_POSIX_OFFSET;
}
else if (id_val == UINT32_MAX)
{
/* We're probably running under a local account, so we're not allowed
to fetch any information from AD beyond the most obvious.
Alternatively we're suffering IT madness and some admin has
actually set the POSIX offset to 0. Either way, fake a reasonable
posix offset and hope for the best. */
id_val = cygheap->dom.lowest_tdo_posix_offset - 0x00800000;
to fetch any information from AD beyond the most obvious. Fake a
reasonable posix offset as above and hope for the best. */
id_val = NOACCESS_POSIX_OFFSET;
}
td->PosixOffset = id_val;
if (id_val < cygheap->dom.lowest_tdo_posix_offset)
cygheap->dom.lowest_tdo_posix_offset = id_val;
}
return td->PosixOffset;
}
@ -1425,7 +1427,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
/* Identity assertion SIDs. */
__small_swprintf (sidstr, L"S-1-18-%u", arg.id & 0xffff);
}
else if (arg.id < 0x100000)
else if (arg.id < PRIMARY_POSIX_OFFSET)
{
/* Nothing. */
debug_printf ("Invalid POSIX id %u", arg.id);
@ -1467,7 +1469,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
{
/* Primary domain */
PWCHAR s = cygheap->dom.primary_sid ().pstring (sidstr);
__small_swprintf (s, L"-%u", arg.id - 0x100000);
__small_swprintf (s, L"-%u", arg.id - PRIMARY_POSIX_OFFSET);
}
posix_offset = 0;
}
@ -1526,7 +1528,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
/* Primary domain account? */
if (!wcscasecmp (dom, cygheap->dom.primary_flat_name ()))
{
posix_offset = 0x100000;
posix_offset = PRIMARY_POSIX_OFFSET;
/* In theory domain should have been set to
cygheap->dom.primary_dns_name (), but it turns out
that not setting the domain here has advantages.
@ -1859,7 +1861,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
if (RtlEqualSid (sid, cygheap->dom.primary_sid ()))
{
domain = cygheap->dom.primary_flat_name ();
posix_offset = 0x100000;
posix_offset = PRIMARY_POSIX_OFFSET;
}
else
for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx)