[NTOS:SE] NtQueryInformationToken: implement TokenGroupsAndPrivileges

TokenGroupsAndPrivileges is the younger sister of two TokenGroups and TokenPrivileges classes. In its purpose there's no huge substantial differences apart that this class comes with its own structure, TOKEN_GROUPS_AND_PRIVILEGES, and that this structure comes with extra information.
This commit is contained in:
George Bișoc
2022-06-19 12:39:23 +02:00
parent f79ec61bdc
commit 9d2de519b2

View File

@@ -905,9 +905,83 @@ NtQueryInformationToken(
}
case TokenGroupsAndPrivileges:
DPRINT1("NtQueryInformationToken(TokenGroupsAndPrivileges) not implemented\n");
Status = STATUS_NOT_IMPLEMENTED;
{
PSID Sid, RestrictedSid;
ULONG SidLen, RestrictedSidLen;
ULONG UserGroupLength, RestrictedSidLength, PrivilegeLength;
PTOKEN_GROUPS_AND_PRIVILEGES GroupsAndPrivs = (PTOKEN_GROUPS_AND_PRIVILEGES)TokenInformation;
DPRINT("NtQueryInformationToken(TokenGroupsAndPrivileges)\n");
UserGroupLength = RtlLengthSidAndAttributes(Token->UserAndGroupCount, Token->UserAndGroups);
RestrictedSidLength = RtlLengthSidAndAttributes(Token->RestrictedSidCount, Token->RestrictedSids);
PrivilegeLength = Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
RequiredLength = sizeof(TOKEN_GROUPS_AND_PRIVILEGES) +
UserGroupLength + RestrictedSidLength + PrivilegeLength;
_SEH2_TRY
{
if (TokenInformationLength >= RequiredLength)
{
GroupsAndPrivs->SidCount = Token->UserAndGroupCount;
GroupsAndPrivs->SidLength = UserGroupLength;
GroupsAndPrivs->Sids = (PSID_AND_ATTRIBUTES)(GroupsAndPrivs + 1);
Sid = (PSID)((ULONG_PTR)GroupsAndPrivs->Sids + (Token->UserAndGroupCount * sizeof(SID_AND_ATTRIBUTES)));
SidLen = UserGroupLength - (Token->UserAndGroupCount * sizeof(SID_AND_ATTRIBUTES));
Status = RtlCopySidAndAttributesArray(Token->UserAndGroupCount,
Token->UserAndGroups,
SidLen,
GroupsAndPrivs->Sids,
Sid,
&Unused.PSid,
&Unused.Ulong);
NT_ASSERT(NT_SUCCESS(Status));
GroupsAndPrivs->RestrictedSidCount = Token->RestrictedSidCount;
GroupsAndPrivs->RestrictedSidLength = RestrictedSidLength;
GroupsAndPrivs->RestrictedSids = NULL;
if (SeTokenIsRestricted(Token))
{
GroupsAndPrivs->RestrictedSids = (PSID_AND_ATTRIBUTES)((ULONG_PTR)GroupsAndPrivs->Sids + UserGroupLength);
RestrictedSid = (PSID)((ULONG_PTR)GroupsAndPrivs->RestrictedSids + (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES)));
RestrictedSidLen = RestrictedSidLength - (Token->RestrictedSidCount * sizeof(SID_AND_ATTRIBUTES));
Status = RtlCopySidAndAttributesArray(Token->RestrictedSidCount,
Token->RestrictedSids,
RestrictedSidLen,
GroupsAndPrivs->RestrictedSids,
RestrictedSid,
&Unused.PSid,
&Unused.Ulong);
NT_ASSERT(NT_SUCCESS(Status));
}
GroupsAndPrivs->PrivilegeCount = Token->PrivilegeCount;
GroupsAndPrivs->PrivilegeLength = PrivilegeLength;
GroupsAndPrivs->Privileges = (PLUID_AND_ATTRIBUTES)((ULONG_PTR)(GroupsAndPrivs + 1) +
UserGroupLength + RestrictedSidLength);
RtlCopyLuidAndAttributesArray(Token->PrivilegeCount,
Token->Privileges,
GroupsAndPrivs->Privileges);
GroupsAndPrivs->AuthenticationId = Token->AuthenticationId;
}
else
{
Status = STATUS_BUFFER_TOO_SMALL;
}
*ReturnLength = RequiredLength;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
break;
}
case TokenRestrictedSids:
{