From dffaab441d09a3b955d358292c550116b76a6410 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 8 Jul 2015 16:49:38 -0400 Subject: [PATCH] Windows: fix RDR detection of ambiguous directory entries The redirector is supposed to reject access to file objects if there is no case exact match and multiple entries match in a case insensitive comparison. The check was only present in the AFSLocateNameEntry() function and not elsewhere. Fix the AFSLocateNameEntry() call and addd the missing checks. Change-Id: I15aba954179fa85e28b348989779bc05122c0037 Reviewed-on: http://gerrit.openafs.org/11929 Tested-by: BuildBot Reviewed-by: Jeffrey Altman --- src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp | 88 ++++++++++++++----- src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp | 17 ++++ .../afsrdr/kernel/lib/AFSNameSupport.cpp | 63 +++++++------ .../kernel/lib/AFSNetworkProviderSupport.cpp | 16 ++++ 4 files changed, 134 insertions(+), 50 deletions(-) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp index a127059fc..63b3e643d 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSFileInfo.cpp @@ -2362,19 +2362,39 @@ AFSSetFileLinkInfo( IN PIRP Irp) AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead, ulTargetCRC, &pTargetDirEntry); - } - if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) && - pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName, - NULL, - NULL)) - { - // - // Try the short name - // - AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree, - ulTargetCRC, - &pTargetDirEntry); + if ( pTargetDirEntry == NULL) + { + + if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) && + RtlIsNameLegalDOS8Dot3( &uniTargetName, + NULL, + NULL)) + { + // + // Try the short name + // + AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree, + ulTargetCRC, + &pTargetDirEntry); + } + } + else + { + // + // Here we have a match on the case insensitive lookup for the name. If there + // Is more than one link entry for this node then fail the lookup request + // + + if( !BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) || + pTargetDirEntry->CaseInsensitiveList.fLink != NULL) + { + + pTargetDirEntry = NULL; + + try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION); + } + } } // @@ -2832,19 +2852,39 @@ AFSSetRenameInfo( IN PIRP Irp) AFSLocateCaseInsensitiveDirEntry( pTargetParentObject->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead, ulTargetCRC, &pTargetDirEntry); - } - if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) && - pTargetDirEntry == NULL && RtlIsNameLegalDOS8Dot3( &uniTargetName, - NULL, - NULL)) - { - // - // Try the short name - // - AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree, - ulTargetCRC, - &pTargetDirEntry); + if ( pTargetDirEntry == NULL) + { + + if ( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) && + RtlIsNameLegalDOS8Dot3( &uniTargetName, + NULL, + NULL)) + { + // + // Try the short name + // + AFSLocateShortNameDirEntry( pTargetParentObject->Specific.Directory.ShortNameTree, + ulTargetCRC, + &pTargetDirEntry); + } + } + else + { + // + // Here we have a match on the case insensitive lookup for the name. If there + // Is more than one link entry for this node then fail the lookup request + // + + if( !BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) || + pTargetDirEntry->CaseInsensitiveList.fLink != NULL) + { + + pTargetDirEntry = NULL; + + try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION); + } + } } // diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index 0081fb304..0211d42db 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -8795,6 +8795,23 @@ AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB, &pDirEntry); } } + else + { + + // + // Here we have a match on the case insensitive lookup for the name. If there + // Is more than one link entry for this node then fail the lookup request + // + + if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) || + pDirEntry->CaseInsensitiveList.fLink != NULL) + { + + AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock); + + try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION); + } + } } if( pDirEntry != NULL) diff --git a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp index 58cb969e3..29e888776 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp @@ -1821,35 +1821,23 @@ AFSLocateNameEntry( IN GUID *AuthGroup, // // Here we have a match on the case insensitive lookup for the name. If there - // Is more than one link entry for this node then fail the lookup request - // + // Is more than one link entry for this node then fail the lookup request + // - pCurrentObject = pDirEntry->ObjectInformation; + if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) || + pDirEntry->CaseInsensitiveList.fLink != NULL) + { - if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) || - pDirEntry->CaseInsensitiveList.fLink != NULL) - { + AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock); - // - // Increment our dir entry ref count since we will decrement it on exit - // + pDirEntry = NULL; - lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount); + try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION); + } - AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING, - AFS_TRACE_LEVEL_VERBOSE, - "AFSLocateNameEntry Increment5 count on %wZ DE %p Ccb %p Cnt %d\n", - &pDirEntry->NameInformation.FileName, - pDirEntry, - NULL, - lCount)); - - AFSReleaseResource( pParentDirEntry->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock); - - try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION); - } - } - } + pCurrentObject = pDirEntry->ObjectInformation; + } + } if( pDirEntry != NULL) { @@ -4027,13 +4015,36 @@ AFSParseName( IN PIRP Irp, } } } + else + { + + // + // Here we have a match on the case insensitive lookup for the name. If there + // Is more than one link entry for this node then fail the lookup request + // + + if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) || + pDirEntry->CaseInsensitiveList.fLink != NULL) + { + + AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock); + + bReleaseTreeLock = FALSE; + + pDirEntry = NULL; + + try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION); + } + } } if( bReleaseTreeLock) { - AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock); - } + AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock); + + bReleaseTreeLock = FALSE; + } // // Be sure we are starting from the correct volume diff --git a/src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp index 66a5dd751..df9c12774 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSNetworkProviderSupport.cpp @@ -1333,6 +1333,22 @@ AFSEnumerateConnection( IN OUT AFSNetworkProviderConnectionCB *ConnectCB, try_return( ntStatus); } + + // + // Here we have a match on the case insensitive lookup for the name. If there + // Is more than one link entry for this node then fail the lookup request + // + + if( !BooleanFlagOn( pShareDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) || + pShareDirEntry->CaseInsensitiveList.fLink != NULL) + { + + AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock); + + pShareDirEntry = NULL; + + try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION); + } } lCount = InterlockedIncrement( &pShareDirEntry->DirOpenReferenceCount); -- 2.39.5