4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-21 16:26:12 +08:00

* 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> 2014-02-27 Corinna Vinschen <corinna@vinschen.de>
* path.cc (find_fast_cwd_pointer): Fix preceeding comment. * path.cc (find_fast_cwd_pointer): Fix preceeding comment.

View File

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

View File

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

View File

@ -117,7 +117,7 @@ pwdgrp::find_group (gid_t gid)
} }
struct group * struct group *
internal_getgrsid (cygpsid &sid) internal_getgrsid (cygpsid &sid, cyg_ldap *pldap)
{ {
struct group *ret; struct group *ret;
@ -134,7 +134,7 @@ internal_getgrsid (cygpsid &sid)
{ {
if ((ret = cygheap->pg.grp_cache.win.find_group (sid))) if ((ret = cygheap->pg.grp_cache.win.find_group (sid)))
return ret; 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; return NULL;
} }
@ -148,7 +148,7 @@ internal_getgrsid_from_db (cygpsid &sid)
} }
struct group * struct group *
internal_getgrnam (const char *name) internal_getgrnam (const char *name, cyg_ldap *pldap)
{ {
struct group *ret; struct group *ret;
@ -165,13 +165,13 @@ internal_getgrnam (const char *name)
{ {
if ((ret = cygheap->pg.grp_cache.win.find_group (name))) if ((ret = cygheap->pg.grp_cache.win.find_group (name)))
return ret; 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; return NULL;
} }
struct group * struct group *
internal_getgrgid (gid_t gid) internal_getgrgid (gid_t gid, cyg_ldap *pldap)
{ {
struct group *ret; struct group *ret;
@ -191,7 +191,7 @@ internal_getgrgid (gid_t gid)
return cygheap->pg.grp_cache.win.add_group_from_windows (gid); return cygheap->pg.grp_cache.win.add_group_from_windows (gid);
} }
else if (gid == ILLEGAL_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; return NULL;
} }
@ -389,7 +389,7 @@ gr_ent::enumerate_local ()
fetch_user_arg_t arg; fetch_user_arg_t arg;
arg.type = SID_arg; arg.type = SID_arg;
arg.sid = &sid; arg.sid = &sid;
char *line = pg.fetch_account_from_windows (arg, true, false); char *line = pg.fetch_account_from_windows (arg, true);
if (line) if (line)
return pg.add_account_post_fetch (line, false); return pg.add_account_post_fetch (line, false);
} }
@ -459,19 +459,21 @@ endgrent_filtered (void *gr)
((gr_ent *) gr)->endgrent (); ((gr_ent *) gr)->endgrent ();
} }
int extern "C" int
internal_getgroups (int gidsetsize, gid_t *grouplist, cygpsid *srchsid) getgroups32 (int gidsetsize, gid_t *grouplist)
{ {
NTSTATUS status; NTSTATUS status;
HANDLE hToken = NULL; HANDLE tok;
ULONG size; ULONG size;
int cnt = 0; int cnt = 0;
struct group *grp; 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) 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) if (cnt < gidsetsize)
grouplist[cnt] = grp->gr_gid; grouplist[cnt] = grp->gr_gid;
@ -483,45 +485,32 @@ internal_getgroups (int gidsetsize, gid_t *grouplist, cygpsid *srchsid)
} }
/* If impersonated, use impersonation token. */ /* If impersonated, use impersonation token. */
if (cygheap->user.issetuid ()) tok = cygheap->user.issetuid () ? cygheap->user.primary_token () : hProcToken;
hToken = cygheap->user.primary_token ();
else
hToken = hProcToken;
status = NtQueryInformationToken (hToken, TokenGroups, NULL, 0, &size); status = NtQueryInformationToken (tok, TokenGroups, NULL, 0, &size);
if (NT_SUCCESS (status) || status == STATUS_BUFFER_TOO_SMALL) if (NT_SUCCESS (status) || status == STATUS_BUFFER_TOO_SMALL)
{ {
PTOKEN_GROUPS groups = (PTOKEN_GROUPS) alloca (size); PTOKEN_GROUPS groups = (PTOKEN_GROUPS) alloca (size);
status = NtQueryInformationToken (hToken, TokenGroups, groups, status = NtQueryInformationToken (tok, TokenGroups, groups, size, &size);
size, &size);
if (NT_SUCCESS (status)) if (NT_SUCCESS (status))
{ {
cygsid sid; cygsid sid;
if (srchsid) for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
{ {
for (DWORD pg = 0; pg < groups->GroupCount; ++pg) cygpsid sid = groups->Groups[pg].Sid;
if ((cnt = (*srchsid == groups->Groups[pg].Sid))) if ((grp = internal_getgrsid (sid, &cldap)))
break;
}
else
{
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
{ {
cygpsid sid = groups->Groups[pg].Sid; if ((groups->Groups[pg].Attributes
if ((grp = internal_getgrsid (sid))) & (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED))
&& sid != well_known_world_sid)
{ {
if ((groups->Groups[pg].Attributes if (cnt < gidsetsize)
& (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED)) grouplist[cnt] = grp->gr_gid;
&& sid != well_known_world_sid) ++cnt;
{ if (gidsetsize && cnt > gidsetsize)
if (cnt < gidsetsize) goto error;
grouplist[cnt] = grp->gr_gid;
++cnt;
if (gidsetsize && cnt > gidsetsize)
goto error;
}
} }
} }
} }
@ -536,12 +525,6 @@ error:
return -1; return -1;
} }
extern "C" int
getgroups32 (int gidsetsize, gid_t *grouplist)
{
return internal_getgroups (gidsetsize, grouplist);
}
#ifdef __x86_64__ #ifdef __x86_64__
EXPORT_ALIAS (getgroups32, getgroups) EXPORT_ALIAS (getgroups32, getgroups)
#else #else
@ -558,7 +541,7 @@ getgroups (int gidsetsize, __gid16_t *grouplist)
if (gidsetsize > 0 && grouplist) if (gidsetsize > 0 && grouplist)
grouplist32 = (gid_t *) alloca (gidsetsize * sizeof (gid_t)); grouplist32 = (gid_t *) alloca (gidsetsize * sizeof (gid_t));
int ret = internal_getgroups (gidsetsize, grouplist32); int ret = getgroups32 (gidsetsize, grouplist32);
if (gidsetsize > 0 && grouplist) if (gidsetsize > 0 && grouplist)
for (int i = 0; i < ret; ++ i) for (int i = 0; i < ret; ++ i)
@ -572,9 +555,11 @@ getgroups (int gidsetsize, __gid16_t *grouplist)
static void static void
get_groups (const char *user, gid_t gid, cygsidlist &gsids) get_groups (const char *user, gid_t gid, cygsidlist &gsids)
{ {
cyg_ldap cldap;
cygheap->user.deimpersonate (); cygheap->user.deimpersonate ();
struct passwd *pw = internal_getpwnam (user); struct passwd *pw = internal_getpwnam (user, &cldap);
struct group *grp = internal_getgrgid (gid); struct group *grp = internal_getgrgid (gid, &cldap);
cygsid usersid, grpsid; cygsid usersid, grpsid;
if (usersid.getfrompw (pw)) if (usersid.getfrompw (pw))
get_server_groups (gsids, usersid, 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 ret = 0;
int cnt = 0; int cnt = 0;
struct group *grp; struct group *grp;
cyg_ldap cldap;
/* Note that it's not defined if groups or ngroups may be NULL! /* 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. 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); cygsidlist tmp_gsids (cygsidlist_auto, 12);
get_groups (user, gid, tmp_gsids); get_groups (user, gid, tmp_gsids);
for (int i = 0; i < tmp_gsids.count (); i++) 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) if (groups && cnt < *ngroups)
groups[cnt] = grp->gr_gid; groups[cnt] = grp->gr_gid;
@ -656,13 +642,14 @@ setgroups32 (int ngroups, const gid_t *grouplist)
cygsidlist gsids (cygsidlist_alloc, ngroups); cygsidlist gsids (cygsidlist_alloc, ngroups);
struct group *grp; struct group *grp;
cyg_ldap cldap;
if (ngroups && !gsids.sids) if (ngroups && !gsids.sids)
return -1; return -1;
for (int gidx = 0; gidx < ngroups; ++gidx) for (int gidx = 0; gidx < ngroups; ++gidx)
{ {
if ((grp = internal_getgrgid (grouplist[gidx])) if ((grp = internal_getgrgid (grouplist[gidx], &cldap))
&& gsids.addfromgr (grp)) && gsids.addfromgr (grp))
continue; continue;
debug_printf ("No sid found for gid %u", grouplist[gidx]); 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; static LARGE_INTEGER last_rediscover;
ULONG ret; ULONG ret;
close (); /* Already open? */
if (lh)
return true;
GetSystemTimeAsFileTime ((LPFILETIME) &start); GetSystemTimeAsFileTime ((LPFILETIME) &start);
/* FIXME? connect_ssl can take ages even when failing, so we're trying to /* FIXME? connect_ssl can take ages even when failing, so we're trying to
do everything the non-SSL (but still encrypted) way. */ 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) if (fetch_unix_sid_from_ad (uid, user, false)
&& user != NO_SID && user != NO_SID
&& (pw = internal_getpwsid (user))) && (pw = internal_getpwsid (user, this)))
return pw->pw_uid; return pw->pw_uid;
} }
else if ((name = fetch_unix_name_from_rfc2307 (uid, false))) 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) if (fetch_unix_sid_from_ad (gid, group, true)
&& group != NO_SID && group != NO_SID
&& (gr = internal_getgrsid (group))) && (gr = internal_getgrsid (group, this)))
return gr->gr_gid; return gr->gr_gid;
} }
else if ((name = fetch_unix_name_from_rfc2307 (gid, true))) else if ((name = fetch_unix_name_from_rfc2307 (gid, true)))

View File

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

View File

@ -12,17 +12,20 @@ details. */
#pragma once #pragma once
#include "sync.h"
#include "ldap.h"
#include "miscfuncs.h"
/* These functions are needed to allow searching and walking through /* These functions are needed to allow searching and walking through
the passwd and group lists */ 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_getpwsid_from_db (cygpsid &sid);
extern struct passwd *internal_getpwnam (const char *); extern struct passwd *internal_getpwnam (const char *, cyg_ldap * = NULL);
extern struct passwd *internal_getpwuid (uid_t); extern struct passwd *internal_getpwuid (uid_t, cyg_ldap * = NULL);
extern struct group *internal_getgrsid (cygpsid &); extern struct group *internal_getgrsid (cygpsid &, cyg_ldap * = NULL);
extern struct group *internal_getgrsid_from_db (cygpsid &sid); extern struct group *internal_getgrsid_from_db (cygpsid &sid);
extern struct group *internal_getgrgid (gid_t); extern struct group *internal_getgrgid (gid_t, cyg_ldap * = NULL);
extern struct group *internal_getgrnam (const char *); extern struct group *internal_getgrnam (const char *, cyg_ldap * = NULL);
int internal_getgroups (int, gid_t *, cygpsid * = NULL);
/* These functions are called from mkpasswd/mkgroup via cygwin_internal. */ /* These functions are called from mkpasswd/mkgroup via cygwin_internal. */
void *setpwent_filtered (int enums, PCWSTR enum_tdoms); 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 *getgrent_filtered (void *gr);
void endgrent_filtered (void *gr); void endgrent_filtered (void *gr);
#include "sync.h"
#include "ldap.h"
#include "miscfuncs.h"
enum fetch_user_arg_type_t { enum fetch_user_arg_type_t {
SID_arg, SID_arg,
NAME_arg, NAME_arg,
@ -107,13 +106,16 @@ class pwdgrp
void *add_account_from_file (cygpsid &sid); void *add_account_from_file (cygpsid &sid);
void *add_account_from_file (const char *name); void *add_account_from_file (const char *name);
void *add_account_from_file (uint32_t id); void *add_account_from_file (uint32_t id);
void *add_account_from_windows (cygpsid &sid, bool group); void *add_account_from_windows (cygpsid &sid, bool group,
void *add_account_from_windows (const char *name, bool group); cyg_ldap *pldap = NULL);
void *add_account_from_windows (uint32_t id, bool group); 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_line (fetch_user_arg_t &arg, const char *line);
char *fetch_account_from_file (fetch_user_arg_t &arg); char *fetch_account_from_file (fetch_user_arg_t &arg);
char *fetch_account_from_windows (fetch_user_arg_t &arg, bool group, 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_pwbuf ();
pwdgrp *prep_tls_grbuf (); pwdgrp *prep_tls_grbuf ();
@ -131,12 +133,13 @@ public:
{ return (struct passwd *) add_account_from_file (name); } { return (struct passwd *) add_account_from_file (name); }
struct passwd *add_user_from_file (uint32_t id) struct passwd *add_user_from_file (uint32_t id)
{ return (struct passwd *) add_account_from_file (id); } { return (struct passwd *) add_account_from_file (id); }
struct passwd *add_user_from_windows (cygpsid &sid) struct passwd *add_user_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL)
{ return (struct passwd *) add_account_from_windows (sid, false); } { return (struct passwd *) add_account_from_windows (sid, false, pldap); }
struct passwd *add_user_from_windows (const char *name) struct passwd *add_user_from_windows (const char *name,
{ return (struct passwd *) add_account_from_windows (name, false); } cyg_ldap* pldap = NULL)
struct passwd *add_user_from_windows (uint32_t id) { return (struct passwd *) add_account_from_windows (name, false, pldap); }
{ return (struct passwd *) add_account_from_windows (id, false); } 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 (cygpsid &sid);
struct passwd *find_user (const char *name); struct passwd *find_user (const char *name);
struct passwd *find_user (uid_t uid); struct passwd *find_user (uid_t uid);
@ -149,12 +152,13 @@ public:
{ return (struct group *) add_account_from_file (name); } { return (struct group *) add_account_from_file (name); }
struct group *add_group_from_file (uint32_t id) struct group *add_group_from_file (uint32_t id)
{ return (struct group *) add_account_from_file (id); } { return (struct group *) add_account_from_file (id); }
struct group *add_group_from_windows (cygpsid &sid) struct group *add_group_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL)
{ return (struct group *) add_account_from_windows (sid, true); } { return (struct group *) add_account_from_windows (sid, true, pldap); }
struct group *add_group_from_windows (const char *name) struct group *add_group_from_windows (const char *name,
{ return (struct group *) add_account_from_windows (name, true); } cyg_ldap *pldap = NULL)
struct group *add_group_from_windows (uint32_t id) { return (struct group *) add_account_from_windows (name, true, pldap); }
{ return (struct group *) add_account_from_windows (id, true); } 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 (cygpsid &sid);
struct group *find_group (const char *name); struct group *find_group (const char *name);
struct group *find_group (gid_t gid); 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 passwd *pw;
struct group *gr; struct group *gr;
int pos; int pos;
cyg_ldap cldap;
RtlCreateAcl (acl, ACL_MAXIMUM_SIZE, ACL_REVISION); RtlCreateAcl (acl, ACL_MAXIMUM_SIZE, ACL_REVISION);
@ -157,7 +158,7 @@ setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
break; break;
case USER: case USER:
case DEF_USER: case DEF_USER:
if (!(pw = internal_getpwuid (aclbufp[i].a_id)) if (!(pw = internal_getpwuid (aclbufp[i].a_id, &cldap))
|| !sid.getfrompw (pw)) || !sid.getfrompw (pw))
{ {
set_errno (EINVAL); set_errno (EINVAL);
@ -179,7 +180,7 @@ setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
break; break;
case GROUP: case GROUP:
case DEF_GROUP: case DEF_GROUP:
if (!(gr = internal_getgrgid (aclbufp[i].a_id)) if (!(gr = internal_getgrgid (aclbufp[i].a_id, &cldap))
|| !sid.getfromgr (gr)) || !sid.getfromgr (gr))
{ {
set_errno (EINVAL); set_errno (EINVAL);
@ -282,6 +283,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
BOOLEAN dummy; BOOLEAN dummy;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
cyg_ldap cldap;
status = RtlGetOwnerSecurityDescriptor (sd, (PSID *) &owner_sid, &dummy); status = RtlGetOwnerSecurityDescriptor (sd, (PSID *) &owner_sid, &dummy);
if (!NT_SUCCESS (status)) if (!NT_SUCCESS (status))
@ -289,7 +291,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
__seterrno_from_nt_status (status); __seterrno_from_nt_status (status);
return -1; return -1;
} }
uid = owner_sid.get_uid (); uid = owner_sid.get_uid (&cldap);
status = RtlGetGroupSecurityDescriptor (sd, (PSID *) &group_sid, &dummy); status = RtlGetGroupSecurityDescriptor (sd, (PSID *) &group_sid, &dummy);
if (!NT_SUCCESS (status)) if (!NT_SUCCESS (status))
@ -297,7 +299,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
__seterrno_from_nt_status (status); __seterrno_from_nt_status (status);
return -1; return -1;
} }
gid = group_sid.get_gid (); gid = group_sid.get_gid (&cldap);
aclent_t lacl[MAX_ACL_ENTRIES]; aclent_t lacl[MAX_ACL_ENTRIES];
memset (&lacl, 0, MAX_ACL_ENTRIES * sizeof (aclent_t)); 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; id = ILLEGAL_GID;
} }
else else
id = ace_sid.get_id (true, &type); id = ace_sid.get_id (TRUE, &type, &cldap);
if (!type) if (!type)
continue; continue;
@ -836,6 +838,7 @@ aclfromtext32 (char *acltextp, int *)
int pos = 0; int pos = 0;
strcpy (buf, acltextp); strcpy (buf, acltextp);
char *lasts; char *lasts;
cyg_ldap cldap;
for (char *c = strtok_r (buf, ",", &lasts); for (char *c = strtok_r (buf, ",", &lasts);
c; c;
c = strtok_r (NULL, ",", &lasts)) c = strtok_r (NULL, ",", &lasts))
@ -855,7 +858,7 @@ aclfromtext32 (char *acltextp, int *)
c += 5; c += 5;
if (isalpha (*c)) if (isalpha (*c))
{ {
struct passwd *pw = internal_getpwnam (c); struct passwd *pw = internal_getpwnam (c, &cldap);
if (!pw) if (!pw)
{ {
set_errno (EINVAL); set_errno (EINVAL);
@ -883,7 +886,7 @@ aclfromtext32 (char *acltextp, int *)
c += 5; c += 5;
if (isalpha (*c)) if (isalpha (*c))
{ {
struct group *gr = internal_getgrnam (c); struct group *gr = internal_getgrnam (c, &cldap);
if (!gr) if (!gr)
{ {
set_errno (EINVAL); set_errno (EINVAL);

View File

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

View File

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

View File

@ -118,11 +118,12 @@ internal_getlogin (cygheap_user &user)
{ {
struct passwd *pw = NULL; struct passwd *pw = NULL;
struct group *gr, *gr2; struct group *gr, *gr2;
cyg_ldap cldap;
cygpsid psid = user.sid (); 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"); debug_printf ("user not found in /etc/passwd");
else else
{ {
@ -131,13 +132,13 @@ internal_getlogin (cygheap_user &user)
myself->uid = pw->pw_uid; myself->uid = pw->pw_uid;
myself->gid = pw->pw_gid; myself->gid = pw->pw_gid;
user.set_name (pw->pw_name); 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 /* 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. 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 If so, pw_gid is taken from windows and might disagree with the
gr_gid from the group file. Overwrite it brutally. */ 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; myself->gid = pw->pw_gid = gr2->gr_gid;
/* Set primary group to the group in /etc/passwd. */ /* Set primary group to the group in /etc/passwd. */
if (gsid != user.groups.pgsid) if (gsid != user.groups.pgsid)
@ -975,12 +976,12 @@ pwdgrp::add_account_from_file (uint32_t id)
} }
void * 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; fetch_user_arg_t arg;
arg.type = SID_arg; arg.type = SID_arg;
arg.sid = &sid; arg.sid = &sid;
char *line = fetch_account_from_windows (arg, group); char *line = fetch_account_from_windows (arg, group, pldap);
if (!line) if (!line)
return NULL; return NULL;
if (cygheap->pg.nss_db_caching ()) if (cygheap->pg.nss_db_caching ())
@ -989,12 +990,12 @@ pwdgrp::add_account_from_windows (cygpsid &sid, bool group)
} }
void * 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; fetch_user_arg_t arg;
arg.type = NAME_arg; arg.type = NAME_arg;
arg.name = name; arg.name = name;
char *line = fetch_account_from_windows (arg, group); char *line = fetch_account_from_windows (arg, group, pldap);
if (!line) if (!line)
return NULL; return NULL;
if (cygheap->pg.nss_db_caching ()) if (cygheap->pg.nss_db_caching ())
@ -1003,12 +1004,12 @@ pwdgrp::add_account_from_windows (const char *name, bool group)
} }
void * 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; fetch_user_arg_t arg;
arg.type = ID_arg; arg.type = ID_arg;
arg.id = id; arg.id = id;
char *line = fetch_account_from_windows (arg, group); char *line = fetch_account_from_windows (arg, group, pldap);
if (!line) if (!line)
return NULL; return NULL;
if (cygheap->pg.nss_db_caching ()) if (cygheap->pg.nss_db_caching ())
@ -1134,13 +1135,13 @@ pwdgrp::fetch_account_from_file (fetch_user_arg_t &arg)
} }
static ULONG 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; uint32_t id_val;
if (!td->PosixOffset && !(td->Flags & DS_DOMAIN_PRIMARY) && td->DomainSid) 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 /* We're probably running under a local account, so we're not allowed
to fetch any information from AD beyond the most obvious. Never 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; - 0x01000000;
} }
else else
id_val = cldap.fetch_posix_offset_for_domain (td->DnsDomainName); id_val = cldap->fetch_posix_offset_for_domain (td->DnsDomainName);
if (id_val) if (id_val)
{ {
td->PosixOffset = id_val; td->PosixOffset = id_val;
@ -1163,7 +1164,7 @@ fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, bool &ldap_open, cyg_ldap &cldap)
char * char *
pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group, pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
bool ugid_caching) cyg_ldap *pldap)
{ {
/* Used in LookupAccount calls. */ /* Used in LookupAccount calls. */
WCHAR namebuf[UNLEN + 1], *name = namebuf; 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 nlen = UNLEN + 1;
DWORD dlen = DNLEN + 1; DWORD dlen = DNLEN + 1;
DWORD slen = MAX_SID_LEN; DWORD slen = MAX_SID_LEN;
cygpsid sid = NO_SID; cygpsid sid (NO_SID);
SID_NAME_USE acc_type; SID_NAME_USE acc_type;
BOOL ret = false; BOOL ret = false;
/* Cygwin user name style. */ /* Cygwin user name style. */
@ -1190,13 +1191,13 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
PWCHAR user = NULL; PWCHAR user = NULL;
PWCHAR home = NULL; PWCHAR home = NULL;
PWCHAR gecos = NULL; PWCHAR gecos = NULL;
/* Temporary stuff. */
PWCHAR p; PWCHAR p;
WCHAR sidstr[128]; WCHAR sidstr[128];
/* Temporary stuff. */
ULONG posix_offset = 0; ULONG posix_offset = 0;
uint32_t id_val; uint32_t id_val;
cyg_ldap cldap; cyg_ldap loc_ldap;
bool ldap_open = false; cyg_ldap *cldap = pldap ?: &loc_ldap;
/* Initialize */ /* Initialize */
if (!cygheap->dom.init ()) 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. */ DC for some weird reason. Use LDAP instead. */
PWCHAR val; PWCHAR val;
if ((ldap_open = cldap.open (NULL)) if (cldap->open (NULL)
&& cldap.fetch_ad_account (sid, group) && cldap->fetch_ad_account (sid, group)
&& (val = cldap.get_group_name ())) && (val = cldap->get_group_name ()))
{ {
wcpcpy (name, val); wcpcpy (name, val);
wcpcpy (dom, L"BUILTIN"); 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) 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) if (td->PosixOffset > posix_offset && td->PosixOffset <= arg.id)
posix_offset = td->PosixOffset; posix_offset = td->PosixOffset;
} }
@ -1452,7 +1453,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
{ {
domain = td->DnsDomainName; domain = td->DnsDomainName;
posix_offset = posix_offset =
fetch_posix_offset (td, ldap_open, cldap); fetch_posix_offset (td, cldap);
break; break;
} }
@ -1474,60 +1475,44 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
/* Generate values. */ /* Generate values. */
if (uid == ILLEGAL_UID) if (uid == ILLEGAL_UID)
uid = posix_offset + sid_sub_auth_rid (sid); uid = posix_offset + sid_sub_auth_rid (sid);
gid = posix_offset + DOMAIN_GROUP_RID_USERS; /* Default. */
if (is_domain_account) if (is_domain_account)
{ {
/* Use LDAP to fetch domain account infos. */ if (acc_type != SidTypeUser)
if (!ldap_open && !cldap.open (NULL))
break; 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; 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) id_val = cldap->get_unix_uid ();
gid = posix_offset + id_val; if (id_val != ILLEGAL_UID
if ((val = cldap.get_user_name ()) && cygheap->ugid_cache.get_uid (id_val)
&& wcscmp (name, val)) == ILLEGAL_UID)
user = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1) cygheap->ugid_cache.add_uid (id_val, uid);
* 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);
}
} }
} }
} }
@ -1629,12 +1614,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, bool group,
*gname = cygheap->pg.nss_separator ()[0]; *gname = cygheap->pg.nss_separator ()[0];
sys_wcstombs (gname + 1, 2 * UNLEN + 1, pgrp); sys_wcstombs (gname + 1, 2 * UNLEN + 1, pgrp);
if ((gr = internal_getgrnam (gname)) if ((gr = internal_getgrnam (gname, cldap))
|| (gr = internal_getgrnam (gname + 1))) || (gr = internal_getgrnam (gname + 1, cldap)))
gid = gr->gr_gid; gid = gr->gr_gid;
} }
if (ugid_caching && uxid if (!pldap && uxid && ((id_val = wcstoul (uxid, &e, 10)), !*e))
&& ((id_val = wcstoul (uxid, &e, 10)), !*e))
{ {
if (acc_type == SidTypeUser) 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)) if (td->DomainSid && RtlEqualSid (sid, td->DomainSid))
{ {
domain = td->NetbiosDomainName; domain = td->NetbiosDomainName;
posix_offset = fetch_posix_offset (td, ldap_open, cldap); posix_offset = fetch_posix_offset (td, cldap);
break; break;
} }
} }