summaryrefslogtreecommitdiffstats
path: root/private/ntos/cntfs/seinfo.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/cntfs/seinfo.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/cntfs/seinfo.c')
-rw-r--r--private/ntos/cntfs/seinfo.c578
1 files changed, 578 insertions, 0 deletions
diff --git a/private/ntos/cntfs/seinfo.c b/private/ntos/cntfs/seinfo.c
new file mode 100644
index 000000000..e7444344b
--- /dev/null
+++ b/private/ntos/cntfs/seinfo.c
@@ -0,0 +1,578 @@
+/*++
+
+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)
+#pragma alloc_text(PAGE, NtfsFsdQuerySecurityInfo)
+#pragma alloc_text(PAGE, NtfsFsdSetSecurityInfo)
+#endif
+
+
+NTSTATUS
+NtfsFsdQuerySecurityInfo (
+ IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
+ IN PIRP Irp
+ )
+
+/*++
+
+Routine Description:
+
+ This routine implements the FSD part of the Query Security Information API
+ calls.
+
+Arguments:
+
+ VolumeDeviceObject - Supplies the device object to use.
+
+ Irp - Supplies the Irp being processed
+
+Return Value:
+
+ NTSTATUS - The Fsd status for the Irp
+
+--*/
+
+{
+ TOP_LEVEL_CONTEXT TopLevelContext;
+ PTOP_LEVEL_CONTEXT ThreadTopLevelContext;
+
+ NTSTATUS Status = STATUS_SUCCESS;
+ PIRP_CONTEXT IrpContext = NULL;
+
+ ASSERT_IRP( Irp );
+
+ UNREFERENCED_PARAMETER( VolumeDeviceObject );
+
+ PAGED_CODE();
+
+ DebugTrace( +1, Dbg, ("NtfsFsdQuerySecurityInfo\n") );
+
+ //
+ // Call the common query Information routine
+ //
+
+ FsRtlEnterFileSystem();
+
+ ThreadTopLevelContext = NtfsSetTopLevelIrp( &TopLevelContext, FALSE, FALSE );
+
+ do {
+
+ try {
+
+ //
+ // We are either initiating this request or retrying it.
+ //
+
+ if (IrpContext == NULL) {
+
+ IrpContext = NtfsCreateIrpContext( Irp, CanFsdWait( Irp ) );
+ NtfsUpdateIrpContextWithTopLevel( IrpContext, ThreadTopLevelContext );
+
+ } else if (Status == STATUS_LOG_FILE_FULL) {
+
+ NtfsCheckpointForLogFileFull( IrpContext );
+ }
+
+ Status = NtfsCommonQuerySecurityInfo( IrpContext, Irp );
+ break;
+
+ } except(NtfsExceptionFilter( IrpContext, GetExceptionInformation() )) {
+
+ //
+ // We had some trouble trying to perform the requested
+ // operation, so we'll abort the I/O request with
+ // the error status that we get back from the
+ // execption code
+ //
+
+ Status = NtfsProcessException( IrpContext, Irp, GetExceptionCode() );
+ }
+
+ } while (Status == STATUS_CANT_WAIT ||
+ Status == STATUS_LOG_FILE_FULL);
+
+ if (ThreadTopLevelContext == &TopLevelContext) {
+ NtfsRestoreTopLevelIrp( ThreadTopLevelContext );
+ }
+
+ FsRtlExitFileSystem();
+
+ //
+ // And return to our caller
+ //
+
+ DebugTrace( -1, Dbg, ("NtfsFsdQuerySecurityInfo -> %08lx\n", Status) );
+
+ return Status;
+}
+
+
+NTSTATUS
+NtfsFsdSetSecurityInfo (
+ IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
+ IN PIRP Irp
+ )
+
+/*++
+
+Routine Description:
+
+ This routine implements the FSD part of the Set Security Information API
+ calls.
+
+Arguments:
+
+ VolumeDeviceObject - Supplies the device object to use.
+
+ Irp - Supplies the Irp being processed
+
+Return Value:
+
+ NTSTATUS - The Fsd status for the Irp
+
+--*/
+
+{
+ TOP_LEVEL_CONTEXT TopLevelContext;
+ PTOP_LEVEL_CONTEXT ThreadTopLevelContext;
+
+ NTSTATUS Status = STATUS_SUCCESS;
+ PIRP_CONTEXT IrpContext = NULL;
+
+ ASSERT_IRP( Irp );
+
+ UNREFERENCED_PARAMETER( VolumeDeviceObject );
+
+ PAGED_CODE();
+
+ DebugTrace( +1, Dbg, ("NtfsFsdSetSecurityInfo\n") );
+
+ //
+ // Call the common query Information routine
+ //
+
+ FsRtlEnterFileSystem();
+
+ ThreadTopLevelContext = NtfsSetTopLevelIrp( &TopLevelContext, FALSE, FALSE );
+
+ do {
+
+ try {
+
+ //
+ // We are either initiating this request or retrying it.
+ //
+
+ if (IrpContext == NULL) {
+
+ IrpContext = NtfsCreateIrpContext( Irp, CanFsdWait( Irp ) );
+ NtfsUpdateIrpContextWithTopLevel( IrpContext, ThreadTopLevelContext );
+
+ } else if (Status == STATUS_LOG_FILE_FULL) {
+
+ NtfsCheckpointForLogFileFull( IrpContext );
+ }
+
+ Status = NtfsCommonSetSecurityInfo( IrpContext, Irp );
+ break;
+
+ } except(NtfsExceptionFilter( IrpContext, GetExceptionInformation() )) {
+
+ //
+ // We had some trouble trying to perform the requested
+ // operation, so we'll abort the I/O request with
+ // the error status that we get back from the
+ // execption code
+ //
+
+ Status = NtfsProcessException( IrpContext, Irp, GetExceptionCode() );
+ }
+
+ } while (Status == STATUS_CANT_WAIT ||
+ Status == STATUS_LOG_FILE_FULL);
+
+ if (ThreadTopLevelContext == &TopLevelContext) {
+ NtfsRestoreTopLevelIrp( ThreadTopLevelContext );
+ }
+
+ FsRtlExitFileSystem();
+
+ //
+ // And return to our caller
+ //
+
+ DebugTrace( -1, Dbg, ("NtfsFsdSetSecurityInfo -> %08lx\n", Status) );
+
+ return Status;
+}
+
+
+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 );
+
+ 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)) {
+
+ Status = STATUS_INVALID_PARAMETER;
+
+ //
+ // If the this handle does not open the entire file then refuse access.
+ //
+
+ } else if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_AS_FILE )) {
+
+ 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, FALSE );
+
+ try {
+
+ if (Fcb->SharedSecurity == NULL) {
+
+ NtfsReleaseFcb( IrpContext, Fcb );
+ AcquiredFcb = FALSE;
+
+ NtfsAcquireExclusiveFcb( IrpContext, Fcb, NULL, FALSE, FALSE );
+ AcquiredFcb = TRUE;
+ }
+
+ Status = NtfsQuerySecurity( IrpContext,
+ Fcb,
+ &IrpSp->Parameters.QuerySecurity.SecurityInformation,
+ (PSECURITY_DESCRIPTOR)Irp->UserBuffer,
+ &IrpSp->Parameters.QuerySecurity.Length );
+
+ 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;
+
+#ifdef _CAIRO_
+ PQUOTA_CONTROL_BLOCK OldQuotaControl;
+ ULONG OldOwnerId;
+ ULONG LargeStdInfo;
+#endif // _CAIRO_
+
+ TYPE_OF_OPEN TypeOfOpen;
+ PVCB Vcb;
+ PFCB Fcb;
+ PSCB Scb;
+ PCCB Ccb;
+
+ ASSERT_IRP_CONTEXT( IrpContext );
+ ASSERT_IRP( Irp );
+
+ 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)) {
+
+ Status = STATUS_INVALID_PARAMETER;
+
+ //
+ // If the this handle does not open the entire file then refuse access.
+ //
+
+ } else if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_AS_FILE )) {
+
+ Status = STATUS_INVALID_PARAMETER;
+
+ } else {
+
+ //
+ // Our operation is to acquire the fcb, do the operation and then
+ // release the fcb
+ //
+
+ NtfsAcquireExclusiveFcb( IrpContext, Fcb, NULL, FALSE, FALSE );
+
+ try {
+
+#ifdef _CAIRO_
+
+ //
+ // 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;
+
+#endif // _CAIRO_
+
+ Status = NtfsModifySecurity( IrpContext,
+ Fcb,
+ &IrpSp->Parameters.SetSecurity.SecurityInformation,
+ IrpSp->Parameters.SetSecurity.SecurityDescriptor );
+
+ if (NT_SUCCESS( Status )) {
+
+#ifdef _CAIRO_
+ //
+ // Make sure the new security descriptor Id is written out.
+ //
+
+ NtfsUpdateStandardInformation( IrpContext, Fcb );
+#endif
+ }
+
+ //
+ // Abort transaction on error by raising.
+ //
+
+ NtfsCleanupTransaction( IrpContext, Status, FALSE );
+
+ //
+ // Set the flag in the Ccb to indicate this change occurred.
+ //
+
+ SetFlag( Ccb->Flags,
+ CCB_FLAG_UPDATE_LAST_CHANGE | CCB_FLAG_SET_ARCHIVE );
+
+ } finally {
+
+ DebugUnwind( NtfsCommonSetSecurityInfo );
+
+#ifdef _CAIRO_
+ 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);
+
+ }
+ }
+#endif // _CAIRO_
+
+ NtfsReleaseFcb( IrpContext, Fcb );
+ }
+ }
+
+ //
+ // Now complete the request and return to our caller
+ //
+
+ NtfsCompleteRequest( &IrpContext, &Irp, Status );
+
+ DebugTrace( -1, Dbg, ("NtfsCommonSetSecurityInfo -> %08lx", Status) );
+
+ return Status;
+}
+