diff --git a/reactos/include/ndk/psfuncs.h b/reactos/include/ndk/psfuncs.h index 3629a1ff30d..253c2764271 100644 --- a/reactos/include/ndk/psfuncs.h +++ b/reactos/include/ndk/psfuncs.h @@ -149,6 +149,13 @@ PsGetCurrentProcessSessionId( // // Process Impersonation Functions // +NTKERNELAPI +BOOLEAN +NTAPI +PsIsThreadImpersonating( + _In_ PETHREAD Thread +); + NTKERNELAPI VOID NTAPI diff --git a/reactos/ntoskrnl/se/audit.c b/reactos/ntoskrnl/se/audit.c index 92b87fa8377..c649afb1a97 100644 --- a/reactos/ntoskrnl/se/audit.c +++ b/reactos/ntoskrnl/se/audit.c @@ -336,6 +336,16 @@ SePrivilegeObjectAuditAlarm(IN HANDLE Handle, UNIMPLEMENTED; } +VOID +NTAPI +SepAdtCloseObjectAuditAlarm( + PUNICODE_STRING SubsystemName, + PVOID HandleId, + PSID Sid) +{ + UNIMPLEMENTED; +} + /* SYSTEM CALLS ***************************************************************/ NTSTATUS @@ -357,13 +367,90 @@ NtAccessCheckAndAuditAlarm(IN PUNICODE_STRING SubsystemName, } -NTSTATUS NTAPI -NtCloseObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN PVOID HandleId, - IN BOOLEAN GenerateOnClose) +NTSTATUS +NTAPI +NtCloseObjectAuditAlarm( + PUNICODE_STRING SubsystemName, + PVOID HandleId, + BOOLEAN GenerateOnClose) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + UNICODE_STRING CapturedSubsystemName; + KPROCESSOR_MODE PreviousMode; + BOOLEAN UseImpersonationToken; + PETHREAD CurrentThread; + BOOLEAN CopyOnOpen, EffectiveOnly; + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; + NTSTATUS Status; + PTOKEN Token; + PAGED_CODE(); + + /* Get the previous mode (only user mode is supported!) */ + PreviousMode = ExGetPreviousMode(); + ASSERT(PreviousMode != KernelMode); + + /* Do we even need to do anything? */ + if (!GenerateOnClose) + { + /* Nothing to do, return success */ + return STATUS_SUCCESS; + } + + /* Validate privilege */ + if (!SeSinglePrivilegeCheck(SeAuditPrivilege, PreviousMode)) + { + DPRINT1("Caller does not have SeAuditPrivilege\n"); + return STATUS_PRIVILEGE_NOT_HELD; + } + + /* Probe and capture the subsystem name */ + Status = ProbeAndCaptureUnicodeString(&CapturedSubsystemName, + PreviousMode, + SubsystemName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to capture subsystem name!\n"); + return Status; + } + + /* Get the current thread and check if it's impersonating */ + CurrentThread = PsGetCurrentThread(); + if (PsIsThreadImpersonating(CurrentThread)) + { + /* Get the impersonation token */ + Token = PsReferenceImpersonationToken(CurrentThread, + &CopyOnOpen, + &EffectiveOnly, + &ImpersonationLevel); + UseImpersonationToken = TRUE; + } + else + { + /* Get the primary token */ + Token = PsReferencePrimaryToken(PsGetCurrentProcess()); + UseImpersonationToken = FALSE; + } + + /* Call the internal function */ + SepAdtCloseObjectAuditAlarm(&CapturedSubsystemName, + HandleId, + Token->UserAndGroups->Sid); + + /* Release the captured subsystem name */ + ReleaseCapturedUnicodeString(&CapturedSubsystemName, PreviousMode); + + /* Check what token we used */ + if (UseImpersonationToken) + { + /* Release impersonation token */ + PsDereferenceImpersonationToken(Token); + } + else + { + /* Release primary token */ + PsDereferencePrimaryToken(Token); + } + + return STATUS_SUCCESS; }