summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog17
-rw-r--r--winsup/cygwin/cygheap.h2
-rw-r--r--winsup/cygwin/ldap.cc6
-rw-r--r--winsup/cygwin/security.h10
-rw-r--r--winsup/cygwin/uinfo.cc34
5 files changed, 49 insertions, 20 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 6c8395df3..c793266e9 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index c4b2ed9ad..b08569d13 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -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; }
diff --git a/winsup/cygwin/ldap.cc b/winsup/cygwin/ldap.cc
index fa19c307e..df7756809 100644
--- a/winsup/cygwin/ldap.cc
+++ b/winsup/cygwin/ldap.cc
@@ -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);
}
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index 6b6c33955..eb3e0f1e5 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -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
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index 0151563fe..ed533bd8a 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -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)