* advapi32.cc (GetTokenInformation): Remove.

(SetTokenInformation): Remove.
	* grp.cc: Replace above functions throughout with their ntdll.dll
	equivalent.
	* sec_auth.cc: Ditto.
	* syscalls.cc: Ditto.
	* uinfo.cc: Ditto.
This commit is contained in:
Corinna Vinschen 2011-04-29 07:34:05 +00:00
parent 541820d0ee
commit 12eac211c9
6 changed files with 181 additions and 140 deletions

View File

@ -1,3 +1,13 @@
2011-04-29 Corinna Vinschen <corinna@vinschen.de>
* advapi32.cc (GetTokenInformation): Remove.
(SetTokenInformation): Remove.
* grp.cc: Replace above functions throughout with their ntdll.dll
equivalent.
* sec_auth.cc: Ditto.
* syscalls.cc: Ditto.
* uinfo.cc: Ditto.
2011-04-29 Corinna Vinschen <corinna@vinschen.de>
* posix_ipc.cc (ipc_cond_timedwait): Only wait for pthread's

View File

@ -82,22 +82,6 @@ OpenThreadToken (HANDLE thread, DWORD access, BOOL as_self, PHANDLE tok)
DEFAULT_NTSTATUS_TO_BOOL_RETURN
}
BOOL WINAPI
GetTokenInformation(HANDLE tok, TOKEN_INFORMATION_CLASS infoclass, LPVOID buf,
DWORD len, PDWORD retlen)
{
NTSTATUS status = NtQueryInformationToken (tok, infoclass, buf, len, retlen);
DEFAULT_NTSTATUS_TO_BOOL_RETURN
}
BOOL WINAPI
SetTokenInformation (HANDLE tok, TOKEN_INFORMATION_CLASS infoclass, PVOID buf,
ULONG len)
{
NTSTATUS status = NtSetInformationToken (tok, infoclass, buf, len);
DEFAULT_NTSTATUS_TO_BOOL_RETURN
}
BOOL WINAPI
RevertToSelf ()
{

View File

@ -1,7 +1,7 @@
/* grp.cc
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2009 Red Hat, Inc.
2007, 2008, 2009, 2011 Red Hat, Inc.
Original stubs by Jason Molenda of Cygnus Support, crash@cygnus.com
First implementation by Gunther Ebert, gunther.ebert@ixos-leipzig.de
@ -21,6 +21,7 @@ details. */
#include "fhandler.h"
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
#include "pwdgrp.h"
static __group32 *group_buf;
@ -314,8 +315,9 @@ internal_getgrent (int pos)
int
internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
{
NTSTATUS status;
HANDLE hToken = NULL;
DWORD size;
ULONG size;
int cnt = 0;
struct __group32 *gr;
@ -344,13 +346,15 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
hToken = cygheap->user.primary_token ();
else
hToken = hProcToken;
if (GetTokenInformation (hToken, TokenGroups, NULL, 0, &size)
|| GetLastError () == ERROR_INSUFFICIENT_BUFFER)
status = NtQueryInformationToken (hToken, TokenGroups, NULL, 0, &size);
if (NT_SUCCESS (status) || status == STATUS_BUFFER_TOO_SMALL)
{
PTOKEN_GROUPS groups = (PTOKEN_GROUPS) alloca (size);
if (GetTokenInformation (hToken, TokenGroups, groups, size, &size))
status = NtQueryInformationToken (hToken, TokenGroups, groups,
size, &size);
if (NT_SUCCESS (status))
{
cygsid sid;
@ -379,7 +383,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
}
}
else
debug_printf ("%d = GetTokenInformation(NULL) %E", size);
debug_printf ("%lu = NtQueryInformationToken(NULL) %p", size, status);
return cnt;
error:

View File

@ -32,7 +32,7 @@ details. */
/* Starting with Windows Vista, the token returned by system functions
is a restricted token. The full admin token is linked to it and can
be fetched with GetTokenInformation. This function returns the original
be fetched with NtQueryInformationToken. This function returns the original
token on pre-Vista, and the elevated token on Vista++ if it's available,
the original token otherwise. The token handle is also made inheritable
since that's necessary anyway. */
@ -42,7 +42,7 @@ get_full_privileged_inheritable_token (HANDLE token)
if (wincap.has_mandatory_integrity_control ())
{
TOKEN_LINKED_TOKEN linked;
DWORD size;
ULONG size;
/* When fetching the linked token without TCB privs, then the linked
token is not a primary token, only an impersonation token, which is
@ -50,8 +50,9 @@ get_full_privileged_inheritable_token (HANDLE token)
token using DuplicateTokenEx does NOT work for the linked token in
this case. So we have to switch on TCB privs to get a primary token.
This is generally performed in the calling functions. */
if (GetTokenInformation (token, TokenLinkedToken,
(PVOID) &linked, sizeof linked, &size))
if (NT_SUCCESS (NtQueryInformationToken (token, TokenLinkedToken,
(PVOID) &linked, sizeof linked,
&size)))
{
debug_printf ("Linked Token: %p", linked.LinkedToken);
if (linked.LinkedToken)
@ -61,8 +62,9 @@ get_full_privileged_inheritable_token (HANDLE token)
/* At this point we don't know if the user actually had TCB
privileges. Check if the linked token is a primary token.
If not, just return the original token. */
if (GetTokenInformation (linked.LinkedToken, TokenType,
(PVOID) &type, sizeof type, &size)
if (NT_SUCCESS (NtQueryInformationToken (linked.LinkedToken,
TokenType, (PVOID) &type,
sizeof type, &size))
&& type != TokenPrimary)
debug_printf ("Linked Token is not a primary token!");
else
@ -660,23 +662,26 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
bool
verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
{
DWORD size;
NTSTATUS status;
ULONG size;
bool intern = false;
if (pintern)
{
TOKEN_SOURCE ts;
if (!GetTokenInformation (token, TokenSource,
&ts, sizeof ts, &size))
debug_printf ("GetTokenInformation(), %E");
status = NtQueryInformationToken (token, TokenSource, &ts, sizeof ts,
&size);
if (!NT_SUCCESS (status))
debug_printf ("NtQueryInformationToken(), %p", status);
else
*pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8);
}
/* Verify usersid */
cygsid tok_usersid = NO_SID;
if (!GetTokenInformation (token, TokenUser,
&tok_usersid, sizeof tok_usersid, &size))
debug_printf ("GetTokenInformation(), %E");
status = NtQueryInformationToken (token, TokenUser, &tok_usersid,
sizeof tok_usersid, &size);
if (!NT_SUCCESS (status))
debug_printf ("NtQueryInformationToken(), %p", status);
if (usersid != tok_usersid)
return false;
@ -705,64 +710,69 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
}
PTOKEN_GROUPS my_grps;
bool sawpg = false, ret = false;
if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size) &&
GetLastError () != ERROR_INSUFFICIENT_BUFFER)
debug_printf ("GetTokenInformation(token, TokenGroups), %E");
else if (!(my_grps = (PTOKEN_GROUPS) alloca (size)))
debug_printf ("alloca (my_grps) failed.");
else if (!GetTokenInformation (token, TokenGroups, my_grps, size, &size))
debug_printf ("GetTokenInformation(my_token, TokenGroups), %E");
else
status = NtQueryInformationToken (token, TokenGroups, NULL, 0, &size);
if (!NT_SUCCESS (status) && status != STATUS_BUFFER_TOO_SMALL)
{
if (groups.issetgroups ()) /* setgroups was called */
{
cygsid gsid;
struct __group32 *gr;
bool saw[groups.sgsids.count ()];
memset (saw, 0, sizeof(saw));
/* token groups found in /etc/group match the user.gsids ? */
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid))
{
int pos = groups.sgsids.position (gsid);
if (pos >= 0)
saw[pos] = true;
else if (groups.pgsid == gsid)
sawpg = true;
#if 0
/* With this `else', verify_token returns false if we find
groups in the token, which are not in the group list set
with setgroups(). That's rather dangerous. What we're
really interested in is that all groups in the setgroups()
list are in the token. A token created through ADVAPI
should be allowed to contain more groups than requested
through setgroups(), esecially since Vista and the
addition of integrity groups. So we disable this statement
for now. */
else if (gsid != well_known_world_sid
&& gsid != usersid)
goto done;
#endif
}
/* user.sgsids groups must be in the token, except for builtin groups.
These can be different on domain member machines compared to
domain controllers, so these builtin groups may be validly missing
from a token created through password or lsaauth logon. */
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
if (!saw[gidx]
&& !groups.sgsids.sids[gidx].is_well_known_sid ()
&& !sid_in_token_groups (my_grps, groups.sgsids.sids[gidx]))
return false;
}
/* The primary group must be in the token */
ret = sawpg
|| sid_in_token_groups (my_grps, groups.pgsid)
|| groups.pgsid == usersid;
debug_printf ("NtQueryInformationToken(token, TokenGroups), %p", status);
return false;
}
return ret;
my_grps = (PTOKEN_GROUPS) alloca (size);
status = NtQueryInformationToken (token, TokenGroups, my_grps, size, &size);
if (!NT_SUCCESS (status))
{
debug_printf ("NtQueryInformationToken(my_token, TokenGroups), %p",
status);
return false;
}
bool sawpg = false;
if (groups.issetgroups ()) /* setgroups was called */
{
cygsid gsid;
struct __group32 *gr;
bool saw[groups.sgsids.count ()];
memset (saw, 0, sizeof(saw));
/* token groups found in /etc/group match the user.gsids ? */
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid))
{
int pos = groups.sgsids.position (gsid);
if (pos >= 0)
saw[pos] = true;
else if (groups.pgsid == gsid)
sawpg = true;
#if 0
/* With this `else', verify_token returns false if we find
groups in the token, which are not in the group list set
with setgroups(). That's rather dangerous. What we're
really interested in is that all groups in the setgroups()
list are in the token. A token created through ADVAPI
should be allowed to contain more groups than requested
through setgroups(), esecially since Vista and the
addition of integrity groups. So we disable this statement
for now. */
else if (gsid != well_known_world_sid
&& gsid != usersid)
goto done;
#endif
}
/* user.sgsids groups must be in the token, except for builtin groups.
These can be different on domain member machines compared to
domain controllers, so these builtin groups may be validly missing
from a token created through password or lsaauth logon. */
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
if (!saw[gidx]
&& !groups.sgsids.sids[gidx].is_well_known_sid ()
&& !sid_in_token_groups (my_grps, groups.sgsids.sids[gidx]))
return false;
}
/* The primary group must be in the token */
return sawpg
|| sid_in_token_groups (my_grps, groups.pgsid)
|| groups.pgsid == usersid;
}
HANDLE
@ -795,7 +805,7 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
HANDLE primary_token = INVALID_HANDLE_VALUE;
PTOKEN_GROUPS my_tok_gsids = NULL;
DWORD size;
ULONG size;
size_t psize = 0;
/* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */
@ -817,26 +827,37 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
id of the user account running current process. */
if (usersid == well_known_system_sid)
/* nothing to do */;
else if (!GetTokenInformation (hProcToken, TokenStatistics,
&stats, sizeof stats, &size))
debug_printf
("GetTokenInformation(hProcToken, TokenStatistics), %E");
else
auth_luid = stats.AuthenticationId;
{
status = NtQueryInformationToken (hProcToken, TokenStatistics,
&stats, sizeof stats, &size);
if (!NT_SUCCESS (status))
debug_printf ("NtQueryInformationToken(hProcToken, "
"TokenStatistics), %p", status);
else
auth_luid = stats.AuthenticationId;
}
/* Retrieving current processes group list to be able to inherit
some important well known group sids. */
if (!GetTokenInformation (hProcToken, TokenGroups, NULL, 0, &size)
&& GetLastError () != ERROR_INSUFFICIENT_BUFFER)
debug_printf ("GetTokenInformation(hProcToken, TokenGroups), %E");
status = NtQueryInformationToken (hProcToken, TokenGroups, NULL, 0,
&size);
if (!NT_SUCCESS (status) && status != STATUS_BUFFER_TOO_SMALL)
debug_printf ("NtQueryInformationToken(hProcToken, TokenGroups), %p",
status);
else if (!(my_tok_gsids = (PTOKEN_GROUPS) malloc (size)))
debug_printf ("malloc (my_tok_gsids) failed.");
else if (!GetTokenInformation (hProcToken, TokenGroups, my_tok_gsids,
size, &size))
else
{
debug_printf ("GetTokenInformation(hProcToken, TokenGroups), %E");
free (my_tok_gsids);
my_tok_gsids = NULL;
status = NtQueryInformationToken (hProcToken, TokenGroups,
my_tok_gsids, size, &size);
if (!NT_SUCCESS (status))
{
debug_printf ("NtQueryInformationToken(hProcToken, TokenGroups), "
"%p", status);
free (my_tok_gsids);
my_tok_gsids = NULL;
}
}
}

View File

@ -2961,6 +2961,8 @@ seteuid32 (__uid32_t uid)
if (new_token != hProcToken)
{
NTSTATUS status;
if (!request_restricted_uid_switch)
{
/* Avoid having HKCU use default user */
@ -2969,21 +2971,27 @@ seteuid32 (__uid32_t uid)
}
/* Try setting owner to same value as user. */
if (!SetTokenInformation (new_token, TokenOwner,
&usersid, sizeof usersid))
debug_printf ("SetTokenInformation(user.token, TokenOwner), %E");
status = NtSetInformationToken (new_token, TokenOwner,
&usersid, sizeof usersid);
if (!NT_SUCCESS (status))
debug_printf ("NtSetInformationToken (user.token, TokenOwner), %p",
status);
/* Try setting primary group in token to current group */
if (!SetTokenInformation (new_token, TokenPrimaryGroup,
&groups.pgsid, sizeof (cygsid)))
debug_printf ("SetTokenInformation(user.token, TokenPrimaryGroup), %E");
status = NtSetInformationToken (new_token, TokenPrimaryGroup,
&groups.pgsid, sizeof (cygsid));
if (!NT_SUCCESS (status))
debug_printf ("NtSetInformationToken (user.token, TokenPrimaryGroup),"
"%p", status);
/* Try setting default DACL */
PACL dacl_buf = (PACL) alloca (MAX_DACL_LEN (5));
if (sec_acl (dacl_buf, true, true, usersid))
{
TOKEN_DEFAULT_DACL tdacl = { dacl_buf };
if (!SetTokenInformation (new_token, TokenDefaultDacl,
&tdacl, sizeof (tdacl)))
debug_printf ("SetTokenInformation (TokenDefaultDacl), %E");
status = NtSetInformationToken (new_token, TokenDefaultDacl,
&tdacl, sizeof (tdacl));
if (!NT_SUCCESS (status))
debug_printf ("NtSetInformationToken (TokenDefaultDacl), %p",
status);
}
}
@ -3095,6 +3103,7 @@ setegid32 (__gid32_t gid)
return 0;
}
NTSTATUS status;
user_groups * groups = &cygheap->user.groups;
cygsid gsid;
struct __group32 * gr = internal_getgrgid (gid);
@ -3110,17 +3119,23 @@ setegid32 (__gid32_t gid)
if (cygheap->user.issetuid ())
{
/* If impersonated, update impersonation token... */
if (!SetTokenInformation (cygheap->user.primary_token (),
TokenPrimaryGroup, &gsid, sizeof gsid))
debug_printf ("SetTokenInformation(primary_token, "
"TokenPrimaryGroup), %E");
if (!SetTokenInformation (cygheap->user.imp_token (), TokenPrimaryGroup,
&gsid, sizeof gsid))
debug_printf ("SetTokenInformation(token, TokenPrimaryGroup), %E");
status = NtSetInformationToken (cygheap->user.primary_token (),
TokenPrimaryGroup, &gsid, sizeof gsid);
if (!NT_SUCCESS (status))
debug_printf ("NtSetInformationToken (primary_token, "
"TokenPrimaryGroup), %p", status);
status = NtSetInformationToken (cygheap->user.imp_token (),
TokenPrimaryGroup, &gsid, sizeof gsid);
if (!NT_SUCCESS (status))
debug_printf ("NtSetInformationToken (token, TokenPrimaryGroup), %p",
status);
}
cygheap->user.deimpersonate ();
if (!SetTokenInformation (hProcToken, TokenPrimaryGroup, &gsid, sizeof gsid))
debug_printf ("SetTokenInformation(hProcToken, TokenPrimaryGroup), %E");
status = NtSetInformationToken (hProcToken, TokenPrimaryGroup,
&gsid, sizeof gsid);
if (!NT_SUCCESS (status))
debug_printf ("NtSetInformationToken (hProcToken, TokenPrimaryGroup), %p",
status);
clear_procimptoken ();
cygheap->user.reimpersonate ();
return 0;

View File

@ -59,32 +59,35 @@ cygheap_user::init ()
else
set_name ("unknown");
DWORD siz;
NTSTATUS status;
ULONG size;
PSECURITY_DESCRIPTOR psd;
if (!GetTokenInformation (hProcToken, TokenPrimaryGroup,
&groups.pgsid, sizeof (cygsid), &siz))
system_printf ("GetTokenInformation (TokenPrimaryGroup), %E");
status = NtQueryInformationToken (hProcToken, TokenPrimaryGroup,
&groups.pgsid, sizeof (cygsid), &size);
if (!NT_SUCCESS (status))
system_printf ("NtQueryInformationToken (TokenPrimaryGroup), %p", status);
/* Get the SID from current process and store it in effec_cygsid */
if (!GetTokenInformation (hProcToken, TokenUser, &effec_cygsid,
sizeof (cygsid), &siz))
status = NtQueryInformationToken (hProcToken, TokenUser, &effec_cygsid,
sizeof (cygsid), &size);
if (!NT_SUCCESS (status))
{
system_printf ("GetTokenInformation (TokenUser), %E");
system_printf ("NtQueryInformationToken (TokenUser), %p", status);
return;
}
/* Set token owner to the same value as token user */
if (!SetTokenInformation (hProcToken, TokenOwner, &effec_cygsid,
sizeof (cygsid)))
debug_printf ("SetTokenInformation(TokenOwner), %E");
status = NtSetInformationToken (hProcToken, TokenOwner, &effec_cygsid,
sizeof (cygsid));
if (!NT_SUCCESS (status))
debug_printf ("NtSetInformationToken(TokenOwner), %p", status);
/* Standard way to build a security descriptor with the usual DACL */
PSECURITY_ATTRIBUTES sa_buf = (PSECURITY_ATTRIBUTES) alloca (1024);
psd = (PSECURITY_DESCRIPTOR)
(sec_user_nih (sa_buf, sid()))->lpSecurityDescriptor;
NTSTATUS status;
BOOLEAN acl_exists, dummy;
TOKEN_DEFAULT_DACL dacl;
@ -94,9 +97,10 @@ cygheap_user::init ()
{
/* Set the default DACL and the process DACL */
if (!SetTokenInformation (hProcToken, TokenDefaultDacl, &dacl,
sizeof (dacl)))
system_printf ("SetTokenInformation (TokenDefaultDacl), %E");
status = NtSetInformationToken (hProcToken, TokenDefaultDacl, &dacl,
sizeof (dacl));
if (!NT_SUCCESS (status))
system_printf ("NtSetInformationToken (TokenDefaultDacl), %p", status);
if ((status = NtSetSecurityObject (NtCurrentProcess (),
DACL_SECURITY_INFORMATION, psd)))
system_printf ("NtSetSecurityObject, %lx", status);
@ -128,9 +132,12 @@ internal_getlogin (cygheap_user &user)
if (gsid != user.groups.pgsid)
{
/* Set primary group to the group in /etc/passwd. */
if (!SetTokenInformation (hProcToken, TokenPrimaryGroup,
&gsid, sizeof gsid))
debug_printf ("SetTokenInformation(TokenPrimaryGroup), %E");
NTSTATUS status = NtSetInformationToken (hProcToken,
TokenPrimaryGroup,
&gsid, sizeof gsid);
if (!NT_SUCCESS (status))
debug_printf ("NtSetInformationToken (TokenPrimaryGroup), %p",
status);
else
user.groups.pgsid = gsid;
clear_procimptoken ();