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 <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>
UNICODE_STRING AFSServerName;
+ UNICODE_STRING AFSMountRootName;
+
ULONG AFSDebugFlags;
AFSFileID GlobalRootFid;
UNICODE_STRING AFSServerName;
+UNICODE_STRING AFSMountRootName;
+
UNICODE_STRING AFSGlobalRootName;
CACHE_MANAGER_CALLBACKS AFSCacheManagerCallbacks;
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;
}
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)
{
AFSReadServerName();
+ AFSReadMountRootName();
+
RtlZeroMemory( &sysVersion,
sizeof( RTL_OSVERSIONINFOW));
stInitLib.AFSServerName = AFSServerName;
+ stInitLib.AFSMountRootName = AFSMountRootName;
+
stInitLib.AFSDebugFlags = AFSDebugFlags;
if( GlobalRootFid != NULL)
AFSReadServerName( void);
NTSTATUS
+AFSReadMountRootName( void);
+
+NTSTATUS
AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo,
IN ULONG SysNameInfoBufferLength);
#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"
extern UNICODE_STRING AFSServerName;
+extern UNICODE_STRING AFSMountRootName;
+
extern UNICODE_STRING AFSGlobalRootName;
extern ERESOURCE AFSDbgLogLock;
UNICODE_STRING AFSServerName;
+UNICODE_STRING AFSMountRootName;
+
AFSVolumeCB *AFSGlobalRoot = NULL;
UNICODE_STRING AFSPIOCtlName;
BOOLEAN bIsRelative = FALSE;
- if( Name->Buffer[ 0] != L'\\')
+ if( Name->Length > 0 &&
+ Name->Buffer[ 0] != L'\\')
{
bIsRelative = TRUE;
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)
{
AFSServerName = LibraryInit->AFSServerName;
+ AFSMountRootName = LibraryInit->AFSMountRootName;
+
AFSDebugFlags = LibraryInit->AFSDebugFlags;
//
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
//
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
pNameArray->LinkCount = lLinkCount;
- //
- // Process over the \\<Global root> 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;
}
BOOLEAN
AFSIsRelativeName( IN UNICODE_STRING *Name);
+BOOLEAN
+AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name);
+
void
AFSUpdateName( IN UNICODE_STRING *Name);
extern UNICODE_STRING AFSServerName;
+extern UNICODE_STRING AFSMountRootName;
+
extern AFSVolumeCB *AFSGlobalRoot;
extern UNICODE_STRING AFSPIOCtlName;