2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/se/audit.c
5 * PURPOSE: Audit functions
7 * PROGRAMMERS: Eric Kohl
8 * Timo Kreuzer (timo.kreuzer@reactos.org)
11 /* INCLUDES *******************************************************************/
17 #define SEP_PRIVILEGE_SET_MAX_COUNT 60
19 /* PRIVATE FUNCTIONS***********************************************************/
23 SeDetailedAuditingWithToken(IN PTOKEN Token
)
31 SeAuditProcessCreate(IN PEPROCESS Process
)
38 SeAuditProcessExit(IN PEPROCESS Process
)
45 SeInitializeProcessAuditName(IN PFILE_OBJECT FileObject
,
47 OUT POBJECT_NAME_INFORMATION
*AuditInfo
)
49 OBJECT_NAME_INFORMATION LocalNameInfo
;
50 POBJECT_NAME_INFORMATION ObjectNameInfo
= NULL
;
51 ULONG ReturnLength
= 8;
57 /* Check if we should do auditing */
63 /* Now query the name */
64 Status
= ObQueryNameString(FileObject
,
66 sizeof(LocalNameInfo
),
68 if (((Status
== STATUS_BUFFER_OVERFLOW
) ||
69 (Status
== STATUS_BUFFER_TOO_SMALL
) ||
70 (Status
== STATUS_INFO_LENGTH_MISMATCH
)) &&
71 (ReturnLength
!= sizeof(LocalNameInfo
)))
73 /* Allocate required size */
74 ObjectNameInfo
= ExAllocatePoolWithTag(NonPagedPool
,
79 /* Query the name again */
80 Status
= ObQueryNameString(FileObject
,
87 /* Check if we got here due to failure */
88 if ((ObjectNameInfo
) &&
89 (!(NT_SUCCESS(Status
)) || (ReturnLength
== sizeof(LocalNameInfo
))))
91 /* First, free any buffer we might've allocated */
93 if (ObjectNameInfo
) ExFreePool(ObjectNameInfo
);
95 /* Now allocate a temporary one */
96 ReturnLength
= sizeof(OBJECT_NAME_INFORMATION
);
97 ObjectNameInfo
= ExAllocatePoolWithTag(NonPagedPool
,
98 sizeof(OBJECT_NAME_INFORMATION
),
103 RtlZeroMemory(ObjectNameInfo
, ReturnLength
);
104 Status
= STATUS_SUCCESS
;
108 /* Check if memory allocation failed */
109 if (!ObjectNameInfo
) Status
= STATUS_NO_MEMORY
;
111 /* Return the audit name */
112 *AuditInfo
= ObjectNameInfo
;
120 SeLocateProcessImageName(IN PEPROCESS Process
,
121 OUT PUNICODE_STRING
*ProcessImageName
)
123 POBJECT_NAME_INFORMATION AuditName
;
124 PUNICODE_STRING ImageName
;
125 PFILE_OBJECT FileObject
;
126 NTSTATUS Status
= STATUS_SUCCESS
;
131 *ProcessImageName
= NULL
;
133 /* Check if we have audit info */
134 AuditName
= Process
->SeAuditProcessCreationInfo
.ImageFileName
;
137 /* Get the file object */
138 Status
= PsReferenceProcessFilePointer(Process
, &FileObject
);
139 if (!NT_SUCCESS(Status
)) return Status
;
141 /* Initialize the audit structure */
142 Status
= SeInitializeProcessAuditName(FileObject
, TRUE
, &AuditName
);
143 if (NT_SUCCESS(Status
))
146 if (InterlockedCompareExchangePointer((PVOID
*)&Process
->
147 SeAuditProcessCreationInfo
.ImageFileName
,
151 /* Someone beat us to it, deallocate our copy */
152 ExFreePool(AuditName
);
156 /* Dereference the file object */
157 ObDereferenceObject(FileObject
);
158 if (!NT_SUCCESS(Status
)) return Status
;
161 /* Get audit info again, now we have it for sure */
162 AuditName
= Process
->SeAuditProcessCreationInfo
.ImageFileName
;
164 /* Allocate the output string */
165 ImageName
= ExAllocatePoolWithTag(NonPagedPool
,
166 AuditName
->Name
.MaximumLength
+
167 sizeof(UNICODE_STRING
),
169 if (!ImageName
) return STATUS_NO_MEMORY
;
171 /* Make a copy of it */
172 RtlCopyMemory(ImageName
,
174 AuditName
->Name
.MaximumLength
+ sizeof(UNICODE_STRING
));
176 /* Fix up the buffer */
177 ImageName
->Buffer
= (PWSTR
)(ImageName
+ 1);
180 *ProcessImageName
= ImageName
;
188 SepAdtCloseObjectAuditAlarm(
189 PUNICODE_STRING SubsystemName
,
198 SepAdtPrivilegedServiceAuditAlarm(
199 PSECURITY_SUBJECT_CONTEXT SubjectContext
,
200 _In_opt_ PUNICODE_STRING SubsystemName
,
201 _In_opt_ PUNICODE_STRING ServiceName
,
203 _In_ PTOKEN PrimaryToken
,
204 _In_ PPRIVILEGE_SET Privileges
,
205 _In_ BOOLEAN AccessGranted
)
212 SeCaptureObjectTypeList(
213 _In_reads_opt_(ObjectTypeListLength
) POBJECT_TYPE_LIST ObjectTypeList
,
214 _In_ ULONG ObjectTypeListLength
,
215 _In_ KPROCESSOR_MODE PreviousMode
,
216 _Out_ POBJECT_TYPE_LIST
*CapturedObjectTypeList
)
220 if (PreviousMode
== KernelMode
)
222 return STATUS_NOT_IMPLEMENTED
;
225 if (ObjectTypeListLength
== 0)
227 *CapturedObjectTypeList
= NULL
;
228 return STATUS_SUCCESS
;
231 if (ObjectTypeList
== NULL
)
233 return STATUS_INVALID_PARAMETER
;
236 /* Calculate the list size and check for integer overflow */
237 Size
= ObjectTypeListLength
* sizeof(OBJECT_TYPE_LIST
);
240 return STATUS_INVALID_PARAMETER
;
243 /* Allocate a new list */
244 *CapturedObjectTypeList
= ExAllocatePoolWithTag(PagedPool
, Size
, TAG_SEPA
);
245 if (*CapturedObjectTypeList
== NULL
)
247 return STATUS_INSUFFICIENT_RESOURCES
;
252 ProbeForRead(ObjectTypeList
, Size
, sizeof(ULONG
));
253 RtlCopyMemory(*CapturedObjectTypeList
, ObjectTypeList
, Size
);
255 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
257 ExFreePoolWithTag(*CapturedObjectTypeList
, TAG_SEPA
);
258 *CapturedObjectTypeList
= NULL
;
259 return _SEH2_GetExceptionCode();
263 return STATUS_SUCCESS
;
268 SeReleaseObjectTypeList(
269 _In_ _Post_invalid_ POBJECT_TYPE_LIST CapturedObjectTypeList
,
270 _In_ KPROCESSOR_MODE PreviousMode
)
272 if ((PreviousMode
!= KernelMode
) && (CapturedObjectTypeList
!= NULL
))
273 ExFreePoolWithTag(CapturedObjectTypeList
, TAG_SEPA
);
276 _Must_inspect_result_
279 SepAccessCheckAndAuditAlarmWorker(
280 _In_ PUNICODE_STRING SubsystemName
,
281 _In_opt_ PVOID HandleId
,
282 _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext
,
283 _In_ PUNICODE_STRING ObjectTypeName
,
284 _In_ PUNICODE_STRING ObjectName
,
285 _In_ PSECURITY_DESCRIPTOR SecurityDescriptor
,
286 _In_opt_ PSID PrincipalSelfSid
,
287 _In_ ACCESS_MASK DesiredAccess
,
288 _In_ AUDIT_EVENT_TYPE AuditType
,
289 _In_ BOOLEAN HaveAuditPrivilege
,
290 _In_reads_opt_(ObjectTypeListLength
) POBJECT_TYPE_LIST ObjectTypeList
,
291 _In_ ULONG ObjectTypeListLength
,
292 _In_ PGENERIC_MAPPING GenericMapping
,
293 _Out_writes_(ObjectTypeListLength
) PACCESS_MASK GrantedAccessList
,
294 _Out_writes_(ObjectTypeListLength
) PNTSTATUS AccessStatusList
,
295 _Out_ PBOOLEAN GenerateOnClose
,
296 _In_ BOOLEAN UseResultList
)
298 ULONG ResultListLength
, i
;
300 /* Get the length of the result list */
301 ResultListLength
= UseResultList
? ObjectTypeListLength
: 1;
303 /// FIXME: we should do some real work here...
306 /// HACK: we just pretend all access is granted!
307 for (i
= 0; i
< ResultListLength
; i
++)
309 GrantedAccessList
[i
] = DesiredAccess
;
310 AccessStatusList
[i
] = STATUS_SUCCESS
;
313 *GenerateOnClose
= FALSE
;
315 return STATUS_SUCCESS
;
318 _Must_inspect_result_
321 SepAccessCheckAndAuditAlarm(
322 _In_ PUNICODE_STRING SubsystemName
,
323 _In_opt_ PVOID HandleId
,
324 _In_ PHANDLE ClientTokenHandle
,
325 _In_ PUNICODE_STRING ObjectTypeName
,
326 _In_ PUNICODE_STRING ObjectName
,
327 _In_ PSECURITY_DESCRIPTOR SecurityDescriptor
,
328 _In_opt_ PSID PrincipalSelfSid
,
329 _In_ ACCESS_MASK DesiredAccess
,
330 _In_ AUDIT_EVENT_TYPE AuditType
,
332 _In_reads_opt_(ObjectTypeListLength
) POBJECT_TYPE_LIST ObjectTypeList
,
333 _In_ ULONG ObjectTypeListLength
,
334 _In_ PGENERIC_MAPPING GenericMapping
,
335 _Out_writes_(ObjectTypeListLength
) PACCESS_MASK GrantedAccessList
,
336 _Out_writes_(ObjectTypeListLength
) PNTSTATUS AccessStatusList
,
337 _Out_ PBOOLEAN GenerateOnClose
,
338 _In_ BOOLEAN UseResultList
)
340 SECURITY_SUBJECT_CONTEXT SubjectContext
;
341 ULONG ResultListLength
;
342 GENERIC_MAPPING LocalGenericMapping
;
343 PTOKEN SubjectContextToken
, ClientToken
;
344 BOOLEAN AllocatedResultLists
;
345 BOOLEAN HaveAuditPrivilege
;
346 PSECURITY_DESCRIPTOR CapturedSecurityDescriptor
;
347 UNICODE_STRING CapturedSubsystemName
, CapturedObjectTypeName
, CapturedObjectName
;
348 ACCESS_MASK GrantedAccess
, *SafeGrantedAccessList
;
349 NTSTATUS AccessStatus
, *SafeAccessStatusList
;
350 PSID CapturedPrincipalSelfSid
;
351 POBJECT_TYPE_LIST CapturedObjectTypeList
;
353 BOOLEAN LocalGenerateOnClose
;
357 /* Only user mode is supported! */
358 ASSERT(ExGetPreviousMode() != KernelMode
);
361 AllocatedResultLists
= FALSE
;
363 CapturedSecurityDescriptor
= NULL
;
364 CapturedSubsystemName
.Buffer
= NULL
;
365 CapturedObjectTypeName
.Buffer
= NULL
;
366 CapturedObjectName
.Buffer
= NULL
;
367 CapturedPrincipalSelfSid
= NULL
;
368 CapturedObjectTypeList
= NULL
;
370 /* Validate AuditType */
371 if ((AuditType
!= AuditEventObjectAccess
) &&
372 (AuditType
!= AuditEventDirectoryServiceAccess
))
374 DPRINT1("Invalid audit type: %u\n", AuditType
);
375 return STATUS_INVALID_PARAMETER
;
378 /* Capture the security subject context */
379 SeCaptureSubjectContext(&SubjectContext
);
381 /* Did the caller pass a token handle? */
382 if (ClientTokenHandle
== NULL
)
384 /* Check if we have a token in the subject context */
385 if (SubjectContext
.ClientToken
== NULL
)
387 Status
= STATUS_NO_IMPERSONATION_TOKEN
;
388 DPRINT1("No token\n");
392 /* Check if we have a valid impersonation level */
393 if (SubjectContext
.ImpersonationLevel
< SecurityIdentification
)
395 Status
= STATUS_BAD_IMPERSONATION_LEVEL
;
396 DPRINT1("Invalid impersonation level 0x%lx\n",
397 SubjectContext
.ImpersonationLevel
);
402 /* Are we using a result list? */
405 /* The list length equals the object type list length */
406 ResultListLength
= ObjectTypeListLength
;
407 if ((ResultListLength
== 0) || (ResultListLength
> 0x1000))
409 Status
= STATUS_INVALID_PARAMETER
;
410 DPRINT1("Invalud ResultListLength: 0x%lx\n", ResultListLength
);
414 /* Allocate a safe buffer from paged pool */
415 SafeGrantedAccessList
= ExAllocatePoolWithTag(PagedPool
,
416 2 * ResultListLength
* sizeof(ULONG
),
418 if (SafeGrantedAccessList
== NULL
)
420 Status
= STATUS_INSUFFICIENT_RESOURCES
;
421 DPRINT1("Failed to allocate access lists\n");
425 SafeAccessStatusList
= (PNTSTATUS
)&SafeGrantedAccessList
[ResultListLength
];
426 AllocatedResultLists
= TRUE
;
430 /* List length is 1 */
431 ResultListLength
= 1;
432 SafeGrantedAccessList
= &GrantedAccess
;
433 SafeAccessStatusList
= &AccessStatus
;
438 /* Probe output buffers */
439 ProbeForWrite(AccessStatusList
,
440 ResultListLength
* sizeof(*AccessStatusList
),
441 sizeof(*AccessStatusList
));
442 ProbeForWrite(GrantedAccessList
,
443 ResultListLength
* sizeof(*GrantedAccessList
),
444 sizeof(*GrantedAccessList
));
446 /* Probe generic mapping and make a local copy */
447 ProbeForRead(GenericMapping
, sizeof(*GenericMapping
), sizeof(ULONG
));
448 LocalGenericMapping
= * GenericMapping
;
450 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
452 Status
= _SEH2_GetExceptionCode();
453 DPRINT1("Exception while probing parameters: 0x%lx\n", Status
);
458 /* Do we have a client token? */
459 if (ClientTokenHandle
!= NULL
)
461 /* Reference the client token */
462 Status
= ObReferenceObjectByHandle(*ClientTokenHandle
,
466 (PVOID
*)&ClientToken
,
468 if (!NT_SUCCESS(Status
))
470 DPRINT1("Failed to reference token handle %p: %lx\n",
471 *ClientTokenHandle
, Status
);
475 SubjectContextToken
= SubjectContext
.ClientToken
;
476 SubjectContext
.ClientToken
= ClientToken
;
479 /* Check for audit privilege */
480 HaveAuditPrivilege
= SeSinglePrivilegeCheck(SeAuditPrivilege
, UserMode
);
481 if (!HaveAuditPrivilege
&& !(Flags
& AUDIT_ALLOW_NO_PRIVILEGE
))
483 DPRINT1("Caller does not have SeAuditPrivilege\n");
484 Status
= STATUS_PRIVILEGE_NOT_HELD
;
488 /* Generic access must already be mapped to non-generic access types! */
489 if (DesiredAccess
& (GENERIC_READ
| GENERIC_WRITE
| GENERIC_EXECUTE
| GENERIC_ALL
))
491 DPRINT1("Generic access rights requested: 0x%lx\n", DesiredAccess
);
492 Status
= STATUS_GENERIC_NOT_MAPPED
;
496 /* Capture the security descriptor */
497 Status
= SeCaptureSecurityDescriptor(SecurityDescriptor
,
501 &CapturedSecurityDescriptor
);
502 if (!NT_SUCCESS(Status
))
504 DPRINT1("Failed to capture security descriptor!\n");
508 /* Validate the Security descriptor */
509 if ((SepGetOwnerFromDescriptor(CapturedSecurityDescriptor
) == NULL
) ||
510 (SepGetGroupFromDescriptor(CapturedSecurityDescriptor
) == NULL
))
512 Status
= STATUS_INVALID_SECURITY_DESCR
;
513 DPRINT1("Invalid security descriptor\n");
517 /* Probe and capture the subsystem name */
518 Status
= ProbeAndCaptureUnicodeString(&CapturedSubsystemName
,
521 if (!NT_SUCCESS(Status
))
523 DPRINT1("Failed to capture subsystem name!\n");
527 /* Probe and capture the object type name */
528 Status
= ProbeAndCaptureUnicodeString(&CapturedObjectTypeName
,
531 if (!NT_SUCCESS(Status
))
533 DPRINT1("Failed to capture object type name!\n");
537 /* Probe and capture the object name */
538 Status
= ProbeAndCaptureUnicodeString(&CapturedObjectName
,
541 if (!NT_SUCCESS(Status
))
543 DPRINT1("Failed to capture object name!\n");
547 /* Check if we have a PrincipalSelfSid */
548 if (PrincipalSelfSid
!= NULL
)
551 Status
= SepCaptureSid(PrincipalSelfSid
,
555 &CapturedPrincipalSelfSid
);
556 if (!NT_SUCCESS(Status
))
558 DPRINT1("Failed to capture PrincipalSelfSid!\n");
563 /* Capture the object type list */
564 Status
= SeCaptureObjectTypeList(ObjectTypeList
,
565 ObjectTypeListLength
,
567 &CapturedObjectTypeList
);
568 if (!NT_SUCCESS(Status
))
570 DPRINT1("Failed to capture object type list!\n");
574 /* Call the worker routine with the captured buffers */
575 SepAccessCheckAndAuditAlarmWorker(&CapturedSubsystemName
,
578 &CapturedObjectTypeName
,
580 CapturedSecurityDescriptor
,
581 CapturedPrincipalSelfSid
,
585 CapturedObjectTypeList
,
586 ObjectTypeListLength
,
587 &LocalGenericMapping
,
588 SafeGrantedAccessList
,
589 SafeAccessStatusList
,
590 &LocalGenerateOnClose
,
593 /* Enter SEH to copy the data back to user mode */
596 /* Loop all result entries (only 1 when no list was requested) */
597 NT_ASSERT(UseResultList
|| (ResultListLength
== 1));
598 for (i
= 0; i
< ResultListLength
; i
++)
600 AccessStatusList
[i
] = SafeAccessStatusList
[i
];
601 GrantedAccessList
[i
] = SafeGrantedAccessList
[i
];
604 *GenerateOnClose
= LocalGenerateOnClose
;
606 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
608 Status
= _SEH2_GetExceptionCode();
609 DPRINT1("Exception while copying back data: 0x%lx\n", Status
);
615 if (CapturedObjectTypeList
!= NULL
)
616 SeReleaseObjectTypeList(CapturedObjectTypeList
, UserMode
);
618 if (CapturedPrincipalSelfSid
!= NULL
)
619 SepReleaseSid(CapturedPrincipalSelfSid
, UserMode
, FALSE
);
621 if (CapturedObjectName
.Buffer
!= NULL
)
622 ReleaseCapturedUnicodeString(&CapturedObjectName
, UserMode
);
624 if (CapturedObjectTypeName
.Buffer
!= NULL
)
625 ReleaseCapturedUnicodeString(&CapturedObjectTypeName
, UserMode
);
627 if (CapturedSubsystemName
.Buffer
!= NULL
)
628 ReleaseCapturedUnicodeString(&CapturedSubsystemName
, UserMode
);
630 if (CapturedSecurityDescriptor
!= NULL
)
631 SeReleaseSecurityDescriptor(CapturedSecurityDescriptor
, UserMode
, FALSE
);
633 if (ClientToken
!= NULL
)
635 ObDereferenceObject(ClientToken
);
636 SubjectContext
.ClientToken
= SubjectContextToken
;
639 if (AllocatedResultLists
)
640 ExFreePoolWithTag(SafeGrantedAccessList
, TAG_SEPA
);
642 /* Release the security subject context */
643 SeReleaseSubjectContext(&SubjectContext
);
649 /* PUBLIC FUNCTIONS ***********************************************************/
656 SeAuditHardLinkCreation(IN PUNICODE_STRING FileName
,
657 IN PUNICODE_STRING LinkName
,
668 SeAuditingFileEvents(IN BOOLEAN AccessGranted
,
669 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
680 SeAuditingFileEventsWithContext(IN BOOLEAN AccessGranted
,
681 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
682 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL
)
693 SeAuditingHardLinkEvents(IN BOOLEAN AccessGranted
,
694 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
705 SeAuditingHardLinkEventsWithContext(IN BOOLEAN AccessGranted
,
706 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
707 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext OPTIONAL
)
718 SeAuditingFileOrGlobalEvents(IN BOOLEAN AccessGranted
,
719 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
720 IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext
)
731 SeCloseObjectAuditAlarm(IN PVOID Object
,
733 IN BOOLEAN PerformAction
)
742 SeDeleteObjectAuditAlarm(IN PVOID Object
,
753 SeOpenObjectAuditAlarm(IN PUNICODE_STRING ObjectTypeName
,
754 IN PVOID Object OPTIONAL
,
755 IN PUNICODE_STRING AbsoluteObjectName OPTIONAL
,
756 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
757 IN PACCESS_STATE AccessState
,
758 IN BOOLEAN ObjectCreated
,
759 IN BOOLEAN AccessGranted
,
760 IN KPROCESSOR_MODE AccessMode
,
761 OUT PBOOLEAN GenerateOnClose
)
765 /* Audits aren't done on kernel-mode access */
766 if (AccessMode
== KernelMode
) return;
768 /* Otherwise, unimplemented! */
777 SeOpenObjectForDeleteAuditAlarm(IN PUNICODE_STRING ObjectTypeName
,
778 IN PVOID Object OPTIONAL
,
779 IN PUNICODE_STRING AbsoluteObjectName OPTIONAL
,
780 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
781 IN PACCESS_STATE AccessState
,
782 IN BOOLEAN ObjectCreated
,
783 IN BOOLEAN AccessGranted
,
784 IN KPROCESSOR_MODE AccessMode
,
785 OUT PBOOLEAN GenerateOnClose
)
795 SePrivilegeObjectAuditAlarm(IN HANDLE Handle
,
796 IN PSECURITY_SUBJECT_CONTEXT SubjectContext
,
797 IN ACCESS_MASK DesiredAccess
,
798 IN PPRIVILEGE_SET Privileges
,
799 IN BOOLEAN AccessGranted
,
800 IN KPROCESSOR_MODE CurrentMode
)
805 /* SYSTEM CALLS ***************************************************************/
809 NtCloseObjectAuditAlarm(
810 PUNICODE_STRING SubsystemName
,
812 BOOLEAN GenerateOnClose
)
814 UNICODE_STRING CapturedSubsystemName
;
815 KPROCESSOR_MODE PreviousMode
;
816 BOOLEAN UseImpersonationToken
;
817 PETHREAD CurrentThread
;
818 BOOLEAN CopyOnOpen
, EffectiveOnly
;
819 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
;
824 /* Get the previous mode (only user mode is supported!) */
825 PreviousMode
= ExGetPreviousMode();
826 ASSERT(PreviousMode
!= KernelMode
);
828 /* Do we even need to do anything? */
829 if (!GenerateOnClose
)
831 /* Nothing to do, return success */
832 return STATUS_SUCCESS
;
835 /* Validate privilege */
836 if (!SeSinglePrivilegeCheck(SeAuditPrivilege
, PreviousMode
))
838 DPRINT1("Caller does not have SeAuditPrivilege\n");
839 return STATUS_PRIVILEGE_NOT_HELD
;
842 /* Probe and capture the subsystem name */
843 Status
= ProbeAndCaptureUnicodeString(&CapturedSubsystemName
,
846 if (!NT_SUCCESS(Status
))
848 DPRINT1("Failed to capture subsystem name!\n");
852 /* Get the current thread and check if it's impersonating */
853 CurrentThread
= PsGetCurrentThread();
854 if (PsIsThreadImpersonating(CurrentThread
))
856 /* Get the impersonation token */
857 Token
= PsReferenceImpersonationToken(CurrentThread
,
860 &ImpersonationLevel
);
861 UseImpersonationToken
= TRUE
;
865 /* Get the primary token */
866 Token
= PsReferencePrimaryToken(PsGetCurrentProcess());
867 UseImpersonationToken
= FALSE
;
870 /* Call the internal function */
871 SepAdtCloseObjectAuditAlarm(&CapturedSubsystemName
,
873 Token
->UserAndGroups
->Sid
);
875 /* Release the captured subsystem name */
876 ReleaseCapturedUnicodeString(&CapturedSubsystemName
, PreviousMode
);
878 /* Check what token we used */
879 if (UseImpersonationToken
)
881 /* Release impersonation token */
882 PsDereferenceImpersonationToken(Token
);
886 /* Release primary token */
887 PsDereferencePrimaryToken(Token
);
890 return STATUS_SUCCESS
;
895 NtDeleteObjectAuditAlarm(IN PUNICODE_STRING SubsystemName
,
897 IN BOOLEAN GenerateOnClose
)
900 return STATUS_NOT_IMPLEMENTED
;
905 NtOpenObjectAuditAlarm(IN PUNICODE_STRING SubsystemName
,
907 IN PUNICODE_STRING ObjectTypeName
,
908 IN PUNICODE_STRING ObjectName
,
909 IN PSECURITY_DESCRIPTOR SecurityDescriptor
,
910 IN HANDLE ClientToken
,
911 IN ULONG DesiredAccess
,
912 IN ULONG GrantedAccess
,
913 IN PPRIVILEGE_SET Privileges
,
914 IN BOOLEAN ObjectCreation
,
915 IN BOOLEAN AccessGranted
,
916 OUT PBOOLEAN GenerateOnClose
)
919 return STATUS_NOT_IMPLEMENTED
;
926 NtPrivilegedServiceAuditAlarm(
927 _In_opt_ PUNICODE_STRING SubsystemName
,
928 _In_opt_ PUNICODE_STRING ServiceName
,
929 _In_ HANDLE ClientToken
,
930 _In_ PPRIVILEGE_SET Privileges
,
931 _In_ BOOLEAN AccessGranted
)
933 KPROCESSOR_MODE PreviousMode
;
935 volatile PPRIVILEGE_SET CapturedPrivileges
= NULL
;
936 UNICODE_STRING CapturedSubsystemName
;
937 UNICODE_STRING CapturedServiceName
;
938 ULONG PrivilegeCount
, PrivilegesSize
;
939 SECURITY_SUBJECT_CONTEXT SubjectContext
;
943 /* Get the previous mode (only user mode is supported!) */
944 PreviousMode
= ExGetPreviousMode();
945 ASSERT(PreviousMode
!= KernelMode
);
947 CapturedSubsystemName
.Buffer
= NULL
;
948 CapturedServiceName
.Buffer
= NULL
;
950 /* Reference the client token */
951 Status
= ObReferenceObjectByHandle(ClientToken
,
957 if (!NT_SUCCESS(Status
))
959 DPRINT1("Failed to reference client token: 0x%lx\n", Status
);
963 /* Validate the token's impersonation level */
964 if ((Token
->TokenType
== TokenImpersonation
) &&
965 (Token
->ImpersonationLevel
< SecurityIdentification
))
967 DPRINT1("Invalid impersonation level (%u)\n", Token
->ImpersonationLevel
);
968 ObfDereferenceObject(Token
);
969 return STATUS_BAD_IMPERSONATION_LEVEL
;
972 /* Validate privilege */
973 if (!SeSinglePrivilegeCheck(SeAuditPrivilege
, PreviousMode
))
975 DPRINT1("Caller does not have SeAuditPrivilege\n");
976 ObfDereferenceObject(Token
);
977 return STATUS_PRIVILEGE_NOT_HELD
;
980 /* Do we have a subsystem name? */
981 if (SubsystemName
!= NULL
)
983 /* Probe and capture the subsystem name */
984 Status
= ProbeAndCaptureUnicodeString(&CapturedSubsystemName
,
987 if (!NT_SUCCESS(Status
))
989 DPRINT1("Failed to capture subsystem name!\n");
994 /* Do we have a service name? */
995 if (ServiceName
!= NULL
)
997 /* Probe and capture the service name */
998 Status
= ProbeAndCaptureUnicodeString(&CapturedServiceName
,
1001 if (!NT_SUCCESS(Status
))
1003 DPRINT1("Failed to capture service name!\n");
1010 /* Probe the basic privilege set structure */
1011 ProbeForRead(Privileges
, sizeof(PRIVILEGE_SET
), sizeof(ULONG
));
1013 /* Validate privilege count */
1014 PrivilegeCount
= Privileges
->PrivilegeCount
;
1015 if (PrivilegeCount
> SEP_PRIVILEGE_SET_MAX_COUNT
)
1017 Status
= STATUS_INVALID_PARAMETER
;
1021 /* Calculate the size of the Privileges structure */
1022 PrivilegesSize
= FIELD_OFFSET(PRIVILEGE_SET
, Privilege
[PrivilegeCount
]);
1024 /* Probe the whole structure */
1025 ProbeForRead(Privileges
, PrivilegesSize
, sizeof(ULONG
));
1027 /* Allocate a temp buffer */
1028 CapturedPrivileges
= ExAllocatePoolWithTag(PagedPool
,
1031 if (CapturedPrivileges
== NULL
)
1033 DPRINT1("Failed to allocate %u bytes\n", PrivilegesSize
);
1034 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1038 /* Copy the privileges */
1039 RtlCopyMemory(CapturedPrivileges
, Privileges
, PrivilegesSize
);
1041 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1043 Status
= _SEH2_GetExceptionCode();
1044 DPRINT1("Got exception 0x%lx\n", Status
);
1049 /* Capture the security subject context */
1050 SeCaptureSubjectContext(&SubjectContext
);
1052 /* Call the internal function */
1053 SepAdtPrivilegedServiceAuditAlarm(&SubjectContext
,
1054 SubsystemName
? &CapturedSubsystemName
: NULL
,
1055 ServiceName
? &CapturedServiceName
: NULL
,
1057 SubjectContext
.PrimaryToken
,
1061 /* Release the security subject context */
1062 SeReleaseSubjectContext(&SubjectContext
);
1064 Status
= STATUS_SUCCESS
;
1067 /* Cleanup resources */
1068 if (CapturedSubsystemName
.Buffer
!= NULL
)
1069 ReleaseCapturedUnicodeString(&CapturedSubsystemName
, PreviousMode
);
1070 if (CapturedServiceName
.Buffer
!= NULL
)
1071 ReleaseCapturedUnicodeString(&CapturedServiceName
, PreviousMode
);
1072 if (CapturedPrivileges
!= NULL
)
1073 ExFreePoolWithTag(CapturedPrivileges
, 0);
1074 ObDereferenceObject(Token
);
1081 NtPrivilegeObjectAuditAlarm(IN PUNICODE_STRING SubsystemName
,
1083 IN HANDLE ClientToken
,
1084 IN ULONG DesiredAccess
,
1085 IN PPRIVILEGE_SET Privileges
,
1086 IN BOOLEAN AccessGranted
)
1089 return STATUS_NOT_IMPLEMENTED
;
1093 _Must_inspect_result_
1097 NtAccessCheckAndAuditAlarm(
1098 _In_ PUNICODE_STRING SubsystemName
,
1099 _In_opt_ PVOID HandleId
,
1100 _In_ PUNICODE_STRING ObjectTypeName
,
1101 _In_ PUNICODE_STRING ObjectName
,
1102 _In_ PSECURITY_DESCRIPTOR SecurityDescriptor
,
1103 _In_ ACCESS_MASK DesiredAccess
,
1104 _In_ PGENERIC_MAPPING GenericMapping
,
1105 _In_ BOOLEAN ObjectCreation
,
1106 _Out_ PACCESS_MASK GrantedAccess
,
1107 _Out_ PNTSTATUS AccessStatus
,
1108 _Out_ PBOOLEAN GenerateOnClose
)
1110 /* Call the internal function */
1111 return SepAccessCheckAndAuditAlarm(SubsystemName
,
1119 AuditEventObjectAccess
,
1130 _Must_inspect_result_
1134 NtAccessCheckByTypeAndAuditAlarm(
1135 _In_ PUNICODE_STRING SubsystemName
,
1136 _In_opt_ PVOID HandleId
,
1137 _In_ PUNICODE_STRING ObjectTypeName
,
1138 _In_ PUNICODE_STRING ObjectName
,
1139 _In_ PSECURITY_DESCRIPTOR SecurityDescriptor
,
1140 _In_opt_ PSID PrincipalSelfSid
,
1141 _In_ ACCESS_MASK DesiredAccess
,
1142 _In_ AUDIT_EVENT_TYPE AuditType
,
1144 _In_reads_opt_(ObjectTypeLength
) POBJECT_TYPE_LIST ObjectTypeList
,
1145 _In_ ULONG ObjectTypeLength
,
1146 _In_ PGENERIC_MAPPING GenericMapping
,
1147 _In_ BOOLEAN ObjectCreation
,
1148 _Out_ PACCESS_MASK GrantedAccess
,
1149 _Out_ PNTSTATUS AccessStatus
,
1150 _Out_ PBOOLEAN GenerateOnClose
)
1152 /* Call the internal function */
1153 return SepAccessCheckAndAuditAlarm(SubsystemName
,
1172 _Must_inspect_result_
1176 NtAccessCheckByTypeResultListAndAuditAlarm(
1177 _In_ PUNICODE_STRING SubsystemName
,
1178 _In_opt_ PVOID HandleId
,
1179 _In_ PUNICODE_STRING ObjectTypeName
,
1180 _In_ PUNICODE_STRING ObjectName
,
1181 _In_ PSECURITY_DESCRIPTOR SecurityDescriptor
,
1182 _In_opt_ PSID PrincipalSelfSid
,
1183 _In_ ACCESS_MASK DesiredAccess
,
1184 _In_ AUDIT_EVENT_TYPE AuditType
,
1186 _In_reads_opt_(ObjectTypeListLength
) POBJECT_TYPE_LIST ObjectTypeList
,
1187 _In_ ULONG ObjectTypeListLength
,
1188 _In_ PGENERIC_MAPPING GenericMapping
,
1189 _In_ BOOLEAN ObjectCreation
,
1190 _Out_writes_(ObjectTypeListLength
) PACCESS_MASK GrantedAccessList
,
1191 _Out_writes_(ObjectTypeListLength
) PNTSTATUS AccessStatusList
,
1192 _Out_ PBOOLEAN GenerateOnClose
)
1194 /* Call the internal function */
1195 return SepAccessCheckAndAuditAlarm(SubsystemName
,
1206 ObjectTypeListLength
,
1214 _Must_inspect_result_
1218 NtAccessCheckByTypeResultListAndAuditAlarmByHandle(
1219 _In_ PUNICODE_STRING SubsystemName
,
1220 _In_opt_ PVOID HandleId
,
1221 _In_ HANDLE ClientToken
,
1222 _In_ PUNICODE_STRING ObjectTypeName
,
1223 _In_ PUNICODE_STRING ObjectName
,
1224 _In_ PSECURITY_DESCRIPTOR SecurityDescriptor
,
1225 _In_opt_ PSID PrincipalSelfSid
,
1226 _In_ ACCESS_MASK DesiredAccess
,
1227 _In_ AUDIT_EVENT_TYPE AuditType
,
1229 _In_reads_opt_(ObjectTypeListLength
) POBJECT_TYPE_LIST ObjectTypeList
,
1230 _In_ ULONG ObjectTypeListLength
,
1231 _In_ PGENERIC_MAPPING GenericMapping
,
1232 _In_ BOOLEAN ObjectCreation
,
1233 _Out_writes_(ObjectTypeListLength
) PACCESS_MASK GrantedAccessList
,
1234 _Out_writes_(ObjectTypeListLength
) PNTSTATUS AccessStatusList
,
1235 _Out_ PBOOLEAN GenerateOnClose
)
1237 UNREFERENCED_PARAMETER(ObjectCreation
);
1239 /* Call the internal function */
1240 return SepAccessCheckAndAuditAlarm(SubsystemName
,
1251 ObjectTypeListLength
,