From 8b8043e5bf1e6599d4b65ea0b0d22e3356df4b9b Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 22 Jan 2014 16:29:26 +0000 Subject: [PATCH] [NTOSKRNL] - Implement NtPrivilegedServiceAuditAlarm, the internal function SepAdtPrivilegedServiceAuditAlarm is not implemented yet. - Stubplement SepAccessCheckAndAuditAlarm and make NtAccessCheckAndAuditAlarm, NtAccessCheckByTypeAndAuditAlarm, NtAccessCheckByTypeResultListAndAuditAlarm and NtAccessCheckByTypeResultListAndAuditAlarmByHandle (love that name) wrappers around it. svn path=/trunk/; revision=61753 --- reactos/ntoskrnl/se/audit.c | 496 +++++++++++++++++++++++++++++++++--- reactos/ntoskrnl/se/semgr.c | 72 +----- 2 files changed, 460 insertions(+), 108 deletions(-) diff --git a/reactos/ntoskrnl/se/audit.c b/reactos/ntoskrnl/se/audit.c index c649afb1a97..608ce41e2ec 100644 --- a/reactos/ntoskrnl/se/audit.c +++ b/reactos/ntoskrnl/se/audit.c @@ -5,6 +5,7 @@ * PURPOSE: Audit functions * * PROGRAMMERS: Eric Kohl + * Timo Kreuzer (timo.kreuzer@reactos.org) */ /* INCLUDES *******************************************************************/ @@ -13,6 +14,8 @@ #define NDEBUG #include +#define SEP_PRIVILEGE_SET_MAX_COUNT 60 + /* PRIVATE FUNCTIONS***********************************************************/ BOOLEAN @@ -180,6 +183,145 @@ SeLocateProcessImageName(IN PEPROCESS Process, return Status; } +VOID +NTAPI +SepAdtCloseObjectAuditAlarm( + PUNICODE_STRING SubsystemName, + PVOID HandleId, + PSID Sid) +{ + UNIMPLEMENTED; +} + +VOID +NTAPI +SepAdtPrivilegedServiceAuditAlarm( + PSECURITY_SUBJECT_CONTEXT SubjectContext, + _In_opt_ PUNICODE_STRING SubsystemName, + _In_opt_ PUNICODE_STRING ServiceName, + _In_ PTOKEN Token, + _In_ PTOKEN PrimaryToken, + _In_ PPRIVILEGE_SET Privileges, + _In_ BOOLEAN AccessGranted ) +{ + UNIMPLEMENTED; +} + +_Must_inspect_result_ +NTSTATUS +NTAPI +SepAccessCheckAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PHANDLE ClientToken, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccessList, + _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatusList, + _Out_ PBOOLEAN GenerateOnClose, + _In_ BOOLEAN UseResultList) +{ + SECURITY_SUBJECT_CONTEXT SubjectContext; + ULONG ResultListLength; + GENERIC_MAPPING LocalGenericMapping; + NTSTATUS Status; + PAGED_CODE(); + + DBG_UNREFERENCED_LOCAL_VARIABLE(LocalGenericMapping); + + /* Only user mode is supported! */ + ASSERT(ExGetPreviousMode() != KernelMode); + + /* Validate AuditType */ + if ((AuditType != AuditEventObjectAccess) && + (AuditType != AuditEventDirectoryServiceAccess)) + { + DPRINT1("Invalid audit type: %u\n", AuditType); + return STATUS_INVALID_PARAMETER; + } + + /* Capture the security subject context */ + SeCaptureSubjectContext(&SubjectContext); + + /* Did the caller pass a token handle? */ + if (ClientToken == NULL) + { + /* Check if we have a token in the subject context */ + if (SubjectContext.ClientToken == NULL) + { + Status = STATUS_NO_IMPERSONATION_TOKEN; + goto Cleanup; + } + + /* Check if we have a valid impersonation level */ + if (SubjectContext.ImpersonationLevel < SecurityIdentification) + { + Status = STATUS_BAD_IMPERSONATION_LEVEL; + goto Cleanup; + } + } + + /* Are we using a result list? */ + if (UseResultList) + { + /* The list length equals the object type list length */ + ResultListLength = ObjectTypeListLength; + if ((ResultListLength == 0) || (ResultListLength > 0x1000)) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + } + else + { + /* List length is 1 */ + ResultListLength = 1; + } + + _SEH2_TRY + { + /* Probe output buffers */ + ProbeForWrite(AccessStatusList, + ResultListLength * sizeof(*AccessStatusList), + sizeof(*AccessStatusList)); + ProbeForWrite(GrantedAccessList, + ResultListLength * sizeof(*GrantedAccessList), + sizeof(*GrantedAccessList)); + + /* Probe generic mapping and make a local copy */ + ProbeForRead(GenericMapping, sizeof(*GenericMapping), sizeof(ULONG)); + LocalGenericMapping = * GenericMapping; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + goto Cleanup; + } + _SEH2_END; + + + UNIMPLEMENTED; + + /* For now pretend everything else is ok */ + Status = STATUS_SUCCESS; + +Cleanup: + + /* Release the security subject context */ + SeReleaseSubjectContext(&SubjectContext); + + return Status; +} + + /* PUBLIC FUNCTIONS ***********************************************************/ /* @@ -336,37 +478,8 @@ SePrivilegeObjectAuditAlarm(IN HANDLE Handle, UNIMPLEMENTED; } -VOID -NTAPI -SepAdtCloseObjectAuditAlarm( - PUNICODE_STRING SubsystemName, - PVOID HandleId, - PSID Sid) -{ - UNIMPLEMENTED; -} - /* SYSTEM CALLS ***************************************************************/ -NTSTATUS -NTAPI -NtAccessCheckAndAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN HANDLE HandleId, - IN PUNICODE_STRING ObjectTypeName, - IN PUNICODE_STRING ObjectName, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN ACCESS_MASK DesiredAccess, - IN PGENERIC_MAPPING GenericMapping, - IN BOOLEAN ObjectCreation, - OUT PACCESS_MASK GrantedAccess, - OUT PNTSTATUS AccessStatus, - OUT PBOOLEAN GenerateOnClose) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - NTSTATUS NTAPI NtCloseObjectAuditAlarm( @@ -483,15 +596,157 @@ NtOpenObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, } -NTSTATUS NTAPI -NtPrivilegedServiceAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN PUNICODE_STRING ServiceName, - IN HANDLE ClientToken, - IN PPRIVILEGE_SET Privileges, - IN BOOLEAN AccessGranted) +__kernel_entry +NTSTATUS +NTAPI +NtPrivilegedServiceAuditAlarm( + _In_opt_ PUNICODE_STRING SubsystemName, + _In_opt_ PUNICODE_STRING ServiceName, + _In_ HANDLE ClientToken, + _In_ PPRIVILEGE_SET Privileges, + _In_ BOOLEAN AccessGranted ) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + KPROCESSOR_MODE PreviousMode; + PTOKEN Token; + volatile PPRIVILEGE_SET CapturedPrivileges = NULL; + UNICODE_STRING CapturedSubsystemName; + UNICODE_STRING CapturedServiceName; + ULONG PrivilegeCount, PrivilegesSize; + SECURITY_SUBJECT_CONTEXT SubjectContext; + NTSTATUS Status; + PAGED_CODE(); + + /* Get the previous mode (only user mode is supported!) */ + PreviousMode = ExGetPreviousMode(); + ASSERT(PreviousMode != KernelMode); + + /* Reference the client token */ + Status = ObReferenceObjectByHandle(ClientToken, + TOKEN_QUERY, + SeTokenObjectType, + PreviousMode, + (PVOID*)&Token, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to reference client token: 0x%lx\n", Status); + return Status; + } + + /* Validate the token's impersonation level */ + if ((Token->TokenType == TokenImpersonation) && + (Token->ImpersonationLevel < SecurityIdentification)) + { + DPRINT1("Invalid impersonation level (%u)\n", Token->ImpersonationLevel); + ObfDereferenceObject(Token); + return STATUS_BAD_IMPERSONATION_LEVEL; + } + + /* Validate privilege */ + if (!SeSinglePrivilegeCheck(SeAuditPrivilege, PreviousMode)) + { + DPRINT1("Caller does not have SeAuditPrivilege\n"); + ObfDereferenceObject(Token); + return STATUS_PRIVILEGE_NOT_HELD; + } + + /* Do we have a subsystem name? */ + if (SubsystemName != NULL) + { + /* Probe and capture the subsystem name */ + Status = ProbeAndCaptureUnicodeString(&CapturedSubsystemName, + PreviousMode, + SubsystemName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to capture subsystem name!\n"); + goto Cleanup; + } + } + + /* Do we have a service name? */ + if (ServiceName != NULL) + { + /* Probe and capture the service name */ + Status = ProbeAndCaptureUnicodeString(&CapturedServiceName, + PreviousMode, + ServiceName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to capture service name!\n"); + goto Cleanup; + } + } + + _SEH2_TRY + { + /* Probe the basic privilege set structure */ + ProbeForRead(Privileges, sizeof(PRIVILEGE_SET), sizeof(ULONG)); + + /* Validate privilege count */ + PrivilegeCount = Privileges->PrivilegeCount; + if (PrivilegeCount > SEP_PRIVILEGE_SET_MAX_COUNT) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + /* Calculate the size of the Privileges structure */ + PrivilegesSize = FIELD_OFFSET(PRIVILEGE_SET, Privilege[PrivilegeCount]); + + /* Probe the whole structure */ + ProbeForRead(Privileges, PrivilegesSize, sizeof(ULONG)); + + /* Allocate a temp buffer */ + CapturedPrivileges = ExAllocatePoolWithTag(PagedPool, + PrivilegesSize, + 'rPeS'); + if (CapturedPrivileges == NULL) + { + DPRINT1("Failed to allocate %u bytes\n", PrivilegesSize); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Cleanup; + } + + /* Copy the privileges */ + RtlCopyMemory(CapturedPrivileges, Privileges, PrivilegesSize); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + DPRINT1("Got exception 0x%lx\n", Status); + goto Cleanup; + } + _SEH2_END; + + /* Capture the security subject context */ + SeCaptureSubjectContext(&SubjectContext); + + /* Call the internal function */ + SepAdtPrivilegedServiceAuditAlarm(&SubjectContext, + &CapturedSubsystemName, + &CapturedServiceName, + Token, + SubjectContext.PrimaryToken, + CapturedPrivileges, + AccessGranted); + + /* Release the security subject context */ + SeReleaseSubjectContext(&SubjectContext); + + Status = STATUS_SUCCESS; + +Cleanup: + /* Cleanup resources */ + if (SubsystemName != NULL) + ReleaseCapturedUnicodeString(&CapturedSubsystemName, PreviousMode); + if (ServiceName != NULL) + ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode); + if (CapturedPrivileges != NULL) + ExFreePoolWithTag(CapturedPrivileges, 0); + ObDereferenceObject(Token); + + return Status; } @@ -507,4 +762,171 @@ NtPrivilegeObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, return STATUS_NOT_IMPLEMENTED; } + +_Must_inspect_result_ +__kernel_entry +NTSTATUS +NTAPI +NtAccessCheckAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ ACCESS_MASK DesiredAccess, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose) +{ + /* Call the internal function */ + return SepAccessCheckAndAuditAlarm(SubsystemName, + HandleId, + NULL, + ObjectTypeName, + ObjectName, + SecurityDescriptor, + NULL, + DesiredAccess, + AuditEventObjectAccess, + 0, + NULL, + 0, + GenericMapping, + GrantedAccess, + AccessStatus, + GenerateOnClose, + FALSE); +} + +_Must_inspect_result_ +__kernel_entry +NTSTATUS +NTAPI +NtAccessCheckByTypeAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeLength, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose) +{ + /* Call the internal function */ + return SepAccessCheckAndAuditAlarm(SubsystemName, + HandleId, + NULL, + ObjectTypeName, + ObjectName, + SecurityDescriptor, + PrincipalSelfSid, + DesiredAccess, + AuditType, + Flags, + ObjectTypeList, + ObjectTypeLength, + GenericMapping, + GrantedAccess, + AccessStatus, + GenerateOnClose, + FALSE); +} + +_Must_inspect_result_ +__kernel_entry +NTSTATUS +NTAPI +NtAccessCheckByTypeResultListAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccessList, + _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatusList, + _Out_ PBOOLEAN GenerateOnClose) +{ + /* Call the internal function */ + return SepAccessCheckAndAuditAlarm(SubsystemName, + HandleId, + NULL, + ObjectTypeName, + ObjectName, + SecurityDescriptor, + PrincipalSelfSid, + DesiredAccess, + AuditType, + Flags, + ObjectTypeList, + ObjectTypeListLength, + GenericMapping, + GrantedAccessList, + AccessStatusList, + GenerateOnClose, + TRUE); +} + +_Must_inspect_result_ +__kernel_entry +NTSTATUS +NTAPI +NtAccessCheckByTypeResultListAndAuditAlarmByHandle( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ HANDLE ClientToken, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccessList, + _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatusList, + _Out_ PBOOLEAN GenerateOnClose) +{ + UNREFERENCED_PARAMETER(ObjectCreation); + + /* Call the internal function */ + return SepAccessCheckAndAuditAlarm(SubsystemName, + HandleId, + &ClientToken, + ObjectTypeName, + ObjectName, + SecurityDescriptor, + PrincipalSelfSid, + DesiredAccess, + AuditType, + Flags, + ObjectTypeList, + ObjectTypeListLength, + GenericMapping, + GrantedAccessList, + AccessStatusList, + GenerateOnClose, + TRUE); +} + /* EOF */ diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index 393b9bf27a5..277f471c9b1 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -617,7 +617,7 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, *GrantedAccess = CurrentAccess & DesiredAccess; - if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == + if ((*GrantedAccess & ~VALID_INHERIT_FLAGS) == (DesiredAccess & ~VALID_INHERIT_FLAGS)) { *AccessStatus = STATUS_SUCCESS; @@ -1072,29 +1072,6 @@ NtAccessCheckByType(IN PSECURITY_DESCRIPTOR SecurityDescriptor, return STATUS_NOT_IMPLEMENTED; } -NTSTATUS -NTAPI -NtAccessCheckByTypeAndAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN HANDLE HandleId, - IN PUNICODE_STRING ObjectTypeName, - IN PUNICODE_STRING ObjectName, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PSID PrincipalSelfSid, - IN ACCESS_MASK DesiredAccess, - IN AUDIT_EVENT_TYPE AuditType, - IN ULONG Flags, - IN POBJECT_TYPE_LIST ObjectTypeList, - IN ULONG ObjectTypeLength, - IN PGENERIC_MAPPING GenericMapping, - IN BOOLEAN ObjectCreation, - OUT PACCESS_MASK GrantedAccess, - OUT PNTSTATUS AccessStatus, - OUT PBOOLEAN GenerateOnClose) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - NTSTATUS NTAPI NtAccessCheckByTypeResultList(IN PSECURITY_DESCRIPTOR SecurityDescriptor, @@ -1113,51 +1090,4 @@ NtAccessCheckByTypeResultList(IN PSECURITY_DESCRIPTOR SecurityDescriptor, return STATUS_NOT_IMPLEMENTED; } -NTSTATUS -NTAPI -NtAccessCheckByTypeResultListAndAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN HANDLE HandleId, - IN PUNICODE_STRING ObjectTypeName, - IN PUNICODE_STRING ObjectName, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PSID PrincipalSelfSid, - IN ACCESS_MASK DesiredAccess, - IN AUDIT_EVENT_TYPE AuditType, - IN ULONG Flags, - IN POBJECT_TYPE_LIST ObjectTypeList, - IN ULONG ObjectTypeLength, - IN PGENERIC_MAPPING GenericMapping, - IN BOOLEAN ObjectCreation, - OUT PACCESS_MASK GrantedAccess, - OUT PNTSTATUS AccessStatus, - OUT PBOOLEAN GenerateOnClose) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -NtAccessCheckByTypeResultListAndAuditAlarmByHandle(IN PUNICODE_STRING SubsystemName, - IN HANDLE HandleId, - IN HANDLE ClientToken, - IN PUNICODE_STRING ObjectTypeName, - IN PUNICODE_STRING ObjectName, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PSID PrincipalSelfSid, - IN ACCESS_MASK DesiredAccess, - IN AUDIT_EVENT_TYPE AuditType, - IN ULONG Flags, - IN POBJECT_TYPE_LIST ObjectTypeList, - IN ULONG ObjectTypeLength, - IN PGENERIC_MAPPING GenericMapping, - IN BOOLEAN ObjectCreation, - OUT PACCESS_MASK GrantedAccess, - OUT PNTSTATUS AccessStatus, - OUT PBOOLEAN GenerateOnClose) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - /* EOF */