diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2014-02-13 14:04:03 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2014-02-13 14:04:03 +0000 |
commit | 85b8256d2ede42f03b5a2791790584853e404fef (patch) | |
tree | 72b64130d93020445f3b9fef105729d0f13f4da8 /winsup/cygwin/uinfo.cc | |
parent | 5f51881a6dac85522fddeedd9484c8d7d48d261b (diff) | |
download | cygnal-85b8256d2ede42f03b5a2791790584853e404fef.tar.gz cygnal-85b8256d2ede42f03b5a2791790584853e404fef.tar.bz2 cygnal-85b8256d2ede42f03b5a2791790584853e404fef.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/uinfo.cc')
-rw-r--r-- | winsup/cygwin/uinfo.cc | 149 |
1 files changed, 89 insertions, 60 deletions
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index f207de577..e6533c23a 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -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; } |