Author: tkreuzer Date: Tue Feb 11 19:15:53 2014 New Revision: 62120
URL: http://svn.reactos.org/svn/reactos?rev=62120&view=rev Log: [NTOSKRNL] Halfplement NtOpenObjectAuditAlarm, Initialize the privilege set in NtAccessCheck
Modified: trunk/reactos/ntoskrnl/se/accesschk.c trunk/reactos/ntoskrnl/se/audit.c
Modified: trunk/reactos/ntoskrnl/se/accesschk.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/accesschk.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/se/accesschk.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/se/accesschk.c [iso-8859-1] Tue Feb 11 19:15:53 2014 @@ -602,6 +602,9 @@ ProbeForWrite(PrivilegeSet, *PrivilegeSetLength, sizeof(ULONG)); ProbeForWrite(GrantedAccess, sizeof(ACCESS_MASK), sizeof(ULONG)); ProbeForWrite(AccessStatus, sizeof(NTSTATUS), sizeof(ULONG)); + + /* Initialize the privilege set */ + PrivilegeSet->PrivilegeCount = 0; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
Modified: trunk/reactos/ntoskrnl/se/audit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/audit.c?rev=621... ============================================================================== --- trunk/reactos/ntoskrnl/se/audit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/se/audit.c [iso-8859-1] Tue Feb 11 19:15:53 2014 @@ -900,23 +900,267 @@ return STATUS_NOT_IMPLEMENTED; }
- -NTSTATUS NTAPI -NtOpenObjectAuditAlarm(IN PUNICODE_STRING SubsystemName, - IN PVOID HandleId, - IN PUNICODE_STRING ObjectTypeName, - IN PUNICODE_STRING ObjectName, - IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN HANDLE ClientToken, - IN ULONG DesiredAccess, - IN ULONG GrantedAccess, - IN PPRIVILEGE_SET Privileges, - IN BOOLEAN ObjectCreation, - IN BOOLEAN AccessGranted, - OUT PBOOLEAN GenerateOnClose) -{ +VOID +NTAPI +SepOpenObjectAuditAlarm( + _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ PTOKEN ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_ ACCESS_MASK GrantedAccess, + _In_opt_ PPRIVILEGE_SET Privileges, + _In_ BOOLEAN ObjectCreation, + _In_ BOOLEAN AccessGranted, + _Out_ PBOOLEAN GenerateOnClose) +{ + DBG_UNREFERENCED_PARAMETER(SubjectContext); + DBG_UNREFERENCED_PARAMETER(SubsystemName); + DBG_UNREFERENCED_PARAMETER(HandleId); + DBG_UNREFERENCED_PARAMETER(ObjectTypeName); + DBG_UNREFERENCED_PARAMETER(ObjectName); + DBG_UNREFERENCED_PARAMETER(SecurityDescriptor); + DBG_UNREFERENCED_PARAMETER(ClientToken); + DBG_UNREFERENCED_PARAMETER(DesiredAccess); + DBG_UNREFERENCED_PARAMETER(GrantedAccess); + DBG_UNREFERENCED_PARAMETER(Privileges); + DBG_UNREFERENCED_PARAMETER(ObjectCreation); + DBG_UNREFERENCED_PARAMETER(AccessGranted); UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + *GenerateOnClose = FALSE; +} + +__kernel_entry +NTSTATUS +NTAPI +NtOpenObjectAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ HANDLE ClientTokenHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ACCESS_MASK GrantedAccess, + _In_opt_ PPRIVILEGE_SET PrivilegeSet, + _In_ BOOLEAN ObjectCreation, + _In_ BOOLEAN AccessGranted, + _Out_ PBOOLEAN GenerateOnClose) +{ + PTOKEN ClientToken; + PSECURITY_DESCRIPTOR CapturedSecurityDescriptor; + UNICODE_STRING CapturedSubsystemName, CapturedObjectTypeName, CapturedObjectName; + ULONG PrivilegeCount, PrivilegeSetSize; + volatile PPRIVILEGE_SET CapturedPrivilegeSet; + BOOLEAN LocalGenerateOnClose; + PVOID CapturedHandleId; + SECURITY_SUBJECT_CONTEXT SubjectContext; + NTSTATUS Status; + PAGED_CODE(); + + /* Only user mode is supported! */ + ASSERT(ExGetPreviousMode() != KernelMode); + + /* Start clean */ + ClientToken = NULL; + CapturedSecurityDescriptor = NULL; + CapturedPrivilegeSet = NULL; + CapturedSubsystemName.Buffer = NULL; + CapturedObjectTypeName.Buffer = NULL; + CapturedObjectName.Buffer = NULL; + + /* Reference the client token */ + Status = ObReferenceObjectByHandle(ClientTokenHandle, + TOKEN_QUERY, + SeTokenObjectType, + UserMode, + (PVOID*)&ClientToken, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to reference token handle %p: %lx\n", + ClientTokenHandle, Status); + return Status; + } + + /* Validate the token's impersonation level */ + if ((ClientToken->TokenType == TokenImpersonation) && + (ClientToken->ImpersonationLevel < SecurityIdentification)) + { + DPRINT1("Invalid impersonation level (%u)\n", ClientToken->ImpersonationLevel); + Status = STATUS_BAD_IMPERSONATION_LEVEL; + goto Cleanup; + } + + /* Check for audit privilege */ + if (!SeSinglePrivilegeCheck(SeAuditPrivilege, UserMode)) + { + DPRINT1("Caller does not have SeAuditPrivilege\n"); + Status = STATUS_PRIVILEGE_NOT_HELD; + goto Cleanup; + } + + /* Check for NULL SecurityDescriptor */ + if (SecurityDescriptor == NULL) + { + /* Nothing to do */ + Status = STATUS_SUCCESS; + goto Cleanup; + } + + /* Capture the security descriptor */ + Status = SeCaptureSecurityDescriptor(SecurityDescriptor, + UserMode, + PagedPool, + FALSE, + &CapturedSecurityDescriptor); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to capture security descriptor!\n"); + goto Cleanup; + } + + _SEH2_TRY + { + /* Check if we have a privilege set */ + if (PrivilegeSet != NULL) + { + /* Probe the basic privilege set structure */ + ProbeForRead(PrivilegeSet, sizeof(PRIVILEGE_SET), sizeof(ULONG)); + + /* Validate privilege count */ + PrivilegeCount = PrivilegeSet->PrivilegeCount; + if (PrivilegeCount > SEP_PRIVILEGE_SET_MAX_COUNT) + { + Status = STATUS_INVALID_PARAMETER; + goto Cleanup; + } + + /* Calculate the size of the PrivilegeSet structure */ + PrivilegeSetSize = FIELD_OFFSET(PRIVILEGE_SET, Privilege[PrivilegeCount]); + + /* Probe the whole structure */ + ProbeForRead(PrivilegeSet, PrivilegeSetSize, sizeof(ULONG)); + + /* Allocate a temp buffer */ + CapturedPrivilegeSet = ExAllocatePoolWithTag(PagedPool, + PrivilegeSetSize, + 'rPeS'); + if (CapturedPrivilegeSet == NULL) + { + DPRINT1("Failed to allocate %u bytes\n", PrivilegeSetSize); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Cleanup; + } + + /* Copy the privileges */ + RtlCopyMemory(CapturedPrivilegeSet, PrivilegeSet, PrivilegeSetSize); + } + + if (HandleId != NULL) + { + ProbeForRead(HandleId, sizeof(PVOID), sizeof(PVOID)); + CapturedHandleId = *(PVOID*)HandleId; + } + + ProbeForWrite(GenerateOnClose, sizeof(BOOLEAN), sizeof(BOOLEAN)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + DPRINT1("Exception while probing parameters: 0x%lx\n", Status); + goto Cleanup; + } + _SEH2_END; + + /* Probe and capture the subsystem name */ + Status = ProbeAndCaptureUnicodeString(&CapturedSubsystemName, + UserMode, + SubsystemName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to capture subsystem name!\n"); + goto Cleanup; + } + + /* Probe and capture the object type name */ + Status = ProbeAndCaptureUnicodeString(&CapturedObjectTypeName, + UserMode, + ObjectTypeName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to capture object type name!\n"); + goto Cleanup; + } + + /* Probe and capture the object name */ + Status = ProbeAndCaptureUnicodeString(&CapturedObjectName, + UserMode, + ObjectName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to capture object name!\n"); + goto Cleanup; + } + + /* Capture the security subject context */ + SeCaptureSubjectContext(&SubjectContext); + + /* Call the internal function */ + SepOpenObjectAuditAlarm(&SubjectContext, + &CapturedSubsystemName, + CapturedHandleId, + &CapturedObjectTypeName, + &CapturedObjectName, + CapturedSecurityDescriptor, + ClientToken, + DesiredAccess, + GrantedAccess, + CapturedPrivilegeSet, + ObjectCreation, + AccessGranted, + &LocalGenerateOnClose); + + /* Release the security subject context */ + SeReleaseSubjectContext(&SubjectContext); + + Status = STATUS_SUCCESS; + + /* Enter SEH to copy the data back to user mode */ + _SEH2_TRY + { + *GenerateOnClose = LocalGenerateOnClose; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + DPRINT1("Exception while copying back data: 0x%lx\n", Status); + } + _SEH2_END; + +Cleanup: + + if (CapturedObjectName.Buffer != NULL) + ReleaseCapturedUnicodeString(&CapturedObjectName, UserMode); + + if (CapturedObjectTypeName.Buffer != NULL) + ReleaseCapturedUnicodeString(&CapturedObjectTypeName, UserMode); + + if (CapturedSubsystemName.Buffer != NULL) + ReleaseCapturedUnicodeString(&CapturedSubsystemName, UserMode); + + if (CapturedSecurityDescriptor != NULL) + SeReleaseSecurityDescriptor(CapturedSecurityDescriptor, UserMode, FALSE); + + if (CapturedPrivilegeSet != NULL) + ExFreePoolWithTag(CapturedPrivilegeSet, 'rPeS'); + + ObDereferenceObject(ClientToken); + + return Status; }
@@ -926,12 +1170,12 @@ NtPrivilegedServiceAuditAlarm( _In_opt_ PUNICODE_STRING SubsystemName, _In_opt_ PUNICODE_STRING ServiceName, - _In_ HANDLE ClientToken, + _In_ HANDLE ClientTokenHandle, _In_ PPRIVILEGE_SET Privileges, _In_ BOOLEAN AccessGranted ) { KPROCESSOR_MODE PreviousMode; - PTOKEN Token; + PTOKEN ClientToken; volatile PPRIVILEGE_SET CapturedPrivileges = NULL; UNICODE_STRING CapturedSubsystemName; UNICODE_STRING CapturedServiceName; @@ -948,11 +1192,11 @@ CapturedServiceName.Buffer = NULL;
/* Reference the client token */ - Status = ObReferenceObjectByHandle(ClientToken, + Status = ObReferenceObjectByHandle(ClientTokenHandle, TOKEN_QUERY, SeTokenObjectType, PreviousMode, - (PVOID*)&Token, + (PVOID*)&ClientToken, NULL); if (!NT_SUCCESS(Status)) { @@ -961,11 +1205,11 @@ }
/* Validate the token's impersonation level */ - if ((Token->TokenType == TokenImpersonation) && - (Token->ImpersonationLevel < SecurityIdentification)) - { - DPRINT1("Invalid impersonation level (%u)\n", Token->ImpersonationLevel); - ObfDereferenceObject(Token); + if ((ClientToken->TokenType == TokenImpersonation) && + (ClientToken->ImpersonationLevel < SecurityIdentification)) + { + DPRINT1("Invalid impersonation level (%u)\n", ClientToken->ImpersonationLevel); + ObDereferenceObject(ClientToken); return STATUS_BAD_IMPERSONATION_LEVEL; }
@@ -973,7 +1217,7 @@ if (!SeSinglePrivilegeCheck(SeAuditPrivilege, PreviousMode)) { DPRINT1("Caller does not have SeAuditPrivilege\n"); - ObfDereferenceObject(Token); + ObDereferenceObject(ClientToken); return STATUS_PRIVILEGE_NOT_HELD; }
@@ -1053,7 +1297,7 @@ SepAdtPrivilegedServiceAuditAlarm(&SubjectContext, SubsystemName ? &CapturedSubsystemName : NULL, ServiceName ? &CapturedServiceName : NULL, - Token, + ClientToken, SubjectContext.PrimaryToken, CapturedPrivileges, AccessGranted); @@ -1067,11 +1311,14 @@ /* Cleanup resources */ if (CapturedSubsystemName.Buffer != NULL) ReleaseCapturedUnicodeString(&CapturedSubsystemName, PreviousMode); + if (CapturedServiceName.Buffer != NULL) ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode); + if (CapturedPrivileges != NULL) - ExFreePoolWithTag(CapturedPrivileges, 0); - ObDereferenceObject(Token); + ExFreePoolWithTag(CapturedPrivileges, 'rPeS'); + + ObDereferenceObject(ClientToken);
return Status; }