Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

seaudit.c File Reference

#include "tokenp.h"
#include "adt.h"
#include "adtp.h"
#include <sertlp.h>

Go to the source code of this file.

Defines

#define INVALID_OBJECT_TYPE_LIST_INDEX   0xFFFFFFFF

Functions

VOID SepProbeAndCaptureString_U (IN PUNICODE_STRING SourceString, OUT PUNICODE_STRING *DestString)
VOID SepFreeCapturedString (IN PUNICODE_STRING CapturedString)
VOID SepAuditTypeList (IN PIOBJECT_TYPE_LIST ObjectTypeList, IN ULONG ObjectTypeListLength, IN PNTSTATUS AccessStatus, IN ULONG StartIndex, OUT PBOOLEAN GenerateSuccessAudit, OUT PBOOLEAN GenerateFailureAudit)
VOID SepExamineSaclEx (IN PACL Sacl, IN PACCESS_TOKEN Token, IN ACCESS_MASK DesiredAccess, IN PIOBJECT_TYPE_LIST ObjectTypeList OPTIONAL, IN ULONG ObjectTypeListLength, IN BOOLEAN ReturnResultList, IN PNTSTATUS AccessStatus, IN PACCESS_MASK GrantedAccess, OUT PBOOLEAN GenerateSuccessAudit, OUT PBOOLEAN GenerateFailureAudit)
NTSTATUS SepAccessCheckAndAuditAlarm (IN PUNICODE_STRING SubsystemName, IN PVOID HandleId, IN PHANDLE ClientToken OPTIONAL, 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 OPTIONAL, IN ULONG ObjectTypeListLength, IN PGENERIC_MAPPING GenericMapping, IN BOOLEAN ObjectCreation, OUT PACCESS_MASK GrantedAccess, OUT PNTSTATUS AccessStatus, OUT PBOOLEAN GenerateOnClose, IN BOOLEAN ReturnResultList)
BOOLEAN SepSinglePrivilegeCheck (LUID DesiredPrivilege, IN PACCESS_TOKEN Token, IN KPROCESSOR_MODE PreviousMode)
BOOLEAN SeCheckAuditPrivilege (IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN KPROCESSOR_MODE PreviousMode)
NTSTATUS NtPrivilegeObjectAuditAlarm (IN PUNICODE_STRING SubsystemName, IN PVOID HandleId, IN HANDLE ClientToken, IN ACCESS_MASK DesiredAccess, IN PPRIVILEGE_SET Privileges, IN BOOLEAN AccessGranted)
VOID SePrivilegeObjectAuditAlarm (IN HANDLE Handle, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN ACCESS_MASK DesiredAccess, IN PPRIVILEGE_SET Privileges, IN BOOLEAN AccessGranted, IN KPROCESSOR_MODE AccessMode)
NTSTATUS NtPrivilegedServiceAuditAlarm (IN PUNICODE_STRING SubsystemName, IN PUNICODE_STRING ServiceName, IN HANDLE ClientToken, IN PPRIVILEGE_SET Privileges, IN BOOLEAN AccessGranted)
VOID SePrivilegedServiceAuditAlarm (IN PUNICODE_STRING ServiceName, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN PPRIVILEGE_SET Privileges, IN BOOLEAN AccessGranted)
NTSTATUS NtAccessCheckAndAuditAlarm (IN PUNICODE_STRING SubsystemName, IN 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)
NTSTATUS NtAccessCheckByTypeAndAuditAlarm (IN PUNICODE_STRING SubsystemName, IN PVOID 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 OPTIONAL, IN ULONG ObjectTypeListLength, IN PGENERIC_MAPPING GenericMapping, IN BOOLEAN ObjectCreation, OUT PACCESS_MASK GrantedAccess, OUT PNTSTATUS AccessStatus, OUT PBOOLEAN GenerateOnClose)
NTSTATUS NtAccessCheckByTypeResultListAndAuditAlarm (IN PUNICODE_STRING SubsystemName, IN PVOID 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 OPTIONAL, IN ULONG ObjectTypeListLength, IN PGENERIC_MAPPING GenericMapping, IN BOOLEAN ObjectCreation, OUT PACCESS_MASK GrantedAccess, OUT PNTSTATUS AccessStatus, OUT PBOOLEAN GenerateOnClose)
NTSTATUS NtAccessCheckByTypeResultListAndAuditAlarmByHandle (IN PUNICODE_STRING SubsystemName, IN PVOID 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 OPTIONAL, IN ULONG ObjectTypeListLength, IN PGENERIC_MAPPING GenericMapping, IN BOOLEAN ObjectCreation, OUT PACCESS_MASK GrantedAccess, OUT PNTSTATUS AccessStatus, OUT PBOOLEAN GenerateOnClose)
NTSTATUS NtOpenObjectAuditAlarm (IN PUNICODE_STRING SubsystemName, IN PVOID HandleId OPTIONAL, IN PUNICODE_STRING ObjectTypeName, IN PUNICODE_STRING ObjectName, IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, IN HANDLE ClientToken, IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK GrantedAccess, IN PPRIVILEGE_SET Privileges OPTIONAL, IN BOOLEAN ObjectCreation, IN BOOLEAN AccessGranted, OUT PBOOLEAN GenerateOnClose)
NTSTATUS NtCloseObjectAuditAlarm (IN PUNICODE_STRING SubsystemName, IN PVOID HandleId, IN BOOLEAN GenerateOnClose)
NTSTATUS NtDeleteObjectAuditAlarm (IN PUNICODE_STRING SubsystemName, IN PVOID HandleId, IN BOOLEAN GenerateOnClose)
VOID SeOpenObjectAuditAlarm (IN PUNICODE_STRING ObjectTypeName, IN PVOID Object OPTIONAL, IN PUNICODE_STRING AbsoluteObjectName OPTIONAL, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PACCESS_STATE AccessState, IN BOOLEAN ObjectCreated, IN BOOLEAN AccessGranted, IN KPROCESSOR_MODE AccessMode, OUT PBOOLEAN GenerateOnClose)
VOID SeOpenObjectForDeleteAuditAlarm (IN PUNICODE_STRING ObjectTypeName, IN PVOID Object OPTIONAL, IN PUNICODE_STRING AbsoluteObjectName OPTIONAL, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PACCESS_STATE AccessState, IN BOOLEAN ObjectCreated, IN BOOLEAN AccessGranted, IN KPROCESSOR_MODE AccessMode, OUT PBOOLEAN GenerateOnClose)
VOID SeTraverseAuditAlarm (IN PLUID OperationID, IN PVOID DirectoryObject, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN BOOLEAN SubjectContextLocked, IN ACCESS_MASK TraverseAccess, IN PPRIVILEGE_SET Privileges OPTIONAL, IN BOOLEAN AccessGranted, IN KPROCESSOR_MODE AccessMode)
VOID SeCreateObjectAuditAlarm (IN PLUID OperationID OPTIONAL, IN PVOID DirectoryObject, IN PUNICODE_STRING ComponentName, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN ACCESS_MASK DesiredAccess, IN PPRIVILEGE_SET Privileges OPTIONAL, IN BOOLEAN AccessGranted, OUT PBOOLEAN AuditPerformed, IN KPROCESSOR_MODE AccessMode)
VOID SeObjectReferenceAuditAlarm (IN PLUID OperationID OPTIONAL, IN PVOID Object, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN ACCESS_MASK DesiredAccess, IN PPRIVILEGE_SET Privileges OPTIONAL, IN BOOLEAN AccessGranted, IN KPROCESSOR_MODE AccessMode)
VOID SeAuditHandleCreation (IN PACCESS_STATE AccessState, IN HANDLE Handle)
VOID SeCloseObjectAuditAlarm (IN PVOID Object, IN HANDLE Handle, IN BOOLEAN GenerateOnClose)
VOID SeDeleteObjectAuditAlarm (IN PVOID Object, IN HANDLE Handle)
VOID SepExamineSacl (IN PACL Sacl, IN PACCESS_TOKEN Token, IN ACCESS_MASK DesiredAccess, IN BOOLEAN AccessGranted, OUT PBOOLEAN GenerateAudit, OUT PBOOLEAN GenerateAlarm)
VOID SepSetAuditInfoForObjectType (IN UCHAR AceFlags, IN ACCESS_MASK AccessMask, IN ACCESS_MASK DesiredAccess, IN PIOBJECT_TYPE_LIST ObjectTypeList, IN ULONG ObjectTypeListLength, IN BOOLEAN ReturnResultList, IN ULONG ObjectTypeIndex, IN PNTSTATUS AccessStatus, IN PACCESS_MASK GrantedAccess, IN BOOLEAN FailedMaximumAllowed, OUT PBOOLEAN GenerateSuccessAudit, OUT PBOOLEAN GenerateFailureAudit)
BOOLEAN SepInitializePrivilegeFilter (BOOLEAN Verbose)
BOOLEAN SepFilterPrivilegeAudits (IN PPRIVILEGE_SET PrivilegeSet)
BOOLEAN SeAuditingFileOrGlobalEvents (IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext)
BOOLEAN SeAuditingFileEvents (IN BOOLEAN AccessGranted, IN PSECURITY_DESCRIPTOR SecurityDescriptor)

Variables

BOOLEAN SepAuditShutdownEvents = FALSE
PLUID * SepFilterPrivileges = NULL
PLUID SepFilterPrivilegesLong []
PLUID SepFilterPrivilegesShort []


Define Documentation

#define INVALID_OBJECT_TYPE_LIST_INDEX   0xFFFFFFFF
 

Referenced by SepExamineSaclEx().


Function Documentation

NTSTATUS NtAccessCheckAndAuditAlarm IN PUNICODE_STRING  SubsystemName,
IN 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
 

Definition at line 1820 of file seaudit.c.

References FALSE, NULL, PAGED_CODE, and SepAccessCheckAndAuditAlarm().

01835 : 01836 01837 See SepAccessCheckAndAuditAlarm. 01838 01839 Arguments: 01840 01841 See SepAccessCheckAndAuditAlarm. 01842 01843 Return Value: 01844 01845 STATUS_SUCCESS - Indicates the call completed successfully. In this 01846 case, ClientStatus receives the result of the access check. 01847 01848 STATUS_PRIVILEGE_NOT_HELD - Indicates the caller does not have 01849 sufficient privilege to use this privileged system service. 01850 01851 --*/ 01852 01853 { 01854 PAGED_CODE(); 01855 return SepAccessCheckAndAuditAlarm( 01856 SubsystemName, 01857 HandleId, 01858 NULL, 01859 ObjectTypeName, 01860 ObjectName, 01861 SecurityDescriptor, 01862 NULL, // No Principal Self sid 01863 DesiredAccess, 01864 AuditEventObjectAccess, // Default to ObjectAccess 01865 0, // No Flags 01866 NULL, // No ObjectType List 01867 0, // No ObjectType List 01868 GenericMapping, 01869 ObjectCreation, 01870 GrantedAccess, 01871 AccessStatus, 01872 GenerateOnClose, 01873 FALSE ); // Return a single GrantedAccess and AccessStatus 01874 01875 }

NTSTATUS NtAccessCheckByTypeAndAuditAlarm IN PUNICODE_STRING  SubsystemName,
IN PVOID  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  OPTIONAL,
IN ULONG  ObjectTypeListLength,
IN PGENERIC_MAPPING  GenericMapping,
IN BOOLEAN  ObjectCreation,
OUT PACCESS_MASK  GrantedAccess,
OUT PNTSTATUS  AccessStatus,
OUT PBOOLEAN  GenerateOnClose
 

Definition at line 1879 of file seaudit.c.

References FALSE, NULL, PAGED_CODE, and SepAccessCheckAndAuditAlarm().

01899 : 01900 01901 See SepAccessCheckAndAuditAlarm. 01902 01903 Arguments: 01904 01905 See SepAccessCheckAndAuditAlarm. 01906 01907 Return Value: 01908 01909 STATUS_SUCCESS - Indicates the call completed successfully. In this 01910 case, ClientStatus receives the result of the access check. 01911 01912 STATUS_PRIVILEGE_NOT_HELD - Indicates the caller does not have 01913 sufficient privilege to use this privileged system service. 01914 01915 --*/ 01916 01917 { 01918 PAGED_CODE(); 01919 return SepAccessCheckAndAuditAlarm( 01920 SubsystemName, 01921 HandleId, 01922 NULL, 01923 ObjectTypeName, 01924 ObjectName, 01925 SecurityDescriptor, 01926 PrincipalSelfSid, 01927 DesiredAccess, 01928 AuditType, 01929 Flags, 01930 ObjectTypeList, 01931 ObjectTypeListLength, 01932 GenericMapping, 01933 ObjectCreation, 01934 GrantedAccess, 01935 AccessStatus, 01936 GenerateOnClose, 01937 FALSE ); // Return a single GrantedAccess and AccessStatus 01938 01939 }

NTSTATUS NtAccessCheckByTypeResultListAndAuditAlarm IN PUNICODE_STRING  SubsystemName,
IN PVOID  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  OPTIONAL,
IN ULONG  ObjectTypeListLength,
IN PGENERIC_MAPPING  GenericMapping,
IN BOOLEAN  ObjectCreation,
OUT PACCESS_MASK  GrantedAccess,
OUT PNTSTATUS  AccessStatus,
OUT PBOOLEAN  GenerateOnClose
 

Definition at line 1943 of file seaudit.c.

References NULL, PAGED_CODE, SepAccessCheckAndAuditAlarm(), and TRUE.

01963 : 01964 01965 See SepAccessCheckAndAuditAlarm. 01966 01967 Arguments: 01968 01969 See SepAccessCheckAndAuditAlarm. 01970 01971 Return Value: 01972 01973 STATUS_SUCCESS - Indicates the call completed successfully. In this 01974 case, ClientStatus receives the result of the access check. 01975 01976 STATUS_PRIVILEGE_NOT_HELD - Indicates the caller does not have 01977 sufficient privilege to use this privileged system service. 01978 01979 --*/ 01980 01981 { 01982 PAGED_CODE(); 01983 return SepAccessCheckAndAuditAlarm( 01984 SubsystemName, 01985 HandleId, 01986 NULL, 01987 ObjectTypeName, 01988 ObjectName, 01989 SecurityDescriptor, 01990 PrincipalSelfSid, 01991 DesiredAccess, 01992 AuditType, 01993 Flags, 01994 ObjectTypeList, 01995 ObjectTypeListLength, 01996 GenericMapping, 01997 ObjectCreation, 01998 GrantedAccess, 01999 AccessStatus, 02000 GenerateOnClose, 02001 TRUE ); // Return an array of GrantedAccess and AccessStatus 02002 02003 }

NTSTATUS NtAccessCheckByTypeResultListAndAuditAlarmByHandle IN PUNICODE_STRING  SubsystemName,
IN PVOID  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  OPTIONAL,
IN ULONG  ObjectTypeListLength,
IN PGENERIC_MAPPING  GenericMapping,
IN BOOLEAN  ObjectCreation,
OUT PACCESS_MASK  GrantedAccess,
OUT PNTSTATUS  AccessStatus,
OUT PBOOLEAN  GenerateOnClose
 

Definition at line 2007 of file seaudit.c.

References ClientToken, PAGED_CODE, SepAccessCheckAndAuditAlarm(), and TRUE.

02028 : 02029 02030 See SepAccessCheckAndAuditAlarm. 02031 02032 Arguments: 02033 02034 See SepAccessCheckAndAuditAlarm. 02035 02036 Return Value: 02037 02038 STATUS_SUCCESS - Indicates the call completed successfully. In this 02039 case, ClientStatus receives the result of the access check. 02040 02041 STATUS_PRIVILEGE_NOT_HELD - Indicates the caller does not have 02042 sufficient privilege to use this privileged system service. 02043 02044 --*/ 02045 02046 { 02047 PAGED_CODE(); 02048 return SepAccessCheckAndAuditAlarm( 02049 SubsystemName, 02050 HandleId, 02051 &ClientToken, 02052 ObjectTypeName, 02053 ObjectName, 02054 SecurityDescriptor, 02055 PrincipalSelfSid, 02056 DesiredAccess, 02057 AuditType, 02058 Flags, 02059 ObjectTypeList, 02060 ObjectTypeListLength, 02061 GenericMapping, 02062 ObjectCreation, 02063 GrantedAccess, 02064 AccessStatus, 02065 GenerateOnClose, 02066 TRUE ); // Return an array of GrantedAccess and AccessStatus 02067 02068 }

NTSTATUS NtCloseObjectAuditAlarm IN PUNICODE_STRING  SubsystemName,
IN PVOID  HandleId,
IN BOOLEAN  GenerateOnClose
 

Definition at line 2492 of file seaudit.c.

References ASSERT, EffectiveToken, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, RtlCopySid(), SeCaptureSubjectContext(), SeCheckAuditPrivilege(), SeLengthSid, SepAdtCloseObjectAuditAlarm(), SepFreeCapturedString(), SepProbeAndCaptureString_U(), SepTokenAuthenticationId, SepTokenUserSid, SeReleaseSubjectContext(), and Status.

02500 : 02501 02502 This routine is used to generate audit and alarm messages when a handle 02503 to a protected subsystem object is deleted. This routine may result in 02504 several messages being generated and sent to Port objects. This may 02505 result in a significant latency before returning. Design of routines 02506 that must call this routine must take this potential latency into 02507 account. This may have an impact on the approach taken for data 02508 structure mutex locking, for example. 02509 02510 This API requires the caller have SeAuditPrivilege privilege. The test 02511 for this privilege is always against the primary token of the calling 02512 process, allowing the caller to be impersonating a client during the 02513 call with no ill effects. 02514 02515 Arguments: 02516 02517 SubsystemName - Supplies a name string identifying the subsystem 02518 calling the routine. 02519 02520 HandleId - A unique value representing the client's handle to the 02521 object. 02522 02523 GenerateOnClose - Is a boolean value returned from a corresponding 02524 NtAccessCheckAndAuditAlarm() call or NtOpenObjectAuditAlarm() call 02525 when the object handle was created. 02526 02527 Return value: 02528 02529 --*/ 02530 02531 { 02532 BOOLEAN Result; 02533 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 02534 KPROCESSOR_MODE PreviousMode; 02535 PUNICODE_STRING CapturedSubsystemName = NULL; 02536 PSID UserSid; 02537 PSID CapturedUserSid = NULL; 02538 NTSTATUS Status; 02539 02540 PAGED_CODE(); 02541 02542 PreviousMode = KeGetPreviousMode(); 02543 02544 ASSERT(PreviousMode != KernelMode); 02545 02546 if (!GenerateOnClose) { 02547 return( STATUS_SUCCESS ); 02548 } 02549 02550 // 02551 // Check for SeAuditPrivilege 02552 // 02553 02554 SeCaptureSubjectContext ( &SubjectSecurityContext ); 02555 02556 Result = SeCheckAuditPrivilege ( 02557 &SubjectSecurityContext, 02558 PreviousMode 02559 ); 02560 02561 if (!Result) { 02562 Status = STATUS_PRIVILEGE_NOT_HELD; 02563 goto Cleanup; 02564 } 02565 02566 UserSid = SepTokenUserSid( EffectiveToken (&SubjectSecurityContext)); 02567 02568 CapturedUserSid = ExAllocatePoolWithTag( 02569 PagedPool, 02570 SeLengthSid( UserSid ), 02571 'iSeS' 02572 ); 02573 02574 if ( CapturedUserSid == NULL ) { 02575 Status = STATUS_INSUFFICIENT_RESOURCES; 02576 goto Cleanup; 02577 } 02578 02579 Status = RtlCopySid ( 02580 SeLengthSid( UserSid ), 02581 CapturedUserSid, 02582 UserSid 02583 ); 02584 02585 ASSERT( NT_SUCCESS( Status )); 02586 02587 02588 try { 02589 02590 SepProbeAndCaptureString_U ( SubsystemName, 02591 &CapturedSubsystemName ); 02592 02593 } except (EXCEPTION_EXECUTE_HANDLER) { 02594 Status = GetExceptionCode(); 02595 goto Cleanup; 02596 } 02597 02598 // 02599 // This routine will check to see if auditing is enabled 02600 // 02601 02602 SepAdtCloseObjectAuditAlarm ( CapturedSubsystemName, 02603 HandleId, 02604 NULL, 02605 CapturedUserSid, 02606 SepTokenAuthenticationId( EffectiveToken( &SubjectSecurityContext )) 02607 ); 02608 02609 Status = STATUS_SUCCESS; 02610 02611 Cleanup: 02612 if ( CapturedSubsystemName != NULL ) { 02613 SepFreeCapturedString( CapturedSubsystemName ); 02614 } 02615 02616 if ( CapturedUserSid != NULL ) { 02617 ExFreePool( CapturedUserSid ); 02618 } 02619 02620 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02621 02622 return Status; 02623 }

NTSTATUS NtDeleteObjectAuditAlarm IN PUNICODE_STRING  SubsystemName,
IN PVOID  HandleId,
IN BOOLEAN  GenerateOnClose
 

Definition at line 2627 of file seaudit.c.

References ASSERT, EffectiveToken, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, RtlCopySid(), SeCaptureSubjectContext(), SeCheckAuditPrivilege(), SeLengthSid, SepAdtDeleteObjectAuditAlarm(), SepFreeCapturedString(), SepProbeAndCaptureString_U(), SepTokenAuthenticationId, SepTokenUserSid, SeReleaseSubjectContext(), and Status.

02635 : 02636 02637 This routine is used to generate audit and alarm messages when an object 02638 in a protected subsystem object is deleted. This routine may result in 02639 several messages being generated and sent to Port objects. This may 02640 result in a significant latency before returning. Design of routines 02641 that must call this routine must take this potential latency into 02642 account. This may have an impact on the approach taken for data 02643 structure mutex locking, for example. 02644 02645 This API requires the caller have SeAuditPrivilege privilege. The test 02646 for this privilege is always against the primary token of the calling 02647 process, allowing the caller to be impersonating a client during the 02648 call with no ill effects. 02649 02650 Arguments: 02651 02652 SubsystemName - Supplies a name string identifying the subsystem 02653 calling the routine. 02654 02655 HandleId - A unique value representing the client's handle to the 02656 object. 02657 02658 GenerateOnClose - Is a boolean value returned from a corresponding 02659 NtAccessCheckAndAuditAlarm() call or NtOpenObjectAuditAlarm() call 02660 when the object handle was created. 02661 02662 Return value: 02663 02664 --*/ 02665 02666 { 02667 BOOLEAN Result; 02668 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 02669 KPROCESSOR_MODE PreviousMode; 02670 PUNICODE_STRING CapturedSubsystemName = NULL; 02671 PSID UserSid; 02672 PSID CapturedUserSid; 02673 NTSTATUS Status; 02674 02675 PAGED_CODE(); 02676 02677 PreviousMode = KeGetPreviousMode(); 02678 02679 ASSERT(PreviousMode != KernelMode); 02680 02681 if (!GenerateOnClose) { 02682 return( STATUS_SUCCESS ); 02683 } 02684 02685 // 02686 // Check for SeAuditPrivilege 02687 // 02688 02689 SeCaptureSubjectContext ( &SubjectSecurityContext ); 02690 02691 Result = SeCheckAuditPrivilege ( 02692 &SubjectSecurityContext, 02693 PreviousMode 02694 ); 02695 02696 if (!Result) { 02697 02698 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02699 return(STATUS_PRIVILEGE_NOT_HELD); 02700 } 02701 02702 UserSid = SepTokenUserSid( EffectiveToken (&SubjectSecurityContext)); 02703 02704 CapturedUserSid = ExAllocatePoolWithTag( 02705 PagedPool, 02706 SeLengthSid( UserSid ), 02707 'iSeS' 02708 ); 02709 02710 if ( CapturedUserSid == NULL ) { 02711 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02712 return( STATUS_INSUFFICIENT_RESOURCES ); 02713 } 02714 02715 Status = RtlCopySid ( 02716 SeLengthSid( UserSid ), 02717 CapturedUserSid, 02718 UserSid 02719 ); 02720 02721 ASSERT( NT_SUCCESS( Status )); 02722 02723 02724 try { 02725 02726 SepProbeAndCaptureString_U ( SubsystemName, 02727 &CapturedSubsystemName ); 02728 02729 } except (EXCEPTION_EXECUTE_HANDLER) { 02730 02731 if ( CapturedSubsystemName != NULL ) { 02732 SepFreeCapturedString( CapturedSubsystemName ); 02733 } 02734 02735 ExFreePool( CapturedUserSid ); 02736 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02737 return GetExceptionCode(); 02738 02739 } 02740 02741 // 02742 // This routine will check to see if auditing is enabled 02743 // 02744 02745 SepAdtDeleteObjectAuditAlarm ( CapturedSubsystemName, 02746 HandleId, 02747 NULL, 02748 CapturedUserSid, 02749 SepTokenAuthenticationId( EffectiveToken( &SubjectSecurityContext )) 02750 ); 02751 02752 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02753 02754 if ( CapturedSubsystemName != NULL ) { 02755 SepFreeCapturedString( CapturedSubsystemName ); 02756 } 02757 02758 ExFreePool( CapturedUserSid ); 02759 02760 return(STATUS_SUCCESS); 02761 }

NTSTATUS NtOpenObjectAuditAlarm IN PUNICODE_STRING  SubsystemName,
IN PVOID HandleId  OPTIONAL,
IN PUNICODE_STRING  ObjectTypeName,
IN PUNICODE_STRING  ObjectName,
IN PSECURITY_DESCRIPTOR SecurityDescriptor  OPTIONAL,
IN HANDLE  ClientToken,
IN ACCESS_MASK  DesiredAccess,
IN ACCESS_MASK  GrantedAccess,
IN PPRIVILEGE_SET Privileges  OPTIONAL,
IN BOOLEAN  ObjectCreation,
IN BOOLEAN  AccessGranted,
OUT PBOOLEAN  GenerateOnClose
 

Definition at line 2072 of file seaudit.c.

References ANYSIZE_ARRAY, ASSERT, ClientToken, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, IsValidElementCount, KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, PagedPool, _SECURITY_SUBJECT_CONTEXT::PrimaryToken, ProbeForRead, ProbeForWriteBoolean, PsGetCurrentProcess, PsProcessAuditId, PTOKEN, SeCaptureSecurityDescriptor(), SeCaptureSubjectContext(), SeCheckAuditPrivilege(), SepAdtAuditThisEvent, SepAdtOpenObjectAuditAlarm(), SepAdtPrivilegeObjectAuditAlarm(), SepExamineSacl(), SepFreeCapturedString(), SepProbeAndCaptureString_U(), SepTokenObjectType, SeReleaseSecurityDescriptor(), SeReleaseSubjectContext(), Status, Token, and TRUE.

02088 : 02089 02090 This routine is used to generate audit and alarm messages when an 02091 attempt is made to access an existing protected subsystem object or 02092 create a new one. This routine may result in several messages being 02093 generated and sent to Port objects. This may result in a significant 02094 latency before returning. Design of routines that must call this 02095 routine must take this potential latency into account. This may have 02096 an impact on the approach taken for data structure mutex locking, for 02097 example. 02098 02099 This routine may not be able to generate a complete audit record 02100 due to memory restrictions. 02101 02102 This API requires the caller have SeAuditPrivilege privilege. The test 02103 for this privilege is always against the primary token of the calling 02104 process, not the impersonation token of the thread. 02105 02106 Arguments: 02107 02108 SubsystemName - Supplies a name string identifying the 02109 subsystem calling the routine. 02110 02111 HandleId - A unique value representing the client's handle to the 02112 object. If the access attempt was not successful (AccessGranted is 02113 FALSE), then this parameter is ignored. 02114 02115 ObjectTypeName - Supplies the name of the type of object being 02116 accessed. 02117 02118 ObjectName - Supplies the name of the object the client 02119 accessed or attempted to access. 02120 02121 SecurityDescriptor - An optional pointer to the security descriptor of 02122 the object being accessed. 02123 02124 ClientToken - A handle to a token object representing the client that 02125 requested the operation. This handle must be obtained from a 02126 communication session layer, such as from an LPC Port or Local 02127 Named Pipe, to prevent possible security policy violations. 02128 02129 DesiredAccess - The desired access mask. This mask must have been 02130 previously mapped to contain no generic accesses. 02131 02132 GrantedAccess - The mask of accesses that were actually granted. 02133 02134 Privileges - Optionally points to a set of privileges that were 02135 required for the access attempt. Those privileges that were held 02136 by the subject are marked using the UsedForAccess flag of the 02137 attributes associated with each privilege. 02138 02139 ObjectCreation - A boolean flag indicating whether the access will 02140 result in a new object being created if granted. A value of TRUE 02141 indicates an object will be created, FALSE indicates an existing 02142 object will be opened. 02143 02144 AccessGranted - Indicates whether the requested access was granted or 02145 not. A value of TRUE indicates the access was granted. A value of 02146 FALSE indicates the access was not granted. 02147 02148 GenerateOnClose - Points to a boolean that is set by the audit 02149 generation routine and must be passed to NtCloseObjectAuditAlarm() 02150 when the object handle is closed. 02151 02152 Return Value: 02153 02154 --*/ 02155 { 02156 02157 KPROCESSOR_MODE PreviousMode; 02158 ULONG PrivilegeParameterLength; 02159 PUNICODE_STRING CapturedSubsystemName = (PUNICODE_STRING) NULL; 02160 PUNICODE_STRING CapturedObjectTypeName = (PUNICODE_STRING) NULL; 02161 PUNICODE_STRING CapturedObjectName = (PUNICODE_STRING) NULL; 02162 PSECURITY_DESCRIPTOR CapturedSecurityDescriptor = (PSECURITY_DESCRIPTOR) NULL; 02163 PPRIVILEGE_SET CapturedPrivileges = NULL; 02164 BOOLEAN LocalGenerateOnClose = FALSE; 02165 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 02166 BOOLEAN Result; 02167 NTSTATUS Status; 02168 BOOLEAN GenerateAudit = FALSE; 02169 BOOLEAN GenerateAlarm = FALSE; 02170 PLUID ClientAuthenticationId = NULL; 02171 HANDLE CapturedHandleId = NULL; 02172 BOOLEAN AuditPerformed; 02173 ULONG PrivilegeCount; 02174 02175 PTOKEN Token; 02176 02177 PAGED_CODE(); 02178 02179 PreviousMode = KeGetPreviousMode(); 02180 02181 ASSERT( PreviousMode != KernelMode ); 02182 02183 Status = ObReferenceObjectByHandle( ClientToken, // Handle 02184 TOKEN_QUERY, // DesiredAccess 02185 SepTokenObjectType, // ObjectType 02186 PreviousMode, // AccessMode 02187 (PVOID *)&Token, // Object 02188 NULL // GrantedAccess 02189 ); 02190 02191 if (!NT_SUCCESS(Status)) { 02192 return( Status ); 02193 } 02194 02195 // 02196 // If the passed token is an impersonation token, make sure 02197 // it is at SecurityIdentification or above. 02198 // 02199 02200 if (Token->TokenType == TokenImpersonation) { 02201 02202 if (Token->ImpersonationLevel < SecurityIdentification) { 02203 02204 ObDereferenceObject( (PVOID)Token ); 02205 02206 return( STATUS_BAD_IMPERSONATION_LEVEL ); 02207 02208 } 02209 } 02210 02211 // 02212 // Check for SeAuditPrivilege. This must be tested against 02213 // the caller's primary token. 02214 // 02215 02216 SeCaptureSubjectContext ( &SubjectSecurityContext ); 02217 02218 Result = SeCheckAuditPrivilege ( 02219 &SubjectSecurityContext, 02220 PreviousMode 02221 ); 02222 02223 if (!Result) { 02224 02225 ObDereferenceObject( (PVOID)Token ); 02226 02227 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02228 02229 return(STATUS_PRIVILEGE_NOT_HELD); 02230 } 02231 02232 // 02233 // This will just return NULL if the input descriptor is NULL 02234 // 02235 02236 Status = SeCaptureSecurityDescriptor ( SecurityDescriptor, 02237 PreviousMode, 02238 PagedPool, 02239 FALSE, 02240 &CapturedSecurityDescriptor 02241 ); 02242 02243 // 02244 // At this point in time, if there's no security descriptor, there's 02245 // nothing to do. Return success. 02246 // 02247 02248 if (!NT_SUCCESS( Status ) || CapturedSecurityDescriptor == NULL) { 02249 02250 ObDereferenceObject( (PVOID)Token ); 02251 02252 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02253 02254 return( Status ); 02255 } 02256 02257 try { 02258 02259 // 02260 // Only capture the privileges if we've completed a successful 02261 // access check. Otherwise they don't mean anything. 02262 // 02263 02264 if (AccessGranted && ARGUMENT_PRESENT(Privileges)) { 02265 02266 ProbeForRead( 02267 Privileges, 02268 sizeof(PRIVILEGE_SET), 02269 sizeof(ULONG) 02270 ); 02271 02272 PrivilegeCount = Privileges->PrivilegeCount; 02273 if (!IsValidElementCount( PrivilegeCount, LUID_AND_ATTRIBUTES) ) { 02274 Status = STATUS_INVALID_PARAMETER; 02275 leave; 02276 } 02277 02278 PrivilegeParameterLength = (ULONG)sizeof(PRIVILEGE_SET) + 02279 ((PrivilegeCount - ANYSIZE_ARRAY) * 02280 (ULONG)sizeof(LUID_AND_ATTRIBUTES) ); 02281 02282 ProbeForRead( 02283 Privileges, 02284 PrivilegeParameterLength, 02285 sizeof(ULONG) 02286 ); 02287 02288 CapturedPrivileges = ExAllocatePoolWithTag( PagedPool, 02289 PrivilegeParameterLength, 02290 'rPeS' 02291 ); 02292 02293 if (CapturedPrivileges != NULL) { 02294 02295 RtlCopyMemory ( CapturedPrivileges, 02296 Privileges, 02297 PrivilegeParameterLength ); 02298 CapturedPrivileges->PrivilegeCount = PrivilegeCount; 02299 } else { 02300 02301 SeReleaseSecurityDescriptor ( CapturedSecurityDescriptor, 02302 PreviousMode, 02303 FALSE ); 02304 02305 ObDereferenceObject( (PVOID)Token ); 02306 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02307 return( STATUS_INSUFFICIENT_RESOURCES ); 02308 } 02309 02310 02311 } 02312 02313 if (ARGUMENT_PRESENT( HandleId )) { 02314 02315 ProbeForRead( (PHANDLE)HandleId, sizeof(PVOID), sizeof(PVOID) ); 02316 CapturedHandleId = *(PHANDLE)HandleId; 02317 } 02318 02319 ProbeForWriteBoolean(GenerateOnClose); 02320 02321 // 02322 // Probe and Capture the parameter strings. 02323 // If we run out of memory attempting to capture 02324 // the strings, the returned pointer will be 02325 // NULL and we will continue with the audit. 02326 // 02327 02328 SepProbeAndCaptureString_U ( SubsystemName, 02329 &CapturedSubsystemName ); 02330 02331 SepProbeAndCaptureString_U ( ObjectTypeName, 02332 &CapturedObjectTypeName ); 02333 02334 SepProbeAndCaptureString_U ( ObjectName, 02335 &CapturedObjectName ); 02336 02337 } except(EXCEPTION_EXECUTE_HANDLER) { 02338 Status = GetExceptionCode(); 02339 } 02340 02341 if (!NT_SUCCESS(Status)) { 02342 02343 if (CapturedSubsystemName != NULL) { 02344 SepFreeCapturedString( CapturedSubsystemName ); 02345 } 02346 02347 if (CapturedObjectTypeName != NULL) { 02348 SepFreeCapturedString( CapturedObjectTypeName ); 02349 } 02350 02351 if (CapturedObjectName != NULL) { 02352 SepFreeCapturedString( CapturedObjectName ); 02353 } 02354 02355 if (CapturedPrivileges != NULL) { 02356 ExFreePool( CapturedPrivileges ); 02357 } 02358 02359 if (CapturedSecurityDescriptor != NULL) { 02360 02361 SeReleaseSecurityDescriptor ( CapturedSecurityDescriptor, 02362 PreviousMode, 02363 FALSE ); 02364 } 02365 02366 ObDereferenceObject( (PVOID)Token ); 02367 02368 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02369 02370 return Status; 02371 02372 } 02373 02374 if ( SepAdtAuditThisEvent( AuditCategoryObjectAccess, &AccessGranted) ) { 02375 02376 SepExamineSacl( 02377 RtlpSaclAddrSecurityDescriptor( (PISECURITY_DESCRIPTOR)CapturedSecurityDescriptor ), 02378 Token, 02379 DesiredAccess | GrantedAccess, 02380 AccessGranted, 02381 &GenerateAudit, 02382 &GenerateAlarm 02383 ); 02384 02385 if (GenerateAudit || GenerateAlarm) { 02386 02387 // 02388 // Take a read lock on the token, because we're going to extract 02389 // the user's Sid from it. 02390 // 02391 02392 LocalGenerateOnClose = TRUE; 02393 02394 AuditPerformed = SepAdtOpenObjectAuditAlarm ( CapturedSubsystemName, 02395 ARGUMENT_PRESENT(HandleId) ? (PVOID)&CapturedHandleId : NULL, 02396 CapturedObjectTypeName, 02397 NULL, 02398 CapturedObjectName, 02399 Token, 02400 SubjectSecurityContext.PrimaryToken, 02401 DesiredAccess, 02402 GrantedAccess, 02403 NULL, 02404 CapturedPrivileges, 02405 ObjectCreation, 02406 AccessGranted, 02407 GenerateAudit, 02408 GenerateAlarm, 02409 PsProcessAuditId( PsGetCurrentProcess() ), 02410 AuditCategoryObjectAccess, 02411 NULL, 02412 0, 02413 NULL 02414 ); 02415 02416 LocalGenerateOnClose = AuditPerformed; 02417 } 02418 } 02419 02420 if ( !(GenerateAudit || GenerateAlarm) ) { 02421 02422 // 02423 // We didn't attempt to generate an audit above, so if privileges were used, 02424 // see if we should generate an audit here. 02425 // 02426 02427 if ( ARGUMENT_PRESENT(Privileges) ) { 02428 02429 if ( SepAdtAuditThisEvent( AuditCategoryPrivilegeUse, &AccessGranted) ) { 02430 02431 AuditPerformed = SepAdtPrivilegeObjectAuditAlarm ( CapturedSubsystemName, 02432 CapturedHandleId, 02433 Token, 02434 SubjectSecurityContext.PrimaryToken, 02435 PsProcessAuditId( PsGetCurrentProcess() ), 02436 DesiredAccess, 02437 CapturedPrivileges, 02438 AccessGranted 02439 ); 02440 // 02441 // If we generate an audit due to use of privilege, don't set generate on close, 02442 // because then we'll have a close audit without a corresponding open audit. 02443 // 02444 02445 LocalGenerateOnClose = FALSE; 02446 } 02447 } 02448 } 02449 02450 if (CapturedSecurityDescriptor != NULL) { 02451 02452 SeReleaseSecurityDescriptor ( CapturedSecurityDescriptor, 02453 PreviousMode, 02454 FALSE ); 02455 } 02456 02457 if (CapturedSubsystemName != NULL) { 02458 SepFreeCapturedString( CapturedSubsystemName ); 02459 } 02460 02461 if (CapturedObjectTypeName != NULL) { 02462 SepFreeCapturedString( CapturedObjectTypeName ); 02463 } 02464 02465 if (CapturedObjectName != NULL) { 02466 SepFreeCapturedString( CapturedObjectName ); 02467 } 02468 02469 if (CapturedPrivileges != NULL) { 02470 ExFreePool( CapturedPrivileges ); 02471 } 02472 02473 ObDereferenceObject( (PVOID)Token ); 02474 02475 SeReleaseSubjectContext ( &SubjectSecurityContext ); 02476 02477 try { 02478 02479 *GenerateOnClose = LocalGenerateOnClose; 02480 02481 } except (EXCEPTION_EXECUTE_HANDLER) { 02482 02483 return GetExceptionCode(); 02484 } 02485 02486 return(STATUS_SUCCESS); 02487 }

NTSTATUS NtPrivilegedServiceAuditAlarm IN PUNICODE_STRING  SubsystemName,
IN PUNICODE_STRING  ServiceName,
IN HANDLE  ClientToken,
IN PPRIVILEGE_SET  Privileges,
IN BOOLEAN  AccessGranted
 

Definition at line 731 of file seaudit.c.

References ANYSIZE_ARRAY, ASSERT, ClientToken, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), IsValidElementCount, KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, PagedPool, _SECURITY_SUBJECT_CONTEXT::PrimaryToken, ProbeForRead, PTOKEN, SeCaptureSubjectContext(), SeCheckAuditPrivilege(), SepAdtPrivilegedServiceAuditAlarm(), SepFreeCapturedString(), SepProbeAndCaptureString_U(), SepTokenObjectType, SeReleaseSubjectContext(), Status, and Token.

00741 : 00742 00743 This routine is used to generate audit and alarm messages when an 00744 attempt is made to perform privileged system service operations. This 00745 routine may result in several messages being generated and sent to Port 00746 objects. This may result in a significant latency before returning. 00747 Design of routines that must call this routine must take this potential 00748 latency into account. This may have an impact on the approach taken 00749 for data structure mutex locking, for example. 00750 00751 This API requires the caller have SeAuditPrivilege privilege. The test 00752 for this privilege is always against the primary token of the calling 00753 process, allowing the caller to be impersonating a client during the 00754 call with no ill effects 00755 00756 Arguments: 00757 00758 SubsystemName - Supplies a name string identifying the subsystem 00759 calling the routine. 00760 00761 ServiceName - Supplies a name of the privileged subsystem service. For 00762 example, "RESET RUNTIME LOCAL SECURITY POLICY" might be specified 00763 by a Local Security Authority service used to update the local 00764 security policy database. 00765 00766 ClientToken - A handle to a token object representing the client that 00767 requested the operation. This handle must be obtained from a 00768 communication session layer, such as from an LPC Port or Local 00769 Named Pipe, to prevent possible security policy violations. 00770 00771 Privileges - Points to a set of privileges required to perform the 00772 privileged operation. Those privileges that were held by the 00773 subject are marked using the UsedForAccess flag of the 00774 attributes associated with each privilege. 00775 00776 AccessGranted - Indicates whether the requested access was granted or 00777 not. A value of TRUE indicates the access was granted. A value of 00778 FALSE indicates the access was not granted. 00779 00780 Return value: 00781 00782 --*/ 00783 00784 { 00785 00786 PPRIVILEGE_SET CapturedPrivileges = NULL; 00787 ULONG PrivilegeParameterLength = 0; 00788 BOOLEAN Result; 00789 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 00790 KPROCESSOR_MODE PreviousMode; 00791 PUNICODE_STRING CapturedSubsystemName = NULL; 00792 PUNICODE_STRING CapturedServiceName = NULL; 00793 NTSTATUS Status; 00794 PTOKEN Token; 00795 ULONG PrivilegeCount; 00796 00797 PAGED_CODE(); 00798 00799 PreviousMode = KeGetPreviousMode(); 00800 00801 ASSERT(PreviousMode != KernelMode); 00802 00803 Status = ObReferenceObjectByHandle( 00804 ClientToken, // Handle 00805 TOKEN_QUERY, // DesiredAccess 00806 SepTokenObjectType, // ObjectType 00807 PreviousMode, // AccessMode 00808 (PVOID *)&Token, // Object 00809 NULL // GrantedAccess 00810 ); 00811 00812 if ( !NT_SUCCESS( Status )) { 00813 return( Status ); 00814 } 00815 00816 // 00817 // If the passed token is an impersonation token, make sure 00818 // it is at SecurityIdentification or above. 00819 // 00820 00821 if (Token->TokenType == TokenImpersonation) { 00822 00823 if (Token->ImpersonationLevel < SecurityIdentification) { 00824 00825 ObDereferenceObject( (PVOID)Token ); 00826 00827 return( STATUS_BAD_IMPERSONATION_LEVEL ); 00828 00829 } 00830 } 00831 00832 // // 00833 // // Make sure the passed token is an impersonation token... 00834 // // 00835 // 00836 // if (Token->TokenType != TokenImpersonation) { 00837 // 00838 // ObDereferenceObject( (PVOID)Token ); 00839 // 00840 // return( STATUS_NO_IMPERSONATION_TOKEN ); 00841 // 00842 // } 00843 // 00844 // // 00845 // // ...and at a high enough impersonation level 00846 // // 00847 // 00848 // if (Token->ImpersonationLevel < SecurityIdentification) { 00849 // 00850 // ObDereferenceObject( (PVOID)Token ); 00851 // 00852 // return( STATUS_BAD_IMPERSONATION_LEVEL ); 00853 // 00854 // } 00855 00856 // 00857 // Check for SeAuditPrivilege 00858 // 00859 00860 SeCaptureSubjectContext ( &SubjectSecurityContext ); 00861 00862 Result = SeCheckAuditPrivilege ( 00863 &SubjectSecurityContext, 00864 PreviousMode 00865 ); 00866 00867 if (!Result) { 00868 00869 ObDereferenceObject( (PVOID)Token ); 00870 00871 SeReleaseSubjectContext ( &SubjectSecurityContext ); 00872 00873 return(STATUS_PRIVILEGE_NOT_HELD); 00874 } 00875 00876 try { 00877 00878 if ( ARGUMENT_PRESENT( SubsystemName )) { 00879 SepProbeAndCaptureString_U ( SubsystemName, 00880 &CapturedSubsystemName ); 00881 } 00882 00883 if ( ARGUMENT_PRESENT( ServiceName )) { 00884 SepProbeAndCaptureString_U ( ServiceName, 00885 &CapturedServiceName ); 00886 00887 } 00888 00889 ProbeForRead( 00890 Privileges, 00891 sizeof(PRIVILEGE_SET), 00892 sizeof(ULONG) 00893 ); 00894 00895 PrivilegeCount = Privileges->PrivilegeCount; 00896 00897 if (!IsValidElementCount( PrivilegeCount, LUID_AND_ATTRIBUTES ) ) { 00898 Status = STATUS_INVALID_PARAMETER; 00899 leave ; 00900 } 00901 PrivilegeParameterLength = (ULONG)sizeof(PRIVILEGE_SET) + 00902 ((PrivilegeCount - ANYSIZE_ARRAY) * 00903 (ULONG)sizeof(LUID_AND_ATTRIBUTES) ); 00904 00905 ProbeForRead( 00906 Privileges, 00907 PrivilegeParameterLength, 00908 sizeof(ULONG) 00909 ); 00910 00911 CapturedPrivileges = ExAllocatePoolWithTag( PagedPool, 00912 PrivilegeParameterLength, 00913 'rPeS' 00914 ); 00915 00916 // 00917 // If ExAllocatePool has failed, too bad. Carry on and do as much of the 00918 // audit as we can. 00919 // 00920 00921 if (CapturedPrivileges != NULL) { 00922 00923 RtlCopyMemory ( CapturedPrivileges, 00924 Privileges, 00925 PrivilegeParameterLength ); 00926 CapturedPrivileges->PrivilegeCount = PrivilegeCount; 00927 00928 } 00929 00930 } except (EXCEPTION_EXECUTE_HANDLER) { 00931 Status = GetExceptionCode(); 00932 } 00933 00934 if (!NT_SUCCESS(Status)) { 00935 00936 if (CapturedSubsystemName != NULL) { 00937 SepFreeCapturedString ( CapturedSubsystemName ); 00938 } 00939 00940 if (CapturedServiceName != NULL) { 00941 SepFreeCapturedString ( CapturedServiceName ); 00942 } 00943 00944 if (CapturedPrivileges != NULL) { 00945 ExFreePool ( CapturedPrivileges ); 00946 } 00947 00948 SeReleaseSubjectContext ( &SubjectSecurityContext ); 00949 00950 ObDereferenceObject( (PVOID)Token ); 00951 00952 return Status; 00953 00954 } 00955 00956 // 00957 // The AuthenticationId is in the read-only part of the token, 00958 // so we may reference it without having the token read-locked. 00959 // 00960 00961 SepAdtPrivilegedServiceAuditAlarm ( CapturedSubsystemName, 00962 CapturedServiceName, 00963 Token, 00964 SubjectSecurityContext.PrimaryToken, 00965 CapturedPrivileges, 00966 AccessGranted ); 00967 00968 if (CapturedSubsystemName != NULL) { 00969 SepFreeCapturedString ( CapturedSubsystemName ); 00970 } 00971 00972 if (CapturedServiceName != NULL) { 00973 SepFreeCapturedString ( CapturedServiceName ); 00974 } 00975 00976 if (CapturedPrivileges != NULL) { 00977 ExFreePool ( CapturedPrivileges ); 00978 } 00979 00980 ObDereferenceObject( (PVOID)Token ); 00981 00982 SeReleaseSubjectContext ( &SubjectSecurityContext ); 00983 00984 return(STATUS_SUCCESS); 00985 }

NTSTATUS NtPrivilegeObjectAuditAlarm IN PUNICODE_STRING  SubsystemName,
IN PVOID  HandleId,
IN HANDLE  ClientToken,
IN ACCESS_MASK  DesiredAccess,
IN PPRIVILEGE_SET  Privileges,
IN BOOLEAN  AccessGranted
 

Definition at line 406 of file seaudit.c.

References ANYSIZE_ARRAY, ASSERT, ClientToken, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), IsValidElementCount, KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, PagedPool, _SECURITY_SUBJECT_CONTEXT::PrimaryToken, ProbeForRead, _SECURITY_SUBJECT_CONTEXT::ProcessAuditId, PTOKEN, SeCaptureSubjectContext(), SeCheckAuditPrivilege(), SepAdtPrivilegeObjectAuditAlarm(), SepFreeCapturedString(), SepProbeAndCaptureString_U(), SepTokenObjectType, SeReleaseSubjectContext(), Status, and Token.

Referenced by IsPrivileged().

00416 : 00417 00418 This routine is used to generate audit and alarm messages when an 00419 attempt is made to perform privileged operations on a protected 00420 subsystem object after the object is already opened. This routine may 00421 result in several messages being generated and sent to Port objects. 00422 This may result in a significant latency before returning. Design of 00423 routines that must call this routine must take this potential latency 00424 into account. This may have an impact on the approach taken for data 00425 structure mutex locking, for example. 00426 00427 This API requires the caller have SeAuditPrivilege privilege. The test 00428 for this privilege is always against the primary token of the calling 00429 process, allowing the caller to be impersonating a client during the 00430 call with no ill effects. 00431 00432 Arguments: 00433 00434 SubsystemName - Supplies a name string identifying the subsystem 00435 calling the routine. 00436 00437 HandleId - A unique value representing the client's handle to the 00438 object. 00439 00440 ClientToken - A handle to a token object representing the client that 00441 requested the operation. This handle must be obtained from a 00442 communication session layer, such as from an LPC Port or Local 00443 Named Pipe, to prevent possible security policy violations. 00444 00445 DesiredAccess - The desired access mask. This mask must have been 00446 previously mapped to contain no generic accesses. 00447 00448 Privileges - The set of privileges required for the requested 00449 operation. Those privileges that were held by the subject are 00450 marked using the UsedForAccess flag of the attributes 00451 associated with each privilege. 00452 00453 AccessGranted - Indicates whether the requested access was granted or 00454 not. A value of TRUE indicates the access was granted. A value of 00455 FALSE indicates the access was not granted. 00456 00457 Return value: 00458 00459 --*/ 00460 { 00461 00462 KPROCESSOR_MODE PreviousMode; 00463 PUNICODE_STRING CapturedSubsystemName = NULL; 00464 PPRIVILEGE_SET CapturedPrivileges = NULL; 00465 ULONG PrivilegeParameterLength; 00466 ULONG PrivilegeCount; 00467 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 00468 BOOLEAN Result; 00469 PTOKEN Token; 00470 NTSTATUS Status; 00471 BOOLEAN AuditPerformed; 00472 00473 PAGED_CODE(); 00474 00475 PreviousMode = KeGetPreviousMode(); 00476 00477 ASSERT(PreviousMode != KernelMode); 00478 00479 Status = ObReferenceObjectByHandle( 00480 ClientToken, // Handle 00481 TOKEN_QUERY, // DesiredAccess 00482 SepTokenObjectType, // ObjectType 00483 PreviousMode, // AccessMode 00484 (PVOID *)&Token, // Object 00485 NULL // GrantedAccess 00486 ); 00487 00488 if (!NT_SUCCESS( Status )) { 00489 return( Status ); 00490 } 00491 00492 // 00493 // If the passed token is an impersonation token, make sure 00494 // it is at SecurityIdentification or above. 00495 // 00496 00497 if (Token->TokenType == TokenImpersonation) { 00498 00499 if (Token->ImpersonationLevel < SecurityIdentification) { 00500 00501 ObDereferenceObject( (PVOID)Token ); 00502 00503 return( STATUS_BAD_IMPERSONATION_LEVEL ); 00504 00505 } 00506 } 00507 00508 // // 00509 // // Make sure the passed token is an impersonation token... 00510 // // 00511 // 00512 // if (Token->TokenType != TokenImpersonation) { 00513 // 00514 // ObDereferenceObject( (PVOID)Token ); 00515 // 00516 // return( STATUS_NO_IMPERSONATION_TOKEN ); 00517 // 00518 // } 00519 // 00520 // // 00521 // // ...and at a high enough impersonation level 00522 // // 00523 // 00524 // if (Token->ImpersonationLevel < SecurityIdentification) { 00525 // 00526 // ObDereferenceObject( (PVOID)Token ); 00527 // 00528 // return( STATUS_BAD_IMPERSONATION_LEVEL ); 00529 // 00530 // } 00531 00532 // 00533 // Check for SeAuditPrivilege 00534 // 00535 00536 SeCaptureSubjectContext ( &SubjectSecurityContext ); 00537 00538 Result = SeCheckAuditPrivilege ( 00539 &SubjectSecurityContext, 00540 PreviousMode 00541 ); 00542 00543 if (!Result) { 00544 00545 ObDereferenceObject( (PVOID)Token ); 00546 SeReleaseSubjectContext ( &SubjectSecurityContext ); 00547 return(STATUS_PRIVILEGE_NOT_HELD); 00548 00549 } 00550 00551 try { 00552 00553 SepProbeAndCaptureString_U ( SubsystemName, 00554 &CapturedSubsystemName ); 00555 00556 ProbeForRead( 00557 Privileges, 00558 sizeof(PRIVILEGE_SET), 00559 sizeof(ULONG) 00560 ); 00561 PrivilegeCount = Privileges->PrivilegeCount; 00562 00563 if (!IsValidElementCount(PrivilegeCount, LUID_AND_ATTRIBUTES)) { 00564 Status= STATUS_INVALID_PARAMETER; 00565 leave ; 00566 } 00567 PrivilegeParameterLength = (ULONG)sizeof(PRIVILEGE_SET) + 00568 ((PrivilegeCount - ANYSIZE_ARRAY) * 00569 (ULONG)sizeof(LUID_AND_ATTRIBUTES) ); 00570 00571 ProbeForRead( 00572 Privileges, 00573 PrivilegeParameterLength, 00574 sizeof(ULONG) 00575 ); 00576 00577 CapturedPrivileges = ExAllocatePoolWithTag( PagedPool, 00578 PrivilegeParameterLength, 00579 'rPeS' 00580 ); 00581 00582 if (CapturedPrivileges != NULL) { 00583 00584 RtlCopyMemory ( CapturedPrivileges, 00585 Privileges, 00586 PrivilegeParameterLength ); 00587 CapturedPrivileges->PrivilegeCount = PrivilegeCount; 00588 } 00589 00590 } except (EXCEPTION_EXECUTE_HANDLER) { 00591 00592 Status = GetExceptionCode(); 00593 } 00594 if (!NT_SUCCESS(Status)) { 00595 00596 if (CapturedPrivileges != NULL) { 00597 ExFreePool( CapturedPrivileges ); 00598 } 00599 00600 if (CapturedSubsystemName != NULL) { 00601 SepFreeCapturedString ( CapturedSubsystemName ); 00602 } 00603 00604 SeReleaseSubjectContext ( &SubjectSecurityContext ); 00605 00606 ObDereferenceObject( (PVOID)Token ); 00607 00608 return Status; 00609 00610 } 00611 00612 // 00613 // No need to lock the token, because the only thing we're going 00614 // to reference in it is the User's Sid, which cannot be changed. 00615 // 00616 00617 // 00618 // SepPrivilegeObjectAuditAlarm will check the global flags 00619 // to determine if we're supposed to be auditing here. 00620 // 00621 00622 AuditPerformed = SepAdtPrivilegeObjectAuditAlarm ( 00623 CapturedSubsystemName, 00624 HandleId, 00625 Token, // ClientToken 00626 SubjectSecurityContext.PrimaryToken, // PrimaryToken 00627 SubjectSecurityContext.ProcessAuditId, 00628 DesiredAccess, 00629 CapturedPrivileges, 00630 AccessGranted 00631 ); 00632 00633 if (CapturedPrivileges != NULL) { 00634 ExFreePool( CapturedPrivileges ); 00635 } 00636 00637 if (CapturedSubsystemName != NULL) { 00638 SepFreeCapturedString ( CapturedSubsystemName ); 00639 } 00640 00641 SeReleaseSubjectContext ( &SubjectSecurityContext ); 00642 00643 ObDereferenceObject( (PVOID)Token ); 00644 00645 return(STATUS_SUCCESS); 00646 }

VOID SeAuditHandleCreation IN PACCESS_STATE  AccessState,
IN HANDLE  Handle
 

Definition at line 3736 of file seaudit.c.

References FALSE, Handle, NULL, PAGED_CODE, _AUX_ACCESS_DATA::PrivilegesUsed, PsGetCurrentProcessId(), PTOKEN, SepAdtOpenObjectAuditAlarm(), SepAdtPrivilegeObjectAuditAlarm(), SeSubsystemName, and TRUE.

Referenced by NtDuplicateObject(), and ObpCreateHandle().

03743 : 03744 03745 This function audits the creation of a handle. 03746 03747 It will examine the AuditHandleCreation field in the passed AccessState, 03748 which will indicate whether auditing was performed when the object 03749 was found or created. 03750 03751 This routine is necessary because object name decoding and handle 03752 allocation occur in widely separate places, preventing us from 03753 auditing everything at once. 03754 03755 Arguments: 03756 03757 AccessState - Supplies a pointer to the AccessState structure 03758 representing this access attempt. 03759 03760 Handle - The newly allocated handle value. 03761 03762 Return Value: 03763 03764 None. 03765 03766 --*/ 03767 03768 { 03769 BOOLEAN AuditPerformed = FALSE; 03770 PAUX_ACCESS_DATA AuxData; 03771 03772 PAGED_CODE(); 03773 03774 AuxData = (PAUX_ACCESS_DATA)AccessState->AuxData; 03775 03776 if ( AccessState->GenerateAudit ) { 03777 03778 if ( AccessState->AuditPrivileges ) { 03779 03780 AuditPerformed = SepAdtPrivilegeObjectAuditAlarm ( 03781 &SeSubsystemName, 03782 Handle, 03783 (PTOKEN)AccessState->SubjectSecurityContext.ClientToken, 03784 (PTOKEN)AccessState->SubjectSecurityContext.PrimaryToken, 03785 &AccessState->SubjectSecurityContext.ProcessAuditId, 03786 AccessState->PreviouslyGrantedAccess, 03787 AuxData->PrivilegesUsed, 03788 TRUE 03789 ); 03790 } else { 03791 03792 AuditPerformed = SepAdtOpenObjectAuditAlarm ( &SeSubsystemName, 03793 &Handle, 03794 &AccessState->ObjectTypeName, 03795 NULL, 03796 &AccessState->ObjectName, 03797 AccessState->SubjectSecurityContext.ClientToken, 03798 AccessState->SubjectSecurityContext.PrimaryToken, 03799 AccessState->OriginalDesiredAccess, 03800 AccessState->PreviouslyGrantedAccess, 03801 &AccessState->OperationID, 03802 AuxData->PrivilegesUsed, 03803 FALSE, 03804 TRUE, 03805 TRUE, 03806 FALSE, 03807 PsGetCurrentProcessId(), 03808 AuditCategoryObjectAccess, 03809 NULL, 03810 0, 03811 NULL ); 03812 } 03813 } 03814 03815 // 03816 // If we generated an 'open' audit, make sure we generate a close 03817 // 03818 03819 AccessState->GenerateOnClose = AuditPerformed; 03820 03821 return; 03822 }

BOOLEAN SeAuditingFileEvents IN BOOLEAN  AccessGranted,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor
 

Definition at line 4693 of file seaudit.c.

References PAGED_CODE, and SepAdtAuditThisEvent.

04700 : 04701 04702 This routine is to be called by a file system to quickly determine 04703 if we are auditing file open events. This allows the file system 04704 to avoid the often considerable setup involved in generating an audit. 04705 04706 Arguments: 04707 04708 AccessGranted - Supplies whether the access attempt was successful 04709 or a failure. 04710 04711 Return Value: 04712 04713 Boolean - TRUE if events of type AccessGranted are being audited, FALSE 04714 otherwise. 04715 04716 --*/ 04717 04718 { 04719 PAGED_CODE(); 04720 04721 UNREFERENCED_PARAMETER( SecurityDescriptor ); 04722 04723 return( SepAdtAuditThisEvent( AuditCategoryObjectAccess, &AccessGranted ) ); 04724 }

BOOLEAN SeAuditingFileOrGlobalEvents IN BOOLEAN  AccessGranted,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor,
IN PSECURITY_SUBJECT_CONTEXT  SubjectSecurityContext
 

Definition at line 4648 of file seaudit.c.

References EffectiveToken, FALSE, NULL, PAGED_CODE, PTOKEN, SepAdtAuditThisEvent, and TRUE.

04656 : 04657 04658 This routine is to be called by a file system to quickly determine 04659 if we are auditing file open events. This allows the file system 04660 to avoid the often considerable setup involved in generating an audit. 04661 04662 Arguments: 04663 04664 AccessGranted - Supplies whether the access attempt was successful 04665 or a failure. 04666 04667 Return Value: 04668 04669 Boolean - TRUE if events of type AccessGranted are being audited, FALSE 04670 otherwise. 04671 04672 --*/ 04673 04674 { 04675 PISECURITY_DESCRIPTOR ISecurityDescriptor = (PISECURITY_DESCRIPTOR) SecurityDescriptor; 04676 04677 PAGED_CODE(); 04678 04679 if ( ((PTOKEN)EffectiveToken( SubjectSecurityContext ))->AuditData != NULL) { 04680 return( TRUE ); 04681 } 04682 04683 if ( RtlpSaclAddrSecurityDescriptor( ISecurityDescriptor ) == NULL ) { 04684 04685 return( FALSE ); 04686 } 04687 04688 return( SepAdtAuditThisEvent( AuditCategoryObjectAccess, &AccessGranted ) ); 04689 }

BOOLEAN SeCheckAuditPrivilege IN PSECURITY_SUBJECT_CONTEXT  SubjectSecurityContext,
IN KPROCESSOR_MODE  PreviousMode
 

Definition at line 199 of file seaudit.c.

References KernelMode, NULL, PAGED_CODE, SeAuditPrivilege, SepPrivilegeCheck(), and SePrivilegedServiceAuditAlarm().

Referenced by NtCloseObjectAuditAlarm(), NtDeleteObjectAuditAlarm(), NtOpenObjectAuditAlarm(), NtPrivilegedServiceAuditAlarm(), NtPrivilegeObjectAuditAlarm(), and SepAccessCheckAndAuditAlarm().

00205 : 00206 00207 This routine specifically searches the primary token (rather than 00208 the effective token) of the calling process for SeAuditPrivilege. 00209 In order to do this it must call the underlying worker 00210 SepPrivilegeCheck directly, to ensure that the correct token is 00211 searched 00212 00213 Arguments: 00214 00215 SubjectSecurityContext - The subject being examined. 00216 00217 PreviousMode - The previous processor mode. 00218 00219 Return Value: 00220 00221 Returns TRUE if the subject has SeAuditPrivilege, FALSE otherwise. 00222 00223 --*/ 00224 { 00225 00226 PRIVILEGE_SET RequiredPrivileges; 00227 BOOLEAN AccessGranted; 00228 00229 PAGED_CODE(); 00230 00231 RequiredPrivileges.PrivilegeCount = 1; 00232 RequiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY; 00233 RequiredPrivileges.Privilege[0].Luid = SeAuditPrivilege; 00234 RequiredPrivileges.Privilege[0].Attributes = 0; 00235 00236 AccessGranted = SepPrivilegeCheck( 00237 SubjectSecurityContext->PrimaryToken, // token 00238 RequiredPrivileges.Privilege, // privilege set 00239 RequiredPrivileges.PrivilegeCount, // privilege count 00240 PRIVILEGE_SET_ALL_NECESSARY, // privilege control 00241 PreviousMode // previous mode 00242 ); 00243 00244 if ( PreviousMode != KernelMode ) { 00245 00246 SePrivilegedServiceAuditAlarm ( 00247 NULL, // BUGWARNING need service name 00248 SubjectSecurityContext, 00249 &RequiredPrivileges, 00250 AccessGranted 00251 ); 00252 } 00253 00254 return( AccessGranted ); 00255 }

VOID SeCloseObjectAuditAlarm IN PVOID  Object,
IN HANDLE  Handle,
IN BOOLEAN  GenerateOnClose
 

Definition at line 3826 of file seaudit.c.

References EffectiveToken, Handle, NTSTATUS(), PAGED_CODE, SeCaptureSubjectContext(), SepAdtCloseObjectAuditAlarm(), SepTokenAuthenticationId, SepTokenUserSid, SeReleaseSubjectContext(), SeSubsystemName, and Status.

Referenced by NtClose().

03834 : 03835 03836 This routine is used to generate audit and alarm messages when a handle 03837 to an object is deleted. 03838 03839 This routine may result in several messages being generated and sent to 03840 Port objects. This may result in a significant latency before 03841 returning. Design of routines that must call this routine must take 03842 this potential latency into account. This may have an impact on the 03843 approach taken for data structure mutex locking, for example. 03844 03845 Arguments: 03846 03847 Object - Address of the object being accessed. This value will not be 03848 used as a pointer (referenced). It is necessary only to enter into 03849 log messages. 03850 03851 Handle - Supplies the handle value assigned to the open. 03852 03853 GenerateOnClose - Is a boolean value returned from a corresponding 03854 SeOpenObjectAuditAlarm() call when the object handle was created. 03855 03856 Return Value: 03857 03858 None. 03859 03860 --*/ 03861 03862 { 03863 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 03864 PSID UserSid; 03865 NTSTATUS Status; 03866 03867 PAGED_CODE(); 03868 03869 if (GenerateOnClose) { 03870 03871 SeCaptureSubjectContext ( &SubjectSecurityContext ); 03872 03873 UserSid = SepTokenUserSid( EffectiveToken (&SubjectSecurityContext)); 03874 03875 03876 SepAdtCloseObjectAuditAlarm ( 03877 &SeSubsystemName, 03878 (PVOID)Handle, 03879 Object, 03880 UserSid, 03881 SepTokenAuthenticationId( EffectiveToken (&SubjectSecurityContext)) 03882 ); 03883 03884 SeReleaseSubjectContext ( &SubjectSecurityContext ); 03885 } 03886 03887 return; 03888 }

VOID SeCreateObjectAuditAlarm IN PLUID OperationID  OPTIONAL,
IN PVOID  DirectoryObject,
IN PUNICODE_STRING  ComponentName,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor,
IN PSECURITY_SUBJECT_CONTEXT  SubjectSecurityContext,
IN ACCESS_MASK  DesiredAccess,
IN PPRIVILEGE_SET Privileges  OPTIONAL,
IN BOOLEAN  AccessGranted,
OUT PBOOLEAN  AuditPerformed,
IN KPROCESSOR_MODE  AccessMode
 

Definition at line 3538 of file seaudit.c.

References DirectoryName, EffectiveToken, ExFreePool(), FALSE, KernelMode, NULL, PAGED_CODE, SepAdtAuditThisEvent, SepAdtCreateObjectAuditAlarm(), SepExamineSacl(), SepQueryNameString(), SepTokenAuthenticationId, SepTokenUserSid, and TRUE.

Referenced by CmpCheckCreateAccess(), and ObCheckCreateObjectAccess().

03553 : 03554 03555 Audits the creation of an object in a directory. 03556 03557 Arguments: 03558 03559 OperationID - Optionally supplies the LUID representing the operation 03560 id for this operation. 03561 03562 DirectoryObject - Provides a pointer to the directory object being 03563 examined. 03564 03565 ComponentName - Provides a pointer to a Unicode string containing the 03566 relative name of the object being created. 03567 03568 SecurityDescriptor - The security descriptor for the passed direcctory. 03569 03570 SubjectSecurityContext - The current subject context. 03571 03572 DesiredAccess - The desired access to the directory. 03573 03574 Privileges - Returns any privileges that were used for the access attempt. 03575 03576 AccessGranted - Returns whether or not the access was successful. 03577 03578 AuditPerformed - Returns whether or not auditing was performed. 03579 03580 AccessMode - The previous mode. 03581 03582 Return Value: 03583 03584 return-value - Description of conditions needed to return value. - or - 03585 None. 03586 03587 --*/ 03588 03589 { 03590 PAGED_CODE(); 03591 #if 0 03592 03593 BOOLEAN GenerateAudit = FALSE; 03594 BOOLEAN GenerateAlarm = FALSE; 03595 PUNICODE_STRING DirectoryName; 03596 POBJECT_NAME_INFORMATION ObjectNameInformation = NULL; 03597 03598 UNREFERENCED_PARAMETER( DirectoryObject ); 03599 UNREFERENCED_PARAMETER( Privileges ); 03600 03601 if (AccessMode == KernelMode) { 03602 return; 03603 } 03604 03605 if ( SecurityDescriptor != NULL ) { 03606 03607 if ( SepAdtAuditThisEvent( AuditCategoryObjectAccess, &AccessGranted )) { 03608 03609 SepExamineSacl( 03610 RtlpSaclAddrSecurityDescriptor( (PISECURITY_DESCRIPTOR)SecurityDescriptor ), 03611 EffectiveToken( SubjectSecurityContext ), 03612 DesiredAccess, 03613 AccessGranted, 03614 &GenerateAudit, 03615 &GenerateAlarm 03616 ); 03617 03618 if ( GenerateAudit || GenerateAlarm ) { 03619 03620 // 03621 // Call ob for the name of the directory. 03622 // 03623 03624 ObjectNameInformation = SepQueryNameString( DirectoryObject ); 03625 03626 if ( ObjectNameInformation != NULL ) { 03627 03628 DirectoryName = &ObjectNameInformation->Name; 03629 } 03630 03631 SepAdtCreateObjectAuditAlarm( 03632 OperationID, 03633 DirectoryName, 03634 ComponentName, 03635 SepTokenUserSid(EffectiveToken( SubjectSecurityContext )), 03636 SepTokenAuthenticationId( EffectiveToken( SubjectSecurityContext )), 03637 DesiredAccess, 03638 AccessGranted, 03639 GenerateAudit, 03640 GenerateAlarm 03641 ); 03642 03643 *AuditPerformed = TRUE; 03644 03645 if ( DirectoryName != NULL ) { 03646 03647 ExFreePool( DirectoryName ); 03648 } 03649 } 03650 } 03651 } 03652 03653 #endif 03654 03655 return; 03656 }

VOID SeDeleteObjectAuditAlarm IN PVOID  Object,
IN HANDLE  Handle
 

Definition at line 3892 of file seaudit.c.

References EffectiveToken, Handle, NTSTATUS(), PAGED_CODE, SeCaptureSubjectContext(), SepAdtDeleteObjectAuditAlarm(), SepTokenAuthenticationId, SepTokenUserSid, SeReleaseSubjectContext(), SeSubsystemName, and Status.

Referenced by NtDeleteKey(), and NtMakeTemporaryObject().

03899 : 03900 03901 This routine is used to generate audit and alarm messages when an object 03902 is marked for deletion. 03903 03904 This routine may result in several messages being generated and sent to 03905 Port objects. This may result in a significant latency before 03906 returning. Design of routines that must call this routine must take 03907 this potential latency into account. This may have an impact on the 03908 approach taken for data structure mutex locking, for example. 03909 03910 Arguments: 03911 03912 Object - Address of the object being accessed. This value will not be 03913 used as a pointer (referenced). It is necessary only to enter into 03914 log messages. 03915 03916 Handle - Supplies the handle value assigned to the open. 03917 03918 Return Value: 03919 03920 None. 03921 03922 --*/ 03923 03924 { 03925 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 03926 PSID UserSid; 03927 NTSTATUS Status; 03928 03929 PAGED_CODE(); 03930 03931 SeCaptureSubjectContext ( &SubjectSecurityContext ); 03932 03933 UserSid = SepTokenUserSid( EffectiveToken (&SubjectSecurityContext)); 03934 03935 03936 03937 SepAdtDeleteObjectAuditAlarm ( 03938 &SeSubsystemName, 03939 (PVOID)Handle, 03940 Object, 03941 UserSid, 03942 SepTokenAuthenticationId( EffectiveToken (&SubjectSecurityContext)) 03943 ); 03944 03945 SeReleaseSubjectContext ( &SubjectSecurityContext ); 03946 03947 return; 03948 }

VOID SeObjectReferenceAuditAlarm IN PLUID OperationID  OPTIONAL,
IN PVOID  Object,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor,
IN PSECURITY_SUBJECT_CONTEXT  SubjectSecurityContext,
IN ACCESS_MASK  DesiredAccess,
IN PPRIVILEGE_SET Privileges  OPTIONAL,
IN BOOLEAN  AccessGranted,
IN KPROCESSOR_MODE  AccessMode
 

Definition at line 3660 of file seaudit.c.

References EffectiveToken, FALSE, KernelMode, NULL, PAGED_CODE, SepAdtAuditThisEvent, SepAdtObjectReferenceAuditAlarm(), and SepExamineSacl().

Referenced by ObpCheckObjectReference().

03673 : 03674 03675 description-of-function. 03676 03677 Arguments: 03678 03679 argument-name - Supplies | Returns description of argument. 03680 . 03681 . 03682 03683 Return Value: 03684 03685 return-value - Description of conditions needed to return value. - or - 03686 None. 03687 03688 --*/ 03689 03690 { 03691 BOOLEAN GenerateAudit = FALSE; 03692 BOOLEAN GenerateAlarm = FALSE; 03693 03694 PAGED_CODE(); 03695 03696 if (AccessMode == KernelMode) { 03697 return; 03698 } 03699 03700 if ( SecurityDescriptor != NULL ) { 03701 03702 if ( SepAdtAuditThisEvent( AuditCategoryDetailedTracking, &AccessGranted )) { 03703 03704 SepExamineSacl( 03705 RtlpSaclAddrSecurityDescriptor( (PISECURITY_DESCRIPTOR)SecurityDescriptor ), 03706 EffectiveToken( SubjectSecurityContext ), 03707 DesiredAccess, 03708 AccessGranted, 03709 &GenerateAudit, 03710 &GenerateAlarm 03711 ); 03712 03713 if ( GenerateAudit || GenerateAlarm ) { 03714 03715 SepAdtObjectReferenceAuditAlarm( 03716 OperationID, 03717 Object, 03718 SubjectSecurityContext, 03719 DesiredAccess, 03720 Privileges, 03721 AccessGranted, 03722 GenerateAudit, 03723 GenerateAlarm 03724 ); 03725 } 03726 } 03727 } 03728 03729 return; 03730 03731 }

VOID SeOpenObjectAuditAlarm IN PUNICODE_STRING  ObjectTypeName,
IN PVOID Object  OPTIONAL,
IN PUNICODE_STRING AbsoluteObjectName  OPTIONAL,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor,
IN PACCESS_STATE  AccessState,
IN BOOLEAN  ObjectCreated,
IN BOOLEAN  AccessGranted,
IN KPROCESSOR_MODE  AccessMode,
OUT PBOOLEAN  GenerateOnClose
 

Definition at line 2765 of file seaudit.c.

References EffectiveToken, ExAllocatePool, ExFreePool(), FALSE, _AUX_ACCESS_DATA::GenericMapping, KernelMode, NULL, PAGED_CODE, PagedPool, _AUX_ACCESS_DATA::PrivilegesUsed, PTOKEN, RtlCopyUnicodeString(), RtlMapGenericMask(), SepAdtAuditThisEvent, SepAdtOpenObjectAuditAlarm(), SepExamineSacl(), SepFilterPrivilegeAudits(), SepQueryNameString(), SepQueryTypeString(), SeSubsystemName, Token, and TRUE.

Referenced by IopParseDevice(), and ObCheckObjectAccess().

02778 : 02779 02780 SeOpenObjectAuditAlarm is used by the object manager that open objects 02781 to generate any necessary audit or alarm messages. The open may be to 02782 existing objects or for newly created objects. No messages will be 02783 generated for Kernel mode accesses. 02784 02785 This routine is used to generate audit and alarm messages when an 02786 attempt is made to open an object. 02787 02788 This routine may result in several messages being generated and sent to 02789 Port objects. This may result in a significant latency before 02790 returning. Design of routines that must call this routine must take 02791 this potential latency into account. This may have an impact on the 02792 approach taken for data structure mutex locking, for example. 02793 02794 Arguments: 02795 02796 ObjectTypeName - Supplies the name of the type of object being 02797 accessed. This must be the same name provided to the 02798 ObCreateObjectType service when the object type was created. 02799 02800 Object - Address of the object accessed. This value will not be used 02801 as a pointer (referenced). It is necessary only to enter into log 02802 messages. If the open was not successful, then this argument is 02803 ignored. Otherwise, it must be provided. 02804 02805 AbsoluteObjectName - Supplies the name of the object being accessed. 02806 If the object doesn't have a name, then this field is left null. 02807 Otherwise, it must be provided. 02808 02809 SecurityDescriptor - A pointer to the security descriptor of the 02810 object being accessed. 02811 02812 AccessState - A pointer to an access state structure containing the 02813 subject context, the remaining desired access types, the granted 02814 access types, and optionally a privilege set to indicate which 02815 privileges were used to permit the access. 02816 02817 ObjectCreated - A boolean flag indicating whether the access resulted 02818 in a new object being created. A value of TRUE indicates an object 02819 was created, FALSE indicates an existing object was opened. 02820 02821 AccessGranted - Indicates if the access was granted or denied based on 02822 the access check or privilege check. 02823 02824 AccessMode - Indicates the access mode used for the access check. One 02825 of UserMode or KernelMode. Messages will not be generated by 02826 kernel mode accesses. 02827 02828 GenerateOnClose - Points to a boolean that is set by the audit 02829 generation routine and must be passed to SeCloseObjectAuditAlarm() 02830 when the object handle is closed. 02831 02832 Return value: 02833 02834 None. 02835 02836 --*/ 02837 { 02838 BOOLEAN GenerateAudit = FALSE; 02839 BOOLEAN GenerateAlarm = FALSE; 02840 ACCESS_MASK RequestedAccess; 02841 POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; 02842 PUNICODE_STRING ObjectTypeNameInfo = NULL; 02843 PUNICODE_STRING ObjectName = NULL; 02844 PUNICODE_STRING LocalObjectTypeName = NULL; 02845 PLUID PrimaryAuthenticationId = NULL; 02846 PLUID ClientAuthenticationId = NULL; 02847 BOOLEAN AuditPrivileges = FALSE; 02848 BOOLEAN AuditPerformed; 02849 PTOKEN Token; 02850 ACCESS_MASK MappedGrantMask = (ACCESS_MASK)0; 02851 ACCESS_MASK MappedDenyMask = (ACCESS_MASK)0; 02852 PAUX_ACCESS_DATA AuxData; 02853 02854 PAGED_CODE(); 02855 02856 if ( AccessMode == KernelMode ) { 02857 return; 02858 } 02859 02860 AuxData = (PAUX_ACCESS_DATA)AccessState->AuxData; 02861 02862 Token = EffectiveToken( &AccessState->SubjectSecurityContext ); 02863 02864 if (ARGUMENT_PRESENT(Token->AuditData)) { 02865 02866 MappedGrantMask = Token->AuditData->GrantMask; 02867 02868 RtlMapGenericMask( 02869 &MappedGrantMask, 02870 &AuxData->GenericMapping 02871 ); 02872 02873 MappedDenyMask = Token->AuditData->DenyMask; 02874 02875 RtlMapGenericMask( 02876 &MappedDenyMask, 02877 &AuxData->GenericMapping 02878 ); 02879 } 02880 02881 if (SecurityDescriptor != NULL) { 02882 02883 RequestedAccess = AccessState->RemainingDesiredAccess | 02884 AccessState->PreviouslyGrantedAccess; 02885 02886 if ( SepAdtAuditThisEvent( AuditCategoryObjectAccess, &AccessGranted )) { 02887 02888 if ( RequestedAccess & (AccessGranted ? MappedGrantMask : MappedDenyMask)) { 02889 02890 GenerateAudit = TRUE; 02891 02892 } else { 02893 02894 SepExamineSacl( 02895 RtlpSaclAddrSecurityDescriptor( (PISECURITY_DESCRIPTOR)SecurityDescriptor ), 02896 Token, 02897 RequestedAccess, 02898 AccessGranted, 02899 &GenerateAudit, 02900 &GenerateAlarm 02901 ); 02902 } 02903 02904 // 02905 // Only generate an audit on close of we're auditing from SACL 02906 // settings. 02907 // 02908 02909 if (GenerateAudit) { 02910 *GenerateOnClose = TRUE; 02911 } 02912 } 02913 } 02914 02915 // 02916 // If we don't generate an audit via the SACL, see if we need to generate 02917 // one for privilege use. 02918 // 02919 // Note that we only audit privileges successfully used to open objects, 02920 // so we don't care about a failed privilege use here. Therefore, only 02921 // do this test of access has been granted. 02922 // 02923 02924 if (!GenerateAudit && (AccessGranted == TRUE)) { 02925 02926 if ( SepAdtAuditThisEvent( AuditCategoryPrivilegeUse, &AccessGranted )) { 02927 02928 if ((AuxData->PrivilegesUsed != NULL) && 02929 (AuxData->PrivilegesUsed->PrivilegeCount > 0) ) { 02930 02931 // 02932 // Make sure these are actually privileges that we want to audit 02933 // 02934 02935 if (SepFilterPrivilegeAudits( AuxData->PrivilegesUsed )) { 02936 02937 GenerateAudit = TRUE; 02938 02939 // 02940 // When we finally try to generate this audit, this flag 02941 // will tell us that we need to audit the fact that we 02942 // used a privilege, as opposed to audit due to the SACL. 02943 // 02944 02945 AccessState->AuditPrivileges = TRUE; 02946 } 02947 } 02948 } 02949 } 02950 02951 // 02952 // Set up either to generate an audit (if the access check has failed), or save 02953 // the stuff that we're going to audit later into the AccessState structure. 02954 // 02955 02956 if (GenerateAudit || GenerateAlarm) { 02957 02958 AccessState->GenerateAudit = TRUE; 02959 02960 // 02961 // Figure out what we've been passed, and obtain as much 02962 // missing information as possible. 02963 // 02964 02965 if ( !ARGUMENT_PRESENT( AbsoluteObjectName )) { 02966 02967 if ( ARGUMENT_PRESENT( Object )) { 02968 02969 ObjectNameInfo = SepQueryNameString( Object ); 02970 02971 if ( ObjectNameInfo != NULL ) { 02972 02973 ObjectName = &ObjectNameInfo->Name; 02974 } 02975 } 02976 02977 } else { 02978 02979 ObjectName = AbsoluteObjectName; 02980 } 02981 02982 if ( !ARGUMENT_PRESENT( ObjectTypeName )) { 02983 02984 if ( ARGUMENT_PRESENT( Object )) { 02985 02986 ObjectTypeNameInfo = SepQueryTypeString( Object ); 02987 02988 if ( ObjectTypeNameInfo != NULL ) { 02989 02990 LocalObjectTypeName = ObjectTypeNameInfo; 02991 } 02992 } 02993 02994 } else { 02995 02996 LocalObjectTypeName = ObjectTypeName; 02997 } 02998 02999 // 03000 // If the access attempt failed, do the audit here. If it succeeded, 03001 // we'll do the audit later, when the handle is allocated. 03002 // 03003 // 03004 03005 if (!AccessGranted) { 03006 03007 AuditPerformed = SepAdtOpenObjectAuditAlarm ( &SeSubsystemName, 03008 NULL, 03009 LocalObjectTypeName, 03010 NULL, 03011 ObjectName, 03012 AccessState->SubjectSecurityContext.ClientToken, 03013 AccessState->SubjectSecurityContext.PrimaryToken, 03014 AccessState->OriginalDesiredAccess, 03015 AccessState->PreviouslyGrantedAccess, 03016 &AccessState->OperationID, 03017 AuxData->PrivilegesUsed, 03018 FALSE, 03019 FALSE, 03020 TRUE, 03021 FALSE, 03022 AccessState->SubjectSecurityContext.ProcessAuditId, 03023 AuditCategoryObjectAccess, 03024 NULL, 03025 0, 03026 NULL ); 03027 } else { 03028 03029 // 03030 // Copy all the stuff we're going to need into the 03031 // AccessState and return. 03032 // 03033 03034 if ( ObjectName != NULL ) { 03035 03036 if ( AccessState->ObjectName.Buffer != NULL ) { 03037 03038 ExFreePool( AccessState->ObjectName.Buffer ); 03039 AccessState->ObjectName.Length = 0; 03040 AccessState->ObjectName.MaximumLength = 0; 03041 } 03042 03043 AccessState->ObjectName.Buffer = ExAllocatePool( PagedPool,ObjectName->MaximumLength ); 03044 if (AccessState->ObjectName.Buffer != NULL) { 03045 03046 AccessState->ObjectName.MaximumLength = ObjectName->MaximumLength; 03047 RtlCopyUnicodeString( &AccessState->ObjectName, ObjectName ); 03048 } 03049 } 03050 03051 if ( LocalObjectTypeName != NULL ) { 03052 03053 if ( AccessState->ObjectTypeName.Buffer != NULL ) { 03054 03055 ExFreePool( AccessState->ObjectTypeName.Buffer ); 03056 AccessState->ObjectTypeName.Length = 0; 03057 AccessState->ObjectTypeName.MaximumLength = 0; 03058 } 03059 03060 AccessState->ObjectTypeName.Buffer = ExAllocatePool( PagedPool, LocalObjectTypeName->MaximumLength ); 03061 if (AccessState->ObjectTypeName.Buffer != NULL) { 03062 03063 AccessState->ObjectTypeName.MaximumLength = LocalObjectTypeName->MaximumLength; 03064 RtlCopyUnicodeString( &AccessState->ObjectTypeName, LocalObjectTypeName ); 03065 } 03066 } 03067 } 03068 03069 if ( ObjectNameInfo != NULL ) { 03070 03071 ExFreePool( ObjectNameInfo ); 03072 } 03073 03074 if ( ObjectTypeNameInfo != NULL ) { 03075 03076 ExFreePool( ObjectTypeNameInfo ); 03077 } 03078 } 03079 03080 return; 03081 }

VOID SeOpenObjectForDeleteAuditAlarm IN PUNICODE_STRING  ObjectTypeName,
IN PVOID Object  OPTIONAL,
IN PUNICODE_STRING AbsoluteObjectName  OPTIONAL,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor,
IN PACCESS_STATE  AccessState,
IN BOOLEAN  ObjectCreated,
IN BOOLEAN  AccessGranted,
IN KPROCESSOR_MODE  AccessMode,
OUT PBOOLEAN  GenerateOnClose
 

Definition at line 3085 of file seaudit.c.

References EffectiveToken, ExAllocatePool, ExFreePool(), FALSE, _AUX_ACCESS_DATA::GenericMapping, KernelMode, NULL, PAGED_CODE, PagedPool, _AUX_ACCESS_DATA::PrivilegesUsed, PTOKEN, RtlCopyUnicodeString(), RtlMapGenericMask(), SepAdtAuditThisEvent, SepAdtOpenObjectAuditAlarm(), SepAdtOpenObjectForDeleteAuditAlarm(), SepExamineSacl(), SepFilterPrivilegeAudits(), SepQueryNameString(), SepQueryTypeString(), SeSubsystemName, Token, and TRUE.

03098 : 03099 03100 SeOpenObjectForDeleteAuditAlarm is used by the object manager that open 03101 objects to generate any necessary audit or alarm messages. The open may 03102 be to existing objects or for newly created objects. No messages will be 03103 generated for Kernel mode accesses. 03104 03105 This routine is used to generate audit and alarm messages when an 03106 attempt is made to open an object with the intent to delete it. 03107 Specifically, this is used by file systems when the flag 03108 FILE_DELETE_ON_CLOSE is specified. 03109 03110 This routine may result in several messages being generated and sent to 03111 Port objects. This may result in a significant latency before 03112 returning. Design of routines that must call this routine must take 03113 this potential latency into account. This may have an impact on the 03114 approach taken for data structure mutex locking, for example. 03115 03116 Arguments: 03117 03118 ObjectTypeName - Supplies the name of the type of object being 03119 accessed. This must be the same name provided to the 03120 ObCreateObjectType service when the object type was created. 03121 03122 Object - Address of the object accessed. This value will not be used 03123 as a pointer (referenced). It is necessary only to enter into log 03124 messages. If the open was not successful, then this argument is 03125 ignored. Otherwise, it must be provided. 03126 03127 AbsoluteObjectName - Supplies the name of the object being accessed. 03128 If the object doesn't have a name, then this field is left null. 03129 Otherwise, it must be provided. 03130 03131 SecurityDescriptor - A pointer to the security descriptor of the 03132 object being accessed. 03133 03134 AccessState - A pointer to an access state structure containing the 03135 subject context, the remaining desired access types, the granted 03136 access types, and optionally a privilege set to indicate which 03137 privileges were used to permit the access. 03138 03139 ObjectCreated - A boolean flag indicating whether the access resulted 03140 in a new object being created. A value of TRUE indicates an object 03141 was created, FALSE indicates an existing object was opened. 03142 03143 AccessGranted - Indicates if the access was granted or denied based on 03144 the access check or privilege check. 03145 03146 AccessMode - Indicates the access mode used for the access check. One 03147 of UserMode or KernelMode. Messages will not be generated by 03148 kernel mode accesses. 03149 03150 GenerateOnClose - Points to a boolean that is set by the audit 03151 generation routine and must be passed to SeCloseObjectAuditAlarm() 03152 when the object handle is closed. 03153 03154 Return value: 03155 03156 None. 03157 03158 --*/ 03159 { 03160 BOOLEAN GenerateAudit = FALSE; 03161 BOOLEAN GenerateAlarm = FALSE; 03162 ACCESS_MASK RequestedAccess; 03163 POBJECT_NAME_INFORMATION ObjectNameInfo = NULL; 03164 PUNICODE_STRING ObjectTypeNameInfo = NULL; 03165 PUNICODE_STRING ObjectName = NULL; 03166 PUNICODE_STRING LocalObjectTypeName = NULL; 03167 PLUID PrimaryAuthenticationId = NULL; 03168 PLUID ClientAuthenticationId = NULL; 03169 BOOLEAN AuditPrivileges = FALSE; 03170 BOOLEAN AuditPerformed; 03171 PTOKEN Token; 03172 ACCESS_MASK MappedGrantMask = (ACCESS_MASK)0; 03173 ACCESS_MASK MappedDenyMask = (ACCESS_MASK)0; 03174 PAUX_ACCESS_DATA AuxData; 03175 03176 PAGED_CODE(); 03177 03178 if ( AccessMode == KernelMode ) { 03179 return; 03180 } 03181 03182 AuxData = (PAUX_ACCESS_DATA)AccessState->AuxData; 03183 03184 Token = EffectiveToken( &AccessState->SubjectSecurityContext ); 03185 03186 if (ARGUMENT_PRESENT(Token->AuditData)) { 03187 03188 MappedGrantMask = Token->AuditData->GrantMask; 03189 03190 RtlMapGenericMask( 03191 &MappedGrantMask, 03192 &AuxData->GenericMapping 03193 ); 03194 03195 MappedDenyMask = Token->AuditData->DenyMask; 03196 03197 RtlMapGenericMask( 03198 &MappedDenyMask, 03199 &AuxData->GenericMapping 03200 ); 03201 } 03202 03203 if (SecurityDescriptor != NULL) { 03204 03205 RequestedAccess = AccessState->RemainingDesiredAccess | 03206 AccessState->PreviouslyGrantedAccess; 03207 03208 if ( SepAdtAuditThisEvent( AuditCategoryObjectAccess, &AccessGranted )) { 03209 03210 if ( RequestedAccess & (AccessGranted ? MappedGrantMask : MappedDenyMask)) { 03211 03212 GenerateAudit = TRUE; 03213 03214 } else { 03215 03216 SepExamineSacl( 03217 RtlpSaclAddrSecurityDescriptor( (PISECURITY_DESCRIPTOR)SecurityDescriptor ), 03218 Token, 03219 RequestedAccess, 03220 AccessGranted, 03221 &GenerateAudit, 03222 &GenerateAlarm 03223 ); 03224 } 03225 03226 // 03227 // Only generate an audit on close of we're auditing from SACL 03228 // settings. 03229 // 03230 03231 if (GenerateAudit) { 03232 *GenerateOnClose = TRUE; 03233 } 03234 } 03235 } 03236 03237 // 03238 // If we don't generate an audit via the SACL, see if we need to generate 03239 // one for privilege use. 03240 // 03241 // Note that we only audit privileges successfully used to open objects, 03242 // so we don't care about a failed privilege use here. Therefore, only 03243 // do this test of access has been granted. 03244 // 03245 03246 if (!GenerateAudit && (AccessGranted == TRUE)) { 03247 03248 if ( SepAdtAuditThisEvent( AuditCategoryPrivilegeUse, &AccessGranted )) { 03249 03250 if ((AuxData->PrivilegesUsed != NULL) && 03251 (AuxData->PrivilegesUsed->PrivilegeCount > 0) ) { 03252 03253 // 03254 // Make sure these are actually privileges that we want to audit 03255 // 03256 03257 if (SepFilterPrivilegeAudits( AuxData->PrivilegesUsed )) { 03258 03259 GenerateAudit = TRUE; 03260 03261 // 03262 // When we finally try to generate this audit, this flag 03263 // will tell us that we need to audit the fact that we 03264 // used a privilege, as opposed to audit due to the SACL. 03265 // 03266 03267 AccessState->AuditPrivileges = TRUE; 03268 } 03269 } 03270 } 03271 } 03272 03273 // 03274 // Set up either to generate an audit (if the access check has failed), or save 03275 // the stuff that we're going to audit later into the AccessState structure. 03276 // 03277 03278 if (GenerateAudit || GenerateAlarm) { 03279 03280 AccessState->GenerateAudit = TRUE; 03281 03282 // 03283 // Figure out what we've been passed, and obtain as much 03284 // missing information as possible. 03285 // 03286 03287 if ( !ARGUMENT_PRESENT( AbsoluteObjectName )) { 03288 03289 if ( ARGUMENT_PRESENT( Object )) { 03290 03291 ObjectNameInfo = SepQueryNameString( Object ); 03292 03293 if ( ObjectNameInfo != NULL ) { 03294 03295 ObjectName = &ObjectNameInfo->Name; 03296 } 03297 } 03298 03299 } else { 03300 03301 ObjectName = AbsoluteObjectName; 03302 } 03303 03304 if ( !ARGUMENT_PRESENT( ObjectTypeName )) { 03305 03306 if ( ARGUMENT_PRESENT( Object )) { 03307 03308 ObjectTypeNameInfo = SepQueryTypeString( Object ); 03309 03310 if ( ObjectTypeNameInfo != NULL ) { 03311 03312 LocalObjectTypeName = ObjectTypeNameInfo; 03313 } 03314 } 03315 03316 } else { 03317 03318 LocalObjectTypeName = ObjectTypeName; 03319 } 03320 03321 // 03322 // If the access attempt failed, do the audit here. If it succeeded, 03323 // we'll do the audit later, when the handle is allocated. 03324 // 03325 // 03326 03327 if (!AccessGranted) { 03328 03329 AuditPerformed = SepAdtOpenObjectAuditAlarm ( &SeSubsystemName, 03330 NULL, 03331 LocalObjectTypeName, 03332 NULL, 03333 ObjectName, 03334 AccessState->SubjectSecurityContext.ClientToken, 03335 AccessState->SubjectSecurityContext.PrimaryToken, 03336 AccessState->OriginalDesiredAccess, 03337 AccessState->PreviouslyGrantedAccess, 03338 &AccessState->OperationID, 03339 AuxData->PrivilegesUsed, 03340 FALSE, 03341 FALSE, 03342 TRUE, 03343 FALSE, 03344 AccessState->SubjectSecurityContext.ProcessAuditId, 03345 AuditCategoryObjectAccess, 03346 NULL, 03347 0, 03348 NULL ); 03349 } else { 03350 03351 // 03352 // Generate the delete audit first 03353 // 03354 03355 SepAdtOpenObjectForDeleteAuditAlarm ( &SeSubsystemName, 03356 NULL, 03357 LocalObjectTypeName, 03358 NULL, 03359 ObjectName, 03360 AccessState->SubjectSecurityContext.ClientToken, 03361 AccessState->SubjectSecurityContext.PrimaryToken, 03362 AccessState->OriginalDesiredAccess, 03363 AccessState->PreviouslyGrantedAccess, 03364 &AccessState->OperationID, 03365 AuxData->PrivilegesUsed, 03366 FALSE, 03367 TRUE, 03368 TRUE, 03369 FALSE, 03370 AccessState->SubjectSecurityContext.ProcessAuditId ); 03371 03372 // 03373 // Copy all the stuff we're going to need into the 03374 // AccessState and return. 03375 // 03376 03377 if ( ObjectName != NULL ) { 03378 03379 if ( AccessState->ObjectName.Buffer != NULL ) { 03380 03381 ExFreePool( AccessState->ObjectName.Buffer ); 03382 AccessState->ObjectName.Length = 0; 03383 AccessState->ObjectName.MaximumLength = 0; 03384 } 03385 03386 AccessState->ObjectName.Buffer = ExAllocatePool( PagedPool,ObjectName->MaximumLength ); 03387 if (AccessState->ObjectName.Buffer != NULL) { 03388 03389 AccessState->ObjectName.MaximumLength = ObjectName->MaximumLength; 03390 RtlCopyUnicodeString( &AccessState->ObjectName, ObjectName ); 03391 } 03392 } 03393 03394 if ( LocalObjectTypeName != NULL ) { 03395 03396 if ( AccessState->ObjectTypeName.Buffer != NULL ) { 03397 03398 ExFreePool( AccessState->ObjectTypeName.Buffer ); 03399 AccessState->ObjectTypeName.Length = 0; 03400 AccessState->ObjectTypeName.MaximumLength = 0; 03401 } 03402 03403 AccessState->ObjectTypeName.Buffer = ExAllocatePool( PagedPool, LocalObjectTypeName->MaximumLength ); 03404 if (AccessState->ObjectTypeName.Buffer != NULL) { 03405 03406 AccessState->ObjectTypeName.MaximumLength = LocalObjectTypeName->MaximumLength; 03407 RtlCopyUnicodeString( &AccessState->ObjectTypeName, LocalObjectTypeName ); 03408 } 03409 } 03410 } 03411 03412 if ( ObjectNameInfo != NULL ) { 03413 03414 ExFreePool( ObjectNameInfo ); 03415 } 03416 03417 if ( ObjectTypeNameInfo != NULL ) { 03418 03419 ExFreePool( ObjectTypeNameInfo ); 03420 } 03421 } 03422 03423 return; 03424 }

NTSTATUS SepAccessCheckAndAuditAlarm IN PUNICODE_STRING  SubsystemName,
IN PVOID  HandleId,
IN PHANDLE ClientToken  OPTIONAL,
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  OPTIONAL,
IN ULONG  ObjectTypeListLength,
IN PGENERIC_MAPPING  GenericMapping,
IN BOOLEAN  ObjectCreation,
OUT PACCESS_MASK  GrantedAccess,
OUT PNTSTATUS  AccessStatus,
OUT PBOOLEAN  GenerateOnClose,
IN BOOLEAN  ReturnResultList
 

Definition at line 1050 of file seaudit.c.

References ASSERT, _SECURITY_SUBJECT_CONTEXT::ClientToken, ClientToken, EffectiveToken, ExAllocateLocallyUniqueId, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, _SECURITY_SUBJECT_CONTEXT::ImpersonationLevel, IsValidElementCount, KernelMode, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, PagedPool, _SECURITY_SUBJECT_CONTEXT::PrimaryToken, ProbeForRead, ProbeForWrite(), ProbeForWriteBoolean, ProbeForWriteUlong, PsGetCurrentProcess, PsProcessAuditId, PTOKEN, SeCaptureObjectTypeList(), SeCaptureSecurityDescriptor(), SeCaptureSid(), SeCaptureSubjectContext(), SeCheckAuditPrivilege(), SeFreeCapturedObjectTypeList(), SeLockSubjectContext(), SepAccessCheck(), SepAdtAuditThisEvent, SepAdtAuditThisEventEx, SepAdtOpenObjectAuditAlarm(), SepAdtPrivilegeObjectAuditAlarm(), SepExamineSaclEx(), SepFreeCapturedString(), SepProbeAndCaptureString_U(), SePrivilegePolicyCheck(), SepTokenIsOwner(), SepTokenObjectType, SeReleaseSecurityDescriptor(), SeReleaseSid(), SeReleaseSubjectContext(), SeUnlockSubjectContext(), Status, and TRUE.

Referenced by NtAccessCheckAndAuditAlarm(), NtAccessCheckByTypeAndAuditAlarm(), NtAccessCheckByTypeResultListAndAuditAlarm(), and NtAccessCheckByTypeResultListAndAuditAlarmByHandle().

01072 : 01073 01074 This system service is used to perform both an access validation and 01075 generate the corresponding audit and alarm messages. This service may 01076 only be used by a protected server that chooses to impersonate its 01077 client and thereby specifies the client security context implicitly. 01078 01079 Arguments: 01080 01081 SubsystemName - Supplies a name string identifying the subsystem 01082 calling the routine. 01083 01084 HandleId - A unique value that will be used to represent the client's 01085 handle to the object. This value is ignored (and may be re-used) 01086 if the access is denied. 01087 01088 ClientToken - Supplies the client token so that the caller does not have 01089 to impersonate before making the kernel call. 01090 01091 ObjectTypeName - Supplies the name of the type of the object being 01092 created or accessed. 01093 01094 ObjectName - Supplies the name of the object being created or accessed. 01095 01096 SecurityDescriptor - A pointer to the Security Descriptor against which 01097 acccess is to be checked. 01098 01099 DesiredAccess - The desired acccess mask. This mask must have been 01100 previously mapped to contain no generic accesses. 01101 01102 AuditType - Specifies the type of audit to be generated. Valid values 01103 are: AuditEventObjectAccess and AuditEventDirectoryServiceAccess. 01104 01105 Flags - Flags modifying the execution of the API: 01106 01107 AUDIT_ALLOW_NO_PRIVILEGE - If the called does not have AuditPrivilege, 01108 the call will silently continue to check access and will 01109 generate no audit. 01110 01111 ObjectTypeList - Supplies a list of GUIDs representing the object (and 01112 sub-objects) being accessed. If no list is present, AccessCheckByType 01113 behaves identically to AccessCheck. 01114 01115 ObjectTypeListLength - Specifies the number of elements in the ObjectTypeList. 01116 01117 GenericMapping - Supplies a pointer to the generic mapping associated 01118 with this object type. 01119 01120 ObjectCreation - A boolean flag indicated whether the access will 01121 result in a new object being created if granted. A value of TRUE 01122 indicates an object will be created, FALSE indicates an existing 01123 object will be opened. 01124 01125 GrantedAccess - Receives a masking indicating which accesses have been 01126 granted. 01127 01128 AccessStatus - Receives an indication of the success or failure of the 01129 access check. If access is granted, STATUS_SUCCESS is returned. 01130 If access is denied, a value appropriate for return to the client 01131 is returned. This will be STATUS_ACCESS_DENIED or, when mandatory 01132 access controls are implemented, STATUS_OBJECT_NOT_FOUND. 01133 01134 GenerateOnClose - Points to a boolean that is set by the audity 01135 generation routine and must be passed to NtCloseObjectAuditAlarm 01136 when the object handle is closed. 01137 01138 ReturnResultList - If true, GrantedAccess and AccessStatus are actually 01139 arrays of entries ObjectTypeListLength elements long. 01140 01141 Return Value: 01142 01143 STATUS_SUCCESS - Indicates the call completed successfully. In this 01144 case, ClientStatus receives the result of the access check. 01145 01146 STATUS_PRIVILEGE_NOT_HELD - Indicates the caller does not have 01147 sufficient privilege to use this privileged system service. 01148 01149 --*/ 01150 01151 { 01152 01153 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 01154 01155 NTSTATUS Status = STATUS_SUCCESS; 01156 01157 ACCESS_MASK LocalGrantedAccess = (ACCESS_MASK)0; 01158 PACCESS_MASK LocalGrantedAccessPointer = NULL; 01159 BOOLEAN LocalGrantedAccessAllocated = FALSE; 01160 NTSTATUS LocalAccessStatus; 01161 PNTSTATUS LocalAccessStatusPointer = NULL; 01162 BOOLEAN LocalGenerateOnClose = FALSE; 01163 POLICY_AUDIT_EVENT_TYPE NtAuditType; 01164 01165 KPROCESSOR_MODE PreviousMode; 01166 01167 PUNICODE_STRING CapturedSubsystemName = (PUNICODE_STRING) NULL; 01168 PUNICODE_STRING CapturedObjectTypeName = (PUNICODE_STRING) NULL; 01169 PUNICODE_STRING CapturedObjectName = (PUNICODE_STRING) NULL; 01170 PSECURITY_DESCRIPTOR CapturedSecurityDescriptor = (PSECURITY_DESCRIPTOR) NULL; 01171 PSID CapturedPrincipalSelfSid = NULL; 01172 PIOBJECT_TYPE_LIST LocalObjectTypeList = NULL; 01173 01174 ACCESS_MASK PreviouslyGrantedAccess = (ACCESS_MASK)0; 01175 GENERIC_MAPPING LocalGenericMapping; 01176 01177 PPRIVILEGE_SET PrivilegeSet = NULL; 01178 01179 BOOLEAN Result; 01180 01181 BOOLEAN AccessGranted; 01182 BOOLEAN AccessDenied; 01183 BOOLEAN GenerateSuccessAudit = FALSE; 01184 BOOLEAN GenerateFailureAudit = FALSE; 01185 LUID OperationId; 01186 BOOLEAN AuditPerformed; 01187 BOOLEAN AvoidAudit = FALSE; 01188 01189 PTOKEN NewToken = NULL; 01190 PTOKEN OldToken = NULL; 01191 BOOLEAN TokenSwapped = FALSE; 01192 01193 PAGED_CODE(); 01194 01195 PreviousMode = KeGetPreviousMode(); 01196 01197 ASSERT( PreviousMode != KernelMode ); 01198 01199 // 01200 // Capture the subject Context 01201 // 01202 01203 SeCaptureSubjectContext ( &SubjectSecurityContext ); 01204 01205 // 01206 // Convert AuditType 01207 // 01208 01209 if ( AuditType == AuditEventObjectAccess ) { 01210 NtAuditType = AuditCategoryObjectAccess; 01211 } else if ( AuditType == AuditEventDirectoryServiceAccess ) { 01212 NtAuditType = AuditCategoryDirectoryServiceAccess; 01213 } else { 01214 Status = STATUS_INVALID_PARAMETER; 01215 goto Cleanup; 01216 } 01217 01218 // 01219 // Impersonation checks should be done only if the ClientToken is NULL. 01220 // 01221 01222 if ( !ARGUMENT_PRESENT( ClientToken ) ) { 01223 01224 // 01225 // Make sure we're impersonating a client... 01226 // 01227 01228 if ( (SubjectSecurityContext.ClientToken == NULL) ) { 01229 Status = STATUS_NO_IMPERSONATION_TOKEN; 01230 goto Cleanup; 01231 } 01232 01233 01234 // 01235 // ...and at a high enough impersonation level 01236 // 01237 01238 if (SubjectSecurityContext.ImpersonationLevel < SecurityIdentification) { 01239 Status = STATUS_BAD_IMPERSONATION_LEVEL; 01240 goto Cleanup; 01241 } 01242 } 01243 01244 try { 01245 01246 if ( ReturnResultList ) { 01247 01248 if ( ObjectTypeListLength == 0 ) { 01249 Status = STATUS_INVALID_PARAMETER; 01250 leave; 01251 } 01252 01253 if (!IsValidElementCount(ObjectTypeListLength, ULONG)) { 01254 Status = STATUS_INVALID_PARAMETER; 01255 leave; 01256 } 01257 ProbeForWrite( 01258 AccessStatus, 01259 sizeof(NTSTATUS) * ObjectTypeListLength, 01260 sizeof(ULONG) 01261 ); 01262 01263 ProbeForWrite( 01264 GrantedAccess, 01265 sizeof(ACCESS_MASK) * ObjectTypeListLength, 01266 sizeof(ULONG) 01267 ); 01268 01269 } else { 01270 ProbeForWriteUlong((PULONG)AccessStatus); 01271 ProbeForWriteUlong((PULONG)GrantedAccess); 01272 } 01273 01274 ProbeForRead( 01275 GenericMapping, 01276 sizeof(GENERIC_MAPPING), 01277 sizeof(ULONG) 01278 ); 01279 01280 LocalGenericMapping = *GenericMapping; 01281 01282 } except (EXCEPTION_EXECUTE_HANDLER) { 01283 01284 Status = GetExceptionCode(); 01285 } 01286 01287 if (!NT_SUCCESS(Status)) { 01288 goto Cleanup; 01289 } 01290 01291 if ( ARGUMENT_PRESENT( ClientToken ) ) { 01292 01293 Status = ObReferenceObjectByHandle( 01294 *ClientToken, // Handle 01295 (ACCESS_MASK)TOKEN_QUERY, // DesiredAccess 01296 SepTokenObjectType, // ObjectType 01297 PreviousMode, // AccessMode 01298 (PVOID *)&NewToken, // Object 01299 NULL // GrantedAccess 01300 ); 01301 01302 if (!NT_SUCCESS(Status)) { 01303 NewToken = NULL; 01304 goto Cleanup; 01305 } 01306 01307 // 01308 // Save the old token so that it can be recovered before 01309 // SeReleaseSubjectContext. 01310 // 01311 01312 OldToken = SubjectSecurityContext.ClientToken; 01313 01314 // 01315 // Set the impersonation token to the one that has been obtained thru 01316 // ClientToken handle. This must be freed later in Cleanup. 01317 // 01318 01319 SubjectSecurityContext.ClientToken = NewToken; 01320 01321 TokenSwapped = TRUE; 01322 } 01323 01324 // 01325 // Check for SeAuditPrivilege 01326 // 01327 01328 Result = SeCheckAuditPrivilege ( 01329 &SubjectSecurityContext, 01330 PreviousMode 01331 ); 01332 01333 if (!Result) { 01334 if ( Flags & AUDIT_ALLOW_NO_PRIVILEGE ) { 01335 AvoidAudit = TRUE; 01336 } else { 01337 Status = STATUS_PRIVILEGE_NOT_HELD; 01338 goto Cleanup; 01339 } 01340 } 01341 01342 if (DesiredAccess & 01343 ( GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL )) { 01344 01345 Status = STATUS_GENERIC_NOT_MAPPED; 01346 goto Cleanup; 01347 } 01348 01349 // 01350 // Capture the passed security descriptor. 01351 // 01352 // SeCaptureSecurityDescriptor probes the input security descriptor, 01353 // so we don't have to 01354 // 01355 01356 Status = SeCaptureSecurityDescriptor ( 01357 SecurityDescriptor, 01358 PreviousMode, 01359 PagedPool, 01360 FALSE, 01361 &CapturedSecurityDescriptor 01362 ); 01363 01364 if (!NT_SUCCESS(Status) ) { 01365 CapturedSecurityDescriptor = NULL; 01366 goto Cleanup; 01367 } 01368 01369 if ( CapturedSecurityDescriptor == NULL ) { 01370 Status = STATUS_INVALID_SECURITY_DESCR; 01371 goto Cleanup; 01372 } 01373 01374 // 01375 // A valid security descriptor must have an owner and a group 01376 // 01377 01378 if ( RtlpOwnerAddrSecurityDescriptor( 01379 (PISECURITY_DESCRIPTOR)CapturedSecurityDescriptor 01380 ) == NULL || 01381 RtlpGroupAddrSecurityDescriptor( 01382 (PISECURITY_DESCRIPTOR)CapturedSecurityDescriptor 01383 ) == NULL ) { 01384 01385 Status = STATUS_INVALID_SECURITY_DESCR; 01386 goto Cleanup; 01387 } 01388 01389 // 01390 // Probe and capture the STRING arguments 01391 // 01392 01393 try { 01394 01395 ProbeForWriteBoolean(GenerateOnClose); 01396 01397 SepProbeAndCaptureString_U ( SubsystemName, &CapturedSubsystemName ); 01398 01399 SepProbeAndCaptureString_U ( ObjectTypeName, &CapturedObjectTypeName ); 01400 01401 SepProbeAndCaptureString_U ( ObjectName, &CapturedObjectName ); 01402 01403 } except (EXCEPTION_EXECUTE_HANDLER) { 01404 01405 Status = GetExceptionCode(); 01406 goto Cleanup; 01407 01408 } 01409 01410 // 01411 // Capture the PrincipalSelfSid. 01412 // 01413 01414 if ( PrincipalSelfSid != NULL ) { 01415 Status = SeCaptureSid( 01416 PrincipalSelfSid, 01417 PreviousMode, 01418 NULL, 0, 01419 PagedPool, 01420 TRUE, 01421 &CapturedPrincipalSelfSid ); 01422 01423 if (!NT_SUCCESS(Status)) { 01424 CapturedPrincipalSelfSid = NULL; 01425 goto Cleanup; 01426 } 01427 } 01428 01429 // 01430 // Capture any Object type list 01431 // 01432 01433 Status = SeCaptureObjectTypeList( ObjectTypeList, 01434 ObjectTypeListLength, 01435 PreviousMode, 01436 &LocalObjectTypeList ); 01437 01438 if (!NT_SUCCESS(Status)) { 01439 goto Cleanup; 01440 } 01441 01442 // 01443 // See if anything (or everything) in the desired access can be 01444 // satisfied by privileges. 01445 // 01446 01447 Status = SePrivilegePolicyCheck( 01448 &DesiredAccess, 01449 &PreviouslyGrantedAccess, 01450 &SubjectSecurityContext, 01451 NULL, 01452 &PrivilegeSet, 01453 PreviousMode 01454 ); 01455 01456 SeLockSubjectContext( &SubjectSecurityContext ); 01457 01458 if (!NT_SUCCESS( Status )) { 01459 AccessGranted = FALSE; 01460 AccessDenied = TRUE; 01461 LocalAccessStatus = Status; 01462 01463 if ( ReturnResultList ) { 01464 ULONG ResultListIndex; 01465 LocalGrantedAccessPointer = 01466 ExAllocatePoolWithTag( PagedPool, (sizeof(ACCESS_MASK)+sizeof(NTSTATUS)) * ObjectTypeListLength, 'aGeS' ); 01467 01468 if (LocalGrantedAccessPointer == NULL) { 01469 SeUnlockSubjectContext( &SubjectSecurityContext ); 01470 Status = STATUS_INSUFFICIENT_RESOURCES; 01471 goto Cleanup; 01472 } 01473 LocalGrantedAccessAllocated = TRUE; 01474 LocalAccessStatusPointer = (PNTSTATUS)(LocalGrantedAccessPointer + ObjectTypeListLength); 01475 01476 for ( ResultListIndex=0; ResultListIndex<ObjectTypeListLength; ResultListIndex++ ) { 01477 LocalGrantedAccessPointer[ResultListIndex] = LocalGrantedAccess; 01478 LocalAccessStatusPointer[ResultListIndex] = LocalAccessStatus; 01479 } 01480 01481 } else { 01482 LocalGrantedAccessPointer = &LocalGrantedAccess; 01483 LocalAccessStatusPointer = &LocalAccessStatus; 01484 } 01485 01486 } else { 01487 01488 // 01489 // If the user in the token is the owner of the object, we 01490 // must automatically grant ReadControl and WriteDac access 01491 // if desired. If the DesiredAccess mask is empty after 01492 // these bits are turned off, we don't have to do any more 01493 // access checking (ref section 4, DSA ACL Arch) 01494 // 01495 01496 if ( DesiredAccess & (WRITE_DAC | READ_CONTROL | MAXIMUM_ALLOWED) ) { 01497 01498 if (SepTokenIsOwner( SubjectSecurityContext.ClientToken, CapturedSecurityDescriptor, TRUE )) { 01499 01500 if ( DesiredAccess & MAXIMUM_ALLOWED ) { 01501 01502 PreviouslyGrantedAccess |= ( WRITE_DAC | READ_CONTROL ); 01503 01504 } else { 01505 01506 PreviouslyGrantedAccess |= (DesiredAccess & (WRITE_DAC | READ_CONTROL)); 01507 } 01508 01509 DesiredAccess &= ~(WRITE_DAC | READ_CONTROL); 01510 } 01511 01512 } 01513 01514 if (DesiredAccess == 0) { 01515 01516 LocalGrantedAccess = PreviouslyGrantedAccess; 01517 AccessGranted = TRUE; 01518 AccessDenied = FALSE; 01519 LocalAccessStatus = STATUS_SUCCESS; 01520 01521 if ( ReturnResultList ) { 01522 ULONG ResultListIndex; 01523 LocalGrantedAccessPointer = 01524 ExAllocatePoolWithTag( PagedPool, (sizeof(ACCESS_MASK)+sizeof(NTSTATUS)) * ObjectTypeListLength, 'aGeS' ); 01525 01526 if (LocalGrantedAccessPointer == NULL) { 01527 Status = STATUS_INSUFFICIENT_RESOURCES; 01528 SeUnlockSubjectContext( &SubjectSecurityContext ); 01529 goto Cleanup; 01530 } 01531 LocalGrantedAccessAllocated = TRUE; 01532 LocalAccessStatusPointer = (PNTSTATUS)(LocalGrantedAccessPointer + ObjectTypeListLength); 01533 01534 for ( ResultListIndex=0; ResultListIndex<ObjectTypeListLength; ResultListIndex++ ) { 01535 LocalGrantedAccessPointer[ResultListIndex] = LocalGrantedAccess; 01536 LocalAccessStatusPointer[ResultListIndex] = LocalAccessStatus; 01537 } 01538 01539 } else { 01540 LocalGrantedAccessPointer = &LocalGrantedAccess; 01541 LocalAccessStatusPointer = &LocalAccessStatus; 01542 } 01543 01544 } else { 01545 01546 // 01547 // Finally, do the access check 01548 // 01549 01550 if ( ReturnResultList ) { 01551 LocalGrantedAccessPointer = 01552 ExAllocatePoolWithTag( PagedPool, (sizeof(ACCESS_MASK)+sizeof(NTSTATUS)) * ObjectTypeListLength, 'aGeS' ); 01553 01554 if (LocalGrantedAccessPointer == NULL) { 01555 Status = STATUS_INSUFFICIENT_RESOURCES; 01556 SeUnlockSubjectContext( &SubjectSecurityContext ); 01557 goto Cleanup; 01558 } 01559 LocalGrantedAccessAllocated = TRUE; 01560 LocalAccessStatusPointer = (PNTSTATUS)(LocalGrantedAccessPointer + ObjectTypeListLength); 01561 01562 } else { 01563 LocalGrantedAccessPointer = &LocalGrantedAccess; 01564 LocalAccessStatusPointer = &LocalAccessStatus; 01565 } 01566 01567 SepAccessCheck ( 01568 CapturedSecurityDescriptor, 01569 CapturedPrincipalSelfSid, 01570 SubjectSecurityContext.PrimaryToken, 01571 SubjectSecurityContext.ClientToken, 01572 DesiredAccess, 01573 LocalObjectTypeList, 01574 ObjectTypeListLength, 01575 &LocalGenericMapping, 01576 PreviouslyGrantedAccess, 01577 PreviousMode, 01578 LocalGrantedAccessPointer, 01579 NULL, // Privileges already checked 01580 LocalAccessStatusPointer, 01581 ReturnResultList, 01582 &AccessGranted, 01583 &AccessDenied 01584 ); 01585 01586 } 01587 } 01588 01589 // 01590 // sound the alarms... 01591 // 01592 01593 if ( !AvoidAudit ) { 01594 if ( SepAdtAuditThisEventEx( NtAuditType, AccessGranted, AccessDenied )) { 01595 01596 SepExamineSaclEx( 01597 RtlpSaclAddrSecurityDescriptor( (PISECURITY_DESCRIPTOR)CapturedSecurityDescriptor ), 01598 EffectiveToken( &SubjectSecurityContext ), 01599 DesiredAccess | PreviouslyGrantedAccess, 01600 LocalObjectTypeList, 01601 ObjectTypeListLength, 01602 ReturnResultList, 01603 LocalAccessStatusPointer, 01604 LocalGrantedAccessPointer, 01605 &GenerateSuccessAudit, 01606 &GenerateFailureAudit 01607 ); 01608 01609 } 01610 01611 if ( GenerateSuccessAudit || 01612 GenerateFailureAudit ) { 01613 01614 // 01615 // Save this to a local here, so we don't 01616 // have to risk accessing user memory and 01617 // potentially having to exit before the audit 01618 // 01619 01620 if ( AccessGranted ) { 01621 01622 // 01623 // SAM calls NtCloseObjectAuditAlarm despite the fact that it may not 01624 // have successfully opened the object, causing a spurious close audit. 01625 // Since no one should rely on this anyway if their access attempt 01626 // failed, make sure it's false and SAM will work properly. 01627 // 01628 01629 LocalGenerateOnClose = TRUE; 01630 } 01631 01632 // 01633 // Generate the success audit if needed. 01634 // 01635 if ( GenerateSuccessAudit ) { 01636 ExAllocateLocallyUniqueId( &OperationId ); 01637 01638 // ?? 01639 ASSERT( AccessGranted ); 01640 AuditPerformed = SepAdtOpenObjectAuditAlarm ( 01641 CapturedSubsystemName, 01642 AccessGranted ? &HandleId : NULL, // Don't audit handle if failure 01643 CapturedObjectTypeName, 01644 0, // IN PVOID Object OPTIONAL, 01645 CapturedObjectName, 01646 SubjectSecurityContext.ClientToken, 01647 SubjectSecurityContext.PrimaryToken, 01648 *LocalGrantedAccessPointer, 01649 *LocalGrantedAccessPointer, 01650 &OperationId, 01651 PrivilegeSet, 01652 ObjectCreation, 01653 TRUE, // Generate success case 01654 TRUE, // Generate audit 01655 FALSE, // Don't generate alarm 01656 PsProcessAuditId( PsGetCurrentProcess() ), 01657 NtAuditType, 01658 LocalObjectTypeList, 01659 ObjectTypeListLength, 01660 ReturnResultList ? LocalGrantedAccessPointer : NULL 01661 ); 01662 } 01663 01664 // 01665 // Generate failure audit if it is needed. 01666 // 01667 if ( GenerateFailureAudit ) { 01668 ExAllocateLocallyUniqueId( &OperationId ); 01669 01670 // ?? 01671 ASSERT( AccessDenied ); 01672 AuditPerformed = SepAdtOpenObjectAuditAlarm ( 01673 CapturedSubsystemName, 01674 AccessGranted ? &HandleId : NULL, // Don't audit handle if failure 01675 CapturedObjectTypeName, 01676 0, // IN PVOID Object OPTIONAL, 01677 CapturedObjectName, 01678 SubjectSecurityContext.ClientToken, 01679 SubjectSecurityContext.PrimaryToken, 01680 DesiredAccess, 01681 DesiredAccess, 01682 &OperationId, 01683 PrivilegeSet, 01684 ObjectCreation, 01685 FALSE, // Generate failure case 01686 TRUE, // Generate audit 01687 FALSE, // Don't generate alarm 01688 PsProcessAuditId( PsGetCurrentProcess() ), 01689 NtAuditType, 01690 LocalObjectTypeList, 01691 ObjectTypeListLength, 01692 ReturnResultList ? LocalGrantedAccessPointer : NULL 01693 ); 01694 } 01695 } else { 01696 01697 // 01698 // We didn't generate an audit due to the SACL. If privileges were used, we need 01699 // to audit that. 01700 // 01701 01702 if ( PrivilegeSet != NULL ) { 01703 01704 if ( SepAdtAuditThisEvent( AuditCategoryPrivilegeUse, &AccessGranted) ) { 01705 01706 AuditPerformed = SepAdtPrivilegeObjectAuditAlarm ( CapturedSubsystemName, 01707 &HandleId, 01708 SubjectSecurityContext.ClientToken, 01709 SubjectSecurityContext.PrimaryToken, 01710 PsProcessAuditId( PsGetCurrentProcess() ), 01711 DesiredAccess, 01712 PrivilegeSet, 01713 AccessGranted 01714 ); 01715 01716 // 01717 // We don't want close audits to be generated. May need to revisit this. 01718 // 01719 01720 LocalGenerateOnClose = FALSE; 01721 } 01722 } 01723 } 01724 } 01725 01726 SeUnlockSubjectContext( &SubjectSecurityContext ); 01727 01728 try { 01729 if ( ReturnResultList ) { 01730 ULONG ResultListIndex; 01731 if ( LocalAccessStatusPointer == NULL ) { 01732 for ( ResultListIndex=0; ResultListIndex<ObjectTypeListLength; ResultListIndex++ ) { 01733 AccessStatus[ResultListIndex] = LocalAccessStatus; 01734 GrantedAccess[ResultListIndex] = LocalGrantedAccess; 01735 } 01736 } else { 01737 for ( ResultListIndex=0; ResultListIndex<ObjectTypeListLength; ResultListIndex++ ) { 01738 AccessStatus[ResultListIndex] = LocalAccessStatusPointer[ResultListIndex]; 01739 GrantedAccess[ResultListIndex] = LocalGrantedAccessPointer[ResultListIndex]; 01740 } 01741 } 01742 01743 } else { 01744 *AccessStatus = LocalAccessStatus; 01745 *GrantedAccess = LocalGrantedAccess; 01746 } 01747 *GenerateOnClose = LocalGenerateOnClose; 01748 Status = STATUS_SUCCESS; 01749 01750 } except (EXCEPTION_EXECUTE_HANDLER) { 01751 01752 Status = GetExceptionCode(); 01753 } 01754 01755 // 01756 // Free locally used resources. 01757 // 01758 Cleanup: 01759 01760 if ( TokenSwapped ) { 01761 01762 // 01763 // Decrement the reference count for the ClientToken that was passed in. 01764 // 01765 01766 ObDereferenceObject( (PVOID)NewToken ); 01767 01768 // 01769 // Reset the value of the token from saved value. 01770 // 01771 01772 SubjectSecurityContext.ClientToken = OldToken; 01773 } 01774 01775 // 01776 // Free any privileges allocated as part of the access check 01777 // 01778 01779 if (PrivilegeSet != NULL) { 01780 ExFreePool( PrivilegeSet ); 01781 } 01782 01783 SeReleaseSubjectContext ( &SubjectSecurityContext ); 01784 01785 SeReleaseSecurityDescriptor ( CapturedSecurityDescriptor, 01786 PreviousMode, 01787 FALSE ); 01788 01789 if (CapturedSubsystemName != NULL) { 01790 SepFreeCapturedString( CapturedSubsystemName ); 01791 } 01792 01793 if (CapturedObjectTypeName != NULL) { 01794 SepFreeCapturedString( CapturedObjectTypeName ); 01795 } 01796 01797 if (CapturedObjectName != NULL) { 01798 SepFreeCapturedString( CapturedObjectName ); 01799 } 01800 01801 if (CapturedPrincipalSelfSid != NULL) { 01802 SeReleaseSid( CapturedPrincipalSelfSid, PreviousMode, TRUE); 01803 } 01804 01805 if ( LocalObjectTypeList != NULL ) { 01806 SeFreeCapturedObjectTypeList( LocalObjectTypeList ); 01807 } 01808 01809 if ( LocalGrantedAccessAllocated ) { 01810 if ( LocalGrantedAccessPointer != NULL ) { 01811 ExFreePool( LocalGrantedAccessPointer ); 01812 } 01813 } 01814 01815 return Status; 01816 }

VOID SepAuditTypeList IN PIOBJECT_TYPE_LIST  ObjectTypeList,
IN ULONG  ObjectTypeListLength,
IN PNTSTATUS  AccessStatus,
IN ULONG  StartIndex,
OUT PBOOLEAN  GenerateSuccessAudit,
OUT PBOOLEAN  GenerateFailureAudit
 

Definition at line 4093 of file seaudit.c.

References Index, NT_SUCCESS, OBJECT_FAILURE_AUDIT, OBJECT_SUCCESS_AUDIT, PAGED_CODE, and TRUE.

Referenced by SepSetAuditInfoForObjectType().

04103 : 04104 04105 This routine determines if any children of the object represented by 04106 StartIndex have a different degree of success than the StartIndex element. 04107 04108 Arguments: 04109 04110 ObjectTypeList - The object type list to update. 04111 04112 ObjectTypeListLength - Number of elements in ObjectTypeList 04113 04114 AccessStatus - Specifies STATUS_SUCCESS or other error code to be 04115 propogated back to the caller 04116 04117 StartIndex - Index to the target element to update. 04118 04119 GenerateSuccessAudit - Returns a boolean indicating whether or not 04120 we should generate a success audit. 04121 04122 GenerateFailureAudit - Returns a boolean indicating whether or not 04123 we should generate a failure audit. 04124 04125 Return Value: 04126 04127 None. 04128 04129 --*/ 04130 04131 { 04132 ULONG Index; 04133 BOOLEAN WasSuccess; 04134 04135 PAGED_CODE(); 04136 04137 // 04138 // Determine if the target was successful. 04139 // 04140 04141 WasSuccess = NT_SUCCESS( AccessStatus[StartIndex] ); 04142 04143 // 04144 // Loop handling all children of the target. 04145 // 04146 04147 for ( Index=StartIndex+1; Index<ObjectTypeListLength; Index++ ) { 04148 04149 // 04150 // By definition, the children of an object are all those entries 04151 // immediately following the target. The list of children (or 04152 // grandchildren) stops as soon as we reach an entry the has the 04153 // same level as the target (a sibling) or lower than the target 04154 // (an uncle). 04155 // 04156 04157 if ( ObjectTypeList[Index].Level <= ObjectTypeList[StartIndex].Level ) { 04158 break; 04159 } 04160 04161 // 04162 // If the child has different access than the target, 04163 // mark the child. 04164 // 04165 04166 if ( WasSuccess && !NT_SUCCESS( AccessStatus[Index]) ) { 04167 *GenerateFailureAudit = TRUE; 04168 ObjectTypeList[Index].Flags |= OBJECT_FAILURE_AUDIT; 04169 } else if ( !WasSuccess && NT_SUCCESS( AccessStatus[Index]) ) { 04170 *GenerateSuccessAudit = TRUE; 04171 ObjectTypeList[Index].Flags |= OBJECT_SUCCESS_AUDIT; 04172 } 04173 04174 } 04175 }

VOID SepExamineSacl IN PACL  Sacl,
IN PACCESS_TOKEN  Token,
IN ACCESS_MASK  DesiredAccess,
IN BOOLEAN  AccessGranted,
OUT PBOOLEAN  GenerateAudit,
OUT PBOOLEAN  GenerateAlarm
 

Definition at line 3952 of file seaudit.c.

References FALSE, FirstAce, NextAce, NULL, PAGED_CODE, SepSidInToken(), Token, and TRUE.

Referenced by NtOpenObjectAuditAlarm(), SeCreateObjectAuditAlarm(), SeObjectReferenceAuditAlarm(), SeOpenObjectAuditAlarm(), SeOpenObjectForDeleteAuditAlarm(), and SeTraverseAuditAlarm().

03963 : 03964 03965 This routine will examine the passed Sacl and determine what 03966 if any action is required based its contents. 03967 03968 Note that this routine is not aware of any system state, ie, 03969 whether or not auditing is currently enabled for either the 03970 system or this particular object type. 03971 03972 Arguments: 03973 03974 Sacl - Supplies a pointer to the Sacl to be examined. 03975 03976 Token - Supplies the effective token of the caller 03977 03978 AccessGranted - Supplies whether or not the access attempt 03979 was successful. 03980 03981 GenerateAudit - Returns a boolean indicating whether or not 03982 we should generate an audit. 03983 03984 GenerateAlarm - Returns a boolean indiciating whether or not 03985 we should generate an alarm. 03986 03987 Return Value: 03988 03989 STATUS_SUCCESS - The operation completed successfully. 03990 03991 --*/ 03992 03993 { 03994 03995 ULONG i; 03996 PVOID Ace; 03997 ULONG AceCount; 03998 ACCESS_MASK AccessMask; 03999 UCHAR AceFlags; 04000 BOOLEAN FailedMaximumAllowed; 04001 04002 PAGED_CODE(); 04003 04004 *GenerateAudit = FALSE; 04005 *GenerateAlarm = FALSE; 04006 04007 // 04008 // If we failed an attempt to open an object for ONLY maximumum allowed, 04009 // then we generate an audit if ANY ACCESS_DENIED audit matching this 04010 // user's list of sids is found 04011 // 04012 04013 FailedMaximumAllowed = FALSE; 04014 if (!AccessGranted && (DesiredAccess & MAXIMUM_ALLOWED)) { 04015 FailedMaximumAllowed = TRUE; 04016 } 04017 04018 // 04019 // If the Sacl is null, do nothing and return 04020 // 04021 04022 if (Sacl == NULL) { 04023 04024 return; 04025 } 04026 04027 AceCount = Sacl->AceCount; 04028 04029 if (AceCount == 0) { 04030 return; 04031 } 04032 04033 // 04034 // Iterate through the ACEs on the Sacl until either we reach 04035 // the end or discover that we have to take all possible actions, 04036 // in which case it doesn't pay to look any further 04037 // 04038 04039 for ( i = 0, Ace = FirstAce( Sacl ) ; 04040 (i < AceCount) && !(*GenerateAudit && *GenerateAlarm); 04041 i++, Ace = NextAce( Ace ) ) { 04042 04043 if ( !(((PACE_HEADER)Ace)->AceFlags & INHERIT_ONLY_ACE)) { 04044 04045 if ( (((PACE_HEADER)Ace)->AceType == SYSTEM_AUDIT_ACE_TYPE) ) { 04046 04047 if ( SepSidInToken( (PACCESS_TOKEN)Token, NULL, &((PSYSTEM_AUDIT_ACE)Ace)->SidStart, FALSE ) ) { 04048 04049 AccessMask = ((PSYSTEM_AUDIT_ACE)Ace)->Mask; 04050 AceFlags = ((PACE_HEADER)Ace)->AceFlags; 04051 04052 if ( AccessMask & DesiredAccess ) { 04053 04054 if (((AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) && AccessGranted) || 04055 ((AceFlags & FAILED_ACCESS_ACE_FLAG) && !AccessGranted)) { 04056 04057 *GenerateAudit = TRUE; 04058 } 04059 } else if ( FailedMaximumAllowed && (AceFlags & FAILED_ACCESS_ACE_FLAG) ) { 04060 *GenerateAudit = TRUE; 04061 } 04062 } 04063 04064 continue; 04065 } 04066 04067 if ( (((PACE_HEADER)Ace)->AceType == SYSTEM_ALARM_ACE_TYPE) ) { 04068 04069 if ( SepSidInToken( (PACCESS_TOKEN)Token, NULL, &((PSYSTEM_ALARM_ACE)Ace)->SidStart, FALSE ) ) { 04070 04071 AccessMask = ((PSYSTEM_ALARM_ACE)Ace)->Mask; 04072 04073 if ( AccessMask & DesiredAccess ) { 04074 04075 AceFlags = ((PACE_HEADER)Ace)->AceFlags; 04076 04077 if (((AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) && AccessGranted) || 04078 ((AceFlags & FAILED_ACCESS_ACE_FLAG) && !AccessGranted)) { 04079 04080 *GenerateAlarm = TRUE; 04081 } 04082 } 04083 } 04084 } 04085 } 04086 } 04087 04088 return; 04089 }

VOID SepExamineSaclEx IN PACL  Sacl,
IN PACCESS_TOKEN  Token,
IN ACCESS_MASK  DesiredAccess,
IN PIOBJECT_TYPE_LIST ObjectTypeList  OPTIONAL,
IN ULONG  ObjectTypeListLength,
IN BOOLEAN  ReturnResultList,
IN PNTSTATUS  AccessStatus,
IN PACCESS_MASK  GrantedAccess,
OUT PBOOLEAN  GenerateSuccessAudit,
OUT PBOOLEAN  GenerateFailureAudit
 

Definition at line 4257 of file seaudit.c.

References FALSE, FirstAce, Index, INVALID_OBJECT_TYPE_LIST_INDEX, NextAce, NT_SUCCESS, NULL, PAGED_CODE, SepObjectInTypeList(), SepSetAuditInfoForObjectType(), SepSidInToken(), Token, and TRUE.

Referenced by SepAccessCheckAndAuditAlarm().

04272 : 04273 04274 This routine will examine the passed Sacl and determine what 04275 if any action is required based its contents. 04276 04277 Note that this routine is not aware of any system state, ie, 04278 whether or not auditing is currently enabled for either the 04279 system or this particular object type. 04280 04281 Arguments: 04282 04283 Sacl - Supplies a pointer to the Sacl to be examined. 04284 04285 Token - Supplies the effective token of the caller 04286 04287 DesiredAccess - Access that the caller wanted to the object 04288 04289 ObjectTypeList - Supplies a list of GUIDs representing the object (and 04290 sub-objects) being accessed. 04291 04292 ObjectTypeListLength - Specifies the number of elements in the ObjectTypeList. 04293 04294 ReturnResultList - If true, AccessStatus and GrantedAccess is actually 04295 an array of entries ObjectTypeListLength elements long. 04296 04297 AccessStatus - Specifies STATUS_SUCCESS or other error code to be 04298 propogated back to the caller 04299 04300 GrantedAccess - Specifies the access granted to the caller. 04301 04302 GenerateSuccessAudit - Returns a boolean indicating whether or not 04303 we should generate a success audit. 04304 04305 GenerateFailureAudit - Returns a boolean indicating whether or not 04306 we should generate a failure audit. 04307 04308 Return Value: 04309 04310 STATUS_SUCCESS - The operation completed successfully. 04311 04312 --*/ 04313 04314 { 04315 04316 ULONG i, j; 04317 PVOID Ace; 04318 ULONG AceCount; 04319 ACCESS_MASK AccessMask; 04320 UCHAR AceFlags; 04321 BOOLEAN FailedMaximumAllowed; 04322 ULONG Index; 04323 ULONG SuccessIndex; 04324 #define INVALID_OBJECT_TYPE_LIST_INDEX 0xFFFFFFFF 04325 04326 PAGED_CODE(); 04327 04328 *GenerateSuccessAudit = FALSE; 04329 *GenerateFailureAudit = FALSE; 04330 04331 // 04332 // If we failed an attempt to open an object for maximumum allowed, 04333 // then we generate an audit if ANY ACCESS_DENIED audit matching this 04334 // user's list of sids is found 04335 // 04336 04337 FailedMaximumAllowed = FALSE; 04338 if (!NT_SUCCESS(*AccessStatus) && (DesiredAccess & MAXIMUM_ALLOWED)) { 04339 FailedMaximumAllowed = TRUE; 04340 } 04341 04342 // 04343 // If the Sacl is null, do nothing and return 04344 // 04345 04346 if (Sacl == NULL) { 04347 return; 04348 } 04349 04350 AceCount = Sacl->AceCount; 04351 04352 if (AceCount == 0) { 04353 return; 04354 } 04355 04356 04357 // 04358 // Iterate through the ACEs on the Sacl until either we reach 04359 // the end or discover that we have to take all possible actions, 04360 // in which case it doesn't pay to look any further 04361 // 04362 04363 for ( i = 0, Ace = FirstAce( Sacl ) ; 04364 (i < AceCount) && !((*GenerateSuccessAudit || *GenerateFailureAudit) && ObjectTypeListLength <= 1 ); 04365 i++, Ace = NextAce( Ace ) ) { 04366 04367 AceFlags = ((PACE_HEADER)Ace)->AceFlags; 04368 04369 if ( !(AceFlags & INHERIT_ONLY_ACE)) { 04370 04371 Index = INVALID_OBJECT_TYPE_LIST_INDEX; 04372 04373 if ( (((PACE_HEADER)Ace)->AceType == SYSTEM_AUDIT_ACE_TYPE) ) { 04374 04375 if ( SepSidInToken( Token, NULL, &((PSYSTEM_AUDIT_ACE)Ace)->SidStart, (BOOLEAN) ((AceFlags & FAILED_ACCESS_ACE_FLAG) != 0) ) ) { 04376 04377 AccessMask = ((PSYSTEM_AUDIT_ACE)Ace)->Mask; 04378 04379 for (j=0; j < ObjectTypeListLength; j++) 04380 { 04381 SepSetAuditInfoForObjectType(AceFlags, 04382 AccessMask, 04383 DesiredAccess, 04384 ObjectTypeList, 04385 ObjectTypeListLength, 04386 ReturnResultList, 04387 j, 04388 AccessStatus, 04389 GrantedAccess, 04390 FailedMaximumAllowed, 04391 GenerateSuccessAudit, 04392 GenerateFailureAudit 04393 ); 04394 } 04395 Index = INVALID_OBJECT_TYPE_LIST_INDEX; 04396 } 04397 04398 // 04399 // Handle an object specific audit ACE 04400 // 04401 } else if ( (((PACE_HEADER)Ace)->AceType == SYSTEM_AUDIT_OBJECT_ACE_TYPE) ) { 04402 GUID *ObjectTypeInAce; 04403 04404 // 04405 // If no object type is in the ACE, 04406 // treat this as a normal audit ACE. 04407 // 04408 04409 AccessMask = ((PSYSTEM_AUDIT_OBJECT_ACE)Ace)->Mask; 04410 ObjectTypeInAce = RtlObjectAceObjectType(Ace); 04411 04412 if ( ObjectTypeInAce == NULL ) { 04413 04414 if ( SepSidInToken( Token, NULL, RtlObjectAceSid(Ace), (BOOLEAN)((AceFlags & FAILED_ACCESS_ACE_FLAG) != 0) ) ) { 04415 04416 for (j=0; j < ObjectTypeListLength; j++) 04417 { 04418 SepSetAuditInfoForObjectType(AceFlags, 04419 AccessMask, 04420 DesiredAccess, 04421 ObjectTypeList, 04422 ObjectTypeListLength, 04423 ReturnResultList, 04424 j, 04425 AccessStatus, 04426 GrantedAccess, 04427 FailedMaximumAllowed, 04428 GenerateSuccessAudit, 04429 GenerateFailureAudit 04430 ); 04431 } 04432 Index = INVALID_OBJECT_TYPE_LIST_INDEX; 04433 } 04434 04435 // 04436 // If no object type list was passed, 04437 // don't generate an audit. 04438 // 04439 04440 } else if ( ObjectTypeListLength == 0 ) { 04441 04442 // Drop through 04443 04444 // 04445 // If an object type is in the ACE, 04446 // Find it in the LocalTypeList before using the ACE. 04447 // 04448 } else { 04449 04450 if ( SepSidInToken( Token, NULL, RtlObjectAceSid(Ace), (BOOLEAN)((AceFlags & FAILED_ACCESS_ACE_FLAG) != 0) ) ) { 04451 04452 if ( !SepObjectInTypeList( ObjectTypeInAce, 04453 ObjectTypeList, 04454 ObjectTypeListLength, 04455 &Index ) ) { 04456 04457 Index = INVALID_OBJECT_TYPE_LIST_INDEX; 04458 } 04459 } 04460 } 04461 04462 } 04463 04464 // 04465 // If the ACE has a matched SID and a matched GUID, 04466 // handle it. 04467 // 04468 04469 if ( Index != INVALID_OBJECT_TYPE_LIST_INDEX ) { 04470 04471 // 04472 // ASSERT: we have an ACE to be audited. 04473 // 04474 // Index is an index into ObjectTypeList of the entry to mark 04475 // as the GUID needs auditing. 04476 // 04477 // SuccessIndex is an index into AccessStatus to determine if 04478 // a success or failure audit is to be generated 04479 // 04480 04481 SepSetAuditInfoForObjectType(AceFlags, 04482 AccessMask, 04483 DesiredAccess, 04484 ObjectTypeList, 04485 ObjectTypeListLength, 04486 ReturnResultList, 04487 Index, 04488 AccessStatus, 04489 GrantedAccess, 04490 FailedMaximumAllowed, 04491 GenerateSuccessAudit, 04492 GenerateFailureAudit 04493 ); 04494 } 04495 04496 } 04497 } 04498 04499 return; 04500 }

BOOLEAN SepFilterPrivilegeAudits IN PPRIVILEGE_SET  PrivilegeSet  ) 
 

Definition at line 4587 of file seaudit.c.

References FALSE, NULL, PAGED_CODE, RtlEqualLuid(), SepFilterPrivileges, and TRUE.

Referenced by SeOpenObjectAuditAlarm(), SeOpenObjectForDeleteAuditAlarm(), SepAdtPrivilegeObjectAuditAlarm(), and SePrivilegedServiceAuditAlarm().

04593 : 04594 04595 This routine will filter out a list of privileges as listed in the 04596 SepFilterPrivileges array. 04597 04598 Arguments: 04599 04600 Privileges - The privilege set to be audited 04601 04602 Return Value: 04603 04604 FALSE means that this use of privilege is not to be audited. 04605 TRUE means that the audit should continue normally. 04606 04607 --*/ 04608 04609 { 04610 PLUID *Privilege; 04611 ULONG Match = 0; 04612 ULONG i; 04613 04614 PAGED_CODE(); 04615 04616 if ( !ARGUMENT_PRESENT(PrivilegeSet) || 04617 (PrivilegeSet->PrivilegeCount == 0) ) { 04618 return( FALSE ); 04619 } 04620 04621 for (i=0; i<PrivilegeSet->PrivilegeCount; i++) { 04622 04623 Privilege = SepFilterPrivileges; 04624 04625 do { 04626 04627 if ( RtlEqualLuid( &PrivilegeSet->Privilege[i].Luid, *Privilege )) { 04628 04629 Match++; 04630 break; 04631 } 04632 04633 } while ( *++Privilege != NULL ); 04634 } 04635 04636 if ( Match == PrivilegeSet->PrivilegeCount ) { 04637 04638 return( FALSE ); 04639 04640 } else { 04641 04642 return( TRUE ); 04643 } 04644 }

VOID SepFreeCapturedString IN PUNICODE_STRING  CapturedString  ) 
 

Definition at line 370 of file seaudit.c.

References ExFreePool(), and PAGED_CODE.

Referenced by NtCloseObjectAuditAlarm(), NtDeleteObjectAuditAlarm(), NtOpenObjectAuditAlarm(), NtPrivilegedServiceAuditAlarm(), NtPrivilegeObjectAuditAlarm(), and SepAccessCheckAndAuditAlarm().

00376 : 00377 00378 Frees a string captured by SepProbeAndCaptureString. 00379 00380 Arguments: 00381 00382 CapturedString - Supplies a pointer to a string previously captured 00383 by SepProbeAndCaptureString. 00384 00385 Return Value: 00386 00387 None. 00388 00389 --*/ 00390 00391 { 00392 PAGED_CODE(); 00393 00394 ExFreePool( CapturedString ); 00395 return; 00396 }

BOOLEAN SepInitializePrivilegeFilter BOOLEAN  Verbose  ) 
 

Definition at line 4556 of file seaudit.c.

References SepFilterPrivileges, SepFilterPrivilegesLong, SepFilterPrivilegesShort, and TRUE.

Referenced by SepAdtInitializePrivilegeAuditing().

04561 : 04562 04563 Initializes SepFilterPrivileges for either normal or verbose auditing. 04564 04565 Arguments: 04566 04567 Verbose - Whether we want to filter by the short or long privileges 04568 list. Verbose == TRUE means use the short list. 04569 04570 Return Value: 04571 04572 TRUE for success, FALSE for failure 04573 04574 --*/ 04575 { 04576 if (Verbose) { 04577 SepFilterPrivileges = SepFilterPrivilegesShort; 04578 } else { 04579 SepFilterPrivileges = SepFilterPrivilegesLong; 04580 } 04581 04582 return( TRUE ); 04583 }

VOID SepProbeAndCaptureString_U IN PUNICODE_STRING  SourceString,
OUT PUNICODE_STRING *  DestString
 

Definition at line 259 of file seaudit.c.

References DestString, ExAllocatePoolWithTag, ExFreePool(), ExSystemExceptionFilter(), NTSTATUS(), NULL, PAGED_CODE, PagedPool, ProbeAndReadUnicodeString, ProbeForRead, SourceString, and Status.

Referenced by NtCloseObjectAuditAlarm(), NtDeleteObjectAuditAlarm(), NtOpenObjectAuditAlarm(), NtPrivilegedServiceAuditAlarm(), NtPrivilegeObjectAuditAlarm(), and SepAccessCheckAndAuditAlarm().

00265 : 00266 00267 Helper routine to probe and capture a Unicode string argument. 00268 00269 This routine may fail due to lack of memory, in which case, 00270 it will return a NULL pointer in the output parameter. 00271 00272 Arguments: 00273 00274 SourceString - Pointer to a Unicode string to be captured. 00275 00276 DestString - Returns a pointer to a captured Unicode string. This 00277 will be one contiguous structure, and thus may be freed by 00278 a single call to ExFreePool(). 00279 00280 Return Value: 00281 00282 None. 00283 00284 --*/ 00285 { 00286 00287 UNICODE_STRING InputString; 00288 ULONG Length; 00289 NTSTATUS Status; 00290 00291 PAGED_CODE(); 00292 00293 // 00294 // Initialize the object name descriptor and capture the specified name 00295 // string. 00296 // 00297 00298 *DestString = NULL; 00299 00300 Status = STATUS_SUCCESS; 00301 try { 00302 00303 // 00304 // Probe and capture the name string descriptor and probe the 00305 // name string, if necessary. 00306 // 00307 00308 InputString = ProbeAndReadUnicodeString(SourceString); 00309 ProbeForRead(InputString.Buffer, 00310 InputString.Length, 00311 sizeof(WCHAR)); 00312 00313 00314 00315 // 00316 // If the length of the string is not an even multiple of the 00317 // size of a UNICODE character or cannot be zero terminated, 00318 // then return an error. 00319 // 00320 00321 Length = InputString.Length; 00322 if (((Length & (sizeof(WCHAR) - 1)) != 0) || 00323 (Length == (MAXUSHORT - sizeof(WCHAR) + 1))) { 00324 Status = STATUS_INVALID_PARAMETER; 00325 00326 } else { 00327 00328 // 00329 // Allocate a buffer for the specified name string. 00330 // 00331 00332 *DestString = ExAllocatePoolWithTag( 00333 PagedPool, 00334 InputString.Length + sizeof(UNICODE_STRING), 00335 'sUeS'); 00336 00337 if (*DestString == NULL) { 00338 Status = STATUS_INSUFFICIENT_RESOURCES; 00339 00340 } else { 00341 (*DestString)->Length = InputString.Length; 00342 (*DestString)->MaximumLength = InputString.Length; 00343 (*DestString)->Buffer = (PWSTR) ((*DestString) + 1); 00344 00345 if (InputString.Length != 0) { 00346 00347 RtlCopyMemory( 00348 (*DestString)->Buffer, 00349 InputString.Buffer, 00350 InputString.Length); 00351 } 00352 00353 } 00354 } 00355 00356 } except(ExSystemExceptionFilter()) { 00357 Status = GetExceptionCode(); 00358 if (*DestString != NULL) { 00359 ExFreePool(*DestString); 00360 *DestString = NULL; 00361 } 00362 } 00363 00364 return; 00365 00366 }

VOID SePrivilegedServiceAuditAlarm IN PUNICODE_STRING  ServiceName,
IN PSECURITY_SUBJECT_CONTEXT  SubjectSecurityContext,
IN PPRIVILEGE_SET  Privileges,
IN BOOLEAN  AccessGranted
 

Definition at line 989 of file seaudit.c.

References EffectiveToken, PAGED_CODE, PTOKEN, RtlEqualSid(), SeLocalSystemSid, SepAdtAuditThisEvent, SepAdtPrivilegedServiceAuditAlarm(), SepFilterPrivilegeAudits(), SepTokenUserSid, SeSubsystemName, and Token.

Referenced by ObpIncrementHandleCount(), RtlpNewSecurityObject(), SeCheckAuditPrivilege(), and SeSinglePrivilegeCheck().

00997 : 00998 00999 This routine is to be called whenever a privileged system service 01000 is attempted. It should be called immediately after the privilege 01001 check regardless of whether or not the test succeeds. 01002 01003 Arguments: 01004 01005 ServiceName - Supplies the name of the privileged system service. 01006 01007 SubjectSecurityContext - The subject security context representing 01008 the caller of the system service. 01009 01010 Privileges - Supplies a privilge set containing the privilege(s) 01011 required for the access. 01012 01013 AccessGranted - Supplies the results of the privilege test. 01014 01015 Return Value: 01016 01017 None. 01018 01019 --*/ 01020 01021 { 01022 PTOKEN Token; 01023 01024 PAGED_CODE(); 01025 01026 if ( SepAdtAuditThisEvent( AuditCategoryPrivilegeUse, &AccessGranted ) && 01027 SepFilterPrivilegeAudits( Privileges )) { 01028 01029 Token = (PTOKEN)EffectiveToken( SubjectSecurityContext ); 01030 01031 if ( RtlEqualSid( SeLocalSystemSid, SepTokenUserSid( Token ))) { 01032 return; 01033 } 01034 01035 SepAdtPrivilegedServiceAuditAlarm ( 01036 &SeSubsystemName, 01037 ServiceName, 01038 SubjectSecurityContext->ClientToken, 01039 SubjectSecurityContext->PrimaryToken, 01040 Privileges, 01041 AccessGranted 01042 ); 01043 } 01044 01045 return; 01046 }

VOID SePrivilegeObjectAuditAlarm IN HANDLE  Handle,
IN PSECURITY_SUBJECT_CONTEXT  SubjectSecurityContext,
IN ACCESS_MASK  DesiredAccess,
IN PPRIVILEGE_SET  Privileges,
IN BOOLEAN  AccessGranted,
IN KPROCESSOR_MODE  AccessMode
 

Definition at line 650 of file seaudit.c.

References Handle, KernelMode, PAGED_CODE, SepAdtPrivilegeObjectAuditAlarm(), and SeSubsystemName.

Referenced by IsPrivileged(), ObpCreateHandle(), and SeCheckPrivilegedObject().

00661 : 00662 00663 This routine is used by object methods that perform privileged 00664 operations to generate audit and alarm messages related to the use 00665 of privileges, or attempts to use privileges. 00666 00667 Arguments: 00668 00669 Object - Address of the object accessed. This value will not be 00670 used as a pointer (referenced). It is necessary only to enter 00671 into log messages. 00672 00673 Handle - Provides the handle value assigned for the open. 00674 00675 SecurityDescriptor - A pointer to the security descriptor of the 00676 object being accessed. 00677 00678 SubjectSecurityContext - A pointer to the captured security 00679 context of the subject attempting to open the object. 00680 00681 DesiredAccess - The desired access mask. This mask must have been 00682 previously mapped to contain no generic accesses. 00683 00684 Privileges - Points to a set of privileges required for the access 00685 attempt. Those privileges that were held by the subject are 00686 marked using the UsedForAccess flag of the PRIVILEGE_ATTRIBUTES 00687 associated with each privilege. 00688 00689 AccessGranted - Indicates whether the access was granted or 00690 denied. A value of TRUE indicates the access was allowed. A 00691 value of FALSE indicates the access was denied. 00692 00693 AccessMode - Indicates the access mode used for the access check. 00694 Messages will not be generated by kernel mode accesses. 00695 00696 Return Value: 00697 00698 None. 00699 00700 --*/ 00701 00702 { 00703 BOOLEAN AuditPerformed; 00704 00705 PAGED_CODE(); 00706 00707 if (AccessMode != KernelMode) { 00708 00709 AuditPerformed = SepAdtPrivilegeObjectAuditAlarm ( 00710 &SeSubsystemName, 00711 Handle, 00712 SubjectSecurityContext->ClientToken, 00713 SubjectSecurityContext->PrimaryToken, 00714 SubjectSecurityContext->ProcessAuditId, 00715 DesiredAccess, 00716 Privileges, 00717 AccessGranted 00718 ); 00719 } 00720 }

VOID SepSetAuditInfoForObjectType IN UCHAR  AceFlags,
IN ACCESS_MASK  AccessMask,
IN ACCESS_MASK  DesiredAccess,
IN PIOBJECT_TYPE_LIST  ObjectTypeList,
IN ULONG  ObjectTypeListLength,
IN BOOLEAN  ReturnResultList,
IN ULONG  ObjectTypeIndex,
IN PNTSTATUS  AccessStatus,
IN PACCESS_MASK  GrantedAccess,
IN BOOLEAN  FailedMaximumAllowed,
OUT PBOOLEAN  GenerateSuccessAudit,
OUT PBOOLEAN  GenerateFailureAudit
 

Definition at line 4179 of file seaudit.c.

References NT_SUCCESS, OBJECT_FAILURE_AUDIT, OBJECT_SUCCESS_AUDIT, SepAuditTypeList(), and TRUE.

Referenced by SepExamineSaclEx().

04195 : 04196 04197 Determine if success/failure audit needs to be generated for 04198 object at ObjectTypeIndex in ObjectTypeList. 04199 04200 This helper function is called only by SepExamineSaclEx. 04201 04202 Arguments: 04203 04204 please refer to arg help for function SepExamineSaclEx 04205 04206 Return Value: 04207 04208 None. 04209 04210 --*/ 04211 { 04212 if ( AccessMask & (DesiredAccess|GrantedAccess[ObjectTypeIndex]) ) { 04213 04214 if ( (AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) && 04215 NT_SUCCESS(AccessStatus[ObjectTypeIndex]) ) { 04216 04217 *GenerateSuccessAudit = TRUE; 04218 if ( ObjectTypeListLength != 0 ) { 04219 04220 ObjectTypeList[ObjectTypeIndex].Flags |= OBJECT_SUCCESS_AUDIT; 04221 if ( ReturnResultList ) { 04222 SepAuditTypeList( ObjectTypeList, 04223 ObjectTypeListLength, 04224 AccessStatus, 04225 ObjectTypeIndex, 04226 GenerateSuccessAudit, 04227 GenerateFailureAudit ); 04228 } 04229 } 04230 04231 } else if ((AceFlags & FAILED_ACCESS_ACE_FLAG) && 04232 !NT_SUCCESS(AccessStatus[ObjectTypeIndex]) ) { 04233 04234 *GenerateFailureAudit = TRUE; 04235 if ( ObjectTypeListLength != 0 ) { 04236 ObjectTypeList[ObjectTypeIndex].Flags |= OBJECT_FAILURE_AUDIT; 04237 if ( ReturnResultList ) { 04238 SepAuditTypeList( ObjectTypeList, 04239 ObjectTypeListLength, 04240 AccessStatus, 04241 ObjectTypeIndex, 04242 GenerateSuccessAudit, 04243 GenerateFailureAudit ); 04244 } 04245 } 04246 } 04247 } else if ( FailedMaximumAllowed && (AceFlags & FAILED_ACCESS_ACE_FLAG) ) { 04248 *GenerateFailureAudit = TRUE; 04249 if ( ObjectTypeListLength != 0 ) { 04250 ObjectTypeList[ObjectTypeIndex].Flags |= OBJECT_FAILURE_AUDIT; 04251 } 04252 } 04253 }

BOOLEAN SepSinglePrivilegeCheck LUID  DesiredPrivilege,
IN PACCESS_TOKEN  Token,
IN KPROCESSOR_MODE  PreviousMode
 

Definition at line 143 of file seaudit.c.

References ASSERT, PAGED_CODE, SepPrivilegeCheck(), SeTcbPrivilege, and Token.

Referenced by SepAccessCheck(), and SePrivilegePolicyCheck().

00151 : 00152 00153 Determines if the passed token has the passed privilege. 00154 00155 Arguments: 00156 00157 DesiredPrivilege - The privilege to be tested for. 00158 00159 Token - The token being examined. 00160 00161 PreviousMode - The previous processor mode. 00162 00163 Return Value: 00164 00165 Returns TRUE of the subject has the passed privilege, FALSE otherwise. 00166 00167 --*/ 00168 00169 { 00170 00171 LUID_AND_ATTRIBUTES Privilege; 00172 BOOLEAN Result; 00173 00174 PAGED_CODE(); 00175 00176 // 00177 // Don't let anyone call this to test for SeTcbPrivilege 00178 // 00179 00180 ASSERT(!((DesiredPrivilege.LowPart == SeTcbPrivilege.LowPart) && 00181 (DesiredPrivilege.HighPart == SeTcbPrivilege.HighPart))); 00182 00183 Privilege.Luid = DesiredPrivilege; 00184 Privilege.Attributes = 0; 00185 00186 Result = SepPrivilegeCheck( 00187 Token, 00188 &Privilege, 00189 1, 00190 PRIVILEGE_SET_ALL_NECESSARY, 00191 PreviousMode 00192 ); 00193 00194 return(Result); 00195 }

VOID SeTraverseAuditAlarm IN PLUID  OperationID,
IN PVOID  DirectoryObject,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor,
IN PSECURITY_SUBJECT_CONTEXT  SubjectSecurityContext,
IN BOOLEAN  SubjectContextLocked,
IN ACCESS_MASK  TraverseAccess,
IN PPRIVILEGE_SET Privileges  OPTIONAL,
IN BOOLEAN  AccessGranted,
IN KPROCESSOR_MODE  AccessMode
 

Definition at line 3429 of file seaudit.c.

References _SE_AUDITING_STATE::AuditOnFailure, _SE_AUDITING_STATE::AuditOnSuccess, EffectiveToken, FALSE, KernelMode, NULL, PAGED_CODE, SeAuditingState, SeLockSubjectContext(), SepAdtTraverseAuditAlarm(), SepExamineSacl(), SepTokenAuthenticationId, SepTokenUserSid, and SeUnlockSubjectContext().

Referenced by IopParseDevice().

03442 : 03443 03444 This routine is called to audit directory traverse operations 03445 specifically. It should be called by parse procedures as they traverse 03446 directories as part of their operation. 03447 03448 Arguments: 03449 03450 OperationID - LUID identifying the operation in progress 03451 03452 DirectoryObject - Pointer to the directory being traversed. 03453 03454 SecurityDescriptor - The security descriptor (if any) attached to the 03455 directory being traversed. 03456 03457 SubjectSecurityContext - Security context of the client. 03458 03459 SubjectContextLocked - Supplies whether the SubjectContext is locked 03460 for shared access. 03461 03462 TraverseAccess - Mask to indicate the traverse access for this object 03463 type. 03464 03465 Privileges - Optional parameter to indicate any privilges that the 03466 subject may have used to gain access to the object. 03467 03468 AccessGranted - Indicates if the access was granted or denied based on 03469 the access check or privilege check. 03470 03471 AccessMode - Indicates the access mode used for the access check. One 03472 of UserMode or KernelMode. Messages will not be generated by 03473 kernel mode accesses. 03474 03475 Return value: 03476 03477 None. 03478 03479 --*/ 03480 03481 { 03482 PAGED_CODE(); 03483 03484 #if 0 03485 BOOLEAN GenerateAudit = FALSE; 03486 BOOLEAN GenerateAlarm = FALSE; 03487 03488 if (AccessMode == KernelMode) { 03489 return; 03490 } 03491 03492 if ((SeAuditingState[AuditEventTraverse].AuditOnSuccess && AccessGranted) || 03493 SeAuditingState[AuditEventTraverse].AuditOnFailure && !AccessGranted) { 03494 03495 if ( SecurityDescriptor != NULL ) { 03496 03497 if ( !SubjectContextLocked ) { 03498 SeLockSubjectContext( SubjectSecurityContext ); 03499 } 03500 03501 SepExamineSacl( 03502 RtlpSaclAddrSecurityDescriptor( (PISECURITY_DESCRIPTOR)SecurityDescriptor ), 03503 EffectiveToken( SubjectSecurityContext ), 03504 TraverseAccess, 03505 AccessGranted, 03506 &GenerateAudit, 03507 &GenerateAlarm 03508 ); 03509 03510 if (GenerateAudit || GenerateAlarm) { 03511 03512 SepAdtTraverseAuditAlarm( 03513 OperationID, 03514 DirectoryObject, 03515 SepTokenUserSid(EffectiveToken( SubjectSecurityContext )), 03516 SepTokenAuthenticationId(EffectiveToken( SubjectSecurityContext )), 03517 TraverseAccess, 03518 Privileges, 03519 AccessGranted, 03520 GenerateAudit, 03521 GenerateAlarm 03522 ); 03523 } 03524 03525 if ( !SubjectContextLocked ) { 03526 SeUnlockSubjectContext( SubjectSecurityContext ); 03527 } 03528 } 03529 } 03530 03531 #endif 03532 03533 return; 03534 }


Variable Documentation

BOOLEAN SepAuditShutdownEvents = FALSE
 

Definition at line 127 of file seaudit.c.

PLUID* SepFilterPrivileges = NULL
 

Definition at line 4520 of file seaudit.c.

Referenced by SepFilterPrivilegeAudits(), and SepInitializePrivilegeFilter().

PLUID SepFilterPrivilegesLong[]
 

Initial value:

Definition at line 4522 of file seaudit.c.

Referenced by SepInitializePrivilegeFilter().

PLUID SepFilterPrivilegesShort[]
 

Initial value:

Definition at line 4545 of file seaudit.c.

Referenced by SepInitializePrivilegeFilter().


Generated on Sat May 15 19:45:34 2004 for test by doxygen 1.3.7