summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog64
-rw-r--r--winsup/cygwin/autoload.cc1
-rw-r--r--winsup/cygwin/external.cc4
-rw-r--r--winsup/cygwin/grp.cc87
-rw-r--r--winsup/cygwin/ldap.cc9
-rw-r--r--winsup/cygwin/passwd.cc18
-rw-r--r--winsup/cygwin/pwdgrp.h58
-rw-r--r--winsup/cygwin/sec_acl.cc17
-rw-r--r--winsup/cygwin/sec_helper.cc27
-rw-r--r--winsup/cygwin/security.h8
-rw-r--r--winsup/cygwin/uinfo.cc132
11 files changed, 237 insertions, 188 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 492e3594c..5ba1e3e9d 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,69 @@
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.
2014-02-25 Christopher Faylor <me.cygwin2014@cgf.cx>
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 65999de46..822a30a44 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -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)
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index a99cfef33..8eec5b1db 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -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:
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc
index 2ced0678e..31bfeda2b 100644
--- a/winsup/cygwin/grp.cc
+++ b/winsup/cygwin/grp.cc
@@ -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)
- if ((cnt = (*srchsid == groups->Groups[pg].Sid)))
- break;
- }
- else
+ for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
{
- 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]);
diff --git a/winsup/cygwin/ldap.cc b/winsup/cygwin/ldap.cc
index 740995a61..cb16b9de8 100644
--- a/winsup/cygwin/ldap.cc
+++ b/winsup/cygwin/ldap.cc
@@ -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)))
diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc
index 1a5564904..d27f424b1 100644
--- a/winsup/cygwin/passwd.cc
+++ b/winsup/cygwin/passwd.cc
@@ -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);
}
diff --git a/winsup/cygwin/pwdgrp.h b/winsup/cygwin/pwdgrp.h
index 808bddb9f..5a8267cea 100644
--- a/winsup/cygwin/pwdgrp.h
+++ b/winsup/cygwin/pwdgrp.h
@@ -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);
diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc
index 099df061c..ec5876099 100644
--- a/winsup/cygwin/sec_acl.cc
+++ b/winsup/cygwin/sec_acl.cc
@@ -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);
diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc
index 8a31693f1..23dfc94e8 100644
--- a/winsup/cygwin/sec_helper.cc
+++ b/winsup/cygwin/sec_helper.cc
@@ -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
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index f283674dc..887634ae0 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -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;
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index 20b218851..e39e08601 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -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)
{
+ if (acc_type != SidTypeUser)
+ break;
+
+ gid = posix_offset + DOMAIN_GROUP_RID_USERS; /* Default. */
/* Use LDAP to fetch domain account infos. */
- if (!ldap_open && !cldap.open (NULL))
+ if (!cldap->open (NULL))
break;
- if (cldap.fetch_ad_account (sid, group))
+ 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. */
- 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 ((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 ((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;
}
}