https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9d2de519b2d2781f3a2bddb54cb4a2bfdbb969a3

commit 9d2de519b2d2781f3a2bddb54cb4a2bfdbb969a3
Author:     George Bișoc <[email protected]>
AuthorDate: Sun Jun 19 12:39:23 2022 +0200
Commit:     George Bișoc <[email protected]>
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:
             {

Reply via email to