* 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.
This commit is contained in:
Corinna Vinschen 2014-02-17 15:36:33 +00:00
parent 1e705e2932
commit a8cf6887a2
12 changed files with 1072 additions and 294 deletions

View File

@ -1,3 +1,72 @@
2014-02-17 Corinna Vinschen <corinna@vinschen.de>
* 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.
2014-02-16 Corinna Vinschen <corinna@vinschen.de>
* miscfuncs.h (NT_readline::close): New function to close handle.

View File

@ -584,6 +584,7 @@ LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
#pragma push_macro ("mangle")
#undef mangle
#define mangle(name, n) #name
LoadDLLfunc (ldap_abandon, 0, wldap32)
LoadDLLfunc (ldap_bind_s, 0, wldap32)
LoadDLLfunc (ldap_count_valuesW, 0, wldap32)
LoadDLLfunc (ldap_first_entry, 0, wldap32)
@ -592,6 +593,8 @@ LoadDLLfunc (ldap_get_values_lenW, 0, wldap32)
LoadDLLfunc (ldap_initW, 0, wldap32)
LoadDLLfunc (ldap_memfreeW, 0, wldap32)
LoadDLLfunc (ldap_next_entry, 0, wldap32)
LoadDLLfunc (ldap_result, 0, wldap32)
LoadDLLfunc (ldap_searchW, 0, wldap32)
LoadDLLfunc (ldap_search_stW, 0, wldap32)
LoadDLLfunc (ldap_set_option, 0, wldap32)
LoadDLLfunc (ldap_sslinitW, 0, wldap32)
@ -610,8 +613,11 @@ LoadDLLfunc (WNetOpenEnumA, 20, mpr)
LoadDLLfunc (DsEnumerateDomainTrustsW, 16, netapi32)
LoadDLLfunc (DsGetDcNameW, 24, netapi32)
LoadDLLfunc (NetApiBufferFree, 4, netapi32)
LoadDLLfunc (NetGroupEnum, 28, netapi32)
LoadDLLfunc (NetLocalGroupEnum, 28, netapi32)
LoadDLLfunc (NetLocalGroupGetInfo, 16, netapi32)
LoadDLLfunc (NetUseGetInfo, 16, netapi32)
LoadDLLfunc (NetUserEnum, 32, netapi32)
LoadDLLfunc (NetUserGetGroups, 28, netapi32)
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
LoadDLLfunc (NetUserGetLocalGroups, 32, netapi32)

View File

@ -400,12 +400,14 @@ class cygheap_pwdgrp
NSS_PRIMARY,
NSS_ALWAYS
};
bool nss_inited;
int pwd_src;
int grp_src;
pfx_t prefix;
WCHAR separator[2];
bool caching;
bool nss_inited;
int pwd_src;
int grp_src;
pfx_t prefix;
WCHAR separator[2];
bool caching;
int enums;
PWCHAR enum_tdoms;
void nss_init_line (const char *line);
void _nss_init ();
@ -432,6 +434,8 @@ public:
inline bool nss_prefix_always () const { return prefix == NSS_ALWAYS; }
inline PCWSTR nss_separator () const { return separator; }
inline bool nss_db_caching () const { return caching; }
inline int nss_db_enums () const { return enums; }
inline PCWSTR nss_db_enum_tdoms () const { return enum_tdoms; }
};
class cygheap_ugid_cache

View File

@ -82,11 +82,9 @@ struct _local_storage
/* passwd.cc */
void *pwbuf;
char pass[_PASSWORD_LEN];
ULONG pw_pos;
/* grp.cc */
void *grbuf;
ULONG grp_pos;
/* dlfcn.cc */
int dl_error;

View File

@ -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,29 +313,102 @@ getgrnam (const char *name)
}
#endif
extern "C" void
endgrent ()
/* getgrent functions are not reentrant. */
static gr_ent grent;
void *
gr_ent::enumerate_caches ()
{
_my_tls.locals.grp_pos = 0;
if (!max && from_files)
{
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 (from_db && cygheap->pg.nss_db_caching ())
{
pwdgrp &grw = cygheap->pg.grp_cache.win;
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 ()
getgrent32 (void)
{
pwdgrp &grf = cygheap->pg.grp_cache.file;
if (cygheap->pg.nss_grp_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;
}
if ((cygheap->pg.nss_grp_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;
}
return NULL;
return grent.getgrent ();
}
#ifdef __x86_64__
@ -347,9 +424,9 @@ getgrent ()
#endif
extern "C" void
setgrent ()
endgrent (void)
{
_my_tls.locals.grp_pos = 0;
grent.endgrent ();
}
int

View File

@ -20,6 +20,7 @@ details. */
#include "pinfo.h"
#include "lm.h"
#include "dsgetdc.h"
#include "tls_pbuf.h"
static LDAP_TIMEVAL tv = { 3, 0 };
@ -54,7 +55,7 @@ PWCHAR tdom_attr[] =
NULL
};
PWCHAR nfs_attr[] =
PWCHAR sid_attr[] =
{
(PWCHAR) L"objectSid",
NULL
@ -216,6 +217,8 @@ err:
void
cyg_ldap::close ()
{
if (msg_id != (ULONG) -1)
ldap_abandon (lh, msg_id);
if (lh)
ldap_unbind (lh);
if (msg)
@ -228,12 +231,13 @@ cyg_ldap::close ()
msg = entry = NULL;
val = NULL;
rootdse = NULL;
msg_id = (ULONG) -1;
}
bool
cyg_ldap::fetch_ad_account (PSID sid, bool group)
{
WCHAR filter[512], *f;
WCHAR filter[140], *f;
LONG len = (LONG) RtlLengthSid (sid);
PBYTE s = (PBYTE) sid;
static WCHAR hex_wchars[] = L"0123456789abcdef";
@ -273,10 +277,109 @@ cyg_ldap::fetch_ad_account (PSID sid, bool group)
return true;
}
bool
cyg_ldap::enumerate_ad_accounts (PCWSTR domain, bool group)
{
tmp_pathbuf tp;
PCWSTR filter;
PWCHAR dse;
if (msg)
{
ldap_memfreeW ((PWCHAR) msg);
msg = entry = NULL;
}
if (val)
{
ldap_value_freeW (val);
val = NULL;
}
if (!group)
filter = L"(&(objectClass=User)"
"(objectCategory=Person)"
/* 512 == ADS_UF_NORMAL_ACCOUNT */
"(userAccountControl:" LDAP_MATCHING_RULE_BIT_AND ":=512)"
"(objectSid=*))";
else if (!domain)
filter = L"(&(objectClass=Group)"
"(objectSid=*))";
else
filter = L"(&(objectClass=Group)"
/* 1 == ACCOUNT_GROUP */
"(!(groupType:" LDAP_MATCHING_RULE_BIT_AND ":=1))"
"(objectSid=*))";
if (!domain)
dse = rootdse;
else
{
/* create rootdse from domain name. */
dse = tp.w_get ();
PCWSTR ps, pe;
PWCHAR d;
d = dse;
for (ps = domain; (pe = wcschr (ps, L'.')); ps = pe + 1)
{
if (d > dse)
d = wcpcpy (d, L",");
d = wcpncpy (wcpcpy (d, L"DC="), ps, pe - ps);
}
if (d > dse)
d = wcpcpy (d, L",");
d = wcpcpy (wcpcpy (d, L"DC="), ps);
}
msg_id = ldap_searchW (lh, dse, LDAP_SCOPE_SUBTREE, (PWCHAR) filter,
sid_attr, 0);
if (msg_id == (ULONG) -1)
{
debug_printf ("ldap_searchW(%W,%W) error 0x%02x", dse, filter,
LdapGetLastError ());
return false;
}
return true;
}
bool
cyg_ldap::next_account (cygsid &sid)
{
ULONG ret;
PLDAP_BERVAL *bval;
if (msg)
{
ldap_memfreeW ((PWCHAR) msg);
msg = entry = NULL;
}
if (val)
{
ldap_value_freeW (val);
val = NULL;
}
ret = ldap_result (lh, msg_id, LDAP_MSG_ONE, &tv, &msg);
if (ret == 0)
{
debug_printf ("ldap_result() timeout!");
return false;
}
if (ret == (ULONG) -1)
{
debug_printf ("ldap_result() error 0x%02x", LdapGetLastError ());
return false;
}
if ((entry = ldap_first_entry (lh, msg))
&& (bval = ldap_get_values_lenW (lh, entry, sid_attr[0])))
{
sid = (PSID) bval[0]->bv_val;
ldap_value_free_len (bval);
return true;
}
return false;
}
uint32_t
cyg_ldap::fetch_posix_offset_for_domain (PCWSTR domain)
{
WCHAR filter[512];
WCHAR filter[300];
ULONG ret;
if (msg)
@ -331,7 +434,7 @@ cyg_ldap::get_num_attribute (int idx)
bool
cyg_ldap::fetch_unix_sid_from_ad (uint32_t id, cygsid &sid, bool group)
{
WCHAR filter[512];
WCHAR filter[48];
ULONG ret;
PLDAP_BERVAL *bval;
@ -345,25 +448,26 @@ cyg_ldap::fetch_unix_sid_from_ad (uint32_t id, cygsid &sid, bool group)
else
__small_swprintf (filter, L"(&(objectClass=User)(uidNumber=%u))", id);
if ((ret = ldap_search_stW (lh, rootdse, LDAP_SCOPE_SUBTREE, filter,
nfs_attr, 0, &tv, &msg)) != LDAP_SUCCESS)
sid_attr, 0, &tv, &msg)) != LDAP_SUCCESS)
{
debug_printf ("ldap_search_stW(%W,%W) error 0x%02x",
rootdse, filter, ret);
return false;
}
if ((entry = ldap_first_entry (lh, msg))
&& (bval = ldap_get_values_lenW (lh, entry, nfs_attr[0])))
&& (bval = ldap_get_values_lenW (lh, entry, sid_attr[0])))
{
sid = (PSID) bval[0]->bv_val;
ldap_value_free_len (bval);
return true;
}
return true;
return false;
}
PWCHAR
cyg_ldap::fetch_unix_name_from_rfc2307 (uint32_t id, bool group)
{
WCHAR filter[512];
WCHAR filter[52];
ULONG ret;
if (msg)

View File

@ -8,6 +8,8 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#pragma once
#pragma push_macro ("DECLSPEC_IMPORT")
#undef DECLSPEC_IMPORT
#define DECLSPEC_IMPORT
@ -32,6 +34,7 @@ class cyg_ldap {
PWCHAR *val;
PWCHAR *attr;
bool isAD;
ULONG msg_id;
bool connect_ssl (PCWSTR domain);
bool connect_non_ssl (PCWSTR domain);
@ -42,7 +45,7 @@ class cyg_ldap {
public:
cyg_ldap () : lh (NULL), rootdse (NULL), msg (NULL), entry (NULL),
val (NULL), isAD (false)
val (NULL), isAD (false), msg_id ((ULONG) -1)
{}
~cyg_ldap () { close (); }
@ -50,6 +53,8 @@ public:
bool open (PCWSTR in_domain);
void close ();
bool fetch_ad_account (PSID sid, bool group);
bool enumerate_ad_accounts (PCWSTR domain, bool group);
bool next_account (cygsid &sid);
uint32_t fetch_posix_offset_for_domain (PCWSTR domain);
uid_t remap_uid (uid_t uid);
gid_t remap_gid (gid_t gid);

View File

@ -10,6 +10,7 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
#include <lm.h>
#include <stdlib.h>
#include <stdio.h>
#include "cygerrno.h"
@ -20,6 +21,9 @@ details. */
#include "pinfo.h"
#include "cygheap.h"
#include "shared_info.h"
#include "miscfuncs.h"
#include "ldap.h"
#include "tls_pbuf.h"
/* Parse /etc/passwd line into passwd structure. */
bool
@ -275,23 +279,365 @@ getpwnam_r (const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, s
return 0;
}
/* getpwent functions are not reentrant. */
static pw_ent pwent;
void
pg_ent::clear_cache ()
{
if (pg.curr_lines)
{
if (state > from_file)
cfree (group ? grp.g.gr_name : pwd.p.pw_name);
pg.curr_lines = 0;
}
}
void
pg_ent::setent (bool _group, int _enums, PCWSTR _enum_tdoms)
{
endent (_group);
if (!_enums && !_enum_tdoms)
{
enums = cygheap->pg.nss_db_enums ();
enum_tdoms = cygheap->pg.nss_db_enum_tdoms ();
}
else
{
enums = _enums;
enum_tdoms = _enum_tdoms;
}
if (_group)
{
from_files = cygheap->pg.nss_grp_files ();
from_db = cygheap->pg.nss_grp_db ();
}
else
{
from_files = cygheap->pg.nss_pwd_files ();
from_db = cygheap->pg.nss_pwd_db ();
}
}
void *
pg_ent::getent (void)
{
void *entry;
switch (state)
{
case rewound:
state = from_cache;
/*FALLTHRU*/
case from_cache:
if (nss_db_enum_caches ()
&& (entry = enumerate_caches ()))
return entry;
state = from_file;
/*FALLTHRU*/
case from_file:
if (from_files
&& nss_db_enum_files ()
&& (entry = enumerate_file ()))
return entry;
state = from_builtin;
/*FALLTHRU*/
case from_builtin:
if (from_db
&& nss_db_enum_builtin ()
&& (entry = enumerate_builtin ()))
return entry;
state = from_local;
/*FALLTHRU*/
case from_local:
if (from_db
&& nss_db_enum_local ()
&& (!cygheap->dom.member_machine ()
|| !nss_db_enum_primary ())
&& (entry = enumerate_local ()))
return entry;
state = from_sam;
/*FALLTHRU*/
case from_sam:
if (from_db
&& nss_db_enum_local ()
&& (entry = enumerate_sam ()))
return entry;
state = from_ad;
/*FALLTHRU*/
case from_ad:
if (cygheap->dom.member_machine ()
&& from_db
&& (entry = enumerate_ad ()))
return entry;
state = finished;
/*FALLTHRU*/
case finished:
break;
}
return NULL;
}
void
pg_ent::endent (bool _group)
{
if (buf)
{
if (state == from_file)
free (buf);
else if (state == from_local || state == from_sam)
NetApiBufferFree (buf);
buf = NULL;
}
if (!pg.curr_lines)
{
if ((group = _group))
{
pg.init_grp ();
pg.pwdgrp_buf = (void *) &grp;
}
else
{
pg.init_pwd ();
pg.pwdgrp_buf = (void *) &pwd;
}
pg.max_lines = 1;
}
else
clear_cache ();
cldap.close ();
rl.close ();
cnt = max = resume = 0;
enums = 0;
enum_tdoms = NULL;
state = rewound;
}
void *
pg_ent::enumerate_file ()
{
void *entry;
if (!cnt)
{
pwdgrp &prf = group ? cygheap->pg.grp_cache.file
: cygheap->pg.pwd_cache.file;
if (prf.check_file (group))
{
if (!buf)
buf = (char *) malloc (NT_MAX_PATH);
if (buf
&& !rl.init (prf.file_attr (), buf, NT_MAX_PATH))
{
free (buf);
buf = NULL;
}
}
}
++cnt;
if ((entry = pg.add_account_post_fetch (rl.gets (), false)))
return entry;
rl.close ();
free (buf);
buf = NULL;
cnt = max = resume = 0;
return NULL;
}
void *
pg_ent::enumerate_builtin ()
{
static const char *pwd_builtins[] = {
/* SYSTEM */
"S-1-5-18",
/* LocalService */
"S-1-5-19",
/* NetworkService */
"S-1-5-20",
/* Administrators */
"S-1-5-32-544",
/* TrustedInstaller */
"S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464",
/* The end */
NULL
};
static const char *grp_builtins[] = {
/* SYSTEM */
"S-1-5-18",
/* TrustedInstaller */
"S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464",
/* The end */
NULL
};
const char **builtins = group ? grp_builtins : pwd_builtins;
if (!builtins[cnt])
{
cnt = max = resume = 0;
return NULL;
}
cygsid sid (builtins[cnt++]);
fetch_user_arg_t arg;
arg.type = SID_arg;
arg.sid = &sid;
char *line = pg.fetch_account_from_windows (arg, group);
return pg.add_account_post_fetch (line, false);
}
void *
pg_ent::enumerate_sam ()
{
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 if (group)
ret = NetGroupEnum (NULL, 2, (PBYTE *) &buf, MAX_PREFERRED_LENGTH,
&max, &total, &resume);
else
ret = NetUserEnum (NULL, 20, FILTER_NORMAL_ACCOUNT, (PBYTE *) &buf,
MAX_PREFERRED_LENGTH, &max, &total,
(PDWORD) &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 (cygheap->dom.account_sid ());
sid_sub_auth (sid, sid_sub_auth_count (sid)) =
group ? ((PGROUP_INFO_2) buf)[cnt].grpi2_group_id
: ((PUSER_INFO_20) buf)[cnt].usri20_user_id;
++cnt;
++sid_sub_auth_count (sid);
fetch_user_arg_t arg;
arg.type = SID_arg;
arg.sid = &sid;
char *line = pg.fetch_account_from_windows (arg, group);
if (line)
return pg.add_account_post_fetch (line, false);
}
cnt = 0;
}
}
void *
pg_ent::enumerate_ad ()
{
while (true)
{
if (!cnt)
{
PDS_DOMAIN_TRUSTSW td;
if (!resume)
{
if (!cldap.open (NULL))
return NULL;
++resume;
if (!nss_db_enum_primary ()
|| !cldap.enumerate_ad_accounts (NULL, group))
continue;
}
else if ((td = cygheap->dom.trusted_domain (resume - 1)))
{
++resume;
if ((td->Flags & DS_DOMAIN_PRIMARY)
|| !td->DomainSid
|| (!nss_db_enum_tdom (td->NetbiosDomainName)
&& !nss_db_enum_tdom (td->DnsDomainName))
|| !cldap.enumerate_ad_accounts (td->DnsDomainName, group))
continue;
}
else
{
cldap.close ();
return NULL;
}
}
++cnt;
cygsid sid;
if (cldap.next_account (sid))
{
fetch_user_arg_t arg;
arg.type = SID_arg;
arg.sid = &sid;
char *line = pg.fetch_account_from_windows (arg, group);
if (line)
return pg.add_account_post_fetch (line, false);
}
cnt = 0;
}
}
void *
pw_ent::enumerate_caches ()
{
if (!max && from_files)
{
pwdgrp &prf = cygheap->pg.pwd_cache.file;
prf.check_file (false);
if (cnt < prf.cached_users ())
return &prf.passwd ()[cnt++].p;
cnt = 0;
max = 1;
}
if (from_db && cygheap->pg.nss_db_caching ())
{
pwdgrp &prw = cygheap->pg.pwd_cache.win;
if (cnt < prw.cached_users ())
return &prw.passwd ()[cnt++].p;
}
cnt = max = 0;
return NULL;
}
void *
pw_ent::enumerate_local ()
{
return NULL;
}
struct passwd *
pw_ent::getpwent (void)
{
if (state == rewound)
setent (false);
else
clear_cache ();
return (struct passwd *) getent ();
}
extern "C" void
setpwent ()
{
pwent.setpwent ();
}
extern "C" struct passwd *
getpwent (void)
{
pwdgrp &prf = cygheap->pg.pwd_cache.file;
if (cygheap->pg.nss_pwd_files ())
{
cygheap->pg.pwd_cache.file.check_file (false);
if (_my_tls.locals.pw_pos < prf.cached_users ())
return &prf.passwd ()[_my_tls.locals.pw_pos++].p;
}
if ((cygheap->pg.nss_pwd_db ()) && cygheap->pg.nss_db_caching ())
{
pwdgrp &prw = cygheap->pg.pwd_cache.win;
if (_my_tls.locals.pw_pos - prf.cached_users () < prw.cached_users ())
return &prw.passwd ()[_my_tls.locals.pw_pos++ - prf.cached_users ()].p;
}
return NULL;
return pwent.getpwent ();
}
extern "C" void
endpwent (void)
{
pwent.endpwent ();
}
#ifndef __x86_64__
@ -302,18 +648,6 @@ getpwduid (__uid16_t)
}
#endif
extern "C" void
setpwent (void)
{
_my_tls.locals.pw_pos = 0;
}
extern "C" void
endpwent (void)
{
_my_tls.locals.pw_pos = 0;
}
extern "C" int
setpassent (int)
{

View File

@ -23,6 +23,8 @@ extern struct group *internal_getgrnam (const char *);
int internal_getgroups (int, gid_t *, cygpsid * = NULL);
#include "sync.h"
#include "ldap.h"
#include "miscfuncs.h"
enum fetch_user_arg_type_t {
SID_arg,
@ -56,6 +58,10 @@ struct pg_grp
class pwdgrp
{
friend class pg_ent;
friend class pw_ent;
friend class gr_ent;
unsigned pwdgrp_buf_elem_size;
void *pwdgrp_buf;
bool (pwdgrp::*parse) ();
@ -87,7 +93,7 @@ class pwdgrp
i = (int) x;
return res;
}
void *add_account_post_fetch (char *line);
void *add_account_post_fetch (char *line, bool lock);
void *add_account_from_file (cygpsid &sid);
void *add_account_from_file (const char *name);
void *add_account_from_file (uint32_t id);
@ -103,6 +109,7 @@ class pwdgrp
public:
ULONG cached_users () const { return curr_lines; }
ULONG cached_groups () const { return curr_lines; }
POBJECT_ATTRIBUTES file_attr () { return &attr; }
bool check_file (bool group);
void init_pwd ();
@ -141,3 +148,96 @@ public:
struct group *find_group (const char *name);
struct group *find_group (gid_t gid);
};
enum nss_enum_t
{
ENUM_NONE = 0x00,
ENUM_CACHE = 0x01,
ENUM_FILES = 0x02,
ENUM_BUILTIN = 0x04,
ENUM_LOCAL = 0x08,
ENUM_PRIMARY = 0x10,
ENUM_TDOMS = 0x20,
ENUM_TDOMS_ALL = 0x40,
ENUM_ALL = 0x7f
};
class pg_ent
{
protected:
pwdgrp pg;
bool group;
pg_pwd pwd;
pg_grp grp;
NT_readline rl;
cyg_ldap cldap;
PCHAR buf;
ULONG cnt;
ULONG max;
ULONG_PTR resume;
int enums;
PCWSTR enum_tdoms;
bool from_files;
bool from_db;
enum {
rewound = 0,
from_cache,
from_file,
from_builtin,
from_local,
from_sam,
from_ad,
finished
} state;
void clear_cache ();
inline bool nss_db_enum_caches () const { return !!(enums & ENUM_CACHE); }
inline bool nss_db_enum_files () const { return !!(enums & ENUM_FILES); }
inline bool nss_db_enum_builtin () const { return !!(enums & ENUM_BUILTIN); }
inline bool nss_db_enum_local () const { return !!(enums & ENUM_LOCAL); }
inline bool nss_db_enum_primary () const { return !!(enums & ENUM_PRIMARY); }
inline bool nss_db_enum_tdom (PWCHAR domain)
{
if (enums & ENUM_TDOMS_ALL)
return true;
if (!(enums & ENUM_TDOMS) || !enum_tdoms || !domain)
return false;
for (PCWSTR td = enum_tdoms; td && *td; td = wcschr (td, L'\0'))
if (!wcscasecmp (td, domain))
return true;
return false;
}
virtual void *enumerate_caches () = 0;
virtual void *enumerate_file ();
virtual void *enumerate_builtin ();
virtual void *enumerate_local () = 0;
virtual void *enumerate_sam ();
virtual void *enumerate_ad ();
public:
void setent (bool _group, int _enums = 0, PCWSTR _enum_tdoms = NULL);
void *getent ();
void endent (bool _group);
};
class pw_ent : public pg_ent
{
void *enumerate_caches ();
void *enumerate_local ();
public:
inline void setpwent (int _enums = 0, PCWSTR _enum_tdoms = NULL)
{ setent (false, _enums, _enum_tdoms); }
struct passwd *getpwent ();
inline void endpwent () { endent (false); }
};
class gr_ent : public pg_ent
{
void *enumerate_caches ();
void *enumerate_local ();
public:
inline void setgrent (int _enums = 0, PCWSTR _enum_tdoms = NULL)
{ setent (true, _enums, _enum_tdoms); }
struct group *getgrent ();
inline void endgrent () { endent (true); }
};

View File

@ -3,115 +3,115 @@
//; $tls::start_offset = -12700;
//; $tls::locals = -12700;
//; $tls::plocals = 0;
//; $tls::local_clib = -11284;
//; $tls::plocal_clib = 1416;
//; $tls::__dontuse = -11284;
//; $tls::p__dontuse = 1416;
//; $tls::func = -10196;
//; $tls::pfunc = 2504;
//; $tls::saved_errno = -10192;
//; $tls::psaved_errno = 2508;
//; $tls::sa_flags = -10188;
//; $tls::psa_flags = 2512;
//; $tls::oldmask = -10184;
//; $tls::poldmask = 2516;
//; $tls::deltamask = -10180;
//; $tls::pdeltamask = 2520;
//; $tls::errno_addr = -10176;
//; $tls::perrno_addr = 2524;
//; $tls::sigmask = -10172;
//; $tls::psigmask = 2528;
//; $tls::sigwait_mask = -10168;
//; $tls::psigwait_mask = 2532;
//; $tls::sigwait_info = -10164;
//; $tls::psigwait_info = 2536;
//; $tls::signal_arrived = -10160;
//; $tls::psignal_arrived = 2540;
//; $tls::will_wait_for_signal = -10156;
//; $tls::pwill_wait_for_signal = 2544;
//; $tls::thread_context = -10152;
//; $tls::pthread_context = 2548;
//; $tls::thread_id = -9940;
//; $tls::pthread_id = 2760;
//; $tls::infodata = -9936;
//; $tls::pinfodata = 2764;
//; $tls::tid = -9788;
//; $tls::ptid = 2912;
//; $tls::_ctinfo = -9784;
//; $tls::p_ctinfo = 2916;
//; $tls::andreas = -9780;
//; $tls::pandreas = 2920;
//; $tls::wq = -9776;
//; $tls::pwq = 2924;
//; $tls::sig = -9748;
//; $tls::psig = 2952;
//; $tls::incyg = -9744;
//; $tls::pincyg = 2956;
//; $tls::spinning = -9740;
//; $tls::pspinning = 2960;
//; $tls::stacklock = -9736;
//; $tls::pstacklock = 2964;
//; $tls::stackptr = -9732;
//; $tls::pstackptr = 2968;
//; $tls::stack = -9728;
//; $tls::pstack = 2972;
//; $tls::initialized = -8704;
//; $tls::pinitialized = 3996;
//; $tls::local_clib = -11292;
//; $tls::plocal_clib = 1408;
//; $tls::__dontuse = -11292;
//; $tls::p__dontuse = 1408;
//; $tls::func = -10204;
//; $tls::pfunc = 2496;
//; $tls::saved_errno = -10200;
//; $tls::psaved_errno = 2500;
//; $tls::sa_flags = -10196;
//; $tls::psa_flags = 2504;
//; $tls::oldmask = -10192;
//; $tls::poldmask = 2508;
//; $tls::deltamask = -10188;
//; $tls::pdeltamask = 2512;
//; $tls::errno_addr = -10184;
//; $tls::perrno_addr = 2516;
//; $tls::sigmask = -10180;
//; $tls::psigmask = 2520;
//; $tls::sigwait_mask = -10176;
//; $tls::psigwait_mask = 2524;
//; $tls::sigwait_info = -10172;
//; $tls::psigwait_info = 2528;
//; $tls::signal_arrived = -10168;
//; $tls::psignal_arrived = 2532;
//; $tls::will_wait_for_signal = -10164;
//; $tls::pwill_wait_for_signal = 2536;
//; $tls::thread_context = -10160;
//; $tls::pthread_context = 2540;
//; $tls::thread_id = -9948;
//; $tls::pthread_id = 2752;
//; $tls::infodata = -9944;
//; $tls::pinfodata = 2756;
//; $tls::tid = -9796;
//; $tls::ptid = 2904;
//; $tls::_ctinfo = -9792;
//; $tls::p_ctinfo = 2908;
//; $tls::andreas = -9788;
//; $tls::pandreas = 2912;
//; $tls::wq = -9784;
//; $tls::pwq = 2916;
//; $tls::sig = -9756;
//; $tls::psig = 2944;
//; $tls::incyg = -9752;
//; $tls::pincyg = 2948;
//; $tls::spinning = -9748;
//; $tls::pspinning = 2952;
//; $tls::stacklock = -9744;
//; $tls::pstacklock = 2956;
//; $tls::stackptr = -9740;
//; $tls::pstackptr = 2960;
//; $tls::stack = -9736;
//; $tls::pstack = 2964;
//; $tls::initialized = -8712;
//; $tls::pinitialized = 3988;
//; __DATA__
#define tls_locals (-12700)
#define tls_plocals (0)
#define tls_local_clib (-11284)
#define tls_plocal_clib (1416)
#define tls___dontuse (-11284)
#define tls_p__dontuse (1416)
#define tls_func (-10196)
#define tls_pfunc (2504)
#define tls_saved_errno (-10192)
#define tls_psaved_errno (2508)
#define tls_sa_flags (-10188)
#define tls_psa_flags (2512)
#define tls_oldmask (-10184)
#define tls_poldmask (2516)
#define tls_deltamask (-10180)
#define tls_pdeltamask (2520)
#define tls_errno_addr (-10176)
#define tls_perrno_addr (2524)
#define tls_sigmask (-10172)
#define tls_psigmask (2528)
#define tls_sigwait_mask (-10168)
#define tls_psigwait_mask (2532)
#define tls_sigwait_info (-10164)
#define tls_psigwait_info (2536)
#define tls_signal_arrived (-10160)
#define tls_psignal_arrived (2540)
#define tls_will_wait_for_signal (-10156)
#define tls_pwill_wait_for_signal (2544)
#define tls_thread_context (-10152)
#define tls_pthread_context (2548)
#define tls_thread_id (-9940)
#define tls_pthread_id (2760)
#define tls_infodata (-9936)
#define tls_pinfodata (2764)
#define tls_tid (-9788)
#define tls_ptid (2912)
#define tls__ctinfo (-9784)
#define tls_p_ctinfo (2916)
#define tls_andreas (-9780)
#define tls_pandreas (2920)
#define tls_wq (-9776)
#define tls_pwq (2924)
#define tls_sig (-9748)
#define tls_psig (2952)
#define tls_incyg (-9744)
#define tls_pincyg (2956)
#define tls_spinning (-9740)
#define tls_pspinning (2960)
#define tls_stacklock (-9736)
#define tls_pstacklock (2964)
#define tls_stackptr (-9732)
#define tls_pstackptr (2968)
#define tls_stack (-9728)
#define tls_pstack (2972)
#define tls_initialized (-8704)
#define tls_pinitialized (3996)
#define tls_local_clib (-11292)
#define tls_plocal_clib (1408)
#define tls___dontuse (-11292)
#define tls_p__dontuse (1408)
#define tls_func (-10204)
#define tls_pfunc (2496)
#define tls_saved_errno (-10200)
#define tls_psaved_errno (2500)
#define tls_sa_flags (-10196)
#define tls_psa_flags (2504)
#define tls_oldmask (-10192)
#define tls_poldmask (2508)
#define tls_deltamask (-10188)
#define tls_pdeltamask (2512)
#define tls_errno_addr (-10184)
#define tls_perrno_addr (2516)
#define tls_sigmask (-10180)
#define tls_psigmask (2520)
#define tls_sigwait_mask (-10176)
#define tls_psigwait_mask (2524)
#define tls_sigwait_info (-10172)
#define tls_psigwait_info (2528)
#define tls_signal_arrived (-10168)
#define tls_psignal_arrived (2532)
#define tls_will_wait_for_signal (-10164)
#define tls_pwill_wait_for_signal (2536)
#define tls_thread_context (-10160)
#define tls_pthread_context (2540)
#define tls_thread_id (-9948)
#define tls_pthread_id (2752)
#define tls_infodata (-9944)
#define tls_pinfodata (2756)
#define tls_tid (-9796)
#define tls_ptid (2904)
#define tls__ctinfo (-9792)
#define tls_p_ctinfo (2908)
#define tls_andreas (-9788)
#define tls_pandreas (2912)
#define tls_wq (-9784)
#define tls_pwq (2916)
#define tls_sig (-9756)
#define tls_psig (2944)
#define tls_incyg (-9752)
#define tls_pincyg (2948)
#define tls_spinning (-9748)
#define tls_pspinning (2952)
#define tls_stacklock (-9744)
#define tls_pstacklock (2956)
#define tls_stackptr (-9740)
#define tls_pstackptr (2960)
#define tls_stack (-9736)
#define tls_pstack (2964)
#define tls_initialized (-8712)
#define tls_pinitialized (3988)

View File

@ -3,115 +3,115 @@
//; $tls::start_offset = -12800;
//; $tls::locals = -12800;
//; $tls::plocals = 0;
//; $tls::local_clib = -11240;
//; $tls::plocal_clib = 1560;
//; $tls::__dontuse = -11240;
//; $tls::p__dontuse = 1560;
//; $tls::func = -9352;
//; $tls::pfunc = 3448;
//; $tls::saved_errno = -9344;
//; $tls::psaved_errno = 3456;
//; $tls::sa_flags = -9340;
//; $tls::psa_flags = 3460;
//; $tls::oldmask = -9336;
//; $tls::poldmask = 3464;
//; $tls::deltamask = -9328;
//; $tls::pdeltamask = 3472;
//; $tls::errno_addr = -9320;
//; $tls::perrno_addr = 3480;
//; $tls::sigmask = -9312;
//; $tls::psigmask = 3488;
//; $tls::sigwait_mask = -9304;
//; $tls::psigwait_mask = 3496;
//; $tls::sigwait_info = -9296;
//; $tls::psigwait_info = 3504;
//; $tls::signal_arrived = -9288;
//; $tls::psignal_arrived = 3512;
//; $tls::will_wait_for_signal = -9280;
//; $tls::pwill_wait_for_signal = 3520;
//; $tls::thread_context = -9272;
//; $tls::pthread_context = 3528;
//; $tls::thread_id = -8440;
//; $tls::pthread_id = 4360;
//; $tls::infodata = -8436;
//; $tls::pinfodata = 4364;
//; $tls::tid = -8288;
//; $tls::ptid = 4512;
//; $tls::_ctinfo = -8280;
//; $tls::p_ctinfo = 4520;
//; $tls::andreas = -8272;
//; $tls::pandreas = 4528;
//; $tls::wq = -8264;
//; $tls::pwq = 4536;
//; $tls::sig = -8216;
//; $tls::psig = 4584;
//; $tls::incyg = -8212;
//; $tls::pincyg = 4588;
//; $tls::spinning = -8208;
//; $tls::pspinning = 4592;
//; $tls::stacklock = -8204;
//; $tls::pstacklock = 4596;
//; $tls::stackptr = -8200;
//; $tls::pstackptr = 4600;
//; $tls::stack = -8192;
//; $tls::pstack = 4608;
//; $tls::initialized = -6144;
//; $tls::pinitialized = 6656;
//; $tls::local_clib = -11248;
//; $tls::plocal_clib = 1552;
//; $tls::__dontuse = -11248;
//; $tls::p__dontuse = 1552;
//; $tls::func = -9360;
//; $tls::pfunc = 3440;
//; $tls::saved_errno = -9352;
//; $tls::psaved_errno = 3448;
//; $tls::sa_flags = -9348;
//; $tls::psa_flags = 3452;
//; $tls::oldmask = -9344;
//; $tls::poldmask = 3456;
//; $tls::deltamask = -9336;
//; $tls::pdeltamask = 3464;
//; $tls::errno_addr = -9328;
//; $tls::perrno_addr = 3472;
//; $tls::sigmask = -9320;
//; $tls::psigmask = 3480;
//; $tls::sigwait_mask = -9312;
//; $tls::psigwait_mask = 3488;
//; $tls::sigwait_info = -9304;
//; $tls::psigwait_info = 3496;
//; $tls::signal_arrived = -9296;
//; $tls::psignal_arrived = 3504;
//; $tls::will_wait_for_signal = -9288;
//; $tls::pwill_wait_for_signal = 3512;
//; $tls::thread_context = -9280;
//; $tls::pthread_context = 3520;
//; $tls::thread_id = -8448;
//; $tls::pthread_id = 4352;
//; $tls::infodata = -8444;
//; $tls::pinfodata = 4356;
//; $tls::tid = -8296;
//; $tls::ptid = 4504;
//; $tls::_ctinfo = -8288;
//; $tls::p_ctinfo = 4512;
//; $tls::andreas = -8280;
//; $tls::pandreas = 4520;
//; $tls::wq = -8272;
//; $tls::pwq = 4528;
//; $tls::sig = -8224;
//; $tls::psig = 4576;
//; $tls::incyg = -8220;
//; $tls::pincyg = 4580;
//; $tls::spinning = -8216;
//; $tls::pspinning = 4584;
//; $tls::stacklock = -8212;
//; $tls::pstacklock = 4588;
//; $tls::stackptr = -8208;
//; $tls::pstackptr = 4592;
//; $tls::stack = -8200;
//; $tls::pstack = 4600;
//; $tls::initialized = -6152;
//; $tls::pinitialized = 6648;
//; __DATA__
#define tls_locals (-12800)
#define tls_plocals (0)
#define tls_local_clib (-11240)
#define tls_plocal_clib (1560)
#define tls___dontuse (-11240)
#define tls_p__dontuse (1560)
#define tls_func (-9352)
#define tls_pfunc (3448)
#define tls_saved_errno (-9344)
#define tls_psaved_errno (3456)
#define tls_sa_flags (-9340)
#define tls_psa_flags (3460)
#define tls_oldmask (-9336)
#define tls_poldmask (3464)
#define tls_deltamask (-9328)
#define tls_pdeltamask (3472)
#define tls_errno_addr (-9320)
#define tls_perrno_addr (3480)
#define tls_sigmask (-9312)
#define tls_psigmask (3488)
#define tls_sigwait_mask (-9304)
#define tls_psigwait_mask (3496)
#define tls_sigwait_info (-9296)
#define tls_psigwait_info (3504)
#define tls_signal_arrived (-9288)
#define tls_psignal_arrived (3512)
#define tls_will_wait_for_signal (-9280)
#define tls_pwill_wait_for_signal (3520)
#define tls_thread_context (-9272)
#define tls_pthread_context (3528)
#define tls_thread_id (-8440)
#define tls_pthread_id (4360)
#define tls_infodata (-8436)
#define tls_pinfodata (4364)
#define tls_tid (-8288)
#define tls_ptid (4512)
#define tls__ctinfo (-8280)
#define tls_p_ctinfo (4520)
#define tls_andreas (-8272)
#define tls_pandreas (4528)
#define tls_wq (-8264)
#define tls_pwq (4536)
#define tls_sig (-8216)
#define tls_psig (4584)
#define tls_incyg (-8212)
#define tls_pincyg (4588)
#define tls_spinning (-8208)
#define tls_pspinning (4592)
#define tls_stacklock (-8204)
#define tls_pstacklock (4596)
#define tls_stackptr (-8200)
#define tls_pstackptr (4600)
#define tls_stack (-8192)
#define tls_pstack (4608)
#define tls_initialized (-6144)
#define tls_pinitialized (6656)
#define tls_local_clib (-11248)
#define tls_plocal_clib (1552)
#define tls___dontuse (-11248)
#define tls_p__dontuse (1552)
#define tls_func (-9360)
#define tls_pfunc (3440)
#define tls_saved_errno (-9352)
#define tls_psaved_errno (3448)
#define tls_sa_flags (-9348)
#define tls_psa_flags (3452)
#define tls_oldmask (-9344)
#define tls_poldmask (3456)
#define tls_deltamask (-9336)
#define tls_pdeltamask (3464)
#define tls_errno_addr (-9328)
#define tls_perrno_addr (3472)
#define tls_sigmask (-9320)
#define tls_psigmask (3480)
#define tls_sigwait_mask (-9312)
#define tls_psigwait_mask (3488)
#define tls_sigwait_info (-9304)
#define tls_psigwait_info (3496)
#define tls_signal_arrived (-9296)
#define tls_psignal_arrived (3504)
#define tls_will_wait_for_signal (-9288)
#define tls_pwill_wait_for_signal (3512)
#define tls_thread_context (-9280)
#define tls_pthread_context (3520)
#define tls_thread_id (-8448)
#define tls_pthread_id (4352)
#define tls_infodata (-8444)
#define tls_pinfodata (4356)
#define tls_tid (-8296)
#define tls_ptid (4504)
#define tls__ctinfo (-8288)
#define tls_p_ctinfo (4512)
#define tls_andreas (-8280)
#define tls_pandreas (4520)
#define tls_wq (-8272)
#define tls_pwq (4528)
#define tls_sig (-8224)
#define tls_psig (4576)
#define tls_incyg (-8220)
#define tls_pincyg (4580)
#define tls_spinning (-8216)
#define tls_pspinning (4584)
#define tls_stacklock (-8212)
#define tls_pstacklock (4588)
#define tls_stackptr (-8208)
#define tls_pstackptr (4592)
#define tls_stack (-8200)
#define tls_pstack (4600)
#define tls_initialized (-6152)
#define tls_pinitialized (6648)

View File

@ -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