* autoload.cc (CheckTokenMembership): Import.

* external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id.
	* grp.cc (internal_getgrsid): Take additional cyg_ldap pointer.
	Forward to pwdgrp::add_group_from_windows.
	(internal_getgrnam): Ditto.
	(internal_getgrgid): Ditto.
	(gr_ent::enumerate_local): Drop ugid_caching bool from call to
	pwdgrp::fetch_account_from_windows.
	(getgroups32): Rename from internal_getgroups and drop getgroups32 stub.
	Drop srchsid parameter and code handling it.  Add local cyg_ldap
	instance and forward to internal_getgrXXX.
	(getgroups): Call getgroups32.
	(get_groups): Add local cyg_ldap instance and forward to
	internal_getgrXXX.
	(getgrouplist): Ditto.
	(setgroups32): Ditto.
	* ldap.cc (cyg_ldap::open): Don't call close.  Return true if connection
	is already open.
	(cyg_ldap::remap_uid): Forward this to internal_getpwsid.
	(cyg_ldap::remap_gid): Forward this to internal_getgrsid.
	* passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer.
	Forward to pwdgrp::add_user_from_windows.
	(internal_getpwnam): Ditto.
	(internal_getpwuid): Ditto.
	(pg_ent::enumerate_builtin): Drop ugid_caching bool from call to
	pwdgrp::fetch_account_from_windows.
	(pg_ent::enumerate_sam): Ditto.
	(pg_ent::enumerate_ad): Ditto.  Forward local cldap instead.
	* pwdgrp.h (internal_getpwsid): Align declaration to above change.
	(internal_getpwnam): Ditto.
	(internal_getpwuid): Ditto.
	(internal_getgrsid): Ditto.
	(internal_getgrgid): Ditto.
	(internal_getgrnam): Ditto.
	(internal_getgroups): Drop declaration.
	(pwdgrp::add_account_from_windows): Align declaration to below change.
	(pwdgrp::add_user_from_windows): Ditto.
	(pwdgrp::add_group_from_windows): Ditto.
	* sec_acl.cc (setacl): Add local cyg_ldap instance and forward to
	internal_getpwuid and internal_getgrgid.
	(getacl): Add local cyg_ldap instance and forward to cygpsid::get_id.
	(aclfromtext32): Add local cyg_ldap instance and forward to
	internal_getpwnam and internal_getgrnam.
	* sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer.
	Forward to internal_getgrsid and internal_getpwsid.
	(get_sids_info): Drop ldap_open.  Forward local cldap to
	internal_getpwsid and internal_getgrXXX.  Call CheckTokenMembership
	rather than internal_getgroups.
	* security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default
	parameter.
	(cygpsid::get_uid): Add cyg_ldap pointer.  Call get_id accordingly.
	(cygpsid::get_gid): Ditto.
	* uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward
	to internal_getpwXXX and internal_getgrXXX calls.
	(pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer.
	Forward to pwdgrp::fetch_account_from_windows.
	(fetch_posix_offset): Drop ldap_open argument and handling.  Get
	cyg_ldap instance as pointer.
	(pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer.
	Use it if it's not NULL, local instance otherwise.  Drop ldap_open.
	Drop fetching extended group arguments from AD for speed.
This commit is contained in:
Corinna Vinschen 2014-02-27 12:57:27 +00:00
parent 8033fd9a65
commit b39fa2c88d
11 changed files with 238 additions and 189 deletions

View File

@ -1,3 +1,67 @@
2014-02-27 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (CheckTokenMembership): Import.
* external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id.
* grp.cc (internal_getgrsid): Take additional cyg_ldap pointer.
Forward to pwdgrp::add_group_from_windows.
(internal_getgrnam): Ditto.
(internal_getgrgid): Ditto.
(gr_ent::enumerate_local): Drop ugid_caching bool from call to
pwdgrp::fetch_account_from_windows.
(getgroups32): Rename from internal_getgroups and drop getgroups32 stub.
Drop srchsid parameter and code handling it. Add local cyg_ldap
instance and forward to internal_getgrXXX.
(getgroups): Call getgroups32.
(get_groups): Add local cyg_ldap instance and forward to
internal_getgrXXX.
(getgrouplist): Ditto.
(setgroups32): Ditto.
* ldap.cc (cyg_ldap::open): Don't call close. Return true if connection
is already open.
(cyg_ldap::remap_uid): Forward this to internal_getpwsid.
(cyg_ldap::remap_gid): Forward this to internal_getgrsid.
* passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer.
Forward to pwdgrp::add_user_from_windows.
(internal_getpwnam): Ditto.
(internal_getpwuid): Ditto.
(pg_ent::enumerate_builtin): Drop ugid_caching bool from call to
pwdgrp::fetch_account_from_windows.
(pg_ent::enumerate_sam): Ditto.
(pg_ent::enumerate_ad): Ditto. Forward local cldap instead.
* pwdgrp.h (internal_getpwsid): Align declaration to above change.
(internal_getpwnam): Ditto.
(internal_getpwuid): Ditto.
(internal_getgrsid): Ditto.
(internal_getgrgid): Ditto.
(internal_getgrnam): Ditto.
(internal_getgroups): Drop declaration.
(pwdgrp::add_account_from_windows): Align declaration to below change.
(pwdgrp::add_user_from_windows): Ditto.
(pwdgrp::add_group_from_windows): Ditto.
* sec_acl.cc (setacl): Add local cyg_ldap instance and forward to
internal_getpwuid and internal_getgrgid.
(getacl): Add local cyg_ldap instance and forward to cygpsid::get_id.
(aclfromtext32): Add local cyg_ldap instance and forward to
internal_getpwnam and internal_getgrnam.
* sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer.
Forward to internal_getgrsid and internal_getpwsid.
(get_sids_info): Drop ldap_open. Forward local cldap to
internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership
rather than internal_getgroups.
* security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default
parameter.
(cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly.
(cygpsid::get_gid): Ditto.
* uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward
to internal_getpwXXX and internal_getgrXXX calls.
(pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer.
Forward to pwdgrp::fetch_account_from_windows.
(fetch_posix_offset): Drop ldap_open argument and handling. Get
cyg_ldap instance as pointer.
(pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer.
Use it if it's not NULL, local instance otherwise. Drop ldap_open.
Drop fetching extended group arguments from AD for speed.
2014-02-27 Corinna Vinschen <corinna@vinschen.de>
* path.cc (find_fast_cwd_pointer): Fix preceeding comment.

View File

@ -536,6 +536,7 @@ wsock_init ()
LoadDLLprime (ws2_32, _wsock_init, 0)
LoadDLLfunc (CheckTokenMembership, 12, advapi32)
LoadDLLfunc (CreateProcessAsUserW, 44, advapi32)
LoadDLLfunc (DeregisterEventSource, 4, advapi32)
LoadDLLfunc (LogonUserW, 24, advapi32)

View File

@ -380,13 +380,13 @@ cygwin_internal (cygwin_getinfo_types t, ...)
case CW_GET_UID_FROM_SID:
{
cygpsid psid = va_arg (arg, PSID);
res = psid.get_id (false, NULL);
res = psid.get_uid (NULL);
}
break;
case CW_GET_GID_FROM_SID:
{
cygpsid psid = va_arg (arg, PSID);
res = psid.get_id (true, NULL);
res = psid.get_gid (NULL);
}
break;
case CW_GET_BINMODE:

View File

@ -117,7 +117,7 @@ pwdgrp::find_group (gid_t gid)
}
struct group *
internal_getgrsid (cygpsid &sid)
internal_getgrsid (cygpsid &sid, cyg_ldap *pldap)
{
struct group *ret;
@ -134,7 +134,7 @@ internal_getgrsid (cygpsid &sid)
{
if ((ret = cygheap->pg.grp_cache.win.find_group (sid)))
return ret;
return cygheap->pg.grp_cache.win.add_group_from_windows (sid);
return cygheap->pg.grp_cache.win.add_group_from_windows (sid, pldap);
}
return NULL;
}
@ -148,7 +148,7 @@ internal_getgrsid_from_db (cygpsid &sid)
}
struct group *
internal_getgrnam (const char *name)
internal_getgrnam (const char *name, cyg_ldap *pldap)
{
struct group *ret;
@ -165,13 +165,13 @@ internal_getgrnam (const char *name)
{
if ((ret = cygheap->pg.grp_cache.win.find_group (name)))
return ret;
return cygheap->pg.grp_cache.win.add_group_from_windows (name);
return cygheap->pg.grp_cache.win.add_group_from_windows (name, pldap);
}
return NULL;
}
struct group *
internal_getgrgid (gid_t gid)
internal_getgrgid (gid_t gid, cyg_ldap *pldap)
{
struct group *ret;
@ -191,7 +191,7 @@ internal_getgrgid (gid_t gid)
return cygheap->pg.grp_cache.win.add_group_from_windows (gid);
}
else if (gid == ILLEGAL_GID)
return cygheap->pg.grp_cache.win.add_group_from_windows (gid);
return cygheap->pg.grp_cache.win.add_group_from_windows (gid, pldap);
return NULL;
}
@ -389,7 +389,7 @@ gr_ent::enumerate_local ()
fetch_user_arg_t arg;
arg.type = SID_arg;
arg.sid = &sid;
char *line = pg.fetch_account_from_windows (arg, true, false);
char *line = pg.fetch_account_from_windows (arg, true);
if (line)
return pg.add_account_post_fetch (line, false);
}
@ -459,19 +459,21 @@ endgrent_filtered (void *gr)
((gr_ent *) gr)->endgrent ();
}
int
internal_getgroups (int gidsetsize, gid_t *grouplist, cygpsid *srchsid)
extern "C" int
getgroups32 (int gidsetsize, gid_t *grouplist)
{
NTSTATUS status;
HANDLE hToken = NULL;
HANDLE tok;
ULONG size;
int cnt = 0;
struct group *grp;
cyg_ldap cldap;
if (!srchsid && cygheap->user.groups.issetgroups ())
if (cygheap->user.groups.issetgroups ())
{
for (int pg = 0; pg < cygheap->user.groups.sgsids.count (); ++pg)
if ((grp = internal_getgrsid (cygheap->user.groups.sgsids.sids[pg])))
if ((grp = internal_getgrsid (cygheap->user.groups.sgsids.sids[pg],
&cldap)))
{
if (cnt < gidsetsize)
grouplist[cnt] = grp->gr_gid;
@ -483,45 +485,32 @@ internal_getgroups (int gidsetsize, gid_t *grouplist, cygpsid *srchsid)
}
/* If impersonated, use impersonation token. */
if (cygheap->user.issetuid ())
hToken = cygheap->user.primary_token ();
else
hToken = hProcToken;
tok = cygheap->user.issetuid () ? cygheap->user.primary_token () : hProcToken;
status = NtQueryInformationToken (hToken, TokenGroups, NULL, 0, &size);
status = NtQueryInformationToken (tok, TokenGroups, NULL, 0, &size);
if (NT_SUCCESS (status) || status == STATUS_BUFFER_TOO_SMALL)
{
PTOKEN_GROUPS groups = (PTOKEN_GROUPS) alloca (size);
status = NtQueryInformationToken (hToken, TokenGroups, groups,
size, &size);
status = NtQueryInformationToken (tok, TokenGroups, groups, size, &size);
if (NT_SUCCESS (status))
{
cygsid sid;
if (srchsid)
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
{
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
if ((cnt = (*srchsid == groups->Groups[pg].Sid)))
break;
}
else
{
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
cygpsid sid = groups->Groups[pg].Sid;
if ((grp = internal_getgrsid (sid, &cldap)))
{
cygpsid sid = groups->Groups[pg].Sid;
if ((grp = internal_getgrsid (sid)))
if ((groups->Groups[pg].Attributes
& (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED))
&& sid != well_known_world_sid)
{
if ((groups->Groups[pg].Attributes
& (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED))
&& sid != well_known_world_sid)
{
if (cnt < gidsetsize)
grouplist[cnt] = grp->gr_gid;
++cnt;
if (gidsetsize && cnt > gidsetsize)
goto error;
}
if (cnt < gidsetsize)
grouplist[cnt] = grp->gr_gid;
++cnt;
if (gidsetsize && cnt > gidsetsize)
goto error;
}
}
}
@ -536,12 +525,6 @@ error:
return -1;
}
extern "C" int
getgroups32 (int gidsetsize, gid_t *grouplist)
{
return internal_getgroups (gidsetsize, grouplist);
}
#ifdef __x86_64__
EXPORT_ALIAS (getgroups32, getgroups)
#else
@ -558,7 +541,7 @@ getgroups (int gidsetsize, __gid16_t *grouplist)
if (gidsetsize > 0 && grouplist)
grouplist32 = (gid_t *) alloca (gidsetsize * sizeof (gid_t));
int ret = internal_getgroups (gidsetsize, grouplist32);
int ret = getgroups32 (gidsetsize, grouplist32);
if (gidsetsize > 0 && grouplist)
for (int i = 0; i < ret; ++ i)
@ -572,9 +555,11 @@ getgroups (int gidsetsize, __gid16_t *grouplist)
static void
get_groups (const char *user, gid_t gid, cygsidlist &gsids)
{
cyg_ldap cldap;
cygheap->user.deimpersonate ();
struct passwd *pw = internal_getpwnam (user);
struct group *grp = internal_getgrgid (gid);
struct passwd *pw = internal_getpwnam (user, &cldap);
struct group *grp = internal_getgrgid (gid, &cldap);
cygsid usersid, grpsid;
if (usersid.getfrompw (pw))
get_server_groups (gsids, usersid, pw);
@ -614,6 +599,7 @@ getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups)
int ret = 0;
int cnt = 0;
struct group *grp;
cyg_ldap cldap;
/* Note that it's not defined if groups or ngroups may be NULL!
GLibc does not check the pointers on entry and just uses them.
@ -626,7 +612,7 @@ getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups)
cygsidlist tmp_gsids (cygsidlist_auto, 12);
get_groups (user, gid, tmp_gsids);
for (int i = 0; i < tmp_gsids.count (); i++)
if ((grp = internal_getgrsid (tmp_gsids.sids[i])) != NULL)
if ((grp = internal_getgrsid (tmp_gsids.sids[i], &cldap)) != NULL)
{
if (groups && cnt < *ngroups)
groups[cnt] = grp->gr_gid;
@ -656,13 +642,14 @@ setgroups32 (int ngroups, const gid_t *grouplist)
cygsidlist gsids (cygsidlist_alloc, ngroups);
struct group *grp;
cyg_ldap cldap;
if (ngroups && !gsids.sids)
return -1;
for (int gidx = 0; gidx < ngroups; ++gidx)
{
if ((grp = internal_getgrgid (grouplist[gidx]))
if ((grp = internal_getgrgid (grouplist[gidx], &cldap))
&& gsids.addfromgr (grp))
continue;
debug_printf ("No sid found for gid %u", grouplist[gidx]);

View File

@ -145,7 +145,10 @@ cyg_ldap::open (PCWSTR domain)
static LARGE_INTEGER last_rediscover;
ULONG ret;
close ();
/* Already open? */
if (lh)
return true;
GetSystemTimeAsFileTime ((LPFILETIME) &start);
/* FIXME? connect_ssl can take ages even when failing, so we're trying to
do everything the non-SSL (but still encrypted) way. */
@ -512,7 +515,7 @@ cyg_ldap::remap_uid (uid_t uid)
{
if (fetch_unix_sid_from_ad (uid, user, false)
&& user != NO_SID
&& (pw = internal_getpwsid (user)))
&& (pw = internal_getpwsid (user, this)))
return pw->pw_uid;
}
else if ((name = fetch_unix_name_from_rfc2307 (uid, false)))
@ -536,7 +539,7 @@ cyg_ldap::remap_gid (gid_t gid)
{
if (fetch_unix_sid_from_ad (gid, group, true)
&& group != NO_SID
&& (gr = internal_getgrsid (group)))
&& (gr = internal_getgrsid (group, this)))
return gr->gr_gid;
}
else if ((name = fetch_unix_name_from_rfc2307 (gid, true)))

View File

@ -101,7 +101,7 @@ pwdgrp::find_user (uid_t uid)
}
struct passwd *
internal_getpwsid (cygpsid &sid)
internal_getpwsid (cygpsid &sid, cyg_ldap *pldap)
{
struct passwd *ret;
@ -118,7 +118,7 @@ internal_getpwsid (cygpsid &sid)
{
if ((ret = cygheap->pg.pwd_cache.win.find_user (sid)))
return ret;
return cygheap->pg.pwd_cache.win.add_user_from_windows (sid);
return cygheap->pg.pwd_cache.win.add_user_from_windows (sid, pldap);
}
return NULL;
}
@ -132,7 +132,7 @@ internal_getpwsid_from_db (cygpsid &sid)
}
struct passwd *
internal_getpwnam (const char *name)
internal_getpwnam (const char *name, cyg_ldap *pldap)
{
struct passwd *ret;
@ -149,13 +149,13 @@ internal_getpwnam (const char *name)
{
if ((ret = cygheap->pg.pwd_cache.win.find_user (name)))
return ret;
return cygheap->pg.pwd_cache.win.add_user_from_windows (name);
return cygheap->pg.pwd_cache.win.add_user_from_windows (name, pldap);
}
return NULL;
}
struct passwd *
internal_getpwuid (uid_t uid)
internal_getpwuid (uid_t uid, cyg_ldap *pldap)
{
struct passwd *ret;
@ -172,7 +172,7 @@ internal_getpwuid (uid_t uid)
{
if ((ret = cygheap->pg.pwd_cache.win.find_user (uid)))
return ret;
return cygheap->pg.pwd_cache.win.add_user_from_windows (uid);
return cygheap->pg.pwd_cache.win.add_user_from_windows (uid, pldap);
}
else if (uid == ILLEGAL_UID)
return cygheap->pg.pwd_cache.win.add_user_from_windows (uid);
@ -500,7 +500,7 @@ pg_ent::enumerate_builtin ()
fetch_user_arg_t arg;
arg.type = SID_arg;
arg.sid = &sid;
char *line = pg.fetch_account_from_windows (arg, group, false);
char *line = pg.fetch_account_from_windows (arg, group);
return pg.add_account_post_fetch (line, false);
}
@ -547,7 +547,7 @@ pg_ent::enumerate_sam ()
fetch_user_arg_t arg;
arg.type = SID_arg;
arg.sid = &sid;
char *line = pg.fetch_account_from_windows (arg, group, false);
char *line = pg.fetch_account_from_windows (arg, group);
if (line)
return pg.add_account_post_fetch (line, false);
}
@ -596,7 +596,7 @@ pg_ent::enumerate_ad ()
fetch_user_arg_t arg;
arg.type = SID_arg;
arg.sid = &sid;
char *line = pg.fetch_account_from_windows (arg, group, false);
char *line = pg.fetch_account_from_windows (arg, group, &cldap);
if (line)
return pg.add_account_post_fetch (line, false);
}

View File

@ -12,17 +12,20 @@ details. */
#pragma once
#include "sync.h"
#include "ldap.h"
#include "miscfuncs.h"
/* These functions are needed to allow searching and walking through
the passwd and group lists */
extern struct passwd *internal_getpwsid (cygpsid &);
extern struct passwd *internal_getpwsid (cygpsid &, cyg_ldap * = NULL);
extern struct passwd *internal_getpwsid_from_db (cygpsid &sid);
extern struct passwd *internal_getpwnam (const char *);
extern struct passwd *internal_getpwuid (uid_t);
extern struct group *internal_getgrsid (cygpsid &);
extern struct passwd *internal_getpwnam (const char *, cyg_ldap * = NULL);
extern struct passwd *internal_getpwuid (uid_t, cyg_ldap * = NULL);
extern struct group *internal_getgrsid (cygpsid &, cyg_ldap * = NULL);
extern struct group *internal_getgrsid_from_db (cygpsid &sid);
extern struct group *internal_getgrgid (gid_t);
extern struct group *internal_getgrnam (const char *);
int internal_getgroups (int, gid_t *, cygpsid * = NULL);
extern struct group *internal_getgrgid (gid_t, cyg_ldap * = NULL);
extern struct group *internal_getgrnam (const char *, cyg_ldap * = NULL);
/* These functions are called from mkpasswd/mkgroup via cygwin_internal. */
void *setpwent_filtered (int enums, PCWSTR enum_tdoms);
@ -32,10 +35,6 @@ void *setgrent_filtered (int enums, PCWSTR enum_tdoms);
void *getgrent_filtered (void *gr);
void endgrent_filtered (void *gr);
#include "sync.h"
#include "ldap.h"
#include "miscfuncs.h"
enum fetch_user_arg_type_t {
SID_arg,
NAME_arg,
@ -107,13 +106,16 @@ class pwdgrp
void *add_account_from_file (cygpsid &sid);
void *add_account_from_file (const char *name);
void *add_account_from_file (uint32_t id);
void *add_account_from_windows (cygpsid &sid, bool group);
void *add_account_from_windows (const char *name, bool group);
void *add_account_from_windows (uint32_t id, bool group);
void *add_account_from_windows (cygpsid &sid, bool group,
cyg_ldap *pldap = NULL);
void *add_account_from_windows (const char *name, bool group,
cyg_ldap *pldap = NULL);
void *add_account_from_windows (uint32_t id, bool group,
cyg_ldap *pldap = NULL);
char *fetch_account_from_line (fetch_user_arg_t &arg, const char *line);
char *fetch_account_from_file (fetch_user_arg_t &arg);
char *fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
bool ugid_caching = true);
cyg_ldap *pldap = NULL);
pwdgrp *prep_tls_pwbuf ();
pwdgrp *prep_tls_grbuf ();
@ -131,12 +133,13 @@ public:
{ return (struct passwd *) add_account_from_file (name); }
struct passwd *add_user_from_file (uint32_t id)
{ return (struct passwd *) add_account_from_file (id); }
struct passwd *add_user_from_windows (cygpsid &sid)
{ return (struct passwd *) add_account_from_windows (sid, false); }
struct passwd *add_user_from_windows (const char *name)
{ return (struct passwd *) add_account_from_windows (name, false); }
struct passwd *add_user_from_windows (uint32_t id)
{ return (struct passwd *) add_account_from_windows (id, false); }
struct passwd *add_user_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL)
{ return (struct passwd *) add_account_from_windows (sid, false, pldap); }
struct passwd *add_user_from_windows (const char *name,
cyg_ldap* pldap = NULL)
{ return (struct passwd *) add_account_from_windows (name, false, pldap); }
struct passwd *add_user_from_windows (uint32_t id, cyg_ldap *pldap = NULL)
{ return (struct passwd *) add_account_from_windows (id, false, pldap); }
struct passwd *find_user (cygpsid &sid);
struct passwd *find_user (const char *name);
struct passwd *find_user (uid_t uid);
@ -149,12 +152,13 @@ public:
{ return (struct group *) add_account_from_file (name); }
struct group *add_group_from_file (uint32_t id)
{ return (struct group *) add_account_from_file (id); }
struct group *add_group_from_windows (cygpsid &sid)
{ return (struct group *) add_account_from_windows (sid, true); }
struct group *add_group_from_windows (const char *name)
{ return (struct group *) add_account_from_windows (name, true); }
struct group *add_group_from_windows (uint32_t id)
{ return (struct group *) add_account_from_windows (id, true); }
struct group *add_group_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL)
{ return (struct group *) add_account_from_windows (sid, true, pldap); }
struct group *add_group_from_windows (const char *name,
cyg_ldap *pldap = NULL)
{ return (struct group *) add_account_from_windows (name, true, pldap); }
struct group *add_group_from_windows (uint32_t id, cyg_ldap *pldap = NULL)
{ return (struct group *) add_account_from_windows (id, true, pldap); }
struct group *find_group (cygpsid &sid);
struct group *find_group (const char *name);
struct group *find_group (gid_t gid);

View File

@ -94,6 +94,7 @@ setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
struct passwd *pw;
struct group *gr;
int pos;
cyg_ldap cldap;
RtlCreateAcl (acl, ACL_MAXIMUM_SIZE, ACL_REVISION);
@ -157,7 +158,7 @@ setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
break;
case USER:
case DEF_USER:
if (!(pw = internal_getpwuid (aclbufp[i].a_id))
if (!(pw = internal_getpwuid (aclbufp[i].a_id, &cldap))
|| !sid.getfrompw (pw))
{
set_errno (EINVAL);
@ -179,7 +180,7 @@ setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
break;
case GROUP:
case DEF_GROUP:
if (!(gr = internal_getgrgid (aclbufp[i].a_id))
if (!(gr = internal_getgrgid (aclbufp[i].a_id, &cldap))
|| !sid.getfromgr (gr))
{
set_errno (EINVAL);
@ -282,6 +283,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
BOOLEAN dummy;
uid_t uid;
gid_t gid;
cyg_ldap cldap;
status = RtlGetOwnerSecurityDescriptor (sd, (PSID *) &owner_sid, &dummy);
if (!NT_SUCCESS (status))
@ -289,7 +291,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
__seterrno_from_nt_status (status);
return -1;
}
uid = owner_sid.get_uid ();
uid = owner_sid.get_uid (&cldap);
status = RtlGetGroupSecurityDescriptor (sd, (PSID *) &group_sid, &dummy);
if (!NT_SUCCESS (status))
@ -297,7 +299,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
__seterrno_from_nt_status (status);
return -1;
}
gid = group_sid.get_gid ();
gid = group_sid.get_gid (&cldap);
aclent_t lacl[MAX_ACL_ENTRIES];
memset (&lacl, 0, MAX_ACL_ENTRIES * sizeof (aclent_t));
@ -367,7 +369,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
id = ILLEGAL_GID;
}
else
id = ace_sid.get_id (true, &type);
id = ace_sid.get_id (TRUE, &type, &cldap);
if (!type)
continue;
@ -836,6 +838,7 @@ aclfromtext32 (char *acltextp, int *)
int pos = 0;
strcpy (buf, acltextp);
char *lasts;
cyg_ldap cldap;
for (char *c = strtok_r (buf, ",", &lasts);
c;
c = strtok_r (NULL, ",", &lasts))
@ -855,7 +858,7 @@ aclfromtext32 (char *acltextp, int *)
c += 5;
if (isalpha (*c))
{
struct passwd *pw = internal_getpwnam (c);
struct passwd *pw = internal_getpwnam (c, &cldap);
if (!pw)
{
set_errno (EINVAL);
@ -883,7 +886,7 @@ aclfromtext32 (char *acltextp, int *)
c += 5;
if (isalpha (*c))
{
struct group *gr = internal_getgrnam (c);
struct group *gr = internal_getgrnam (c, &cldap);
if (!gr)
{
set_errno (EINVAL);

View File

@ -93,7 +93,7 @@ cygpsid::operator== (const char *nsidstr) const
}
uid_t
cygpsid::get_id (BOOL search_grp, int *type)
cygpsid::get_id (BOOL search_grp, int *type, cyg_ldap *pldap)
{
/* First try to get SID from group, then passwd */
uid_t id = ILLEGAL_UID;
@ -103,7 +103,7 @@ cygpsid::get_id (BOOL search_grp, int *type)
struct group *gr;
if (cygheap->user.groups.pgsid == psid)
id = myself->gid;
else if ((gr = internal_getgrsid (*this)))
else if ((gr = internal_getgrsid (*this, pldap)))
id = gr->gr_gid;
if (id != ILLEGAL_UID)
{
@ -117,7 +117,7 @@ cygpsid::get_id (BOOL search_grp, int *type)
struct passwd *pw;
if (*this == cygheap->user.sid ())
id = myself->uid;
else if ((pw = internal_getpwsid (*this)))
else if ((pw = internal_getpwsid (*this, pldap)))
id = pw->pw_uid;
if (id != ILLEGAL_UID && type)
*type = USER;
@ -297,10 +297,9 @@ get_sids_info (cygpsid owner_sid, cygpsid group_sid, uid_t * uidret, gid_t * gid
{
struct passwd *pw;
struct group *gr = NULL;
bool ret = false;
BOOL ret = false;
PWCHAR domain;
cyg_ldap cldap;
bool ldap_open = false;
owner_sid.debug_print ("get_sids_info: owner SID =");
group_sid.debug_print ("get_sids_info: group SID =");
@ -318,7 +317,7 @@ get_sids_info (cygpsid owner_sid, cygpsid group_sid, uid_t * uidret, gid_t * gid
if (map_gid == ILLEGAL_GID)
{
domain = cygheap->dom.get_rfc2307_domain ();
if ((ldap_open = cldap.open (domain)))
if (cldap.open (domain))
map_gid = cldap.remap_gid (gid);
if (map_gid == ILLEGAL_GID)
map_gid = MAP_UNIX_TO_CYGWIN_ID (gid);
@ -326,7 +325,7 @@ get_sids_info (cygpsid owner_sid, cygpsid group_sid, uid_t * uidret, gid_t * gid
}
*gidret = map_gid;
}
else if ((gr = internal_getgrsid (group_sid)))
else if ((gr = internal_getgrsid (group_sid, &cldap)))
*gidret = gr->gr_gid;
else
*gidret = ILLEGAL_GID;
@ -335,9 +334,11 @@ get_sids_info (cygpsid owner_sid, cygpsid group_sid, uid_t * uidret, gid_t * gid
{
*uidret = myself->uid;
if (*gidret == myself->gid)
ret = true;
ret = TRUE;
else
ret = (internal_getgroups (0, NULL, &group_sid) > 0);
CheckTokenMembership (cygheap->user.issetuid ()
? cygheap->user.imp_token () : NULL,
group_sid, &ret);
}
else if (sid_id_auth (owner_sid) == 22)
{
@ -347,7 +348,7 @@ get_sids_info (cygpsid owner_sid, cygpsid group_sid, uid_t * uidret, gid_t * gid
if (map_uid == ILLEGAL_UID)
{
domain = cygheap->dom.get_rfc2307_domain ();
if ((ldap_open || cldap.open (domain)))
if (cldap.open (domain))
map_uid = cldap.remap_uid (uid);
if (map_uid == ILLEGAL_UID)
map_uid = MAP_UNIX_TO_CYGWIN_ID (uid);
@ -355,11 +356,11 @@ get_sids_info (cygpsid owner_sid, cygpsid group_sid, uid_t * uidret, gid_t * gid
}
*uidret = map_uid;
}
else if ((pw = internal_getpwsid (owner_sid)))
else if ((pw = internal_getpwsid (owner_sid, &cldap)))
{
*uidret = pw->pw_uid;
if (gr || (*gidret != ILLEGAL_GID
&& (gr = internal_getgrgid (*gidret))))
&& (gr = internal_getgrgid (*gidret, &cldap))))
for (int idx = 0; gr->gr_mem[idx]; ++idx)
if ((ret = strcasematch (pw->pw_name, gr->gr_mem[idx])))
break;
@ -367,7 +368,7 @@ get_sids_info (cygpsid owner_sid, cygpsid group_sid, uid_t * uidret, gid_t * gid
else
*uidret = ILLEGAL_UID;
return ret;
return (bool) ret;
}
PSECURITY_DESCRIPTOR

View File

@ -138,6 +138,8 @@ extern "C"
}
#endif
class cyg_ldap;
class cygpsid {
protected:
PSID psid;
@ -146,9 +148,9 @@ public:
cygpsid (PSID nsid) { psid = nsid; }
operator PSID () const { return psid; }
const PSID operator= (PSID nsid) { return psid = nsid;}
uid_t get_id (BOOL search_grp, int *type = NULL);
int get_uid () { return get_id (FALSE); }
int get_gid () { return get_id (TRUE); }
uid_t get_id (BOOL search_grp, int *type, cyg_ldap *pldap);
int get_uid (cyg_ldap *pldap) { return get_id (FALSE, NULL, pldap); }
int get_gid (cyg_ldap *pldap) { return get_id (TRUE, NULL, pldap); }
PWCHAR pstring (PWCHAR nsidstr) const;
PWCHAR string (PWCHAR nsidstr) const;

View File

@ -118,11 +118,12 @@ internal_getlogin (cygheap_user &user)
{
struct passwd *pw = NULL;
struct group *gr, *gr2;
cyg_ldap cldap;
cygpsid psid = user.sid ();
pw = internal_getpwsid (psid);
pw = internal_getpwsid (psid, &cldap);
if (!pw && !(pw = internal_getpwnam (user.name ())))
if (!pw && !(pw = internal_getpwnam (user.name (), &cldap)))
debug_printf ("user not found in /etc/passwd");
else
{
@ -131,13 +132,13 @@ internal_getlogin (cygheap_user &user)
myself->uid = pw->pw_uid;
myself->gid = pw->pw_gid;
user.set_name (pw->pw_name);
if (gsid.getfromgr (gr = internal_getgrgid (pw->pw_gid)))
if (gsid.getfromgr (gr = internal_getgrgid (pw->pw_gid, &cldap)))
{
/* We might have a group file with a group entry for the current
user's primary group, but the current user has no entry in passwd.
If so, pw_gid is taken from windows and might disagree with the
gr_gid from the group file. Overwrite it brutally. */
if ((gr2 = internal_getgrsid (gsid)) && gr2 != gr)
if ((gr2 = internal_getgrsid (gsid, &cldap)) && gr2 != gr)
myself->gid = pw->pw_gid = gr2->gr_gid;
/* Set primary group to the group in /etc/passwd. */
if (gsid != user.groups.pgsid)
@ -975,12 +976,12 @@ pwdgrp::add_account_from_file (uint32_t id)
}
void *
pwdgrp::add_account_from_windows (cygpsid &sid, bool group)
pwdgrp::add_account_from_windows (cygpsid &sid, bool group, cyg_ldap *pldap)
{
fetch_user_arg_t arg;
arg.type = SID_arg;
arg.sid = &sid;
char *line = fetch_account_from_windows (arg, group);
char *line = fetch_account_from_windows (arg, group, pldap);
if (!line)
return NULL;
if (cygheap->pg.nss_db_caching ())
@ -989,12 +990,12 @@ pwdgrp::add_account_from_windows (cygpsid &sid, bool group)
}
void *
pwdgrp::add_account_from_windows (const char *name, bool group)
pwdgrp::add_account_from_windows (const char *name, bool group, cyg_ldap *pldap)
{
fetch_user_arg_t arg;
arg.type = NAME_arg;
arg.name = name;
char *line = fetch_account_from_windows (arg, group);
char *line = fetch_account_from_windows (arg, group, pldap);
if (!line)
return NULL;
if (cygheap->pg.nss_db_caching ())
@ -1003,12 +1004,12 @@ pwdgrp::add_account_from_windows (const char *name, bool group)
}
void *
pwdgrp::add_account_from_windows (uint32_t id, bool group)
pwdgrp::add_account_from_windows (uint32_t id, bool group, cyg_ldap *pldap)
{
fetch_user_arg_t arg;
arg.type = ID_arg;
arg.id = id;
char *line = fetch_account_from_windows (arg, group);
char *line = fetch_account_from_windows (arg, group, pldap);
if (!line)
return NULL;
if (cygheap->pg.nss_db_caching ())
@ -1134,13 +1135,13 @@ pwdgrp::fetch_account_from_file (fetch_user_arg_t &arg)
}
static ULONG
fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, bool &ldap_open, cyg_ldap &cldap)
fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, 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)))
if (!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
@ -1149,7 +1150,7 @@ fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, bool &ldap_open, cyg_ldap &cldap)
- 0x01000000;
}
else
id_val = cldap.fetch_posix_offset_for_domain (td->DnsDomainName);
id_val = cldap->fetch_posix_offset_for_domain (td->DnsDomainName);
if (id_val)
{
td->PosixOffset = id_val;
@ -1163,7 +1164,7 @@ fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, bool &ldap_open, cyg_ldap &cldap)
char *
pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
bool ugid_caching)
cyg_ldap *pldap)
{
/* Used in LookupAccount calls. */
WCHAR namebuf[UNLEN + 1], *name = namebuf;
@ -1172,7 +1173,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
DWORD nlen = UNLEN + 1;
DWORD dlen = DNLEN + 1;
DWORD slen = MAX_SID_LEN;
cygpsid sid = NO_SID;
cygpsid sid (NO_SID);
SID_NAME_USE acc_type;
BOOL ret = false;
/* Cygwin user name style. */
@ -1190,13 +1191,13 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
PWCHAR user = NULL;
PWCHAR home = NULL;
PWCHAR gecos = NULL;
/* Temporary stuff. */
PWCHAR p;
WCHAR sidstr[128];
/* Temporary stuff. */
ULONG posix_offset = 0;
uint32_t id_val;
cyg_ldap cldap;
bool ldap_open = false;
cyg_ldap loc_ldap;
cyg_ldap *cldap = pldap ?: &loc_ldap;
/* Initialize */
if (!cygheap->dom.init ())
@ -1219,9 +1220,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
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 ()))
if (cldap->open (NULL)
&& cldap->fetch_ad_account (sid, group)
&& (val = cldap->get_group_name ()))
{
wcpcpy (name, val);
wcpcpy (dom, L"BUILTIN");
@ -1355,7 +1356,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx)
{
fetch_posix_offset (td, ldap_open, cldap);
fetch_posix_offset (td, cldap);
if (td->PosixOffset > posix_offset && td->PosixOffset <= arg.id)
posix_offset = td->PosixOffset;
}
@ -1452,7 +1453,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
{
domain = td->DnsDomainName;
posix_offset =
fetch_posix_offset (td, ldap_open, cldap);
fetch_posix_offset (td, cldap);
break;
}
@ -1474,60 +1475,44 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
/* Generate values. */
if (uid == ILLEGAL_UID)
uid = posix_offset + sid_sub_auth_rid (sid);
gid = posix_offset + DOMAIN_GROUP_RID_USERS; /* Default. */
if (is_domain_account)
{
/* Use LDAP to fetch domain account infos. */
if (!ldap_open && !cldap.open (NULL))
if (acc_type != SidTypeUser)
break;
if (cldap.fetch_ad_account (sid, group))
gid = posix_offset + DOMAIN_GROUP_RID_USERS; /* Default. */
/* Use LDAP to fetch domain account infos. */
if (!cldap->open (NULL))
break;
if (cldap->fetch_ad_account (sid, group))
{
PWCHAR val;
if (acc_type == SidTypeUser)
if ((id_val = cldap->get_primary_gid ()) != ILLEGAL_GID)
gid = posix_offset + id_val;
if ((val = cldap->get_user_name ())
&& wcscmp (name, val))
user = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
* sizeof (WCHAR)), val);
if ((val = cldap->get_gecos ()))
gecos = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
* sizeof (WCHAR)), val);
if ((val = cldap->get_home ()))
home = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
* sizeof (WCHAR)), val);
if ((val = cldap->get_shell ()))
shell = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
* sizeof (WCHAR)), val);
/* Check and, if necessary, add unix<->windows id mapping on
the fly, unless we're called from getpwent. */
if (!pldap)
{
if ((id_val = cldap.get_primary_gid ()) != ILLEGAL_GID)
gid = posix_offset + id_val;
if ((val = cldap.get_user_name ())
&& wcscmp (name, val))
user = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
* sizeof (WCHAR)), val);
if ((val = cldap.get_gecos ()))
gecos = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
* sizeof (WCHAR)), val);
if ((val = cldap.get_home ()))
home = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
* sizeof (WCHAR)), val);
if ((val = cldap.get_shell ()))
shell = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
* sizeof (WCHAR)), val);
/* Check and, if necessary, add unix<->windows
id mapping on the fly. */
if (ugid_caching)
{
id_val = cldap.get_unix_uid ();
if (id_val != ILLEGAL_UID
&& cygheap->ugid_cache.get_uid (id_val)
== ILLEGAL_UID)
cygheap->ugid_cache.add_uid (id_val, uid);
}
}
else /* SidTypeGroup */
{
if ((val = cldap.get_group_name ())
&& wcscmp (name, val))
user = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
* sizeof (WCHAR)), val);
/* Check and, if necessary, add unix<->windows
id mapping on the fly. */
if (ugid_caching)
{
id_val = cldap.get_unix_gid ();
if (id_val != ILLEGAL_GID
&& cygheap->ugid_cache.get_gid (id_val)
== ILLEGAL_GID)
cygheap->ugid_cache.add_gid (id_val, uid);
}
id_val = cldap->get_unix_uid ();
if (id_val != ILLEGAL_UID
&& cygheap->ugid_cache.get_uid (id_val)
== ILLEGAL_UID)
cygheap->ugid_cache.add_uid (id_val, uid);
}
}
}
@ -1629,12 +1614,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
*gname = cygheap->pg.nss_separator ()[0];
sys_wcstombs (gname + 1, 2 * UNLEN + 1, pgrp);
if ((gr = internal_getgrnam (gname))
|| (gr = internal_getgrnam (gname + 1)))
if ((gr = internal_getgrnam (gname, cldap))
|| (gr = internal_getgrnam (gname + 1, cldap)))
gid = gr->gr_gid;
}
if (ugid_caching && uxid
&& ((id_val = wcstoul (uxid, &e, 10)), !*e))
if (!pldap && uxid && ((id_val = wcstoul (uxid, &e, 10)), !*e))
{
if (acc_type == SidTypeUser)
{
@ -1744,7 +1728,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
if (td->DomainSid && RtlEqualSid (sid, td->DomainSid))
{
domain = td->NetbiosDomainName;
posix_offset = fetch_posix_offset (td, ldap_open, cldap);
posix_offset = fetch_posix_offset (td, cldap);
break;
}
}