From 92bfaae062c596d678220dcb93f9dc61304d3c5a Mon Sep 17 00:00:00 2001 From: Peter Scott Date: Wed, 14 Dec 2011 12:27:54 -0700 Subject: [PATCH] Windows: Track AuthGroup in Context Control Block Tracking the AuthGroup in the File Control Block proved to be insufficient to ensure that dirty extents can be stored back to the file server when an anti-virus service opens a file in authgroup without 'write' permission immediate after the application performing a WriteFile() opens it. In this situation the Fcb ends up with the AuthGroup set to the anti-virus value and not the one that belongs to the writing application. Tracking the AuthGroup by Ccb provides the ability to select an AuthGroup from the list of open handles instead of tracking the most recent one. Change-Id: I851ea646feb531d7c765e1cf789a4ba541e4a150 Reviewed-on: http://gerrit.openafs.org/6333 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- .../afsrdr/common/AFSRedirCommonStructs.h | 8 +- src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp | 18 +- src/WINNT/afsrdr/kernel/lib/AFSClose.cpp | 65 ++++--- .../afsrdr/kernel/lib/AFSCommSupport.cpp | 44 +---- src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp | 47 +++-- src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp | 7 +- .../afsrdr/kernel/lib/AFSExtentsSupport.cpp | 100 +++++++++- src/WINNT/afsrdr/kernel/lib/AFSFSControl.cpp | 2 +- src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp | 83 ++++++++- src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp | 12 +- .../afsrdr/kernel/lib/AFSFlushBuffers.cpp | 6 +- src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp | 174 ++++++++++++++---- .../afsrdr/kernel/lib/AFSLockControl.cpp | 6 +- .../afsrdr/kernel/lib/AFSNameSupport.cpp | 14 +- src/WINNT/afsrdr/kernel/lib/AFSRead.cpp | 15 +- src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp | 13 +- src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp | 10 +- .../afsrdr/kernel/lib/Include/AFSCommon.h | 35 +++- .../afsrdr/kernel/lib/Include/AFSDefines.h | 1 + .../afsrdr/kernel/lib/Include/AFSStructs.h | 12 ++ 20 files changed, 503 insertions(+), 169 deletions(-) diff --git a/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h b/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h index 7219ab771..a8a9a22a6 100644 --- a/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h +++ b/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h @@ -178,6 +178,8 @@ typedef struct _AFS_NONPAGED_FCB FAST_MUTEX AdvancedHdrMutex; + ERESOURCE CcbListLock; + union { @@ -301,10 +303,12 @@ typedef struct AFS_FCB struct _AFS_OBJECT_INFORMATION_CB *ObjectInformation; // - // Authentication group GUID + // Ccb list pointers // - GUID AuthGroup; + struct _AFS_CCB *CcbListHead; + + struct _AFS_CCB *CcbListTail; // // Union for node type specific information diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp index 527c6751b..70e7f2427 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCleanup.cpp @@ -354,7 +354,8 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, // the file // - AFSTearDownFcbExtents( pFcb); + AFSTearDownFcbExtents( pFcb, + &pCcb->AuthGroup); ntStatus = STATUS_SUCCESS; @@ -372,7 +373,7 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, @@ -513,7 +514,8 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, if( pFcb->Specific.File.ExtentsDirtyCount) { - AFSFlushExtents( pFcb); + AFSFlushExtents( pFcb, + &pCcb->AuthGroup); } if( pFcb->OpenHandleCount == 0) @@ -540,7 +542,7 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, @@ -708,7 +710,7 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, @@ -813,7 +815,7 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, @@ -973,7 +975,7 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, @@ -1078,7 +1080,7 @@ AFSCleanup( IN PDEVICE_OBJECT LibDeviceObject, AFSProcessRequest( AFS_REQUEST_TYPE_CLEANUP_PROCESSING, ulNotificationFlags | AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pObjectInfo->FileId, &stFileCleanup, diff --git a/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp b/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp index 959aad96f..eb4844947 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSClose.cpp @@ -136,7 +136,7 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_CLOSE, AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, NULL, &stParentFileId, (void *)&stPIOCtlClose, @@ -150,7 +150,8 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, // Remove the Ccb and de-allocate it // - ntStatus = AFSRemoveCcb( pCcb); + ntStatus = AFSRemoveCcb( pFcb, + pCcb); if( !NT_SUCCESS( ntStatus)) { @@ -230,7 +231,8 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, // Remove the Ccb and de-allocate it // - ntStatus = AFSRemoveCcb( pCcb); + ntStatus = AFSRemoveCcb( pFcb, + pCcb); if( !NT_SUCCESS( ntStatus)) { @@ -304,27 +306,6 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, pDirCB = pCcb->DirectoryCB; - // - // Remove the Ccb and de-allocate it - // - - ntStatus = AFSRemoveCcb( pCcb); - - if( !NT_SUCCESS( ntStatus)) - { - - AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, - AFS_TRACE_LEVEL_WARNING, - "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", - ntStatus); - - // - // We can't actually fail a close operation so reset the status - // - - ntStatus = STATUS_SUCCESS; - } - // // If this entry is deleted then remove the object from the volume tree // @@ -482,7 +463,8 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, if( pFcb->Specific.File.ExtentsDirtyCount) { - AFSFlushExtents( pFcb); + AFSFlushExtents( pFcb, + &pCcb->AuthGroup); } // @@ -500,7 +482,8 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, // Tear 'em down, we'll not be needing them again // - if( AFSTearDownFcbExtents( pFcb)) + if( AFSTearDownFcbExtents( pFcb, + &pCcb->AuthGroup)) { // @@ -510,7 +493,7 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, AFSProcessRequest( AFS_REQUEST_TYPE_FLUSH_FILE, AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, NULL, &pFcb->ObjectInformation->FileId, NULL, @@ -528,13 +511,36 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, if( pFcb->Specific.File.ExtentsDirtyCount) { - AFSFlushExtents( pFcb); + AFSFlushExtents( pFcb, + &pCcb->AuthGroup); } } AFSReleaseResource( &pFcb->NPFcb->Resource); } + // + // Remove the Ccb and de-allocate it + // + + ntStatus = AFSRemoveCcb( pFcb, + pCcb); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_WARNING, + "AFSClose Failed to remove Ccb from Fcb Status %08lX\n", + ntStatus); + + // + // We can't actually fail a close operation so reset the status + // + + ntStatus = STATUS_SUCCESS; + } + // // Decrement the reference count on the Fcb. this is protecting it from teardown. // @@ -597,7 +603,8 @@ AFSClose( IN PDEVICE_OBJECT LibDeviceObject, // Remove the Ccb and de-allocate it // - ntStatus = AFSRemoveCcb( pCcb); + ntStatus = AFSRemoveCcb( pFcb, + pCcb); if( !NT_SUCCESS( ntStatus)) { diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp index 51311ab61..f8fa9f8c6 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCommSupport.cpp @@ -1543,14 +1543,14 @@ try_exit: NTSTATUS AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB, - IN BOOLEAN CheckOnly) + IN GUID *AuthGroup, + IN BOOLEAN CheckOnly) { NTSTATUS ntStatus = STATUS_SUCCESS; ULONG ulResultLen = 0; AFSFileDeleteCB stDelete; AFSFileDeleteResultCB stDeleteResult; ULONG ulRequestFlags = AFS_REQUEST_FLAG_SYNCHRONOUS; - GUID *pAuthGroup = NULL; __Enter { @@ -1566,14 +1566,9 @@ AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB, ulRequestFlags |= AFS_REQUEST_FLAG_CHECK_ONLY; } - if( DirectoryCB->ObjectInformation->Fcb != NULL) - { - pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup; - } - ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_DELETE_FILE, ulRequestFlags, - pAuthGroup, + AuthGroup, &DirectoryCB->NameInformation.FileName, &DirectoryCB->ObjectInformation->FileId, &stDelete, @@ -1622,6 +1617,7 @@ try_exit: NTSTATUS AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo, + IN GUID *AuthGroup, IN AFSObjectInfoCB *ParentObjectInfo, IN AFSObjectInfoCB *TargetParentObjectInfo, IN AFSDirectoryCB *DirectoryCB, @@ -1633,7 +1629,6 @@ AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo, AFSFileRenameCB *pRenameCB = NULL; AFSFileRenameResultCB *pRenameResultCB = NULL; ULONG ulResultLen = 0; - GUID *pAuthGroup = NULL; __Enter { @@ -1665,11 +1660,6 @@ AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo, TargetName->Buffer, TargetName->Length); - if( ObjectInfo->Fcb != NULL) - { - pAuthGroup = &ObjectInfo->Fcb->AuthGroup; - } - // // Use the same buffer for the result control block // @@ -1680,7 +1670,7 @@ AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RENAME_FILE, AFS_REQUEST_FLAG_SYNCHRONOUS, - pAuthGroup, + AuthGroup, &DirectoryCB->NameInformation.FileName, &ObjectInfo->FileId, pRenameCB, @@ -2042,7 +2032,6 @@ AFSNotifyPipeTransceive( IN AFSCcb *Ccb, void *pInputSystemBuffer = NULL, *pOutputSystemBuffer = NULL; ULONG ulBufferLength = OutputLength; AFSPipeIORequestCB *pIoRequest = NULL; - GUID *pAuthGroup = NULL; __Enter { @@ -2095,11 +2084,6 @@ AFSNotifyPipeTransceive( IN AFSCcb *Ccb, try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } - if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL) - { - pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup; - } - // // Send the call to the service // @@ -2108,7 +2092,7 @@ AFSNotifyPipeTransceive( IN AFSCcb *Ccb, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_TRANSCEIVE, AFS_REQUEST_FLAG_SYNCHRONOUS, - pAuthGroup, + &Ccb->AuthGroup, &Ccb->DirectoryCB->NameInformation.FileName, NULL, pIoRequest, @@ -2172,7 +2156,6 @@ AFSNotifySetPipeInfo( IN AFSCcb *Ccb, NTSTATUS ntStatus = STATUS_SUCCESS; AFSPipeInfoRequestCB *pInfoRequest = NULL; - GUID *pAuthGroup = NULL; __Enter { @@ -2203,18 +2186,13 @@ AFSNotifySetPipeInfo( IN AFSCcb *Ccb, DataBuffer, InputLength); - if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL) - { - pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup; - } - // // Send the call to the service // ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_SET_INFO, AFS_REQUEST_FLAG_SYNCHRONOUS, - pAuthGroup, + &Ccb->AuthGroup, &Ccb->DirectoryCB->NameInformation.FileName, NULL, pInfoRequest, @@ -2257,7 +2235,6 @@ AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb, NTSTATUS ntStatus = STATUS_SUCCESS; AFSPipeInfoRequestCB stInfoRequest; ULONG ulBytesProcessed = 0; - GUID *pAuthGroup = NULL; __Enter { @@ -2275,18 +2252,13 @@ AFSNotifyQueryPipeInfo( IN AFSCcb *Ccb, ulBytesProcessed = OutputLength; - if( Ccb->DirectoryCB->ObjectInformation->Fcb != NULL) - { - pAuthGroup = &Ccb->DirectoryCB->ObjectInformation->Fcb->AuthGroup; - } - // // Send the call to the service // ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_QUERY_INFO, AFS_REQUEST_FLAG_SYNCHRONOUS, - pAuthGroup, + &Ccb->AuthGroup, &Ccb->DirectoryCB->NameInformation.FileName, NULL, &stInfoRequest, diff --git a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp index 13554aefa..c74b5688d 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp @@ -1042,6 +1042,10 @@ try_exit: if( pCcb != NULL) { + RtlCopyMemory( &pCcb->AuthGroup, + &stAuthGroup, + sizeof( GUID)); + // // If we have a substitute name, then use it // @@ -1124,10 +1128,6 @@ try_exit: ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED); - RtlCopyMemory( &pFcb->AuthGroup, - &stAuthGroup, - sizeof( GUID)); - // // For files perform additional processing // @@ -1168,6 +1168,12 @@ try_exit: // KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime); + + if( pCcb != NULL) + { + AFSInsertCcb( pFcb, + pCcb); + } } else { @@ -1611,6 +1617,8 @@ AFSOpenRoot( IN PIRP Irp, (*Ccb)->DirectoryCB = VolumeCB->DirectoryCB; + (*Ccb)->GrantedAccess = *pDesiredAccess; + // // OK, update the share access on the fileobject // @@ -1682,7 +1690,8 @@ try_exit: if( bAllocatedCcb) { - AFSRemoveCcb( *Ccb); + AFSRemoveCcb( NULL, + *Ccb); *Ccb = NULL; } @@ -1911,6 +1920,8 @@ AFSProcessCreate( IN PIRP Irp, (*Ccb)->DirectoryCB = pDirEntry; + (*Ccb)->GrantedAccess = *pDesiredAccess; + // // If this is a file, update the headers filesizes. // @@ -2116,6 +2127,7 @@ try_exit: FALSE); // Leave it in the enum list so the worker cleans it up AFSNotifyDelete( pDirEntry, + AuthGroup, FALSE); // @@ -2130,7 +2142,8 @@ try_exit: if( bAllocatedCcb) { - AFSRemoveCcb( *Ccb); + AFSRemoveCcb( NULL, + *Ccb); } if( bAllocatedFcb) @@ -2286,6 +2299,8 @@ AFSOpenTargetDirectory( IN PIRP Irp, (*Ccb)->DirectoryCB = ParentDirectoryCB; + (*Ccb)->GrantedAccess = *pDesiredAccess; + if( TargetDirectoryCB != NULL && FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName, TargetName, @@ -2396,7 +2411,8 @@ try_exit: if( bAllocatedCcb) { - AFSRemoveCcb( *Ccb); + AFSRemoveCcb( NULL, + *Ccb); } *Ccb = NULL; @@ -2508,6 +2524,7 @@ AFSProcessOpen( IN PIRP Irp, { ntStatus = AFSNotifyDelete( DirectoryCB, + AuthGroup, TRUE); if( !NT_SUCCESS( ntStatus)) @@ -2775,6 +2792,8 @@ AFSProcessOpen( IN PIRP Irp, (*Ccb)->FileAccess = ulFileAccess; + (*Ccb)->GrantedAccess = *pDesiredAccess; + // // Perform the access check on the target if this is a mount point or symlink // @@ -2915,7 +2934,8 @@ try_exit: if( bAllocatedCcb) { - AFSRemoveCcb( *Ccb); + AFSRemoveCcb( NULL, + *Ccb); } *Ccb = NULL; @@ -3131,6 +3151,8 @@ AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject, (*Ccb)->DirectoryCB = DirectoryCB; + (*Ccb)->GrantedAccess = *pDesiredAccess; + // // Need to purge any data currently in the cache // @@ -3335,7 +3357,8 @@ try_exit: if( bAllocatedCcb) { - AFSRemoveCcb( *Ccb); + AFSRemoveCcb( NULL, + *Ccb); } *Ccb = NULL; @@ -3616,7 +3639,8 @@ try_exit: if( bAllocatedCcb) { - AFSRemoveCcb( *Ccb); + AFSRemoveCcb( NULL, + *Ccb); *Ccb = NULL; } @@ -3830,7 +3854,8 @@ try_exit: if( bAllocatedCcb) { - AFSRemoveCcb( *Ccb); + AFSRemoveCcb( NULL, + *Ccb); *Ccb = NULL; } diff --git a/src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp b/src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp index e05d4dc6b..5e4157ac3 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSDirControl.cpp @@ -228,7 +228,7 @@ AFSQueryDirectory( IN PIRP Irp) // Tell the service to prime the cache of the directory content // - ntStatus = AFSEnumerateDirectoryNoResponse( &pFcb->AuthGroup, + ntStatus = AFSEnumerateDirectoryNoResponse( &pCcb->AuthGroup, &pFcb->ObjectInformation->FileId); if( !NT_SUCCESS( ntStatus)) @@ -290,7 +290,7 @@ AFSQueryDirectory( IN PIRP Irp) pFcb->ObjectInformation->FileId.Vnode, pFcb->ObjectInformation->FileId.Unique); - ntStatus = AFSVerifyEntry( &pFcb->AuthGroup, + ntStatus = AFSVerifyEntry( &pCcb->AuthGroup, pCcb->DirectoryCB); if( !NT_SUCCESS( ntStatus)) @@ -742,7 +742,7 @@ AFSQueryDirectory( IN PIRP Irp) // AFSValidateEntry( pDirEntry, - &pFcb->AuthGroup, + &pCcb->AuthGroup, FALSE, FALSE); @@ -768,6 +768,7 @@ AFSQueryDirectory( IN PIRP Irp) pDirEntry, &pCcb->FullFileName, pCcb->NameArray, + &pCcb->AuthGroup, &stFileInfo))) { diff --git a/src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp index 66300ed5a..07387204a 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSExtentsSupport.cpp @@ -106,7 +106,8 @@ AFSLockForExtentsTrimNoWait( IN AFSFcb *Fcb) // Pull all the extents away from the FCB. // BOOLEAN -AFSTearDownFcbExtents( IN AFSFcb *Fcb ) +AFSTearDownFcbExtents( IN AFSFcb *Fcb, + IN GUID *AuthGroup) { BOOLEAN bFoundExtents = FALSE; AFSNonPagedFcb *pNPFcb = Fcb->NPFcb; @@ -118,10 +119,31 @@ AFSTearDownFcbExtents( IN AFSFcb *Fcb ) BOOLEAN locked = FALSE; NTSTATUS ntStatus; AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension; + GUID *pAuthGroup = AuthGroup; + GUID stAuthGroup; __Enter { + if( pAuthGroup == NULL) + { + + RtlZeroMemory( &stAuthGroup, + sizeof( GUID)); + + ntStatus = AFSRetrieveValidAuthGroup( Fcb, + NULL, + TRUE, + &stAuthGroup); + + if( !NT_SUCCESS( ntStatus)) + { + try_return( ntStatus); + } + + pAuthGroup = &stAuthGroup; + } + // // Ensure that no one is working with the extents and grab the // lock @@ -276,7 +298,7 @@ AFSTearDownFcbExtents( IN AFSFcb *Fcb ) ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS, AFS_REQUEST_FLAG_SYNCHRONOUS, - &Fcb->AuthGroup, + pAuthGroup, NULL, &Fcb->ObjectInformation->FileId, pRelease, @@ -668,6 +690,7 @@ try_exit: NTSTATUS AFSRequestExtents( IN AFSFcb *Fcb, + IN AFSCcb *Ccb, IN PLARGE_INTEGER Offset, IN ULONG Size, OUT BOOLEAN *FullyMapped) @@ -905,7 +928,7 @@ AFSRequestExtents( IN AFSFcb *Fcb, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS, 0, - &Fcb->AuthGroup, + &Ccb->AuthGroup, NULL, &Fcb->ObjectInformation->FileId, &request, @@ -945,6 +968,7 @@ try_exit: NTSTATUS AFSRequestExtentsAsync( IN AFSFcb *Fcb, + IN AFSCcb *Ccb, IN PLARGE_INTEGER Offset, IN ULONG Size) { @@ -1043,7 +1067,7 @@ AFSRequestExtentsAsync( IN AFSFcb *Fcb, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS, 0, - &Fcb->AuthGroup, + &Ccb->AuthGroup, NULL, &Fcb->ObjectInformation->FileId, &request, @@ -2292,6 +2316,7 @@ AFSProcessReleaseFileExtents( IN PIRP Irp) AFSObjectInfoCB *pObjectInfo = NULL; BOOLEAN bLocked = FALSE; BOOLEAN bDirtyExtents = FALSE; + GUID stAuthGroup; __Enter { @@ -2558,8 +2583,21 @@ AFSProcessReleaseFileExtents( IN PIRP Irp) // Stash away the auth group // + RtlZeroMemory( &stAuthGroup, + sizeof( GUID)); + + ntStatus = AFSRetrieveValidAuthGroup( pFcb, + NULL, + TRUE, + &stAuthGroup); + + if( !NT_SUCCESS( ntStatus)) + { + try_return( ntStatus); + } + RtlCopyMemory( &pFile->AuthGroup, - &pFcb->AuthGroup, + &stAuthGroup, sizeof( GUID)); // @@ -2726,7 +2764,8 @@ try_exit: } NTSTATUS -AFSFlushExtents( IN AFSFcb *Fcb) +AFSFlushExtents( IN AFSFcb *Fcb, + IN GUID *AuthGroup) { AFSNonPagedFcb *pNPFcb = Fcb->NPFcb; AFSExtent *pExtent, *pNextExtent; @@ -2741,6 +2780,8 @@ AFSFlushExtents( IN AFSFcb *Fcb) LARGE_INTEGER liLastFlush; AFSExtent *pDirtyListHead = NULL, *pDirtyListTail = NULL; AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension; + GUID *pAuthGroup = AuthGroup; + GUID stAuthGroup; ASSERT( Fcb->Header.NodeTypeCode == AFS_FILE_FCB); @@ -2755,6 +2796,25 @@ AFSFlushExtents( IN AFSFcb *Fcb) __Enter { + if( pAuthGroup == NULL) + { + + RtlZeroMemory( &stAuthGroup, + sizeof( GUID)); + + ntStatus = AFSRetrieveValidAuthGroup( Fcb, + NULL, + TRUE, + &stAuthGroup); + + if( !NT_SUCCESS( ntStatus)) + { + try_return( ntStatus); + } + + pAuthGroup = &stAuthGroup; + } + // // Lock extents while we count and set up the array to send to // the service @@ -2953,7 +3013,7 @@ AFSFlushExtents( IN AFSFcb *Fcb) ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS, AFS_REQUEST_FLAG_SYNCHRONOUS, - &Fcb->AuthGroup, + pAuthGroup, NULL, &Fcb->ObjectInformation->FileId, pRelease, @@ -3020,7 +3080,8 @@ try_exit: } NTSTATUS -AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb) +AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb, + IN GUID *AuthGroup) { AFSNonPagedFcb *pNPFcb = Fcb->NPFcb; AFSExtent *pExtent; @@ -3035,6 +3096,8 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb) LARGE_INTEGER liLastFlush; ULONG ulRemainingExtentLength = 0; AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension; + GUID *pAuthGroup = AuthGroup; + GUID stAuthGroup; ASSERT( Fcb->Header.NodeTypeCode == AFS_FILE_FCB); @@ -3049,6 +3112,25 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb) __Enter { + if( pAuthGroup == NULL) + { + + RtlZeroMemory( &stAuthGroup, + sizeof( GUID)); + + ntStatus = AFSRetrieveValidAuthGroup( Fcb, + NULL, + TRUE, + &stAuthGroup); + + if( !NT_SUCCESS( ntStatus)) + { + try_return( ntStatus); + } + + pAuthGroup = &stAuthGroup; + } + // // Look for a start in the list to flush entries // @@ -3236,7 +3318,7 @@ AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb) ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS, AFS_REQUEST_FLAG_SYNCHRONOUS, - &Fcb->AuthGroup, + pAuthGroup, NULL, &Fcb->ObjectInformation->FileId, pRelease, diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFSControl.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFSControl.cpp index 2bc99081c..825f88630 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFSControl.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFSControl.cpp @@ -379,7 +379,7 @@ AFSProcessUserFsRequest( IN PIRP Irp) pCcb->DirectoryCB->ObjectInformation->FileId.Vnode, pCcb->DirectoryCB->ObjectInformation->FileId.Unique); - ntStatus = AFSVerifyEntry( &pFcb->AuthGroup, + ntStatus = AFSVerifyEntry( &pCcb->AuthGroup, pCcb->DirectoryCB); if( !NT_SUCCESS( ntStatus)) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp index 134077a26..6d79ea855 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFcbSupport.cpp @@ -146,6 +146,8 @@ AFSInitFcb( IN AFSDirectoryCB *DirEntry, ExInitializeResourceLite( &pNPFcb->PagingResource); + ExInitializeResourceLite( &pNPFcb->CcbListLock); + pFcb->Header.Resource = &pNPFcb->Resource; pFcb->Header.PagingIoResource = &pNPFcb->PagingResource; @@ -316,6 +318,8 @@ try_exit: ExDeleteResourceLite( &pNPFcb->PagingResource); + ExDeleteResourceLite( &pNPFcb->CcbListLock); + ExDeleteResourceLite( &pNPFcb->Resource); } @@ -930,6 +934,8 @@ AFSInitRootFcb( IN ULONGLONG ProcessID, ExInitializeResourceLite( &pNPFcb->PagingResource); + ExInitializeResourceLite( &pNPFcb->CcbListLock); + pFcb->Header.Resource = &pNPFcb->Resource; pFcb->Header.PagingIoResource = &pNPFcb->PagingResource; @@ -1002,6 +1008,8 @@ AFSRemoveRootFcb( IN AFSFcb *RootFcb) ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource); + ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock); + // // The non paged region // @@ -1077,7 +1085,7 @@ AFSRemoveFcb( IN AFSFcb *Fcb) ExDeleteResourceLite( &Fcb->NPFcb->PagingResource); - + ExDeleteResourceLite( &Fcb->NPFcb->CcbListLock); // // The non paged region @@ -1165,11 +1173,52 @@ try_exit: // NTSTATUS -AFSRemoveCcb( IN AFSCcb *Ccb) +AFSRemoveCcb( IN AFSFcb *Fcb, + IN AFSCcb *Ccb) { NTSTATUS ntStatus = STATUS_SUCCESS; + if( Fcb != NULL && + BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST)) + { + + AFSAcquireExcl( &Fcb->NPFcb->CcbListLock, + TRUE); + + if( Ccb->ListEntry.fLink == NULL) + { + + Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink; + + if( Fcb->CcbListTail != NULL) + { + Fcb->CcbListTail->ListEntry.fLink = NULL; + } + } + else + { + ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink; + } + + if( Ccb->ListEntry.bLink == NULL) + { + + Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink; + + if( Fcb->CcbListHead != NULL) + { + Fcb->CcbListHead->ListEntry.bLink = NULL; + } + } + else + { + ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink; + } + + AFSReleaseResource( &Fcb->NPFcb->CcbListLock); + } + if( Ccb->MaskName.Buffer != NULL) { @@ -1216,3 +1265,33 @@ AFSRemoveCcb( IN AFSCcb *Ccb) return ntStatus; } + +NTSTATUS +AFSInsertCcb( IN AFSFcb *Fcb, + IN AFSCcb *Ccb) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + AFSAcquireExcl( &Fcb->NPFcb->CcbListLock, + TRUE); + + if( Fcb->CcbListHead == NULL) + { + Fcb->CcbListHead = Ccb; + } + else + { + Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb; + + Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail; + } + + Fcb->CcbListTail = Ccb; + + SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST); + + AFSReleaseResource( &Fcb->NPFcb->CcbListLock); + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp index 8b95c133b..92354e4fa 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp @@ -672,7 +672,7 @@ try_exit: ntStatus = AFSUpdateFileInformation( &stParentFileId, pFcb->ObjectInformation, - &pFcb->AuthGroup); + &pCcb->AuthGroup); if( !NT_SUCCESS( ntStatus)) { @@ -796,6 +796,7 @@ AFSQueryBasicInfo( IN PIRP Irp, DirectoryCB, &uniParentPath, NULL, + &pCcb->AuthGroup, &stFileInfo))) { ulFileAttribs = stFileInfo.FileAttributes; @@ -902,6 +903,7 @@ AFSQueryStandardInfo( IN PIRP Irp, DirectoryCB, &uniParentPath, NULL, + &pCcb->AuthGroup, &stFileInfo))) { ulFileAttribs = stFileInfo.FileAttributes; @@ -1384,6 +1386,7 @@ AFSQueryNetworkInfo( IN PIRP Irp, DirectoryCB, &uniParentPath, NULL, + &pCcb->AuthGroup, &stFileInfo))) { ulFileAttribs = stFileInfo.FileAttributes; @@ -1560,6 +1563,7 @@ AFSQueryAttribTagInfo( IN PIRP Irp, DirectoryCB, &uniParentPath, NULL, + &pCcb->AuthGroup, &stFileInfo))) { ulFileAttribs = stFileInfo.FileAttributes; @@ -1927,6 +1931,7 @@ AFSSetDispositionInfo( IN PIRP Irp, // ntStatus = AFSNotifyDelete( DirectoryCB, + &pCcb->AuthGroup, TRUE); if( !NT_SUCCESS( ntStatus)) @@ -2330,6 +2335,7 @@ AFSSetRenameInfo( IN PIRP Irp) // ntStatus = AFSNotifyRename( pSrcFcb->ObjectInformation, + &pSrcCcb->AuthGroup, pSrcFcb->ObjectInformation->ParentObjectInformation, pTargetDcb->ObjectInformation, pSrcCcb->DirectoryCB, @@ -2770,7 +2776,7 @@ AFSSetAllocationInfo( IN PIRP Irp, { ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId, pFcb->ObjectInformation, - &pFcb->AuthGroup); + &pCcb->AuthGroup); } if (NT_SUCCESS(ntStatus)) @@ -2931,7 +2937,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp, ntStatus = AFSUpdateFileInformation( &pFcb->ObjectInformation->ParentObjectInformation->FileId, pFcb->ObjectInformation, - &pFcb->AuthGroup); + &pCcb->AuthGroup); if( NT_SUCCESS(ntStatus)) { diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFlushBuffers.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFlushBuffers.cpp index f4805162d..d868a4999 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFlushBuffers.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFlushBuffers.cpp @@ -119,12 +119,14 @@ AFSFlushBuffers( IN PDEVICE_OBJECT LibDeviceObject, // Now, flush to the server - if there is stuff to do // - ntStatus = AFSFlushExtents( pFcb); + ntStatus = AFSFlushExtents( pFcb, + &pCcb->AuthGroup); if( !NT_SUCCESS( ntStatus)) { - AFSReleaseExtentsWithFlush( pFcb); + AFSReleaseExtentsWithFlush( pFcb, + &pCcb->AuthGroup); ntStatus = STATUS_SUCCESS; } diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index 70af5727f..f6f973f8f 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -1825,7 +1825,8 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB) // for any writes or reads to the cache to complete) // - (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb); + (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb, + NULL); } break; @@ -1892,7 +1893,8 @@ AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB) // for any writes or reads to the cache to complete) // - (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb); + (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb, + NULL); } pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1; @@ -2444,7 +2446,8 @@ AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB, // for any writes or reads to the cache to complete) // - (VOID) AFSTearDownFcbExtents( pFcb); + (VOID) AFSTearDownFcbExtents( pFcb, + NULL); } pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink; @@ -2836,7 +2839,8 @@ AFSVerifyEntry( IN GUID *AuthGroup, if ( bPurgeExtents) { - AFSFlushExtents( pObjectInfo->Fcb); + AFSFlushExtents( pObjectInfo->Fcb, + AuthGroup); } // @@ -3156,7 +3160,8 @@ AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus) // for any writes or reads to the cache to complete) // - (VOID) AFSTearDownFcbExtents( pFcb); + (VOID) AFSTearDownFcbExtents( pFcb, + NULL); } pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink; @@ -3914,7 +3919,8 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry, if ( bPurgeExtents) { - AFSFlushExtents( pCurrentFcb); + AFSFlushExtents( pCurrentFcb, + AuthGroup); } // @@ -5598,6 +5604,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB, IN AFSDirectoryCB *DirectoryCB, IN UNICODE_STRING *ParentPathName, IN AFSNameArrayHdr *RelatedNameArray, + IN GUID *AuthGroup, OUT AFSFileInfoCB *FileInfo) { @@ -5610,7 +5617,6 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB, WCHAR *pwchBuffer = NULL; UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName; ULONG ulNameDifference = 0; - GUID *pAuthGroup = NULL; __Enter { @@ -5627,17 +5633,8 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB, AFSReleaseResource( &DirectoryCB->NonPaged->Lock); - if( ParentDirectoryCB->ObjectInformation->Fcb != NULL) - { - pAuthGroup = &ParentDirectoryCB->ObjectInformation->Fcb->AuthGroup; - } - else if( DirectoryCB->ObjectInformation->Fcb != NULL) - { - pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup; - } - ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation, - pAuthGroup, + AuthGroup, FALSE, &pDirEntry); @@ -6292,11 +6289,21 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB, WCHAR *pwchBuffer = NULL; UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName; ULONG ulNameDifference = 0; - GUID *pAuthGroup = NULL; + GUID stAuthGroup; __Enter { + ntStatus = AFSRetrieveValidAuthGroup( NULL, + DirectoryCB->ObjectInformation, + FALSE, + &stAuthGroup); + + if( !NT_SUCCESS( ntStatus)) + { + try_return( ntStatus); + } + // // Retrieve a target name for the entry // @@ -6309,13 +6316,8 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB, AFSReleaseResource( &DirectoryCB->NonPaged->Lock); - if( DirectoryCB->ObjectInformation->Fcb != NULL) - { - pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup; - } - ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation, - pAuthGroup, + &stAuthGroup, FALSE, &pDirEntry); @@ -6667,10 +6669,12 @@ AFSCleanupFcb( IN AFSFcb *Fcb, // Now perform another flush on the file // - if( !NT_SUCCESS( AFSFlushExtents( Fcb))) + if( !NT_SUCCESS( AFSFlushExtents( Fcb, + NULL))) { - AFSReleaseExtentsWithFlush( Fcb); + AFSReleaseExtentsWithFlush( Fcb, + NULL); } } @@ -6679,7 +6683,8 @@ AFSCleanupFcb( IN AFSFcb *Fcb, BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED)) { - AFSTearDownFcbExtents( Fcb); + AFSTearDownFcbExtents( Fcb, + NULL); } try_return( ntStatus); @@ -6699,12 +6704,13 @@ AFSCleanupFcb( IN AFSFcb *Fcb, (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart) >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart)) { - - if( !NT_SUCCESS( AFSFlushExtents( Fcb)) && + if( !NT_SUCCESS( AFSFlushExtents( Fcb, + NULL)) && Fcb->OpenReferenceCount == 0) { - AFSReleaseExtentsWithFlush( Fcb); + AFSReleaseExtentsWithFlush( Fcb, + NULL); } } else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) || @@ -6715,7 +6721,8 @@ AFSCleanupFcb( IN AFSFcb *Fcb, // The file has been marked as invalid. Dump it // - AFSTearDownFcbExtents( Fcb); + AFSTearDownFcbExtents( Fcb, + NULL); } // @@ -6779,7 +6786,8 @@ AFSCleanupFcb( IN AFSFcb *Fcb, // Tear em down we'll not be needing them again // - AFSTearDownFcbExtents( Fcb); + AFSTearDownFcbExtents( Fcb, + NULL); } } @@ -8396,3 +8404,105 @@ AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName, return; } +NTSTATUS +AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb, + IN AFSObjectInfoCB *ObjectInfo, + IN BOOLEAN WriteAccess, + OUT GUID *AuthGroup) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + GUID stAuthGroup, stZeroAuthGroup; + BOOLEAN bFoundAuthGroup = FALSE; + AFSCcb *pCcb = NULL; + AFSFcb *pFcb = Fcb; + + __Enter + { + + RtlZeroMemory( &stAuthGroup, + sizeof( GUID)); + + RtlZeroMemory( &stZeroAuthGroup, + sizeof( GUID)); + + if( Fcb == NULL) + { + + if( ObjectInfo != NULL && + ObjectInfo->Fcb != NULL) + { + pFcb = ObjectInfo->Fcb; + } + } + + if( pFcb != NULL) + { + + AFSAcquireShared( &Fcb->NPFcb->CcbListLock, + TRUE); + + pCcb = Fcb->CcbListHead; + + while( pCcb != NULL) + { + + if( WriteAccess && + pCcb->GrantedAccess & FILE_WRITE_DATA) + { + RtlCopyMemory( &stAuthGroup, + &pCcb->AuthGroup, + sizeof( GUID)); + + bFoundAuthGroup = TRUE; + + break; + } + else if( pCcb->GrantedAccess != 0) + { + // + // At least get the read-only access + // + + RtlCopyMemory( &stAuthGroup, + &pCcb->AuthGroup, + sizeof( GUID)); + + bFoundAuthGroup = TRUE; + } + + pCcb = (AFSCcb *)pCcb->ListEntry.fLink; + } + + AFSReleaseResource( &Fcb->NPFcb->CcbListLock); + } + + if( !bFoundAuthGroup) + { + + AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(), + (ULONGLONG)PsGetCurrentThreadId(), + &stAuthGroup); + + if( RtlCompareMemory( &stZeroAuthGroup, + &stAuthGroup, + sizeof( GUID)) == sizeof( GUID)) + { + + DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n"); + + try_return( ntStatus = STATUS_ACCESS_DENIED); + } + } + + RtlCopyMemory( AuthGroup, + &stAuthGroup, + sizeof( GUID)); + +try_exit: + + NOTHING; + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/lib/AFSLockControl.cpp b/src/WINNT/afsrdr/kernel/lib/AFSLockControl.cpp index 634cc606f..c6e6b7d3a 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSLockControl.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSLockControl.cpp @@ -133,7 +133,7 @@ AFSLockControl( IN PDEVICE_OBJECT LibDeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_BYTE_RANGE_LOCK, AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pFcb->ObjectInformation->FileId, &stLockRequestCB, @@ -161,7 +161,7 @@ AFSLockControl( IN PDEVICE_OBJECT LibDeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK_ALL, AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pFcb->ObjectInformation->FileId, (void *)&stUnlockRequestCB, @@ -217,7 +217,7 @@ AFSLockControl( IN PDEVICE_OBJECT LibDeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK, AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, &pFcb->ObjectInformation->FileId, (void *)&stUnlockRequestCB, diff --git a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp index 7e1689008..8bb007bcf 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp @@ -935,7 +935,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup, ntStatus = AFSProcessDFSLink( pDirEntry, FileObject, - &uniRemainingPath); + &uniRemainingPath, + AuthGroup); } else { @@ -4304,14 +4305,14 @@ try_exit: NTSTATUS AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry, IN PFILE_OBJECT FileObject, - IN UNICODE_STRING *RemainingPath) + IN UNICODE_STRING *RemainingPath, + IN GUID *AuthGroup) { NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; UNICODE_STRING uniReparseName; UNICODE_STRING uniMUPDeviceName; AFSDirEnumEntry *pDirEntry = NULL; - GUID *pAuthGroup = NULL; __Enter { @@ -4333,13 +4334,8 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry, if( DirEntry->NameInformation.TargetName.Length == 0) { - if( DirEntry->ObjectInformation->Fcb != NULL) - { - pAuthGroup = &DirEntry->ObjectInformation->Fcb->AuthGroup; - } - ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation, - pAuthGroup, + AuthGroup, FALSE, &pDirEntry); diff --git a/src/WINNT/afsrdr/kernel/lib/AFSRead.cpp b/src/WINNT/afsrdr/kernel/lib/AFSRead.cpp index 2ef0f7c72..220fdfb4c 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSRead.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSRead.cpp @@ -195,6 +195,7 @@ AFSNonCachedRead( IN PDEVICE_OBJECT DeviceObject, IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); PFILE_OBJECT pFileObject = pIrpSp->FileObject; AFSFcb *pFcb = (AFSFcb *)pFileObject->FsContext; + AFSCcb *pCcb = (AFSCcb *)pFileObject->FsContext2; BOOLEAN bSynchronousIo = IoIsOperationSynchronous(Irp); VOID *pSystemBuffer = NULL; BOOLEAN bPagingIo = BooleanFlagOn( Irp->Flags, IRP_PAGING_IO); @@ -285,6 +286,7 @@ AFSNonCachedRead( IN PDEVICE_OBJECT DeviceObject, ulReadByteCount); ntStatus = AFSRequestExtentsAsync( pFcb, + pCcb, &StartingByte, ulReadByteCount); @@ -357,6 +359,7 @@ AFSNonCachedRead( IN PDEVICE_OBJECT DeviceObject, ulReadByteCount); ntStatus = AFSRequestExtentsAsync( pFcb, + pCcb, &StartingByte, ulReadByteCount); @@ -700,7 +703,8 @@ AFSNonCachedRead( IN PDEVICE_OBJECT DeviceObject, // The data is there now. Give back the extents now so the service // has some in hand // - (VOID) AFSReleaseExtentsWithFlush( pFcb); + (VOID) AFSReleaseExtentsWithFlush( pFcb, + &pCcb->AuthGroup); try_exit: @@ -1151,7 +1155,7 @@ AFSCommonRead( IN PDEVICE_OBJECT DeviceObject, if( !bPagingIo && !bNonCachedIo) { - ntStatus = AFSRequestExtentsAsync( pFcb, &liStartingByte, ulByteCount); + ntStatus = AFSRequestExtentsAsync( pFcb, pCcb, &liStartingByte, ulByteCount); if (!NT_SUCCESS(ntStatus)) { @@ -1316,7 +1320,8 @@ AFSCommonRead( IN PDEVICE_OBJECT DeviceObject, pFcb->Specific.File.ExtentLength > 1500) { - AFSQueueFlushExtents( pFcb); + AFSQueueFlushExtents( pFcb, + &pCcb->AuthGroup); } #endif @@ -1450,7 +1455,7 @@ AFSIOCtlRead( IN PDEVICE_OBJECT DeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_READ, AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, NULL, &stParentFID, (void *)&stIORequestCB, @@ -1564,7 +1569,7 @@ AFSShareRead( IN PDEVICE_OBJECT DeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_READ, AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, NULL, (void *)&stIoRequest, diff --git a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp index ae92834a7..b975ac211 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSWorker.cpp @@ -685,12 +685,14 @@ AFSWorkerThread( IN PVOID Context) case AFS_WORK_FLUSH_FCB: { - ntStatus = AFSFlushExtents( pWorkItem->Specific.Fcb.Fcb); + ntStatus = AFSFlushExtents( pWorkItem->Specific.Fcb.Fcb, + &pWorkItem->AuthGroup); if( !NT_SUCCESS( ntStatus)) { - AFSReleaseExtentsWithFlush( pWorkItem->Specific.Fcb.Fcb); + AFSReleaseExtentsWithFlush( pWorkItem->Specific.Fcb.Fcb, + &pWorkItem->AuthGroup); } ASSERT( pWorkItem->Specific.Fcb.Fcb->OpenReferenceCount != 0); @@ -1949,7 +1951,8 @@ AFSQueueWorkerRequestAtHead( IN AFSWorkItem *WorkItem) } NTSTATUS -AFSQueueFlushExtents( IN AFSFcb *Fcb) +AFSQueueFlushExtents( IN AFSFcb *Fcb, + IN GUID *AuthGroup) { NTSTATUS ntStatus = STATUS_SUCCESS; @@ -2023,6 +2026,10 @@ AFSQueueFlushExtents( IN AFSFcb *Fcb) pWorkItem->RequestType = AFS_WORK_FLUSH_FCB; + RtlCopyMemory( &pWorkItem->AuthGroup, + AuthGroup, + sizeof( GUID)); + pWorkItem->Specific.Fcb.Fcb = Fcb; InterlockedIncrement( &Fcb->OpenReferenceCount); diff --git a/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp b/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp index 12ff9e6f3..559549cd7 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSWrite.cpp @@ -424,7 +424,7 @@ AFSCommonWrite( IN PDEVICE_OBJECT DeviceObject, if( !bPagingIo && !bNonCachedIo) { - ntStatus = AFSRequestExtentsAsync( pFcb, &liStartingByte, ulByteCount); + ntStatus = AFSRequestExtentsAsync( pFcb, pCcb, &liStartingByte, ulByteCount); if (!NT_SUCCESS(ntStatus)) { @@ -761,7 +761,7 @@ AFSIOCtlWrite( IN PDEVICE_OBJECT DeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_WRITE, AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, NULL, &stParentFID, (void *)&stIORequestCB, @@ -889,6 +889,7 @@ AFSNonCachedWrite( IN PDEVICE_OBJECT DeviceObject, ByteCount); ntStatus = AFSRequestExtentsAsync( pFcb, + pCcb, &StartingByte, ByteCount); @@ -959,6 +960,7 @@ AFSNonCachedWrite( IN PDEVICE_OBJECT DeviceObject, ByteCount); ntStatus = AFSRequestExtentsAsync( pFcb, + pCcb, &StartingByte, ByteCount); @@ -1672,7 +1674,7 @@ AFSExtendingWrite( IN AFSFcb *Fcb, ntStatus = AFSUpdateFileInformation( &Fcb->ObjectInformation->ParentObjectInformation->FileId, Fcb->ObjectInformation, - &Fcb->AuthGroup); + &pCcb->AuthGroup); AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, AFS_TRACE_LEVEL_VERBOSE, @@ -1804,7 +1806,7 @@ AFSShareWrite( IN PDEVICE_OBJECT DeviceObject, ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_WRITE, AFS_REQUEST_FLAG_SYNCHRONOUS, - &pFcb->AuthGroup, + &pCcb->AuthGroup, &pCcb->DirectoryCB->NameInformation.FileName, NULL, pIoRequest, diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h index e8c506d24..e2e471700 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h @@ -189,10 +189,12 @@ AFSUpdateFileInformation( IN AFSFileID *ParentFid, NTSTATUS AFSNotifyDelete( IN AFSDirectoryCB *DirectoryCB, - IN BOOLEAN CheckOnly); + IN GUID *AuthGroup, + IN BOOLEAN CheckOnly); NTSTATUS AFSNotifyRename( IN AFSObjectInfoCB *ObjectInfo, + IN GUID *AuthGroup, IN AFSObjectInfoCB *ParentObjectInfo, IN AFSObjectInfoCB *TargetParentObjectInfo, IN AFSDirectoryCB *DirectoryCB, @@ -346,6 +348,7 @@ AFSExtentContains( IN AFSExtent *Extent, IN PLARGE_INTEGER Offset); NTSTATUS AFSRequestExtents( IN AFSFcb *Fcb, + IN AFSCcb *Ccb, IN PLARGE_INTEGER Offset, IN ULONG Size, OUT BOOLEAN *FullyMApped); @@ -358,6 +361,7 @@ BOOLEAN AFSDoExtentsMapRegion(IN AFSFcb *Fcb, NTSTATUS AFSRequestExtentsAsync( IN AFSFcb *Fcb, + IN AFSCcb *Ccb, IN PLARGE_INTEGER Offset, IN ULONG Size); @@ -379,10 +383,12 @@ AFSProcessSetExtents( IN AFSFcb *pFcb, IN AFSFileExtentCB *Result); NTSTATUS -AFSFlushExtents( IN AFSFcb *pFcb); +AFSFlushExtents( IN AFSFcb *pFcb, + IN GUID *AuthGroup); NTSTATUS -AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb); +AFSReleaseExtentsWithFlush( IN AFSFcb *Fcb, + IN GUID *AuthGroup); VOID AFSMarkDirty( IN AFSFcb *pFcb, @@ -391,7 +397,8 @@ AFSMarkDirty( IN AFSFcb *pFcb, IN LARGE_INTEGER *StartingByte); BOOLEAN -AFSTearDownFcbExtents( IN AFSFcb *Fcb ) ; +AFSTearDownFcbExtents( IN AFSFcb *Fcb, + IN GUID *AuthGroup); void AFSTrimExtents( IN AFSFcb *Fcb, @@ -503,7 +510,12 @@ void AFSRemoveFcb( IN AFSFcb *Fcb); NTSTATUS -AFSRemoveCcb( IN AFSCcb *Ccb); +AFSRemoveCcb( IN AFSFcb *Fcb, + IN AFSCcb *Ccb); + +NTSTATUS +AFSInsertCcb( IN AFSFcb *Fcb, + IN AFSCcb *Ccb); // // AFSNameSupport.cpp Prototypes @@ -577,7 +589,8 @@ AFSBuildRootVolume( IN GUID *AuthGroup, NTSTATUS AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry, IN PFILE_OBJECT FileObject, - IN UNICODE_STRING *RemainingPath); + IN UNICODE_STRING *RemainingPath, + IN GUID *AuthGroup); // // AFSNetworkProviderSupport.cpp @@ -1253,6 +1266,7 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB, IN AFSDirectoryCB *DirectoryCB, IN UNICODE_STRING *ParentPathName, IN AFSNameArrayHdr *RelatedNameArray, + IN GUID *AuthGroup, OUT AFSFileInfoCB *FileInfo); AFSObjectInfoCB * @@ -1352,6 +1366,12 @@ void AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName, OUT UNICODE_STRING *ParentPath); +NTSTATUS +AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb, + IN AFSObjectInfoCB *ObjectInfo, + IN BOOLEAN WriteAccess, + OUT GUID *AuthGroup); + // // AFSWorker.cpp Prototypes // @@ -1418,7 +1438,8 @@ NTSTATUS AFSShutdownVolumeWorker( IN AFSVolumeCB *VolumeCB); NTSTATUS -AFSQueueFlushExtents( IN AFSFcb *Fcb); +AFSQueueFlushExtents( IN AFSFcb *Fcb, + IN GUID *AuthGroup); NTSTATUS AFSQueueAsyncRead( IN PDEVICE_OBJECT DeviceObject, diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h index 62abdd906..a8370ffcd 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSDefines.h @@ -233,6 +233,7 @@ NTSTATUS #define CCB_FLAGS_DIRECTORY_QUERY_MAPPED 0x00000020 #define CCB_FLAG_MASK_PIOCTL_QUERY 0x00000040 #define CCB_FLAG_MASK_OPENED_REPARSE_POINT 0x00000080 +#define CCB_FLAG_INSERTED_CCB_LIST 0x00000100 // // DirEntry flags diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h index 37b9c7008..a2c14b549 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSStructs.h @@ -81,6 +81,8 @@ typedef struct _AFS_CCB ULONG Flags; + AFSListEntry ListEntry; + // // Directory enumeration informaiton // @@ -121,6 +123,8 @@ typedef struct _AFS_CCB UNICODE_STRING NotifyMask; + ACCESS_MASK GrantedAccess; + // // File unwind info // @@ -146,6 +150,12 @@ typedef struct _AFS_CCB ULONG FileAccess; + // + // Authentication group GUID + // + + GUID AuthGroup; + } AFSCcb; // @@ -575,6 +585,8 @@ typedef struct _AFS_WORK_ITEM ULONGLONG ProcessID; + GUID AuthGroup; + union { struct -- 2.39.5