|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
SeInfo.c
Abstract:
This module implements the Security Info routines for NTFS called by the dispatch driver.
Author:
Gary Kimura [GaryKi] 26-Dec-1991
Revision History:
--*/
#include "NtfsProc.h"
//
// The debug trace level
//
#define Dbg (DEBUG_TRACE_SEINFO)
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, NtfsCommonQuerySecurityInfo)
#pragma alloc_text(PAGE, NtfsCommonSetSecurityInfo)
#endif
NTSTATUS NtfsCommonQuerySecurityInfo ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp )
/*++
Routine Description:
This is the common routine for querying security information called by both the fsd and fsp threads.
Arguments:
Irp - Supplies the Irp to process
Return Value:
NTSTATUS - the return status for the operation
--*/
{ NTSTATUS Status; PIO_STACK_LOCATION IrpSp; PFILE_OBJECT FileObject;
TYPE_OF_OPEN TypeOfOpen; PVCB Vcb; PFCB Fcb; PSCB Scb; PCCB Ccb;
BOOLEAN AcquiredFcb = TRUE;
ASSERT_IRP_CONTEXT( IrpContext ); ASSERT_IRP( Irp ); ASSERT( FlagOn( IrpContext->TopLevelIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL ));
PAGED_CODE();
//
// Get the current Irp stack location
//
IrpSp = IoGetCurrentIrpStackLocation( Irp );
DebugTrace( +1, Dbg, ("NtfsCommonQuerySecurityInfo") ); DebugTrace( 0, Dbg, ("IrpContext = %08lx\n", IrpContext) ); DebugTrace( 0, Dbg, ("Irp = %08lx\n", Irp) );
//
// Extract and decode the file object
//
FileObject = IrpSp->FileObject; TypeOfOpen = NtfsDecodeFileObject( IrpContext, FileObject, &Vcb, &Fcb, &Scb, &Ccb, TRUE );
//
// The only type of opens we accept are user file and directory opens
//
if ((TypeOfOpen != UserFileOpen) && (TypeOfOpen != UserDirectoryOpen) && (TypeOfOpen != UserViewIndexOpen)) {
Status = STATUS_INVALID_PARAMETER;
} else {
//
// Our operation is to acquire the fcb, do the operation and then
// release the fcb. If the security descriptor for this file is
// not already loaded we will release the Fcb and then acquire both
// the Vcb and Fcb. We must have the Vcb to examine our parent's
// security descriptor.
//
NtfsAcquireSharedFcb( IrpContext, Fcb, NULL, 0 );
try {
if (Fcb->SharedSecurity == NULL) {
NtfsReleaseFcb( IrpContext, Fcb ); AcquiredFcb = FALSE;
NtfsAcquireExclusiveFcb( IrpContext, Fcb, NULL, 0 ); AcquiredFcb = TRUE; }
//
// Make sure the volume is still mounted.
//
if (FlagOn( Scb->ScbState, SCB_STATE_VOLUME_DISMOUNTED )) {
Status = STATUS_VOLUME_DISMOUNTED; leave; }
Status = NtfsQuerySecurity( IrpContext, Fcb, &IrpSp->Parameters.QuerySecurity.SecurityInformation, (PSECURITY_DESCRIPTOR)Irp->UserBuffer, &IrpSp->Parameters.QuerySecurity.Length );
if (NT_SUCCESS( Status )) {
Irp->IoStatus.Information = IrpSp->Parameters.QuerySecurity.Length;
} else if (Status == STATUS_BUFFER_TOO_SMALL) {
Irp->IoStatus.Information = IrpSp->Parameters.QuerySecurity.Length;
Status = STATUS_BUFFER_OVERFLOW; }
//
// Abort transaction on error by raising.
//
NtfsCleanupTransaction( IrpContext, Status, FALSE );
} finally {
DebugUnwind( NtfsCommonQuerySecurityInfo );
if (AcquiredFcb) {
NtfsReleaseFcb( IrpContext, Fcb ); } } }
//
// Now complete the request and return to our caller
//
NtfsCompleteRequest( IrpContext, Irp, Status );
DebugTrace( -1, Dbg, ("NtfsCommonQuerySecurityInfo -> %08lx", Status) );
return Status; }
NTSTATUS NtfsCommonSetSecurityInfo ( IN PIRP_CONTEXT IrpContext, IN PIRP Irp )
/*++
Routine Description:
This is the common routine for Setting security information called by both the fsd and fsp threads.
Arguments:
Irp - Supplies the Irp to process
Return Value:
NTSTATUS - the return status for the operation
--*/
{ NTSTATUS Status; PIO_STACK_LOCATION IrpSp; PFILE_OBJECT FileObject; PQUOTA_CONTROL_BLOCK OldQuotaControl = NULL; ULONG OldOwnerId; ULONG LargeStdInfo;
TYPE_OF_OPEN TypeOfOpen; PVCB Vcb; PFCB Fcb; PSCB Scb; PCCB Ccb;
ASSERT_IRP_CONTEXT( IrpContext ); ASSERT_IRP( Irp ); ASSERT( FlagOn( IrpContext->TopLevelIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL ));
PAGED_CODE();
//
// Get the current Irp stack location
//
IrpSp = IoGetCurrentIrpStackLocation( Irp );
DebugTrace( +1, Dbg, ("NtfsCommonSetSecurityInfo") ); DebugTrace( 0, Dbg, ("IrpContext = %08lx\n", IrpContext) ); DebugTrace( 0, Dbg, ("Irp = %08lx\n", Irp) );
//
// Extract and decode the file object
//
FileObject = IrpSp->FileObject; TypeOfOpen = NtfsDecodeFileObject( IrpContext, FileObject, &Vcb, &Fcb, &Scb, &Ccb, TRUE );
//
// The only type of opens we accept are user file and directory opens
//
if ((TypeOfOpen != UserFileOpen) && (TypeOfOpen != UserDirectoryOpen) && (TypeOfOpen != UserViewIndexOpen)) {
Status = STATUS_INVALID_PARAMETER;
} else if (NtfsIsVolumeReadOnly( Vcb )) {
Status = STATUS_MEDIA_WRITE_PROTECTED; } else { //
// Capture the source information.
//
IrpContext->SourceInfo = Ccb->UsnSourceInfo;
//
// Our operation is to acquire the fcb, do the operation and then
// release the fcb
//
NtfsAcquireExclusiveFcb( IrpContext, Fcb, NULL, 0 );
try {
//
// Make sure the volume is still mounted.
//
if (FlagOn( Scb->ScbState, SCB_STATE_VOLUME_DISMOUNTED )) {
Status = STATUS_VOLUME_DISMOUNTED; leave; }
//
// Post the change to the Usn Journal.
//
NtfsPostUsnChange( IrpContext, Scb, USN_REASON_SECURITY_CHANGE );
//
// Capture the current OwnerId, Qutoa Control Block and
// size of standard information.
//
OldQuotaControl = Fcb->QuotaControl; OldOwnerId = Fcb->OwnerId; LargeStdInfo = Fcb->FcbState & FCB_STATE_LARGE_STD_INFO;
Status = NtfsModifySecurity( IrpContext, Fcb, &IrpSp->Parameters.SetSecurity.SecurityInformation, IrpSp->Parameters.SetSecurity.SecurityDescriptor );
if (NT_SUCCESS( Status )) {
//
// Make sure the new security descriptor Id is written out.
//
NtfsUpdateStandardInformation( IrpContext, Fcb ); }
//
// Abort transaction on error by raising.
//
NtfsCleanupTransaction( IrpContext, Status, FALSE );
//
// Set the flag in the Ccb to indicate this change occurred.
//
if (!IsDirectory( &Fcb->Info )) { SetFlag( Ccb->Flags, CCB_FLAG_UPDATE_LAST_CHANGE | CCB_FLAG_SET_ARCHIVE ); }
} finally {
DebugUnwind( NtfsCommonSetSecurityInfo );
if (AbnormalTermination()) {
//
// The request failed. Restore the owner and
// QuotaControl are restored.
//
if ((Fcb->QuotaControl != OldQuotaControl) && (Fcb->QuotaControl != NULL)) {
//
// A new quota control block was assigned.
// Dereference it.
//
NtfsDereferenceQuotaControlBlock( Fcb->Vcb, &Fcb->QuotaControl ); }
Fcb->QuotaControl = OldQuotaControl; Fcb->OwnerId = OldOwnerId;
if (LargeStdInfo == 0) {
//
// The standard information has be returned to
// its orginal size.
//
ClearFlag( Fcb->FcbState, FCB_STATE_LARGE_STD_INFO ); }
} else {
//
// The request succeed. If the quota control block was
// changed then derefence the old block.
//
if ((Fcb->QuotaControl != OldQuotaControl) && (OldQuotaControl != NULL)) {
NtfsDereferenceQuotaControlBlock( Fcb->Vcb, &OldQuotaControl); } }
} }
//
// Now complete the request and return to our caller
//
NtfsCompleteRequest( IrpContext, Irp, Status );
DebugTrace( -1, Dbg, ("NtfsCommonSetSecurityInfo -> %08lx", Status) );
return Status; }
|