https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9d2de519b2d2781f3a2bd…
commit 9d2de519b2d2781f3a2bddb54cb4a2bfdbb969a3
Author: George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Sun Jun 19 12:39:23 2022 +0200
Commit: George Bișoc <george.bisoc(a)reactos.org>
CommitDate: Sun Jun 19 17:22:04 2022 +0200
[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.
---
ntoskrnl/se/tokencls.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 76 insertions(+), 2 deletions(-)
diff --git a/ntoskrnl/se/tokencls.c b/ntoskrnl/se/tokencls.c
index 24adad4f61c..8bb5598ce9e 100644
--- a/ntoskrnl/se/tokencls.c
+++ b/ntoskrnl/se/tokencls.c
@@ -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:
{