diff options
Diffstat (limited to 'winsup/cygwin/grp.cc')
-rw-r--r-- | winsup/cygwin/grp.cc | 111 |
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 |