ReactOS 0.4.15-dev-8058-ga7cbb60
debug.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Security subsystem debug routines support
5 * COPYRIGHT: Copyright 2022-2023 George Bișoc <george.bisoc@reactos.org>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include <ntoskrnl.h>
11#define NDEBUG
12#include <debug.h>
13
14/* PRIVATE FUNCTIONS **********************************************************/
15
16#ifndef NDEBUG
26static
28SepGetAceTypeString(
30{
31#define TOSTR(x) #x
32 static const PCSTR AceTypes[] =
33 {
52 };
53#undef TOSTR
54
55 if (AceType < RTL_NUMBER_OF(AceTypes))
56 return AceTypes[AceType];
57 else
58 return "UNKNOWN TYPE";
59}
60
65static
66VOID
67SepDumpAceFlags(
69{
70#define ACE_FLAG_PRINT(x) \
71 if (AceFlags & x) \
72 { \
73 DbgPrint(#x "\n"); \
74 }
75
76 ACE_FLAG_PRINT(OBJECT_INHERIT_ACE);
77 ACE_FLAG_PRINT(CONTAINER_INHERIT_ACE);
78 ACE_FLAG_PRINT(NO_PROPAGATE_INHERIT_ACE);
79 ACE_FLAG_PRINT(INHERIT_ONLY_ACE);
80 ACE_FLAG_PRINT(INHERITED_ACE);
81#undef ACE_FLAG_PRINT
82}
83
88static
89VOID
90SepDumpAces(
91 _In_ PACL Acl)
92{
94 PACE Ace;
96 PSID Sid;
97 UNICODE_STRING SidString;
98
99 /* Loop all ACEs and dump their info */
100 for (AceIndex = 0; AceIndex < Acl->AceCount; AceIndex++)
101 {
102 /* Get the ACE at this index */
103 Status = RtlGetAce(Acl, AceIndex, (PVOID*)&Ace);
104 if (!NT_SUCCESS(Status))
105 {
106 /*
107 * Normally this should never happen.
108 * Just fail gracefully and stop further
109 * debugging of ACEs.
110 */
111 DbgPrint("SepDumpAces(): Failed to find the next ACE, stop dumping info...\n");
112 return;
113 }
114
115 DbgPrint("================== %lu# ACE DUMP INFO ==================\n", AceIndex);
116 DbgPrint("Ace -> 0x%p\n", Ace);
117 DbgPrint("Ace->Header -> 0x%p\n", Ace->Header);
118 DbgPrint("Ace->Header.AceType -> %s\n", SepGetAceTypeString(Ace->Header.AceType));
119 DbgPrint("Ace->AccessMask -> 0x%08lx\n", Ace->AccessMask);
120
122 ASSERT(Sid);
124 DbgPrint("Ace SID -> %wZ\n", &SidString);
125 RtlFreeUnicodeString(&SidString);
126
127 DbgPrint("Ace->Header.AceSize -> %u\n", Ace->Header.AceSize);
128 DbgPrint("Ace->Header.AceFlags:\n");
129 SepDumpAceFlags(Ace->Header.AceFlags);
130 }
131}
132
137static
138VOID
139SepDumpAclInfo(
140 _In_ PACL Acl,
141 _In_ BOOLEAN IsSacl)
142{
143 /* Dump relevant info */
144 DbgPrint("================== %s DUMP INFO ==================\n", IsSacl ? "SACL" : "DACL");
145 DbgPrint("Acl->AclRevision -> %u\n", Acl->AclRevision);
146 DbgPrint("Acl->AclSize -> %u\n", Acl->AclSize);
147 DbgPrint("Acl->AceCount -> %u\n", Acl->AceCount);
148
149 /* Dump all the ACEs present on this ACL */
150 SepDumpAces(Acl);
151}
152
157static
158VOID
159SepDumpSdControlInfo(
161{
162#define SD_CONTROL_PRINT(x) \
163 if (SdControl & x) \
164 { \
165 DbgPrint(#x "\n"); \
166 }
167
168 SD_CONTROL_PRINT(SE_OWNER_DEFAULTED);
169 SD_CONTROL_PRINT(SE_GROUP_DEFAULTED);
170 SD_CONTROL_PRINT(SE_DACL_PRESENT);
171 SD_CONTROL_PRINT(SE_DACL_DEFAULTED);
172 SD_CONTROL_PRINT(SE_SACL_PRESENT);
173 SD_CONTROL_PRINT(SE_SACL_DEFAULTED);
174 SD_CONTROL_PRINT(SE_DACL_UNTRUSTED);
175 SD_CONTROL_PRINT(SE_SERVER_SECURITY);
176 SD_CONTROL_PRINT(SE_DACL_AUTO_INHERIT_REQ);
177 SD_CONTROL_PRINT(SE_SACL_AUTO_INHERIT_REQ);
178 SD_CONTROL_PRINT(SE_DACL_AUTO_INHERITED);
179 SD_CONTROL_PRINT(SE_SACL_AUTO_INHERITED);
180 SD_CONTROL_PRINT(SE_DACL_PROTECTED);
181 SD_CONTROL_PRINT(SE_SACL_PROTECTED);
182 SD_CONTROL_PRINT(SE_RM_CONTROL_VALID);
183 SD_CONTROL_PRINT(SE_SELF_RELATIVE);
184#undef SD_CONTROL_PRINT
185}
186
191static
192VOID
193SepDumpSidsOfToken(
195 _In_ ULONG SidCount)
196{
197 ULONG SidIndex;
198 UNICODE_STRING SidString;
199
200 /* Loop all SIDs and dump them */
201 for (SidIndex = 0; SidIndex < SidCount; SidIndex++)
202 {
203 RtlConvertSidToUnicodeString(&SidString, Sids[SidIndex].Sid, TRUE);
204 DbgPrint("%lu# %wZ\n", SidIndex, &SidString);
205 RtlFreeUnicodeString(&SidString);
206 }
207}
208#endif
209
210/* PUBLIC FUNCTIONS ***********************************************************/
211
216VOID
219{
220#ifndef NDEBUG
221 UNICODE_STRING SidString;
222 PSID OwnerSid, GroupSid;
223 PACL Dacl, Sacl;
224#endif
225
226 /* Don't dump anything if no SD was provided */
228 {
229 return;
230 }
231
232#ifndef NDEBUG
233 /* Cache the necessary security buffers to dump info from */
238
239 DbgPrint("================== SECURITY DESCRIPTOR DUMP INFO ==================\n");
240 DbgPrint("SecurityDescriptor -> 0x%p\n", SecurityDescriptor);
241 DbgPrint("SecurityDescriptor->Revision -> %u\n", SecurityDescriptor->Revision);
242 DbgPrint("SecurityDescriptor->Control:\n");
243 SepDumpSdControlInfo(SecurityDescriptor->Control);
244
245 /* Dump the Owner SID if the SD belongs to an owner */
246 if (OwnerSid)
247 {
248 RtlConvertSidToUnicodeString(&SidString, OwnerSid, TRUE);
249 DbgPrint("SD Owner SID -> %wZ\n", &SidString);
250 RtlFreeUnicodeString(&SidString);
251 }
252
253 /* Dump the Group SID if the SD belongs to a group */
254 if (GroupSid)
255 {
256 RtlConvertSidToUnicodeString(&SidString, GroupSid, TRUE);
257 DbgPrint("SD Group SID -> %wZ\n", &SidString);
258 RtlFreeUnicodeString(&SidString);
259 }
260
261 /* Dump the ACL contents of SACL if this SD has one */
262 if (Sacl)
263 {
264 SepDumpAclInfo(Sacl, TRUE);
265 }
266
267 /* Dump the ACL contents of DACL if this SD has one */
268 if (Dacl)
269 {
270 SepDumpAclInfo(Dacl, FALSE);
271 }
272#endif
273}
274
279VOID
282{
283#ifndef NDEBUG
284 UNICODE_STRING SidString;
285#endif
286
287 /* Don't dump anything if no token was provided */
288 if (!Token)
289 {
290 return;
291 }
292
293#ifndef NDEBUG
294 /* Dump relevant token info */
295 DbgPrint("================== ACCESS TOKEN DUMP INFO ==================\n");
296 DbgPrint("Token -> 0x%p\n", Token);
297 DbgPrint("Token->ImageFileName -> %s\n", Token->ImageFileName);
298 DbgPrint("Token->TokenSource.SourceName -> \"%-.*s\"\n",
299 RTL_NUMBER_OF(Token->TokenSource.SourceName),
300 Token->TokenSource.SourceName);
301 DbgPrint("Token->TokenSource.SourceIdentifier -> %lu.%lu\n",
302 Token->TokenSource.SourceIdentifier.HighPart,
303 Token->TokenSource.SourceIdentifier.LowPart);
304
305 RtlConvertSidToUnicodeString(&SidString, Token->PrimaryGroup, TRUE);
306 DbgPrint("Token primary group SID -> %wZ\n", &SidString);
307 RtlFreeUnicodeString(&SidString);
308
309 DbgPrint("Token user and groups SIDs:\n");
310 SepDumpSidsOfToken(Token->UserAndGroups, Token->UserAndGroupCount);
311
313 {
314 DbgPrint("Token restricted SIDs:\n");
315 SepDumpSidsOfToken(Token->RestrictedSids, Token->RestrictedSidCount);
316 }
317#endif
318}
319
324VOID
326 _In_ PACCESS_CHECK_RIGHTS AccessRights)
327{
328 /*
329 * Dump the access rights only if we have remaining rights
330 * to dump in the first place. RemainingAccessRights can be 0
331 * if access check procedure has failed prematurely and this
332 * member hasn't been filled yet.
333 */
334 if (!AccessRights->RemainingAccessRights)
335 {
336 return;
337 }
338
339#ifndef NDEBUG
340 DbgPrint("================== ACCESS CHECK RIGHTS STATISTICS ==================\n");
341 DbgPrint("Remaining access rights -> 0x%08lx\n", AccessRights->RemainingAccessRights);
342 DbgPrint("Granted access rights -> 0x%08lx\n", AccessRights->GrantedAccessRights);
343 DbgPrint("Denied access rights -> 0x%08lx\n", AccessRights->DeniedAccessRights);
344#endif
345}
346
352VOID
354 _In_ PACCESS_MASK GrantedAccessList,
355 _In_ PNTSTATUS AccessStatusList,
356 _In_ BOOLEAN IsResultList,
357 _In_ POBJECT_TYPE_LIST_INTERNAL ObjectTypeList,
358 _In_ ULONG ObjectTypeListLength)
359{
360#ifndef NDEBUG
361 ULONG ResultListIndex;
362 ULONG ObjectTypeIndex;
363 ULONG ResultListLength;
364
365 DbgPrint("================== ACCESS & STATUS OBJECT TYPE LIST STATISTICS ==================\n");
366 ResultListLength = IsResultList ? ObjectTypeListLength : 1;
367 for (ResultListIndex = 0; ResultListIndex < ResultListLength; ResultListIndex++)
368 {
369 DbgPrint("Result Index #%lu, Granted access rights -> 0x%08lx, Access status -> 0x%08lx\n",
370 ResultListIndex, GrantedAccessList[ResultListIndex], AccessStatusList[ResultListIndex]);
371 }
372
373 for (ObjectTypeIndex = 0; ObjectTypeIndex < ObjectTypeListLength; ObjectTypeIndex++)
374 {
375 DbgPrint("================== #%lu OBJECT ACCESS RIGHTS ==================\n", ObjectTypeIndex);
376 DbgPrint("Remaining access rights -> 0x%08lx\n", ObjectTypeList[ObjectTypeIndex].ObjectAccessRights.RemainingAccessRights);
377 DbgPrint("Granted access rights -> 0x%08lx\n", ObjectTypeList[ObjectTypeIndex].ObjectAccessRights.GrantedAccessRights);
378 DbgPrint("Denied access rights -> 0x%08lx\n", ObjectTypeList[ObjectTypeIndex].ObjectAccessRights.DeniedAccessRights);
379 }
380#endif
381}
382
383/* EOF */
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
LONG NTSTATUS
Definition: precomp.h:26
@ Ace
Definition: card.h:12
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const ACEFLAG AceFlags[]
Definition: security.c:2624
static const ACEFLAG AceType[]
Definition: security.c:2583
Status
Definition: gdiplustypes.h:25
#define DbgPrint
Definition: hal.h:12
WORD SECURITY_DESCRIPTOR_CONTROL
Definition: lsa.idl:37
#define ASSERT(a)
Definition: mode.c:44
* PNTSTATUS
Definition: strlen.c:14
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1593
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL Sacl
Definition: rtlfuncs.h:1595
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1133
ACCESS_MASK * PACCESS_MASK
Definition: nt_native.h:41
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI NTSTATUS NTAPI RtlConvertSidToUnicodeString(OUT PUNICODE_STRING DestinationString, IN PVOID Sid, IN BOOLEAN AllocateDestinationString)
FORCEINLINE PSID SepGetOwnerFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:109
FORCEINLINE PSID SepGetGroupFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:89
PSID NTAPI SepGetSidFromAce(_In_ PACE Ace)
Captures a security identifier from a given access control entry. This identifier is valid for the wh...
Definition: sid.c:572
FORCEINLINE PACL SepGetDaclFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:129
FORCEINLINE PACL SepGetSaclFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:151
VOID SepDumpTokenDebugInfo(_In_opt_ PTOKEN Token)
Dumps debug information of an access token to the debugger.
Definition: debug.c:280
VOID SepDumpAccessAndStatusList(_In_ PACCESS_MASK GrantedAccessList, _In_ PNTSTATUS AccessStatusList, _In_ BOOLEAN IsResultList, _In_ POBJECT_TYPE_LIST_INTERNAL ObjectTypeList, _In_ ULONG ObjectTypeListLength)
Dumps access and status values of each object type in the result list.
Definition: debug.c:353
VOID SepDumpAccessRightsStats(_In_ PACCESS_CHECK_RIGHTS AccessRights)
Dumps security access rights to the debugger.
Definition: debug.c:325
VOID SepDumpSdDebugInfo(_In_opt_ PISECURITY_DESCRIPTOR SecurityDescriptor)
Dumps debug information of a security descriptor to the debugger.
Definition: debug.c:217
BOOLEAN NTAPI SeTokenIsRestricted(_In_ PACCESS_TOKEN Token)
Determines if a token is restricted or not, based upon the token flags.
Definition: token.c:2126
Definition: rtltypes.h:993
#define INHERITED_ACE
Definition: ph.h:47
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG
Definition: typedefs.h:59
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
_In_ ULONG AceIndex
Definition: rtlfuncs.h:1862
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:747
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define SE_OWNER_DEFAULTED
Definition: setypes.h:819
#define ACCESS_DENIED_CALLBACK_ACE_TYPE
Definition: setypes.h:733
#define SE_SACL_PROTECTED
Definition: setypes.h:832
#define SE_DACL_DEFAULTED
Definition: setypes.h:822
#define SE_DACL_PROTECTED
Definition: setypes.h:831
#define SE_DACL_AUTO_INHERITED
Definition: setypes.h:829
#define SE_SERVER_SECURITY
Definition: setypes.h:826
#define ACCESS_DENIED_OBJECT_ACE_TYPE
Definition: setypes.h:726
#define SYSTEM_AUDIT_ACE_TYPE
Definition: setypes.h:719
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:717
#define ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE
Definition: setypes.h:734
#define SE_DACL_AUTO_INHERIT_REQ
Definition: setypes.h:827
#define SE_SELF_RELATIVE
Definition: setypes.h:834
#define SE_SACL_DEFAULTED
Definition: setypes.h:824
#define SE_SACL_AUTO_INHERITED
Definition: setypes.h:830
#define SYSTEM_ALARM_CALLBACK_ACE_TYPE
Definition: setypes.h:737
#define SYSTEM_ALARM_ACE_TYPE
Definition: setypes.h:720
#define OBJECT_INHERIT_ACE
Definition: setypes.h:746
#define SE_DACL_UNTRUSTED
Definition: setypes.h:825
#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE
Definition: setypes.h:738
#define NO_PROPAGATE_INHERIT_ACE
Definition: setypes.h:748
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:718
#define SE_SACL_PRESENT
Definition: setypes.h:823
#define SYSTEM_AUDIT_CALLBACK_ACE_TYPE
Definition: setypes.h:736
#define SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE
Definition: setypes.h:739
#define SYSTEM_MANDATORY_LABEL_ACE_TYPE
Definition: setypes.h:741
#define SE_SACL_AUTO_INHERIT_REQ
Definition: setypes.h:828
#define ACCESS_ALLOWED_OBJECT_ACE_TYPE
Definition: setypes.h:725
#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE
Definition: setypes.h:722
#define SE_GROUP_DEFAULTED
Definition: setypes.h:820
#define SYSTEM_ALARM_OBJECT_ACE_TYPE
Definition: setypes.h:728
#define ACCESS_ALLOWED_CALLBACK_ACE_TYPE
Definition: setypes.h:732
#define SE_RM_CONTROL_VALID
Definition: setypes.h:833
#define SYSTEM_AUDIT_OBJECT_ACE_TYPE
Definition: setypes.h:727
#define ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE
Definition: setypes.h:735
#define SE_DACL_PRESENT
Definition: setypes.h:821
unsigned char UCHAR
Definition: xmlstorage.h:181