Ejemplo n.º 1
0
NTSTATUS
NTAPI
NpCommonSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject,
                        IN PIRP Irp)
{
    NODE_TYPE_CODE NodeTypeCode;
    PIO_STACK_LOCATION IoStack;
    NTSTATUS Status;
    PNP_FCB Fcb;
    PNP_CCB Ccb;
    ULONG NamedPipeEnd;
    PSECURITY_DESCRIPTOR OldSecurityDescriptor;
    PSECURITY_DESCRIPTOR TempSecurityDescriptor;
    PSECURITY_DESCRIPTOR NewSecurityDescriptor;
    PAGED_CODE();

    IoStack = IoGetCurrentIrpStackLocation(Irp);

    NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
                                      (PVOID*)&Fcb,
                                      &Ccb,
                                      &NamedPipeEnd);
    if (!NodeTypeCode) return STATUS_PIPE_DISCONNECTED;
    if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_INVALID_PARAMETER;

    OldSecurityDescriptor = TempSecurityDescriptor = Fcb->SecurityDescriptor;
    Status = SeSetSecurityDescriptorInfo(NULL,
                                         &IoStack->Parameters.SetSecurity.SecurityInformation,
                                         IoStack->Parameters.SetSecurity.SecurityDescriptor,
                                         &TempSecurityDescriptor,
                                         TRUE,
                                         IoGetFileObjectGenericMapping());
    if (!NT_SUCCESS(Status)) return Status;

    Status = ObLogSecurityDescriptor(TempSecurityDescriptor, &NewSecurityDescriptor, 1);
    ASSERT(TempSecurityDescriptor != OldSecurityDescriptor);
    ExFreePoolWithTag(TempSecurityDescriptor, 0);

    if (!NT_SUCCESS(Status)) return Status;

    Fcb->SecurityDescriptor = NewSecurityDescriptor;
    ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
    return Status;
}
Ejemplo n.º 2
0
VOID
NtfsInitializeNtfsData (
    IN PDRIVER_OBJECT DriverObject
    )

/*++

Routine Description:

    This routine initializes the global ntfs data record

Arguments:

    DriverObject - Supplies the driver object for NTFS

Return Value:

    None.

--*/

{
    USHORT FileLockMaxDepth;
    USHORT IoContextMaxDepth;
    USHORT IrpContextMaxDepth;
    USHORT KeventMaxDepth;
    USHORT ScbNonpagedMaxDepth;
    USHORT ScbSnapshotMaxDepth;

    USHORT CcbDataMaxDepth;
    USHORT CcbMaxDepth;
    USHORT DeallocatedRecordsMaxDepth;
    USHORT FcbDataMaxDepth;
    USHORT FcbIndexMaxDepth;
    USHORT IndexContextMaxDepth;
    USHORT LcbMaxDepth;
    USHORT NukemMaxDepth;
    USHORT ScbDataMaxDepth;

    PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL;
    BOOLEAN CapturedSubjectContext = FALSE;

    PACL SystemDacl = NULL;
    ULONG SystemDaclLength;

    PSID AdminSid = NULL;
    PSID SystemSid = NULL;
    NTSTATUS Status = STATUS_SUCCESS;

    PAGED_CODE();

    DebugTrace( +1, Dbg, ("NtfsInitializeNtfsData\n") );

    //
    //  Zero the record and set its node type code and size
    //

    RtlZeroMemory( &NtfsData, sizeof(NTFS_DATA));

    NtfsData.NodeTypeCode = NTFS_NTC_DATA_HEADER;
    NtfsData.NodeByteSize = sizeof(NTFS_DATA);

    //
    //  Initialize the queue of mounted Vcbs
    //

    InitializeListHead(&NtfsData.VcbQueue);

    //
    //  This list head keeps track of closes yet to be done.
    //

    InitializeListHead( &NtfsData.AsyncCloseList );
    InitializeListHead( &NtfsData.DelayedCloseList );

    ExInitializeWorkItem( &NtfsData.NtfsCloseItem,
                          (PWORKER_THREAD_ROUTINE)NtfsFspClose,
                          NULL );

    //
    //  Set the driver object, device object, and initialize the global
    //  resource protecting the file system
    //

    NtfsData.DriverObject = DriverObject;

    ExInitializeResource( &NtfsData.Resource );

    //
    //  Now allocate and initialize the s-list structures used as our pool
    //  of IRP context records.  The size of the zone is based on the
    //  system memory size.  We also initialize the spin lock used to protect
    //  the zone.
    //

    KeInitializeSpinLock( &NtfsData.StrucSupSpinLock );
    {

        switch ( MmQuerySystemSize() ) {

        case MmSmallSystem:

            NtfsData.FreeEresourceTotal = 14;

            //
            //  Nonpaged Lookaside list maximum depths
            //

            FileLockMaxDepth           = 8;
            IoContextMaxDepth          = 8;
            IrpContextMaxDepth         = 4;
            KeventMaxDepth             = 8;
            ScbNonpagedMaxDepth        = 8;
            ScbSnapshotMaxDepth        = 8;

            //
            //  Paged Lookaside list maximum depths
            //

            CcbDataMaxDepth            = 4;
            CcbMaxDepth                = 4;
            DeallocatedRecordsMaxDepth = 8;
            FcbDataMaxDepth            = 8;
            FcbIndexMaxDepth           = 4;
            IndexContextMaxDepth       = 8;
            LcbMaxDepth                = 4;
            NukemMaxDepth              = 8;
            ScbDataMaxDepth            = 4;

            SetFlag( NtfsData.Flags, NTFS_FLAGS_SMALL_SYSTEM );
            NtfsMaxDelayedCloseCount = MAX_DELAYED_CLOSE_COUNT;

            break;

        case MmMediumSystem:

            NtfsData.FreeEresourceTotal = 30;

            //
            //  Nonpaged Lookaside list maximum depths
            //

            FileLockMaxDepth           = 8;
            IoContextMaxDepth          = 8;
            IrpContextMaxDepth         = 8;
            KeventMaxDepth             = 8;
            ScbNonpagedMaxDepth        = 30;
            ScbSnapshotMaxDepth        = 8;

            //
            //  Paged Lookaside list maximum depths
            //

            CcbDataMaxDepth            = 12;
            CcbMaxDepth                = 6;
            DeallocatedRecordsMaxDepth = 8;
            FcbDataMaxDepth            = 30;
            FcbIndexMaxDepth           = 12;
            IndexContextMaxDepth       = 8;
            LcbMaxDepth                = 12;
            NukemMaxDepth              = 8;
            ScbDataMaxDepth            = 12;

            SetFlag( NtfsData.Flags, NTFS_FLAGS_MEDIUM_SYSTEM );
            NtfsMaxDelayedCloseCount = 4 * MAX_DELAYED_CLOSE_COUNT;

            break;

        case MmLargeSystem:

            SetFlag( NtfsData.Flags, NTFS_FLAGS_LARGE_SYSTEM );
            NtfsMaxDelayedCloseCount = 16 * MAX_DELAYED_CLOSE_COUNT;

            if (MmIsThisAnNtAsSystem()) {

                NtfsData.FreeEresourceTotal = 256;

                //
                //  Nonpaged Lookaside list maximum depths
                //

                FileLockMaxDepth           = 8;
                IoContextMaxDepth          = 8;
                IrpContextMaxDepth         = 256;
                KeventMaxDepth             = 8;
                ScbNonpagedMaxDepth        = 128;
                ScbSnapshotMaxDepth        = 8;

                //
                //  Paged Lookaside list maximum depths
                //

                CcbDataMaxDepth            = 40;
                CcbMaxDepth                = 20;
                DeallocatedRecordsMaxDepth = 8;
                FcbDataMaxDepth            = 128;
                FcbIndexMaxDepth           = 40;
                IndexContextMaxDepth       = 8;
                LcbMaxDepth                = 40;
                NukemMaxDepth              = 8;
                ScbDataMaxDepth            = 40;

            } else {

                NtfsData.FreeEresourceTotal = 128;

                //
                //  Nonpaged Lookaside list maximum depths
                //

                FileLockMaxDepth           = 8;
                IoContextMaxDepth          = 8;
                IrpContextMaxDepth         = 64;
                KeventMaxDepth             = 8;
                ScbNonpagedMaxDepth        = 64;
                ScbSnapshotMaxDepth        = 8;

                //
                //  Paged Lookaside list maximum depths
                //

                CcbDataMaxDepth            = 20;
                CcbMaxDepth                = 10;
                DeallocatedRecordsMaxDepth = 8;
                FcbDataMaxDepth            = 64;
                FcbIndexMaxDepth           = 20;
                IndexContextMaxDepth       = 8;
                LcbMaxDepth                = 20;
                NukemMaxDepth              = 8;
                ScbDataMaxDepth            = 20;
            }

            break;
        }

        NtfsMinDelayedCloseCount = NtfsMaxDelayedCloseCount * 4 / 5;

    }

    //
    //  Initialize our various lookaside lists.  To make it a bit more readable we'll
    //  define two quick macros to do the initialization
    //

#if DBG && i386 && defined (NTFSPOOLCHECK)
#define NPagedInit(L,S,T,D) { ExInitializeNPagedLookasideList( (L), NtfsDebugAllocatePoolWithTag, NtfsDebugFreePool, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#define PagedInit(L,S,T,D)  { ExInitializePagedLookasideList(  (L), NtfsDebugAllocatePoolWithTag, NtfsDebugFreePool, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#else   //  DBG && i386
#define NPagedInit(L,S,T,D) { ExInitializeNPagedLookasideList( (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#define PagedInit(L,S,T,D)  { ExInitializePagedLookasideList(  (L), NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, S, T, D); }
#endif  //  DBG && i386

    NPagedInit( &NtfsFileLockLookasideList,    sizeof(FILE_LOCK),       'kftN', FileLockMaxDepth );
    NPagedInit( &NtfsIoContextLookasideList,   sizeof(NTFS_IO_CONTEXT), 'IftN', IoContextMaxDepth );
    NPagedInit( &NtfsIrpContextLookasideList,  sizeof(IRP_CONTEXT),     'iftN', IrpContextMaxDepth );
    NPagedInit( &NtfsKeventLookasideList,      sizeof(KEVENT),          'KftN', KeventMaxDepth );
    NPagedInit( &NtfsScbNonpagedLookasideList, sizeof(SCB_NONPAGED),    'nftN', ScbNonpagedMaxDepth );
    NPagedInit( &NtfsScbSnapshotLookasideList, sizeof(SCB_SNAPSHOT),    'TftN', ScbSnapshotMaxDepth );

    PagedInit(  &NtfsCcbLookasideList,                sizeof(CCB),                 'CftN', CcbMaxDepth );
    PagedInit(  &NtfsCcbDataLookasideList,            sizeof(CCB_DATA),            'cftN', CcbDataMaxDepth );
    PagedInit(  &NtfsDeallocatedRecordsLookasideList, sizeof(DEALLOCATED_RECORDS), 'DftN', DeallocatedRecordsMaxDepth );
    PagedInit(  &NtfsFcbDataLookasideList,            sizeof(FCB_DATA),            'fftN', FcbDataMaxDepth );
    PagedInit(  &NtfsFcbIndexLookasideList,           sizeof(FCB_INDEX),           'FftN', FcbIndexMaxDepth );
    PagedInit(  &NtfsIndexContextLookasideList,       sizeof(INDEX_CONTEXT),       'EftN', IndexContextMaxDepth );
    PagedInit(  &NtfsLcbLookasideList,                sizeof(LCB),                 'lftN', LcbMaxDepth );
    PagedInit(  &NtfsNukemLookasideList,              sizeof(NUKEM),               'NftN', NukemMaxDepth );
    PagedInit(  &NtfsScbDataLookasideList,            SIZEOF_SCB_DATA,             'sftN', ScbDataMaxDepth );

    //
    //  Initialize the cache manager callback routines,  First are the routines
    //  for normal file manipulations, followed by the routines for
    //  volume manipulations.
    //

    {
        PCACHE_MANAGER_CALLBACKS Callbacks = &NtfsData.CacheManagerCallbacks;

        Callbacks->AcquireForLazyWrite  = &NtfsAcquireScbForLazyWrite;
        Callbacks->ReleaseFromLazyWrite = &NtfsReleaseScbFromLazyWrite;
        Callbacks->AcquireForReadAhead  = &NtfsAcquireScbForReadAhead;
        Callbacks->ReleaseFromReadAhead = &NtfsReleaseScbFromReadAhead;
    }

    {
        PCACHE_MANAGER_CALLBACKS Callbacks = &NtfsData.CacheManagerVolumeCallbacks;

        Callbacks->AcquireForLazyWrite  = &NtfsAcquireVolumeFileForLazyWrite;
        Callbacks->ReleaseFromLazyWrite = &NtfsReleaseVolumeFileFromLazyWrite;
        Callbacks->AcquireForReadAhead  = NULL;
        Callbacks->ReleaseFromReadAhead = NULL;
    }

    //
    //  Initialize the queue of read ahead threads
    //

    InitializeListHead(&NtfsData.ReadAheadThreads);

    //
    //  Set up global pointer to our process.
    //

    NtfsData.OurProcess = PsGetCurrentProcess();

    //
    //  Use a try-finally to cleanup on errors.
    //

    try {

        SECURITY_DESCRIPTOR NewDescriptor;
        SID_IDENTIFIER_AUTHORITY Authority = SECURITY_NT_AUTHORITY;

        SubjectContext = NtfsAllocatePool( PagedPool, sizeof( SECURITY_SUBJECT_CONTEXT ));
        SeCaptureSubjectContext( SubjectContext );
        CapturedSubjectContext = TRUE;

        //
        //  Build the default security descriptor which gives full access to
        //  system and administrator.
        //

        AdminSid = (PSID) NtfsAllocatePool( PagedPool, RtlLengthRequiredSid( 2 ));
        RtlInitializeSid( AdminSid, &Authority, 2 );
        *(RtlSubAuthoritySid( AdminSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
        *(RtlSubAuthoritySid( AdminSid, 1 )) = DOMAIN_ALIAS_RID_ADMINS;

        SystemSid = (PSID) NtfsAllocatePool( PagedPool, RtlLengthRequiredSid( 1 ));
        RtlInitializeSid( SystemSid, &Authority, 1 );
        *(RtlSubAuthoritySid( SystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;

        SystemDaclLength = sizeof( ACL ) +
                           (2 * sizeof( ACCESS_ALLOWED_ACE )) +
                           SeLengthSid( AdminSid ) +
                           SeLengthSid( SystemSid ) +
                           8; // The 8 is just for good measure

        SystemDacl = NtfsAllocatePool( PagedPool, SystemDaclLength );

        Status = RtlCreateAcl( SystemDacl, SystemDaclLength, ACL_REVISION2 );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlAddAccessAllowedAce( SystemDacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         SystemSid );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlAddAccessAllowedAce( SystemDacl,
                                         ACL_REVISION2,
                                         GENERIC_ALL,
                                         AdminSid );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlCreateSecurityDescriptor( &NewDescriptor,
                                              SECURITY_DESCRIPTOR_REVISION1 );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = RtlSetDaclSecurityDescriptor( &NewDescriptor,
                                               TRUE,
                                               SystemDacl,
                                               FALSE );

        if (!NT_SUCCESS( Status )) { leave; }

        Status = SeAssignSecurity( NULL,
                                   &NewDescriptor,
                                   &NtfsData.DefaultDescriptor,
                                   FALSE,
                                   SubjectContext,
                                   IoGetFileObjectGenericMapping(),
                                   PagedPool );

        if (!NT_SUCCESS( Status )) { leave; }

        NtfsData.DefaultDescriptorLength = RtlLengthSecurityDescriptor( NtfsData.DefaultDescriptor );

        ASSERT( SeValidSecurityDescriptor( NtfsData.DefaultDescriptorLength,
                                           NtfsData.DefaultDescriptor ));

    } finally {

        if (CapturedSubjectContext) {

            SeReleaseSubjectContext( SubjectContext );
        }

        if (SubjectContext != NULL) { NtfsFreePool( SubjectContext ); }

        if (SystemDacl != NULL) { NtfsFreePool( SystemDacl ); }

        if (AdminSid != NULL) { NtfsFreePool( AdminSid ); }

        if (SystemSid != NULL) { NtfsFreePool( SystemSid ); }
    }

    //
    //  Raise if we hit an error building the security descriptor.
    //

    if (!NT_SUCCESS( Status )) { ExRaiseStatus( Status ); }

    //
    //  And return to our caller
    //

    DebugTrace( -1, Dbg, ("NtfsInitializeNtfsData -> VOID\n") );

    return;
}
Ejemplo n.º 3
0
NTSTATUS
FatExplicitDeviceAccessGranted (
    IN PIRP_CONTEXT IrpContext,
    IN PDEVICE_OBJECT DeviceObject,
    IN PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE ProcessorMode
    )

/*++

Routine Description:

    This function asks whether the SID described in the input access state has
    been granted any explicit access to the given device object.  It does this
    by acquiring a token stripped of its ability to acquire access via the
    Everyone SID and re-doing the access check.

Arguments:

    DeviceObject - the device whose ACL will be checked
    
    AccessState - the access state describing the security context to be checked
    
    ProcessorMode - the mode this check should occur against

Return Value:

    NTSTATUS - Indicating whether explicit access was granted.

--*/

{
    NTSTATUS Status;

    PACCESS_TOKEN OriginalAccessToken;
    PACCESS_TOKEN RestrictedAccessToken;
    
    PACCESS_TOKEN *EffectiveToken;
    
    ACCESS_MASK GrantedAccess;

    PAGED_CODE();

    UNREFERENCED_PARAMETER( IrpContext );

    //
    //  If the access state indicates that specific access other
    //  than traverse was acquired, either Everyone does have such
    //  access or explicit access was granted.  In both cases, we're
    //  happy to let this proceed.
    //

    if (AccessState->PreviouslyGrantedAccess & (SPECIFIC_RIGHTS_ALL ^
                                                FILE_TRAVERSE)) {

        return STATUS_SUCCESS;
    }

    //
    //  If the manage volume privilege is held, this also permits access.
    //

    if (FatCheckManageVolumeAccess( IrpContext,
                                    AccessState,
                                    ProcessorMode )) {

        return STATUS_SUCCESS;
    }

    //
    //  Capture the subject context as a prelude to everything below.
    //

    SeLockSubjectContext( &AccessState->SubjectSecurityContext );
    
    //
    //  Convert the token in the subject context into one which does not
    //  acquire access through the Everyone SID.
    //
    //  The logic for deciding which token is effective comes from
    //  SeQuerySubjectContextToken; since there is no natural way
    //  of getting a pointer to it, do it by hand.
    //
    
    if (ARGUMENT_PRESENT( AccessState->SubjectSecurityContext.ClientToken )) {
        EffectiveToken = &AccessState->SubjectSecurityContext.ClientToken;
    } else {
        EffectiveToken = &AccessState->SubjectSecurityContext.PrimaryToken;
    }

    OriginalAccessToken = *EffectiveToken;
    Status = FatCreateRestrictEveryoneToken( OriginalAccessToken, &RestrictedAccessToken );

    if (!NT_SUCCESS(Status)) {
        
        SeReleaseSubjectContext( &AccessState->SubjectSecurityContext );
        return Status;
    }

    //
    //  Now see if the resulting context has access to the device through
    //  its explicitly granted access.  We swap in our restricted token
    //  for this check as the effective client token.
    //

    *EffectiveToken = RestrictedAccessToken;
    
#ifdef _MSC_VER
#pragma prefast( suppress: 28175, "we're a file system, this is ok to touch" )
#endif
    SeAccessCheck( DeviceObject->SecurityDescriptor,
                   &AccessState->SubjectSecurityContext,
                   FALSE,
                   AccessState->OriginalDesiredAccess,
                   0,
                   NULL,
                   IoGetFileObjectGenericMapping(),
                   ProcessorMode,
                   &GrantedAccess,
                   &Status );
    
    *EffectiveToken = OriginalAccessToken;
    
    //
    //  Cleanup and return.
    //

    SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
    ObDereferenceObject( RestrictedAccessToken );

    return Status;
}
Ejemplo n.º 4
0
IO_STATUS_BLOCK
MsCreateClientEnd (
    IN PFCB Fcb,
    IN PFILE_OBJECT FileObject,
    IN ACCESS_MASK DesiredAccess,
    IN USHORT ShareAccess,
    IN PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE RequestorMode,
    IN PETHREAD UserThread
    )

/*++

Routine Description:

    This routine performs the operation for opening the client end of a
    mailslot.  This routine does not complete the IRP, it performs the
    function and then returns a status.

Arguments:

    Fcb - Supplies the FCB for the mailslot being accessed.

    FileObject - Supplies the file object associated with the client end.

    DesiredAccess - Supplies the caller's desired access.

    ShareAccess - Supplies the caller's share access.

Return Value:

    IO_STATUS_BLOCK - Returns the appropriate status for the operation

--*/

{
    IO_STATUS_BLOCK iosb;
    PCCB ccb;

    BOOLEAN accessGranted;
    ACCESS_MASK grantedAccess;
    UNICODE_STRING name;
    PPRIVILEGE_SET Privileges = NULL;
    BOOLEAN shareAccessUpdated = FALSE;

    PAGED_CODE();
    DebugTrace(+1, Dbg, "MsCreateClientEnd\n", 0 );

    try {

        //
        //  First do an access check for the user against the Fcb
        //

        SeLockSubjectContext( &AccessState->SubjectSecurityContext );

        accessGranted = SeAccessCheck( Fcb->SecurityDescriptor,
                                       &AccessState->SubjectSecurityContext,
                                       TRUE,                        // Tokens are locked
                                       DesiredAccess,
                                       0,
                                       &Privileges,
                                       IoGetFileObjectGenericMapping(),
                                       RequestorMode,
                                       &grantedAccess,
                                       &iosb.Status );

        if (Privileges != NULL) {

              (VOID) SeAppendPrivileges(
                         AccessState,
                         Privileges
                         );

            SeFreePrivileges( Privileges );
        }

        if (accessGranted) {
            AccessState->PreviouslyGrantedAccess |= grantedAccess;
            AccessState->RemainingDesiredAccess &= ~grantedAccess;
        }

        RtlInitUnicodeString( &name, L"Mailslot" );

        SeOpenObjectAuditAlarm( &name,
                                NULL,
                                &FileObject->FileName,
                                Fcb->SecurityDescriptor,
                                AccessState,
                                FALSE,
                                accessGranted,
                                RequestorMode,
                                &AccessState->GenerateOnClose );


        SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );

        if (!accessGranted) {

            DebugTrace(0, Dbg, "Access Denied\n", 0 );

            try_return( iosb.Status );
        }

        //
        // Now make sure our share access is okay.
        //

        if (!NT_SUCCESS(iosb.Status = IoCheckShareAccess( DesiredAccess,
                                                          ShareAccess,
                                                          FileObject,
                                                          &Fcb->ShareAccess,
                                                          TRUE ))) {

            DebugTrace(0, Dbg, "Sharing violation\n", 0);

            try_return( NOTHING );
        }

        shareAccessUpdated = TRUE;

        //
        // Create a CCB for this client.
        //

        ccb = MsCreateCcb( Fcb );

        //
        // Set the file object back pointers and our pointer to the
        // server file object.
        //

        MsSetFileObject( FileObject,
                         ccb,
                         NULL );

        ccb->FileObject = FileObject;

        //
        //  And set our return status
        //

        iosb.Status = STATUS_SUCCESS;
        iosb.Information = FILE_OPENED;


    try_exit: NOTHING;
    } finally {

        DebugTrace(-1, Dbg, "MsCreateClientEnd -> %08lx\n", iosb.Status);

        if (!NT_SUCCESS(iosb.Status) || AbnormalTermination()) {
            if (shareAccessUpdated) {
                IoRemoveShareAccess( FileObject, &Fcb->ShareAccess );
            }
        }

    }

    return iosb;
}
Ejemplo n.º 5
0
NTSTATUS
IrpCreateFile(
			  IN PUNICODE_STRING FilePath,
			  IN ACCESS_MASK DesiredAccess,
			  IN ULONG FileAttributes,
			  IN ULONG ShareAccess,
			  IN ULONG CreateDisposition,
			  IN ULONG CreateOptions,
			  IN PDEVICE_OBJECT DeviceObject,
			  IN PDEVICE_OBJECT RealDevice,
			  OUT PFILE_OBJECT *FileObject
			  )
// 			  OUT PFILE_OBJECT *FileObject,
// 			  IN ACCESS_MASK DesiredAccess,
// 			  IN PUNICODE_STRING FilePath,
// 			  OUT PIO_STATUS_BLOCK IoStatusBlock,
// 			  IN PLARGE_INTEGER AllocationSize OPTIONAL,
// 			  IN ULONG FileAttributes,
// 			  IN ULONG ShareAccess,
// 			  IN ULONG CreateDisposition,
// 			  IN ULONG CreateOptions,
// 			  IN PVOID EaBuffer OPTIONAL,
// 			  IN ULONG EaLength)
{
	NTSTATUS ntStatus;

	HANDLE hFile;
	PFILE_OBJECT  _FileObject;
	UNICODE_STRING UniDeviceNameString;
	OBJECT_ATTRIBUTES ObjectAttributes;
	IO_STATUS_BLOCK IoStatusBlock;
	WCHAR *FileNameBuffer=NULL;
	WORD FileObjectSize;
	WIN_VER_DETAIL WinVer;

	PIRP Irp;
	KEVENT kEvent;
	PIO_STACK_LOCATION IrpSp;
	ACCESS_STATE AccessState;
	AUX_ACCESS_DATA AuxData;
	IO_SECURITY_CONTEXT SecurityContext;

	InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE, 0, NULL);
	WinVer=GetWindowsVersion();
	if (WinVer==WINDOWS_VERSION_2K||
		WinVer==WINDOWS_VERSION_XP||
		WinVer==WINDOWS_VERSION_2K3||
		WinVer==WINDOWS_VERSION_2K3_SP1_SP2)
	{
		FileObjectSize=0x70;
	}
	else if (WinVer==WINDOWS_VERSION_VISTA_2008||WinVer==WINDOWS_VERSION_7_7000||WinVer==WINDOWS_VERSION_7_7600_UP)
	{
		FileObjectSize=0x80;
	}
	else
	{
		return STATUS_UNSUCCESSFUL;
	}

	ntStatus = ObCreateObject(KernelMode,
		*IoFileObjectType,
		&ObjectAttributes,
		KernelMode,
		NULL,
		FileObjectSize,
		0,
		0,
		&_FileObject);

	if(!NT_SUCCESS(ntStatus))
	{
		if (DebugOn)
			KdPrint(("[PsVoid] IrpCreateFile: ObCreateObject 0x%X.\n",ntStatus));
		return ntStatus;
	}

	Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
	if(Irp == NULL)
	{
		if (DebugOn)
			KdPrint(("[PsVoid] IrpCreateFile: IoAllocateIrp 0x%X.\n",ntStatus));
		ObDereferenceObject(_FileObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);

	RtlZeroMemory(_FileObject, FileObjectSize);
	_FileObject->Type = IO_TYPE_FILE;
	_FileObject->Size = FileObjectSize;
	_FileObject->DeviceObject = RealDevice;
	_FileObject->Flags = FO_SYNCHRONOUS_IO;
	FileNameBuffer=ExAllocatePool(NonPagedPool,FilePath->MaximumLength);
	if (FileNameBuffer==NULL)
	{
		ObDereferenceObject(_FileObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	RtlCopyMemory(FileNameBuffer,FilePath->Buffer,FilePath->Length);
    _FileObject->FileName.Buffer=FileNameBuffer;
	_FileObject->FileName.Length=FilePath->Length;
	_FileObject->FileName.MaximumLength=FilePath->MaximumLength;
	if (WinVer==WINDOWS_VERSION_VISTA_2008||WinVer==WINDOWS_VERSION_7_7000||WinVer==WINDOWS_VERSION_7_7600_UP)
	{
		PLIST_ENTRY IrpList;
		IrpList=(PLIST_ENTRY)((DWORD)FileObject+0x74);
		IrpList->Flink=IrpList;
		IrpList->Blink=IrpList;
	}

	KeInitializeEvent(&_FileObject->Lock, SynchronizationEvent, FALSE);
	KeInitializeEvent(&_FileObject->Event, NotificationEvent, FALSE);

	RtlZeroMemory(&AuxData, sizeof(AUX_ACCESS_DATA));
	ntStatus = SeCreateAccessState( &AccessState,
		&AuxData,
		DesiredAccess,
		IoGetFileObjectGenericMapping());

	if (!NT_SUCCESS(ntStatus))
	{
		if (DebugOn)
			KdPrint(("[PsVoid] IrpCreateFile: SeCreateAccessState 0x%X.\n",ntStatus));
		IoFreeIrp(Irp);
		ObDereferenceObject(_FileObject);
		ExFreePool(FileNameBuffer);
		return ntStatus;
	}

	SecurityContext.SecurityQos = NULL;
	SecurityContext.AccessState = &AccessState;
	SecurityContext.DesiredAccess = DesiredAccess;
	SecurityContext.FullCreateOptions = 0;

	Irp->MdlAddress = NULL;
	Irp->AssociatedIrp.SystemBuffer = NULL;
	Irp->Flags = IRP_CREATE_OPERATION|IRP_SYNCHRONOUS_API;
	Irp->RequestorMode = KernelMode;
	Irp->UserIosb = &IoStatusBlock;
	Irp->UserEvent = &kEvent;
	Irp->PendingReturned = FALSE;
	Irp->Cancel = FALSE;
	Irp->CancelRoutine = NULL;
	Irp->Tail.Overlay.Thread = PsGetCurrentThread();
	Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
	Irp->Tail.Overlay.OriginalFileObject = _FileObject;

	IrpSp = IoGetNextIrpStackLocation(Irp);
	IrpSp->MajorFunction = IRP_MJ_CREATE;
	IrpSp->DeviceObject = DeviceObject;
	IrpSp->FileObject = _FileObject;
	IrpSp->Parameters.Create.SecurityContext = &SecurityContext;
	IrpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
	IrpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
	IrpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
	IrpSp->Parameters.Create.EaLength = 0;

	IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
	ntStatus = IoCallDriver(DeviceObject, Irp);
	if(ntStatus == STATUS_PENDING)
		KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);

	ntStatus = IoStatusBlock.Status;

	if(!NT_SUCCESS(ntStatus))
	{
		if (DebugOn)
			KdPrint(("[PsVoid] IrpCreateFile: IoCallDriver 0x%X.\n",ntStatus));
		_FileObject->DeviceObject = NULL;
		ObDereferenceObject(_FileObject);

	}
	else
	{
		InterlockedIncrement(&_FileObject->DeviceObject->ReferenceCount);
		if (_FileObject->Vpb)
			InterlockedIncrement(&_FileObject->Vpb->ReferenceCount);
		*FileObject = _FileObject;
	}


	return ntStatus;
}
Ejemplo n.º 6
0
NTSTATUS
	IrpCreateFile(
	IN PUNICODE_STRING FileName,
	IN ACCESS_MASK DesiredAccess,
	__out PIO_STATUS_BLOCK IoStatusBlock,
	IN ULONG FileAttributes,
	IN ULONG ShareAccess,
	IN ULONG CreateDisposition,
	IN ULONG CreateOptions,
	IN PDEVICE_OBJECT DeviceObject,
	IN PDEVICE_OBJECT RealDevice,
	OUT PFILE_OBJECT *Object
	)
{
	NTSTATUS status;
	KEVENT event;
	PIRP irp;
	PIO_STACK_LOCATION irpSp;
	IO_SECURITY_CONTEXT securityContext;
	ACCESS_STATE accessState;
	OBJECT_ATTRIBUTES objectAttributes;
	PFILE_OBJECT fileObject;
	AUX_ACCESS_DATA auxData;

	PAGED_CODE();

	RtlZeroMemory(&auxData, sizeof(AUX_ACCESS_DATA));
	
	InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE| OBJ_KERNEL_HANDLE, 0, NULL);

	status = ObCreateObject(KernelMode,
		*IoFileObjectType,
		&objectAttributes,
		KernelMode,
		NULL,
		sizeof(FILE_OBJECT),
		0,
		0,
		(PVOID *)&fileObject);

	if (!NT_SUCCESS(status)) {
		return status;
	}

	RtlZeroMemory(fileObject, sizeof(FILE_OBJECT));
	fileObject->Type = IO_TYPE_FILE;
	fileObject->Size = sizeof(FILE_OBJECT);
	fileObject->DeviceObject = RealDevice;
	//	fileObject->RelatedFileObject = NULL;
	fileObject->Flags = FO_SYNCHRONOUS_IO;
	fileObject->FileName.MaximumLength = FileName->MaximumLength;
	fileObject->FileName.Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPool, FileName->MaximumLength, 'File');
	//fileObject->FileObjectExtension
	if (fileObject->FileName.Buffer == NULL) {
		ObDereferenceObject(fileObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlCopyUnicodeString(&fileObject->FileName, FileName);
	KeInitializeEvent(&fileObject->Lock, SynchronizationEvent, FALSE);
	KeInitializeEvent(&fileObject->Event, NotificationEvent, FALSE);

	irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
	
	if (irp == NULL) {
		ObDereferenceObject(fileObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	KeInitializeEvent(&event, SynchronizationEvent, FALSE);

	irp->MdlAddress = NULL;
	irp->Flags |= IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
	irp->RequestorMode = KernelMode;
	irp->UserIosb = IoStatusBlock;
	////LCXL:CHANGE
	irp->UserEvent = &event;
	//irp->UserEvent = NULL;
	irp->PendingReturned = FALSE;
	irp->Cancel = FALSE;
	irp->CancelRoutine = NULL;
	irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
	irp->Tail.Overlay.AuxiliaryBuffer = NULL;
	irp->Tail.Overlay.OriginalFileObject = fileObject;

	status = SeCreateAccessState(&accessState,
		&auxData,
		DesiredAccess,
		IoGetFileObjectGenericMapping());

	if (!NT_SUCCESS(status)) {
		IoFreeIrp(irp);
		ExFreePool(fileObject->FileName.Buffer);
		ObDereferenceObject(fileObject);
		return status;
	}

	securityContext.SecurityQos = NULL;
	securityContext.AccessState = &accessState;
	securityContext.DesiredAccess = DesiredAccess;
	securityContext.FullCreateOptions = 0;

	irpSp = IoGetNextIrpStackLocation(irp);
	irpSp->MajorFunction = IRP_MJ_CREATE;
	irpSp->DeviceObject = DeviceObject;
	irpSp->FileObject = fileObject;
	irpSp->Parameters.Create.SecurityContext = &securityContext;
	irpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
	irpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
	irpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
	irpSp->Parameters.Create.EaLength = 0;

	IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
	status = IoCallDriver(DeviceObject, irp);

	if (status == STATUS_PENDING) {
		KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
	}

	status = IoStatusBlock->Status;

	if (!NT_SUCCESS(status)) {
		ExFreePool(fileObject->FileName.Buffer);
		fileObject->FileName.Length = 0;
		fileObject->DeviceObject = NULL;
		ObDereferenceObject(fileObject);
	} else {
		InterlockedIncrement(&fileObject->DeviceObject->ReferenceCount);
		if (fileObject->Vpb) {
			InterlockedIncrement((PLONG)&fileObject->Vpb->ReferenceCount);
		}
		*Object = fileObject;
		KdPrint(("IrpCreateFile:Open file success! object = %x\n", fileObject));
	}

	return status;
}
Ejemplo n.º 7
0
NTSTATUS
AfdCreateRawSecurityDescriptor(
    VOID
    )

/*++

Routine Description:

    This routine creates a security descriptor which gives access
    only to Administrtors and LocalSystem. This descriptor is used
    to access check raw endpoint opens.

Arguments:

    None.

Return Value:

    STATUS_SUCCESS or an appropriate error code.

--*/

{
    PACL                  rawAcl;
    NTSTATUS              status;
    BOOLEAN               memoryAllocated = FALSE;
    PSECURITY_DESCRIPTOR  afdSecurityDescriptor;
    ULONG                 afdSecurityDescriptorLength;
    CHAR                  buffer[SECURITY_DESCRIPTOR_MIN_LENGTH];
    PSECURITY_DESCRIPTOR  localSecurityDescriptor =
                             (PSECURITY_DESCRIPTOR) &buffer;
    SECURITY_INFORMATION  securityInformation = DACL_SECURITY_INFORMATION;


    //
    // Get a pointer to the security descriptor from the AFD device object.
    //
    status = ObGetObjectSecurity(
                 AfdDeviceObject,
                 &afdSecurityDescriptor,
                 &memoryAllocated
                 );

    if (!NT_SUCCESS(status)) {
        KdPrint((
            "AFD: Unable to get security descriptor, error: %x\n",
            status
            ));
        ASSERT(memoryAllocated == FALSE);
        return(status);
    }

    //
    // Build a local security descriptor with an ACL giving only
    // administrators and system access.
    //
    status = AfdBuildDeviceAcl(&rawAcl);

    if (!NT_SUCCESS(status)) {
        KdPrint(("AFD: Unable to create Raw ACL, error: %x\n", status));
        goto error_exit;
    }

    (VOID) RtlCreateSecurityDescriptor(
                localSecurityDescriptor,
                SECURITY_DESCRIPTOR_REVISION
                );

    (VOID) RtlSetDaclSecurityDescriptor(
                localSecurityDescriptor,
                TRUE,
                rawAcl,
                FALSE
                );

    //
    // Make a copy of the AFD descriptor. This copy will be the raw descriptor.
    //
    afdSecurityDescriptorLength = RtlLengthSecurityDescriptor(
                                      afdSecurityDescriptor
                                      );

    AfdRawSecurityDescriptor = AFD_ALLOCATE_POOL(
                                   PagedPool,
                                   afdSecurityDescriptorLength,
                                   AFD_SECURITY_POOL_TAG
                                   );

    if (AfdRawSecurityDescriptor == NULL) {
        KdPrint(("AFD: couldn't allocate security descriptor\n"));
        goto error_exit;
    }

    RtlMoveMemory(
        AfdRawSecurityDescriptor,
        afdSecurityDescriptor,
        afdSecurityDescriptorLength
        );

    //
    // Now apply the local descriptor to the raw descriptor.
    //
    status = SeSetSecurityDescriptorInfo(
                 NULL,
                 &securityInformation,
                 localSecurityDescriptor,
                 &AfdRawSecurityDescriptor,
                 PagedPool,
                 IoGetFileObjectGenericMapping()
                 );

    if (!NT_SUCCESS(status)) {
        KdPrint(("AFD: SeSetSecurity failed, %lx\n", status));
        AFD_FREE_POOL(
            AfdRawSecurityDescriptor,
            AFD_SECURITY_POOL_TAG
            );
        AFD_FREE_POOL(
            rawAcl,
            AFD_SECURITY_POOL_TAG
            );
        AfdRawSecurityDescriptor = NULL;
        goto error_exit;
    }

    status = STATUS_SUCCESS;

error_exit:

    ObReleaseObjectSecurity(
        afdSecurityDescriptor,
        memoryAllocated
        );

    return(status);
}
Ejemplo n.º 8
0
NTSTATUS
AfdBuildDeviceAcl(
    OUT PACL *DeviceAcl
    )

/*++

Routine Description:

    This routine builds an ACL which gives Administrators and LocalSystem
    principals full access. All other principals have no access.

Arguments:

    DeviceAcl - Output pointer to the new ACL.

Return Value:

    STATUS_SUCCESS or an appropriate error code.

--*/

{
    PGENERIC_MAPPING GenericMapping;
    PSID AdminsSid;
    PSID SystemSid;
    ULONG AclLength;
    NTSTATUS Status;
    ACCESS_MASK AccessMask = GENERIC_ALL;
    PACL NewAcl;

    //
    // Enable access to all the globally defined SIDs
    //

    GenericMapping = IoGetFileObjectGenericMapping();

    RtlMapGenericMask( &AccessMask, GenericMapping );

    SeEnableAccessToExports();

    AdminsSid = SeExports->SeAliasAdminsSid;
    SystemSid = SeExports->SeLocalSystemSid;

    AclLength = sizeof( ACL )                    +
                2 * sizeof( ACCESS_ALLOWED_ACE ) +
                RtlLengthSid( AdminsSid )         +
                RtlLengthSid( SystemSid )         -
                2 * sizeof( ULONG );

    NewAcl = AFD_ALLOCATE_POOL(
                 PagedPool,
                 AclLength,
                 AFD_SECURITY_POOL_TAG
                 );

    if (NewAcl == NULL) {
        return( STATUS_INSUFFICIENT_RESOURCES );
    }

    Status = RtlCreateAcl (NewAcl, AclLength, ACL_REVISION );

    if (!NT_SUCCESS( Status )) {
        AFD_FREE_POOL(
            NewAcl,
            AFD_SECURITY_POOL_TAG
            );
        return( Status );
    }

    Status = RtlAddAccessAllowedAce (
                 NewAcl,
                 ACL_REVISION2,
                 AccessMask,
                 AdminsSid
                 );

    ASSERT( NT_SUCCESS( Status ));

    Status = RtlAddAccessAllowedAce (
                 NewAcl,
                 ACL_REVISION2,
                 AccessMask,
                 SystemSid
                 );

    ASSERT( NT_SUCCESS( Status ));

    *DeviceAcl = NewAcl;

    return( STATUS_SUCCESS );

} // AfdBuildDeviceAcl