From: Jeffrey Altman Date: Thu, 1 Nov 2012 00:59:30 +0000 (-0400) Subject: Windows: Use MountRoot for Absolute Symlinks X-Git-Tag: upstream/1.8.0_pre1^2~1841 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=ba718cba9285fc9f663b0fd15524bc5474cca893;p=packages%2Fo%2Fopenafs.git Windows: Use MountRoot for Absolute Symlinks Replace the absolute symlink processing in AFSLocateName(). Implement AFSIsAbsoluteAFSName() to test whether or not the path is in fact an absolute /afs path by comparing the input string to the registry MountRoot value which specifies the case sensitive root path for all absolute symlinks stored in the AFS cell. If a symlink target path begins with a directory separator and is not an absolute afs path name, return an error. Construct the substitution string using the target path without the MountRoot prefix. Add functionality to AFSRedir.sys to read the MountRoot from the registry and pass it on to AFSRedirLib.sys. Change-Id: Ie1df24da1e6de257c73dc34c80a75288bad47d29 Reviewed-on: http://gerrit.openafs.org/8353 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- diff --git a/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h b/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h index 1303ec838..adbabfce9 100644 --- a/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h +++ b/src/WINNT/afsrdr/common/AFSRedirCommonStructs.h @@ -786,6 +786,8 @@ typedef struct _AFS_LIBRARY_INIT_CB UNICODE_STRING AFSServerName; + UNICODE_STRING AFSMountRootName; + ULONG AFSDebugFlags; AFSFileID GlobalRootFid; diff --git a/src/WINNT/afsrdr/kernel/fs/AFSData.cpp b/src/WINNT/afsrdr/kernel/fs/AFSData.cpp index 4fd9894e4..f1cc27aa8 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSData.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSData.cpp @@ -64,6 +64,8 @@ HANDLE AFSMUPHandle = NULL; UNICODE_STRING AFSServerName; +UNICODE_STRING AFSMountRootName; + UNICODE_STRING AFSGlobalRootName; CACHE_MANAGER_CALLBACKS AFSCacheManagerCallbacks; diff --git a/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp index 3b867371e..893199201 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp @@ -960,7 +960,7 @@ AFSReadServerName() AFSServerName.Buffer = NULL; paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - paramTable[0].Name = AFS_NETBIOS_NAME; + paramTable[0].Name = AFS_REG_NETBIOS_NAME; paramTable[0].EntryContext = &AFSServerName; paramTable[0].DefaultType = REG_NONE; @@ -996,6 +996,107 @@ try_exit: return ntStatus; } +NTSTATUS +AFSReadMountRootName() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + ULONG Default = 0; + UNICODE_STRING paramPath; + RTL_QUERY_REGISTRY_TABLE paramTable[2]; + + __Enter + { + + // + // Setup the paramPath buffer. + // + + paramPath.MaximumLength = PAGE_SIZE; + paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool, + paramPath.MaximumLength, + AFS_GENERIC_MEMORY_17_TAG); + + // + // If it exists, setup the path. + // + + if( paramPath.Buffer == NULL) + { + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + // + // Move in the paths + // + + RtlZeroMemory( paramPath.Buffer, + paramPath.MaximumLength); + + RtlCopyMemory( ¶mPath.Buffer[ 0], + L"\\TransarcAFSDaemon\\Parameters", + 58); + + paramPath.Length = 58; + + RtlZeroMemory( paramTable, + sizeof( paramTable)); + + // + // Setup the table to query the registry for the needed value + // + + AFSMountRootName.Length = 0; + AFSMountRootName.MaximumLength = 0; + AFSMountRootName.Buffer = NULL; + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_REG_MOUNT_ROOT; + paramTable[0].EntryContext = &AFSMountRootName; + + paramTable[0].DefaultType = REG_NONE; + paramTable[0].DefaultData = NULL; + paramTable[0].DefaultLength = 0; + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + if ( NT_SUCCESS( ntStatus)) + { + if ( AFSMountRootName.Buffer[0] == L'/') + { + + AFSMountRootName.Buffer[0] = L'\\'; + } + } + + // + // Free up the buffer + // + + ExFreePool( paramPath.Buffer); + +try_exit: + + if( !NT_SUCCESS( ntStatus)) + { + + RtlInitUnicodeString( &AFSMountRootName, + L"\\afs"); + } + } + + return ntStatus; +} + NTSTATUS AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo, IN ULONG SysNameInfoBufferLength) diff --git a/src/WINNT/afsrdr/kernel/fs/AFSInit.cpp b/src/WINNT/afsrdr/kernel/fs/AFSInit.cpp index 83e22f79f..8ff1be2f0 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSInit.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSInit.cpp @@ -108,6 +108,8 @@ DriverEntry( PDRIVER_OBJECT DriverObject, AFSReadServerName(); + AFSReadMountRootName(); + RtlZeroMemory( &sysVersion, sizeof( RTL_OSVERSIONINFOW)); diff --git a/src/WINNT/afsrdr/kernel/fs/AFSLibrarySupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSLibrarySupport.cpp index bed174dab..2186bc19d 100644 --- a/src/WINNT/afsrdr/kernel/fs/AFSLibrarySupport.cpp +++ b/src/WINNT/afsrdr/kernel/fs/AFSLibrarySupport.cpp @@ -870,6 +870,8 @@ AFSInitializeLibrary( IN AFSFileID *GlobalRootFid, stInitLib.AFSServerName = AFSServerName; + stInitLib.AFSMountRootName = AFSMountRootName; + stInitLib.AFSDebugFlags = AFSDebugFlags; if( GlobalRootFid != NULL) diff --git a/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h index e2b464350..65c14af66 100644 --- a/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h @@ -456,6 +456,9 @@ AFSInitServerStrings( void); NTSTATUS AFSReadServerName( void); +NTSTATUS +AFSReadMountRootName( void); + NTSTATUS AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo, IN ULONG SysNameInfoBufferLength); diff --git a/src/WINNT/afsrdr/kernel/fs/Include/AFSDefines.h b/src/WINNT/afsrdr/kernel/fs/Include/AFSDefines.h index 4f57d8766..239e4ff9f 100644 --- a/src/WINNT/afsrdr/kernel/fs/Include/AFSDefines.h +++ b/src/WINNT/afsrdr/kernel/fs/Include/AFSDefines.h @@ -48,7 +48,8 @@ #define AFS_REG_TRACE_BUFFER_LENGTH L"TraceBufferSize" // in KB #define AFS_REG_MAX_DIRTY L"MaxDirtyMb" #define AFS_REG_MAX_IO L"MaxIOMb" -#define AFS_NETBIOS_NAME L"NetbiosName" +#define AFS_REG_NETBIOS_NAME L"NetbiosName" +#define AFS_REG_MOUNT_ROOT L"MountRoot" #define AFS_REG_SHUTDOWN_STATUS L"ShutdownStatus" #define AFS_REG_REQUIRE_CLEAN_SHUTDOWN L"RequireCleanShutdown" diff --git a/src/WINNT/afsrdr/kernel/fs/Include/AFSExtern.h b/src/WINNT/afsrdr/kernel/fs/Include/AFSExtern.h index 9197d584d..524c851f2 100644 --- a/src/WINNT/afsrdr/kernel/fs/Include/AFSExtern.h +++ b/src/WINNT/afsrdr/kernel/fs/Include/AFSExtern.h @@ -67,6 +67,8 @@ extern HANDLE AFSMUPHandle; extern UNICODE_STRING AFSServerName; +extern UNICODE_STRING AFSMountRootName; + extern UNICODE_STRING AFSGlobalRootName; extern ERESOURCE AFSDbgLogLock; diff --git a/src/WINNT/afsrdr/kernel/lib/AFSData.cpp b/src/WINNT/afsrdr/kernel/lib/AFSData.cpp index 7f69fa18f..b7b25d4e6 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSData.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSData.cpp @@ -56,6 +56,8 @@ HANDLE AFSSysProcess = NULL; UNICODE_STRING AFSServerName; +UNICODE_STRING AFSMountRootName; + AFSVolumeCB *AFSGlobalRoot = NULL; UNICODE_STRING AFSPIOCtlName; diff --git a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp index dc2654968..f5d00aa14 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp @@ -4778,7 +4778,8 @@ AFSIsRelativeName( IN UNICODE_STRING *Name) BOOLEAN bIsRelative = FALSE; - if( Name->Buffer[ 0] != L'\\') + if( Name->Length > 0 && + Name->Buffer[ 0] != L'\\') { bIsRelative = TRUE; @@ -4787,6 +4788,53 @@ AFSIsRelativeName( IN UNICODE_STRING *Name) return bIsRelative; } +BOOLEAN +AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name) +{ + UNICODE_STRING uniTempName; + BOOLEAN bIsAbsolute = FALSE; + + // + // An absolute AFS path must begin with \afs\... or equivalent + // + + if ( Name->Length == 0 || + Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) || + Name->Buffer[ 0] != L'\\' || + Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\') + { + + return FALSE; + } + + uniTempName.Length = AFSMountRootName.Length; + uniTempName.MaximumLength = AFSMountRootName.Length; + + uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool, + uniTempName.MaximumLength, + AFS_NAME_BUFFER_TWO_TAG); + + if( uniTempName.Buffer == NULL) + { + + return FALSE; + } + + RtlCopyMemory( uniTempName.Buffer, + Name->Buffer, + AFSMountRootName.Length); + + bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName, + &AFSMountRootName, + TRUE)); + + AFSExFreePoolWithTag( uniTempName.Buffer, + AFS_NAME_BUFFER_TWO_TAG); + + return bIsAbsolute; +} + + void AFSUpdateName( IN UNICODE_STRING *Name) { @@ -7735,6 +7783,8 @@ AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit) AFSServerName = LibraryInit->AFSServerName; + AFSMountRootName = LibraryInit->AFSMountRootName; + AFSDebugFlags = LibraryInit->AFSDebugFlags; // diff --git a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp index f637ef49e..6f6783a8a 100644 --- a/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp +++ b/src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp @@ -619,6 +619,26 @@ AFSLocateNameEntry( IN GUID *AuthGroup, pCurrentObject->FileId.Vnode, pCurrentObject->FileId.Unique); + if ( !AFSIsAbsoluteAFSName( &pDirEntry->NameInformation.TargetName)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSLocateNameEntry Name %wZ contains invalid server name\n", + &pDirEntry->NameInformation.TargetName); + + // + // The correct response would be STATUS_OBJECT_PATH_INVALID + // but that prevents cmd.exe from performing a recursive + // directory enumeration when opening a directory entry + // that represents a symlink to an invalid path is discovered. + // + + AFSReleaseResource( &pDirEntry->NonPaged->Lock); + + try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND); + } + // // We'll substitute this name into the current process name // starting at where we sit in the path @@ -664,10 +684,10 @@ AFSLocateNameEntry( IN GUID *AuthGroup, // RtlCopyMemory( uniTempName.Buffer, - pDirEntry->NameInformation.TargetName.Buffer, - pDirEntry->NameInformation.TargetName.Length); + &pDirEntry->NameInformation.TargetName.Buffer[ AFSMountRootName.Length/sizeof( WCHAR)], + pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length); - uniTempName.Length = pDirEntry->NameInformation.TargetName.Length; + uniTempName.Length = pDirEntry->NameInformation.TargetName.Length - AFSMountRootName.Length; // // And now any remaining portion of the name @@ -790,35 +810,6 @@ AFSLocateNameEntry( IN GUID *AuthGroup, pNameArray->LinkCount = lLinkCount; - // - // Process over the \\ portion of the name - // - - FsRtlDissectName( uniPathName, - &uniComponentName, - &uniRemainingPath); - - if( RtlCompareUnicodeString( &uniComponentName, - &AFSServerName, - TRUE) != 0) - { - - AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, - AFS_TRACE_LEVEL_ERROR, - "AFSLocateNameEntry Name %wZ contains invalid server name\n", - &uniPathName); - - // - // The correct response would be STATUS_OBJECT_PATH_INVALID - // but that prevents cmd.exe from performing a recursive - // directory enumeration when opening a directory entry - // that represents a symlink to an invalid path is discovered. - // - try_return( ntStatus = STATUS_OBJECT_PATH_NOT_FOUND); - } - - uniPathName = uniRemainingPath; - pParentDirEntry = NULL; } diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h index 022a6ba8f..416c39d97 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h @@ -1227,6 +1227,9 @@ AFSEnumerateGlobalRoot( IN GUID *AuthGroup); BOOLEAN AFSIsRelativeName( IN UNICODE_STRING *Name); +BOOLEAN +AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name); + void AFSUpdateName( IN UNICODE_STRING *Name); diff --git a/src/WINNT/afsrdr/kernel/lib/Include/AFSExtern.h b/src/WINNT/afsrdr/kernel/lib/Include/AFSExtern.h index a9b23fbd3..09cbee082 100644 --- a/src/WINNT/afsrdr/kernel/lib/Include/AFSExtern.h +++ b/src/WINNT/afsrdr/kernel/lib/Include/AFSExtern.h @@ -61,6 +61,8 @@ extern HANDLE AFSSysProcess; extern UNICODE_STRING AFSServerName; +extern UNICODE_STRING AFSMountRootName; + extern AFSVolumeCB *AFSGlobalRoot; extern UNICODE_STRING AFSPIOCtlName;