summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/grp.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-02-17 15:36:33 +0000
committerCorinna Vinschen <corinna@vinschen.de>2014-02-17 15:36:33 +0000
commita8cf6887a2ea00524ebf330eb50a05cf8e67bc5c (patch)
tree63b01096a3b6deb0afe5fdfddc43ec5ddd1487c6 /winsup/cygwin/grp.cc
parent1e705e29329a0bca000bfb1f199042ffedfe477b (diff)
downloadcygnal-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/grp.cc')
-rw-r--r--winsup/cygwin/grp.cc111
1 files changed, 94 insertions, 17 deletions
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc
index 09a8daa37..6f9b4b9bb 100644
--- a/winsup/cygwin/grp.cc
+++ b/winsup/cygwin/grp.cc
@@ -13,6 +13,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
+#include <lm.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -23,6 +24,9 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
+#include "miscfuncs.h"
+#include "ldap.h"
+#include "tls_pbuf.h"
static char * NO_COPY_RO null_ptr;
@@ -309,31 +313,104 @@ getgrnam (const char *name)
}
#endif
-extern "C" void
-endgrent ()
-{
- _my_tls.locals.grp_pos = 0;
-}
+/* getgrent functions are not reentrant. */
+static gr_ent grent;
-extern "C" struct group *
-getgrent32 ()
+void *
+gr_ent::enumerate_caches ()
{
- pwdgrp &grf = cygheap->pg.grp_cache.file;
- if (cygheap->pg.nss_grp_files ())
+ if (!max && from_files)
{
- cygheap->pg.grp_cache.file.check_file (true);
- if (_my_tls.locals.grp_pos < grf.cached_groups ())
- return &grf.group ()[_my_tls.locals.grp_pos++].g;
+ pwdgrp &grf = cygheap->pg.grp_cache.file;
+ grf.check_file (true);
+ if (cnt < grf.cached_groups ())
+ return &grf.group ()[cnt++].g;
+ cnt = 0;
+ max = 1;
}
- if ((cygheap->pg.nss_grp_db ()) && cygheap->pg.nss_db_caching ())
+ if (from_db && cygheap->pg.nss_db_caching ())
{
pwdgrp &grw = cygheap->pg.grp_cache.win;
- if (_my_tls.locals.grp_pos - grf.cached_groups () < grw.cached_groups ())
- return &grw.group ()[_my_tls.locals.grp_pos++ - grf.cached_groups ()].g;
+ if (cnt < grw.cached_groups ())
+ return &grw.group ()[cnt++].g;
}
+ cnt = max = 0;
return NULL;
}
+void *
+gr_ent::enumerate_local ()
+{
+ while (true)
+ {
+ if (!cnt)
+ {
+ DWORD total;
+ NET_API_STATUS ret;
+
+ if (buf)
+ {
+ NetApiBufferFree (buf);
+ buf = NULL;
+ }
+ if (resume == ULONG_MAX)
+ ret = ERROR_NO_MORE_ITEMS;
+ else
+ ret = NetLocalGroupEnum (NULL, 0, (PBYTE *) &buf,
+ MAX_PREFERRED_LENGTH,
+ &max, &total, &resume);
+ if (ret == NERR_Success)
+ resume = ULONG_MAX;
+ else if (ret != ERROR_MORE_DATA)
+ {
+ cnt = max = resume = 0;
+ return NULL;
+ }
+ }
+ while (cnt < max)
+ {
+ cygsid sid;
+ DWORD slen = MAX_SID_LEN;
+ WCHAR dom[DNLEN + 1];
+ DWORD dlen = DNLEN + 1;
+ SID_NAME_USE acc_type;
+
+ LookupAccountNameW (NULL,
+ ((PLOCALGROUP_INFO_0) buf)[cnt++].lgrpi0_name,
+ sid, &slen, dom, &dlen, &acc_type);
+ fetch_user_arg_t arg;
+ arg.type = SID_arg;
+ arg.sid = &sid;
+ char *line = pg.fetch_account_from_windows (arg, true);
+ if (line)
+ return pg.add_account_post_fetch (line, false);
+ }
+ cnt = 0;
+ }
+}
+
+struct group *
+gr_ent::getgrent (void)
+{
+ if (state == rewound)
+ setent (true);
+ else
+ clear_cache ();
+ return (struct group *) getent ();
+}
+
+extern "C" void
+setgrent ()
+{
+ grent.setgrent ();
+}
+
+extern "C" struct group *
+getgrent32 (void)
+{
+ return grent.getgrent ();
+}
+
#ifdef __x86_64__
EXPORT_ALIAS (getgrent32, getgrent)
#else
@@ -347,9 +424,9 @@ getgrent ()
#endif
extern "C" void
-setgrent ()
+endgrent (void)
{
- _my_tls.locals.grp_pos = 0;
+ grent.endgrent ();
}
int