diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2014-02-17 15:36:33 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2014-02-17 15:36:33 +0000 |
commit | a8cf6887a2ea00524ebf330eb50a05cf8e67bc5c (patch) | |
tree | 63b01096a3b6deb0afe5fdfddc43ec5ddd1487c6 /winsup/cygwin/uinfo.cc | |
parent | 1e705e29329a0bca000bfb1f199042ffedfe477b (diff) | |
download | cygnal-a8cf6887a2ea00524ebf330eb50a05cf8e67bc5c.tar.gz cygnal-a8cf6887a2ea00524ebf330eb50a05cf8e67bc5c.tar.bz2 cygnal-a8cf6887a2ea00524ebf330eb50a05cf8e67bc5c.zip |
* autoload.cc (ldap_abandon): Import.
(ldap_result): Import.
(ldap_searchW): Import.
(NetGroupEnum): Import.
(NetLocalGroupEnum): Import.
(NetUserEnum): Import.
* cygheap.h (class cygheap_pwdgrp): Add members enums and enum_tdoms.
(cygheap_pwdgrp::nss_db_enums): New inline method.
(cygheap_pwdgrp::nss_db_enum_tdoms): Ditto.
* cygtls.h (struct _local_storage): Drop unused members pw_pos and
grp_pos.
* grp.cc (grent): New static variable of class gr_ent.
(gr_ent::enumerate_caches): New method.
(gr_ent::enumerate_local): New method.
(gr_ent::getgrent): New method.
(setgrent): Call gr_ent method.
(getgrent32): Ditto.
(endgrent): Ditto.
* ldap.cc (sid_attr): Rename from nfs_attr.
(cyg_ldap::close): Abandon still running asynchronous search.
(cyg_ldap::fetch_ad_account): Reduce filter buffer size.
(cyg_ldap::enumerate_ad_accounts): New method.
(cyg_ldap::next_account): New method.
(cyg_ldap::fetch_posix_offset_for_domain): Reduce filter buffer size.
(cyg_ldap::fetch_unix_sid_from_ad): Ditto. Fix return value in case
no value has been read.
(cyg_ldap::fetch_unix_name_from_rfc2307): Reduce filter buffer size.
* ldap.h (class cyg_ldap): Add msg_id member.
(cyg_ldap::enumerate_ad_accounts): Declare.
(cyg_ldap::next_account): Declare:
* passwd.cc (pwent): New static variable of class pw_ent.
(pg_ent::clear_cache): New method.
(pg_ent::setent): New method.
(pg_ent::getent): New method.
(pg_ent::endent): New method.
(pg_ent::enumerate_file): New method.
(pg_ent::enumerate_builtin): New method.
(pg_ent::enumerate_sam): New method.
(pg_ent::enumerate_ad): New method.
(pw_ent::enumerate_caches): New method.
(pw_ent::enumerate_local): New method.
(pw_ent::getpwent): New method.
(setpwent): Call pw_ent method.
(getpwent): Ditto.
(endpwent): Ditto.
* pwdgrp.h (class pwdgrp): Define pg_ent, pw_ent and gr_ent as friend
classes.
(pwdgrp::add_account_post_fetch): Declare with extra bool parameter.
(pwdgrp::file_attr): New inline method.
(enum nss_enum_t): Define.
(class pg_ent): Define.
(class pw_ent): Define.
(class gr_ent): Define.
* tlsoffsets.h: Regenerate.
* tlsoffsets64.h: Ditto.
* uinfo.cc (cygheap_pwdgrp::init): Initialize enums and enum_tdoms.
(cygheap_pwdgrp::nss_init_line): Fix typo in preceeding comment.
Handle new "db_enum" keyword.
(pwdgrp::add_account_post_fetch): Take additional `bool lock' parameter
and acquire pglock before adding element to array if lock is true.
(pwdgrp::add_account_from_file): Call add_account_post_fetch with lock
set to true.
(pwdgrp::add_account_from_windows): Ditto in case of caching.
(pwdgrp::fetch_account_from_windows): Handle builtin aliases only
known to the domain controller. Only call NetLocalGroupGetInfo for
aliases.
Diffstat (limited to 'winsup/cygwin/uinfo.cc')
-rw-r--r-- | winsup/cygwin/uinfo.cc | 109 |
1 files changed, 95 insertions, 14 deletions
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index 5a0177b82..be7bd34f2 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -562,15 +562,18 @@ cygheap_pwdgrp::init () db_prefix: auto db_cache: yes db_separator: + + db_enum: cache builtin */ pwd_src = (NSS_FILES | NSS_DB); grp_src = (NSS_FILES | NSS_DB); prefix = NSS_AUTO; separator[0] = L'+'; caching = true; + enums = (ENUM_CACHE | ENUM_BUILTIN); + enum_tdoms = NULL; } -/* The /etc/nssswitch.conf file is read exactly once by the root process of a +/* The /etc/nsswitch.conf file is read exactly once by the root process of a process tree. We can't afford methodical changes during the lifetime of a process tree. */ void @@ -662,6 +665,58 @@ cygheap_pwdgrp::nss_init_line (const char *line) else debug_printf ("Invalid nsswitch.conf content: %s", line); } + else if (!strncmp (c, "enum:", 5)) + { + tmp_pathbuf tp; + char *tdoms = tp.c_get (); + char *td = tdoms; + int new_enums = ENUM_NONE; + + td[0] = '\0'; + c += 5; + c += strspn (c, " \t"); + while (!strchr (" \t", *c)) + { + const char *e = c + strcspn (c, " \t"); + if (!strncmp (c, "none", 4) && strchr (" \t", c[4])) + new_enums = ENUM_NONE; + else if (!strncmp (c, "builtin", 7) && strchr (" \t", c[7])) + new_enums |= ENUM_BUILTIN; + else if (!strncmp (c, "cache", 5) && strchr (" \t", c[5])) + new_enums |= ENUM_CACHE; + else if (!strncmp (c, "files", 5) && strchr (" \t", c[5])) + new_enums |= ENUM_FILES; + else if (!strncmp (c, "local", 5) && strchr (" \t", c[5])) + new_enums |= ENUM_LOCAL; + else if (!strncmp (c, "primary", 7) && strchr (" \t", c[7])) + new_enums |= ENUM_PRIMARY; + else if (!strncmp (c, "alltrusted", 10) && strchr (" \t", c[10])) + new_enums |= ENUM_TDOMS | ENUM_TDOMS_ALL; + else if (!strncmp (c, "all", 3) && strchr (" \t", c[3])) + new_enums |= ENUM_ALL; + else + { + td = stpcpy (stpncpy (td, c, e - c), " "); + new_enums |= ENUM_TDOMS; + } + c = e; + c += strspn (c, " \t"); + } + if ((new_enums & (ENUM_TDOMS | ENUM_TDOMS_ALL)) == ENUM_TDOMS) + { + if (td > tdoms) + { + PWCHAR spc; + sys_mbstowcs_alloc (&enum_tdoms, HEAP_BUF, tdoms); + /* Convert string to REG_MULTI_SZ-style. */ + while ((spc = wcsrchr (enum_tdoms, L' '))) + *spc = L'\0'; + } + else + new_enums &= ~(ENUM_TDOMS | ENUM_TDOMS_ALL); + } + enums = new_enums; + } break; case '\0': case '#': @@ -867,15 +922,17 @@ get_logon_sid () } void * -pwdgrp::add_account_post_fetch (char *line) +pwdgrp::add_account_post_fetch (char *line, bool lock) { if (line) { void *ret; - pglock.init ("pglock")->acquire (); + if (lock) + pglock.init ("pglock")->acquire (); add_line (line); ret = ((char *) pwdgrp_buf) + (curr_lines - 1) * pwdgrp_buf_elem_size; - pglock.release (); + if (lock) + pglock.release (); return ret; } return NULL; @@ -890,7 +947,7 @@ pwdgrp::add_account_from_file (cygpsid &sid) arg.type = SID_arg; arg.sid = &sid; char *line = fetch_account_from_file (arg); - return (struct passwd *) add_account_post_fetch (line); + return (struct passwd *) add_account_post_fetch (line, true); } void * @@ -902,7 +959,7 @@ pwdgrp::add_account_from_file (const char *name) arg.type = NAME_arg; arg.name = name; char *line = fetch_account_from_file (arg); - return (struct passwd *) add_account_post_fetch (line); + return (struct passwd *) add_account_post_fetch (line, true); } void * @@ -914,7 +971,7 @@ pwdgrp::add_account_from_file (uint32_t id) arg.type = ID_arg; arg.id = id; char *line = fetch_account_from_file (arg); - return (struct passwd *) add_account_post_fetch (line); + return (struct passwd *) add_account_post_fetch (line, true); } void * @@ -927,8 +984,8 @@ pwdgrp::add_account_from_windows (cygpsid &sid, bool group) if (!line) return NULL; if (cygheap->pg.nss_db_caching ()) - return add_account_post_fetch (line); - return (prep_tls_pwbuf ())->add_account_post_fetch (line); + return add_account_post_fetch (line, true); + return (prep_tls_pwbuf ())->add_account_post_fetch (line, false); } void * @@ -941,8 +998,8 @@ pwdgrp::add_account_from_windows (const char *name, bool group) if (!line) return NULL; if (cygheap->pg.nss_db_caching ()) - return add_account_post_fetch (line); - return (prep_tls_pwbuf ())->add_account_post_fetch (line); + return add_account_post_fetch (line, true); + return (prep_tls_pwbuf ())->add_account_post_fetch (line, false); } void * @@ -955,8 +1012,8 @@ pwdgrp::add_account_from_windows (uint32_t id, bool group) if (!line) return NULL; if (cygheap->pg.nss_db_caching ()) - return add_account_post_fetch (line); - return (prep_tls_pwbuf ())->add_account_post_fetch (line); + return add_account_post_fetch (line, true); + return (prep_tls_pwbuf ())->add_account_post_fetch (line, false); } /* Check if file exists and if it has been written to since last checked. @@ -1149,6 +1206,28 @@ 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 + && cygheap->dom.member_machine () + && sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */ + && sid_sub_auth (sid, 0) == SECURITY_BUILTIN_DOMAIN_RID) + { + /* LookupAccountSid called on a non-DC cannot resolve aliases which + are not defined in the local SAM. If we encounter an alias which + can't be resolved, and if we're a domain member machine, ask a DC. + Do *not* use LookupAccountSidW. It can take ages when called on a + DC for some weird reason. Use LDAP instead. */ + PWCHAR val; + + if ((ldap_open = cldap.open (NULL)) + && cldap.fetch_ad_account (sid, group) + && (val = cldap.get_group_name ())) + { + wcpcpy (name, val); + wcpcpy (dom, L"BUILTIN"); + acc_type = SidTypeAlias; + ret = true; + } + } if (!ret) debug_printf ("LookupAccountSid(%W), %E", sid.string (sidstr)); break; @@ -1478,7 +1557,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group) /* Set comment variable for below attribute loop. */ comment = ui->usri4_comment; } - else /* SidTypeGroup || SidTypeAlias */ + else if (acc_type == SidTypeAlias) { nas = NetLocalGroupGetInfo (NULL, name, 1, (PBYTE *) &gi); if (nas != NERR_Success) @@ -1489,6 +1568,8 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group) /* Set comment variable for below attribute loop. */ comment = gi->lgrpi1_comment; } + else /* SidTypeGroup. No way to add a comment to "None" :( */ + break; /* Local SAM accounts have only a handful attributes available to home users. Therefore, fetch additional passwd/group attributes from the "Description" field |