* ldap.cc (cyg_ldap::fetch_posix_offset_for_domain): If domain name
has no dot, it's a Netbios name. Change the search filter expression accordingly and filter by flatName. Add comment. * uinfo.cc (cygheap_domain_info::init): Gracefully handle NULL DnsDomainName and DomainSid members in DS_DOMAIN_TRUSTSW strutures. Add comment. Fix comment preceeding fetching the mapping server from registry. (pwdgrp::fetch_account_from_file): Convert str to a local array. (fetch_posix_offset): New static function. (pwdgrp::fetch_account_from_windows): Add debug output in case LookupAccountSidW fails. Simplify code by calling fetch_posix_offset where appropriate. If LookupAccountSidW fails, check if the SID is one of the known trusted domains. If so, create a more informative account entry.
This commit is contained in:
parent
5f51881a6d
commit
85b8256d2e
|
@ -1,3 +1,20 @@
|
||||||
|
2014-02-13 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* ldap.cc (cyg_ldap::fetch_posix_offset_for_domain): If domain name
|
||||||
|
has no dot, it's a Netbios name. Change the search filter expression
|
||||||
|
accordingly and filter by flatName. Add comment.
|
||||||
|
* uinfo.cc (cygheap_domain_info::init): Gracefully handle NULL
|
||||||
|
DnsDomainName and DomainSid members in DS_DOMAIN_TRUSTSW strutures.
|
||||||
|
Add comment. Fix comment preceeding fetching the mapping server
|
||||||
|
from registry.
|
||||||
|
(pwdgrp::fetch_account_from_file): Convert str to a local array.
|
||||||
|
(fetch_posix_offset): New static function.
|
||||||
|
(pwdgrp::fetch_account_from_windows): Add debug output in case
|
||||||
|
LookupAccountSidW fails. Simplify code by calling fetch_posix_offset
|
||||||
|
where appropriate. If LookupAccountSidW fails, check if the SID is
|
||||||
|
one of the known trusted domains. If so, create a more informative
|
||||||
|
account entry.
|
||||||
|
|
||||||
2014-02-12 Corinna Vinschen <corinna@vinschen.de>
|
2014-02-12 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* uinfo.cc (cygheap_pwdgrp::nss_init_line): Explicitely ignore a colon
|
* uinfo.cc (cygheap_pwdgrp::nss_init_line): Explicitely ignore a colon
|
||||||
|
|
|
@ -289,7 +289,10 @@ cyg_ldap::fetch_posix_offset_for_domain (PCWSTR domain)
|
||||||
ldap_value_freeW (val);
|
ldap_value_freeW (val);
|
||||||
val = NULL;
|
val = NULL;
|
||||||
}
|
}
|
||||||
__small_swprintf (filter, L"(&(objectClass=trustedDomain)(name=%W))", domain);
|
/* If domain name has no dot, it's a Netbios name. In that case, filter
|
||||||
|
by flatName rather than by name. */
|
||||||
|
__small_swprintf (filter, L"(&(objectClass=trustedDomain)(%W=%W))",
|
||||||
|
wcschr (domain, L'.') ? L"name" : L"flatName", domain);
|
||||||
if ((ret = ldap_search_stW (lh, rootdse, LDAP_SCOPE_SUBTREE, filter,
|
if ((ret = ldap_search_stW (lh, rootdse, LDAP_SCOPE_SUBTREE, filter,
|
||||||
attr = tdom_attr, 0, &tv, &msg)) != LDAP_SUCCESS)
|
attr = tdom_attr, 0, &tv, &msg)) != LDAP_SUCCESS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -777,22 +777,32 @@ cygheap_domain_info::init ()
|
||||||
{
|
{
|
||||||
/* Copy... */
|
/* Copy... */
|
||||||
tdom[idx].NetbiosDomainName = cwcsdup (td[idx].NetbiosDomainName);
|
tdom[idx].NetbiosDomainName = cwcsdup (td[idx].NetbiosDomainName);
|
||||||
tdom[idx].DnsDomainName = cwcsdup (td[idx].DnsDomainName);
|
/* DnsDomainName as well as DomainSid can be NULL. The reason is
|
||||||
|
usually a domain of type TRUST_TYPE_DOWNLEVEL. This can be an
|
||||||
|
old pre-AD domain, or a Netware domain, etc. If DnsDomainName
|
||||||
|
is NULL, just set it to NetbiosDomainName. This simplifies
|
||||||
|
subsequent code which doesn't have to check for a NULL pointer. */
|
||||||
|
tdom[idx].DnsDomainName = td[idx].DnsDomainName
|
||||||
|
? cwcsdup (td[idx].DnsDomainName)
|
||||||
|
: tdom[idx].NetbiosDomainName;
|
||||||
|
if (td[idx].DomainSid)
|
||||||
|
{
|
||||||
ULONG len = RtlLengthSid (td[idx].DomainSid);
|
ULONG len = RtlLengthSid (td[idx].DomainSid);
|
||||||
tdom[idx].DomainSid = cmalloc_abort(HEAP_BUF, len);
|
tdom[idx].DomainSid = cmalloc_abort(HEAP_BUF, len);
|
||||||
RtlCopySid (len, tdom[idx].DomainSid, td[idx].DomainSid);
|
RtlCopySid (len, tdom[idx].DomainSid, td[idx].DomainSid);
|
||||||
|
}
|
||||||
/* ...and set PosixOffset to 0. This */
|
/* ...and set PosixOffset to 0. This */
|
||||||
tdom[idx].PosixOffset = 0;
|
tdom[idx].PosixOffset = 0;
|
||||||
}
|
}
|
||||||
NetApiBufferFree (td);
|
NetApiBufferFree (td);
|
||||||
tdom_count = tdom_cnt;
|
tdom_count = tdom_cnt;
|
||||||
}
|
}
|
||||||
/* If we have NFS installed, we make use of a name mapping server. This
|
/* If we have Microsoft Client for NFS installed, we make use of a name
|
||||||
can be either Active Directory to map uids/gids directly to Windows SIDs,
|
mapping server. This can be either Active Directory to map uids/gids
|
||||||
or an AD LDS or other RFC 2307 compatible identity store. The name of
|
directly to Windows SIDs, or an AD LDS or other RFC 2307 compatible
|
||||||
the mapping domain can be fetched from the registry key created by the
|
identity store. The name of the mapping domain can be fetched from the
|
||||||
NFS client installation and entered by the user via nfsadmin or the
|
registry key created by the NFS client installation and entered by the
|
||||||
"Services For NFS" MMC snap-in.
|
user via nfsadmin or the "Services For NFS" MMC snap-in.
|
||||||
|
|
||||||
Reference:
|
Reference:
|
||||||
http://blogs.technet.com/b/filecab/archive/2012/10/09/nfs-identity-mapping-in-windows-server-2012.aspx
|
http://blogs.technet.com/b/filecab/archive/2012/10/09/nfs-identity-mapping-in-windows-server-2012.aspx
|
||||||
|
@ -1042,7 +1052,7 @@ pwdgrp::fetch_account_from_file (fetch_user_arg_t &arg)
|
||||||
NT_readline rl;
|
NT_readline rl;
|
||||||
tmp_pathbuf tp;
|
tmp_pathbuf tp;
|
||||||
char *buf = tp.c_get ();
|
char *buf = tp.c_get ();
|
||||||
char *str = tp.c_get ();
|
char str[128];
|
||||||
char *ret = NULL;
|
char *ret = NULL;
|
||||||
|
|
||||||
/* Create search string. */
|
/* Create search string. */
|
||||||
|
@ -1066,6 +1076,34 @@ pwdgrp::fetch_account_from_file (fetch_user_arg_t &arg)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ULONG
|
||||||
|
fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, bool &ldap_open, cyg_ldap &cldap)
|
||||||
|
{
|
||||||
|
uint32_t id_val;
|
||||||
|
|
||||||
|
if (!td->PosixOffset && !(td->Flags & DS_DOMAIN_PRIMARY) && td->DomainSid)
|
||||||
|
{
|
||||||
|
if (!ldap_open && !(ldap_open = cldap.open (NULL)))
|
||||||
|
{
|
||||||
|
/* We're probably running under a local account, so we're not allowed
|
||||||
|
to fetch any information from AD beyond the most obvious. Never
|
||||||
|
mind, just fake a reasonable posix offset. */
|
||||||
|
id_val = cygheap->dom.lowest_tdo_posix_offset
|
||||||
|
- 0x01000000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
id_val = cldap.fetch_posix_offset_for_domain (td->DnsDomainName);
|
||||||
|
if (id_val)
|
||||||
|
{
|
||||||
|
td->PosixOffset = id_val;
|
||||||
|
if (id_val < cygheap->dom.lowest_tdo_posix_offset)
|
||||||
|
cygheap->dom.lowest_tdo_posix_offset = id_val;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return td->PosixOffset;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group)
|
pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group)
|
||||||
{
|
{
|
||||||
|
@ -1111,6 +1149,8 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group)
|
||||||
case SID_arg:
|
case SID_arg:
|
||||||
sid = *arg.sid;
|
sid = *arg.sid;
|
||||||
ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type);
|
ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type);
|
||||||
|
if (!ret)
|
||||||
|
debug_printf ("LookupAccountSid(%W), %E", sid.string (sidstr));
|
||||||
break;
|
break;
|
||||||
case NAME_arg:
|
case NAME_arg:
|
||||||
/* Skip leading domain separator. This denotes an alias or well-known
|
/* Skip leading domain separator. This denotes an alias or well-known
|
||||||
|
@ -1235,23 +1275,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group)
|
||||||
|
|
||||||
for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx)
|
for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx)
|
||||||
{
|
{
|
||||||
/* If we don't have the PosixOffset of the domain, fetch it.
|
fetch_posix_offset (td, ldap_open, cldap);
|
||||||
Skip primary domain. */
|
|
||||||
if (!td->PosixOffset && !(td->Flags & DS_DOMAIN_PRIMARY))
|
|
||||||
{
|
|
||||||
if (!ldap_open && !(ldap_open = cldap.open (NULL)))
|
|
||||||
id_val = cygheap->dom.lowest_tdo_posix_offset
|
|
||||||
- 0x01000000;
|
|
||||||
else
|
|
||||||
id_val =
|
|
||||||
cldap.fetch_posix_offset_for_domain (td->DnsDomainName);
|
|
||||||
if (id_val)
|
|
||||||
{
|
|
||||||
td->PosixOffset = id_val;
|
|
||||||
if (id_val < cygheap->dom.lowest_tdo_posix_offset)
|
|
||||||
cygheap->dom.lowest_tdo_posix_offset = id_val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (td->PosixOffset > posix_offset && td->PosixOffset <= arg.id)
|
if (td->PosixOffset > posix_offset && td->PosixOffset <= arg.id)
|
||||||
posix_offset = td->PosixOffset;
|
posix_offset = td->PosixOffset;
|
||||||
}
|
}
|
||||||
|
@ -1344,34 +1368,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group)
|
||||||
for (ULONG idx = 0;
|
for (ULONG idx = 0;
|
||||||
(td = cygheap->dom.trusted_domain (idx));
|
(td = cygheap->dom.trusted_domain (idx));
|
||||||
++idx)
|
++idx)
|
||||||
|
if (!wcscmp (dom, td->NetbiosDomainName))
|
||||||
{
|
{
|
||||||
if (wcscmp (dom, td->NetbiosDomainName))
|
|
||||||
continue;
|
|
||||||
domain = td->DnsDomainName;
|
domain = td->DnsDomainName;
|
||||||
posix_offset = td->PosixOffset;
|
posix_offset =
|
||||||
/* If we don't have the PosixOffset of the domain,
|
fetch_posix_offset (td, ldap_open, cldap);
|
||||||
fetch it. */
|
|
||||||
if (!posix_offset)
|
|
||||||
{
|
|
||||||
if (!ldap_open && !(ldap_open = cldap.open (NULL)))
|
|
||||||
{
|
|
||||||
/* We're probably running under a local account,
|
|
||||||
so we're not allowed to fetch any information
|
|
||||||
from AD beyond the most obvious. Never mind,
|
|
||||||
just fake a reasonable posix offset. */
|
|
||||||
id_val = cygheap->dom.lowest_tdo_posix_offset
|
|
||||||
- 0x01000000;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
id_val =
|
|
||||||
cldap.fetch_posix_offset_for_domain (domain);
|
|
||||||
if (id_val)
|
|
||||||
{
|
|
||||||
td->PosixOffset = posix_offset = id_val;
|
|
||||||
if (id_val < cygheap->dom.lowest_tdo_posix_offset)
|
|
||||||
cygheap->dom.lowest_tdo_posix_offset = id_val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1638,10 +1639,38 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group)
|
||||||
__small_swprintf (name = namebuf, L"%d", uid & UNIX_POSIX_MASK);
|
__small_swprintf (name = namebuf, L"%d", uid & UNIX_POSIX_MASK);
|
||||||
name_style = fully_qualified;
|
name_style = fully_qualified;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
|
||||||
|
&& sid_sub_auth (sid, 0) == SECURITY_NT_NON_UNIQUE)
|
||||||
|
{
|
||||||
|
/* Check if we know the domain. If so, create a passwd/group
|
||||||
|
entry with domain prefix and RID as username. */
|
||||||
|
PDS_DOMAIN_TRUSTSW td = NULL;
|
||||||
|
|
||||||
|
sid_sub_auth_count (sid) = sid_sub_auth_count (sid) - 1;
|
||||||
|
for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx)
|
||||||
|
if (td->DomainSid && RtlEqualSid (sid, td->DomainSid))
|
||||||
|
{
|
||||||
|
domain = td->NetbiosDomainName;
|
||||||
|
posix_offset = fetch_posix_offset (td, ldap_open, cldap);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (domain)
|
||||||
|
{
|
||||||
|
sid_sub_auth_count (sid) = sid_sub_auth_count (sid) + 1;
|
||||||
|
wcscpy (dom, domain);
|
||||||
|
__small_swprintf (name = namebuf, L"%W(%u)",
|
||||||
|
group ? L"Group" : L"User",
|
||||||
|
sid_sub_auth_rid (sid));
|
||||||
|
uid = posix_offset + sid_sub_auth_rid (sid);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wcpcpy (dom, L"Unknown");
|
wcpcpy (dom, L"Unknown");
|
||||||
wcpcpy (name = namebuf, group ? L"Group" : L"User");
|
wcpcpy (name = namebuf, group ? L"Group" : L"User");
|
||||||
|
}
|
||||||
name_style = fully_qualified;
|
name_style = fully_qualified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue