* 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

@ -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;
}
}
}