* 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>
|
||||
|
||||
* 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);
|
||||
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,
|
||||
attr = tdom_attr, 0, &tv, &msg)) != LDAP_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -777,22 +777,32 @@ cygheap_domain_info::init ()
|
|||
{
|
||||
/* Copy... */
|
||||
tdom[idx].NetbiosDomainName = cwcsdup (td[idx].NetbiosDomainName);
|
||||
tdom[idx].DnsDomainName = cwcsdup (td[idx].DnsDomainName);
|
||||
ULONG len = RtlLengthSid (td[idx].DomainSid);
|
||||
tdom[idx].DomainSid = cmalloc_abort(HEAP_BUF, len);
|
||||
RtlCopySid (len, tdom[idx].DomainSid, td[idx].DomainSid);
|
||||
/* 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);
|
||||
tdom[idx].DomainSid = cmalloc_abort(HEAP_BUF, len);
|
||||
RtlCopySid (len, tdom[idx].DomainSid, td[idx].DomainSid);
|
||||
}
|
||||
/* ...and set PosixOffset to 0. This */
|
||||
tdom[idx].PosixOffset = 0;
|
||||
}
|
||||
NetApiBufferFree (td);
|
||||
tdom_count = tdom_cnt;
|
||||
}
|
||||
/* If we have NFS installed, we make use of a name mapping server. This
|
||||
can be either Active Directory to map uids/gids directly to Windows SIDs,
|
||||
or an AD LDS or other RFC 2307 compatible identity store. The name of
|
||||
the mapping domain can be fetched from the registry key created by the
|
||||
NFS client installation and entered by the user via nfsadmin or the
|
||||
"Services For NFS" MMC snap-in.
|
||||
/* If we have Microsoft Client for NFS installed, we make use of a name
|
||||
mapping server. This can be either Active Directory to map uids/gids
|
||||
directly to Windows SIDs, or an AD LDS or other RFC 2307 compatible
|
||||
identity store. The name of the mapping domain can be fetched from the
|
||||
registry key created by the NFS client installation and entered by the
|
||||
user via nfsadmin or the "Services For NFS" MMC snap-in.
|
||||
|
||||
Reference:
|
||||
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;
|
||||
tmp_pathbuf tp;
|
||||
char *buf = tp.c_get ();
|
||||
char *str = tp.c_get ();
|
||||
char str[128];
|
||||
char *ret = NULL;
|
||||
|
||||
/* Create search string. */
|
||||
|
@ -1066,6 +1076,34 @@ pwdgrp::fetch_account_from_file (fetch_user_arg_t &arg)
|
|||
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 *
|
||||
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:
|
||||
sid = *arg.sid;
|
||||
ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type);
|
||||
if (!ret)
|
||||
debug_printf ("LookupAccountSid(%W), %E", sid.string (sidstr));
|
||||
break;
|
||||
case NAME_arg:
|
||||
/* 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)
|
||||
{
|
||||
/* If we don't have the PosixOffset of the domain, fetch it.
|
||||
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;
|
||||
}
|
||||
}
|
||||
fetch_posix_offset (td, ldap_open, cldap);
|
||||
if (td->PosixOffset > posix_offset && td->PosixOffset <= arg.id)
|
||||
posix_offset = td->PosixOffset;
|
||||
}
|
||||
|
@ -1344,36 +1368,13 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group)
|
|||
for (ULONG idx = 0;
|
||||
(td = cygheap->dom.trusted_domain (idx));
|
||||
++idx)
|
||||
{
|
||||
if (wcscmp (dom, td->NetbiosDomainName))
|
||||
continue;
|
||||
domain = td->DnsDomainName;
|
||||
posix_offset = td->PosixOffset;
|
||||
/* If we don't have the PosixOffset of the domain,
|
||||
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;
|
||||
}
|
||||
if (!wcscmp (dom, td->NetbiosDomainName))
|
||||
{
|
||||
domain = td->DnsDomainName;
|
||||
posix_offset =
|
||||
fetch_posix_offset (td, ldap_open, cldap);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!domain)
|
||||
{
|
||||
|
@ -1640,8 +1641,36 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group)
|
|||
}
|
||||
else
|
||||
{
|
||||
wcpcpy (dom, L"Unknown");
|
||||
wcpcpy (name = namebuf, group ? L"Group" : L"User");
|
||||
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
|
||||
{
|
||||
wcpcpy (dom, L"Unknown");
|
||||
wcpcpy (name = namebuf, group ? L"Group" : L"User");
|
||||
}
|
||||
name_style = fully_qualified;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue