* grp.cc (internal_getgroups): Take additional timeout_ns parameter.

Restrict fetching group account entries from user token groups by
	timeout_ns 100ns-intervals.  Add preceding comment to explain why.
	* pwdgrp.h (internal_getgroups): Align prototype.
	* times.cc (GetTickCount_ns): New function.
	* uinfo.cc (internal_getlogin): Call internal_getgroups wih 300ms
	timeout.
	* winsup.h (GetTickCount_ns): Declare.
This commit is contained in:
Corinna Vinschen 2015-02-20 15:13:46 +00:00
parent 89a3749928
commit d6f62a1178
6 changed files with 46 additions and 7 deletions

View File

@ -1,3 +1,14 @@
2015-02-20 Corinna Vinschen <corinna@vinschen.de>
* grp.cc (internal_getgroups): Take additional timeout_ns parameter.
Restrict fetching group account entries from user token groups by
timeout_ns 100ns-intervals. Add preceding comment to explain why.
* pwdgrp.h (internal_getgroups): Align prototype.
* times.cc (GetTickCount_ns): New function.
* uinfo.cc (internal_getlogin): Call internal_getgroups wih 300ms
timeout.
* winsup.h (GetTickCount_ns): Declare.
2015-02-19 Jon TURNEY <jon.turney@dronecode.org.uk>
* Makefile.in (sigfe.o): Use CFLAGS.

View File

@ -1,7 +1,7 @@
/* grp.cc
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009, 2011, 2012, 2013, 2014 Red Hat, Inc.
2008, 2009, 2011, 2012, 2013, 2014, 2015 Red Hat, Inc.
Original stubs by Jason Molenda of Cygnus Support, crash@cygnus.com
First implementation by Gunther Ebert, gunther.ebert@ixos-leipzig.de
@ -492,8 +492,12 @@ endgrent_filtered (void *gr)
((gr_ent *) gr)->endgrent ();
}
/* timeout_ns (in 100ns units) is set to non-0 when called from
internal_getlogin. This restricts fetching of the user's groups at process
tree startup to a (hopefully) bearable time. */
int
internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap)
internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap,
const DWORD timeout_ns)
{
NTSTATUS status;
HANDLE tok;
@ -527,6 +531,10 @@ internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap)
status = NtQueryInformationToken (tok, TokenGroups, groups, size, &size);
if (NT_SUCCESS (status))
{
ULONGLONG t0;
if (timeout_ns)
t0 = GetTickCount_ns ();
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
{
cygpsid sid = groups->Groups[pg].Sid;
@ -543,6 +551,8 @@ internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap)
goto error;
}
}
if (timeout_ns && GetTickCount_ns () - t0 >= timeout_ns)
break;
}
}
}

View File

@ -1,6 +1,6 @@
/* pwdgrp.h
Copyright 2001, 2002, 2003, 2014 Red Hat inc.
Copyright 2001, 2002, 2003, 2014, 2015 Red Hat inc.
Stuff common to pwd and grp handling.
@ -27,7 +27,7 @@ extern struct group *internal_getgrsid_from_db (cygpsid &sid);
extern struct group *internal_getgrgid (gid_t, cyg_ldap * = NULL);
extern struct group *internal_getgrnam (const char *, cyg_ldap * = NULL);
extern int internal_getgroups (int, gid_t *, cyg_ldap *);
extern int internal_getgroups (int, gid_t *, cyg_ldap *, const DWORD = 0);
/* These functions are called from mkpasswd/mkgroup via cygwin_internal. */
void *setpwent_filtered (int enums, PCWSTR enum_tdoms);

View File

@ -1,7 +1,7 @@
/* times.cc
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Red Hat, Inc.
This file is part of Cygwin.
@ -42,6 +42,23 @@ get_system_time (PLARGE_INTEGER systime)
: GetSystemTimeAsFileTime ((LPFILETIME) systime);
}
/* There's no GetTickCount64 on pre-Vista. This is the do-it-yourself kit,
as it was implemented as hires_ms::timeGetTime_ns once. Resurrect the
functionality to allow reliable (albeit low res) timing values. The
function returns the value in 100ns interval to avoid a division by 10000. */
ULONGLONG
GetTickCount_ns ()
{
LARGE_INTEGER t;
do
{
t.HighPart = SharedUserData.InterruptTime.High1Time;
t.LowPart = SharedUserData.InterruptTime.LowPart;
}
while (t.HighPart != SharedUserData.InterruptTime.High2Time);
return (ULONGLONG) t.QuadPart;
}
/* Cygwin internal */
static uint64_t __stdcall
__to_clock_t (PLARGE_INTEGER src, int flag)

View File

@ -125,7 +125,7 @@ internal_getlogin (cygheap_user &user)
pwd = internal_getpwsid (user.sid (), &cldap);
pgrp = internal_getgrsid (user.groups.pgsid, &cldap);
if (!cygheap->pg.nss_cygserver_caching ())
internal_getgroups (0, NULL, &cldap);
internal_getgroups (0, NULL, &cldap, 3000000U); /* 300ms in 100ns units */
if (!pwd)
debug_printf ("user not found in passwd DB");
else

View File

@ -1,7 +1,7 @@
/* winsup.h: main Cygwin header file.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Red Hat, Inc.
This file is part of Cygwin.
@ -207,6 +207,7 @@ void __reg2 nofinalslash (const char *src, char *dst);
void __reg3 *hook_or_detect_cygwin (const char *, const void *, WORD&, HANDLE h = NULL);
/* Time related */
ULONGLONG GetTickCount_ns ();
void __stdcall totimeval (struct timeval *, PLARGE_INTEGER, int, int);
time_t __stdcall to_time_t (PLARGE_INTEGER);
void __stdcall to_timestruc_t (PLARGE_INTEGER, timestruc_t *);