From ff7a446194001fa5ca4c0b04dca3d1f8cb59a677 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 26 Oct 2016 13:16:27 -0700 Subject: [PATCH] tst: winfsp-tests: WIP --- tst/winfsp-tests/hooks.c | 111 ++++++++++++++++------------------- tst/winfsp-tests/info-test.c | 23 +++++--- 2 files changed, 66 insertions(+), 68 deletions(-) diff --git a/tst/winfsp-tests/hooks.c b/tst/winfsp-tests/hooks.c index 6af40d52..d5d4408d 100644 --- a/tst/winfsp-tests/hooks.c +++ b/tst/winfsp-tests/hooks.c @@ -103,6 +103,23 @@ static VOID PrepareFileName(PCWSTR FileName, PWSTR FileNameBuf) } } +static VOID MaybeAdjustTraversePrivilege(BOOL Enable) +{ + if (OptNoTraverseToken) + { + TOKEN_PRIVILEGES Privileges; + DWORD LastError = GetLastError(); + + Privileges.PrivilegeCount = 1; + Privileges.Privileges[0].Attributes = Enable ? SE_PRIVILEGE_ENABLED : 0; + Privileges.Privileges[0].Luid = OptNoTraverseLuid; + if (!AdjustTokenPrivileges(OptNoTraverseToken, FALSE, &Privileges, 0, 0, 0)) + ABORT("cannot adjust traverse privilege"); + + SetLastError(LastError); + } +} + HANDLE HookCreateFileW( LPCWSTR lpFileName, DWORD dwDesiredAccess, @@ -113,72 +130,28 @@ HANDLE HookCreateFileW( HANDLE hTemplateFile) { WCHAR FileNameBuf[FILENAMEBUF_SIZE]; - TOKEN_PRIVILEGES Privileges; + HANDLE Handle; PrepareFileName(lpFileName, FileNameBuf); - if (OptNoTraverseToken) - { - Privileges.PrivilegeCount = 1; - Privileges.Privileges[0].Attributes = 0; - Privileges.Privileges[0].Luid = OptNoTraverseLuid; - if (!AdjustTokenPrivileges(OptNoTraverseToken, FALSE, &Privileges, 0, 0, 0)) - ABORT("cannot disable traverse privilege"); - } - - HANDLE h; - if (!OptResilient) - h = CreateFileW( - FileNameBuf, - dwDesiredAccess, - dwShareMode, - lpSecurityAttributes, - dwCreationDisposition, - dwFlagsAndAttributes, - hTemplateFile); - else - h = ResilientCreateFileW( - FileNameBuf, - dwDesiredAccess, - dwShareMode, - lpSecurityAttributes, - dwCreationDisposition, - dwFlagsAndAttributes, - hTemplateFile); - DWORD LastError = GetLastError(); - - if (OptNoTraverseToken) - { - Privileges.PrivilegeCount = 1; - Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - Privileges.Privileges[0].Luid = OptNoTraverseLuid; - if (!AdjustTokenPrivileges(OptNoTraverseToken, FALSE, &Privileges, 0, 0, 0)) - ABORT("cannot enable traverse privilege"); - } - -#if 0 - FspDebugLog("CreateFileW(\"%S\", %#lx, %#lx, %p, %#lx, %#lx, %p) = %p[%#lx]\n", + MaybeAdjustTraversePrivilege(FALSE); + Handle = (OptResilient ? ResilientCreateFileW : CreateFileW)( FileNameBuf, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, - hTemplateFile, - h, INVALID_HANDLE_VALUE != h ? 0 : LastError); -#endif - - SetLastError(LastError); - return h; + hTemplateFile); + MaybeAdjustTraversePrivilege(TRUE); + return Handle; } BOOL HookCloseHandle( HANDLE hObject) { - if (!OptResilient) - return CloseHandle(hObject); - else - return ResilientCloseHandle(hObject); + return (OptResilient ? ResilientCloseHandle : CloseHandle)( + hObject); } BOOL HookCreateDirectoryW( @@ -186,33 +159,43 @@ BOOL HookCreateDirectoryW( LPSECURITY_ATTRIBUTES lpSecurityAttributes) { WCHAR FileNameBuf[FILENAMEBUF_SIZE]; + BOOL Success; PrepareFileName(lpPathName, FileNameBuf); - return CreateDirectoryW(FileNameBuf, lpSecurityAttributes); + MaybeAdjustTraversePrivilege(FALSE); + Success = CreateDirectoryW(FileNameBuf, lpSecurityAttributes); + MaybeAdjustTraversePrivilege(TRUE); + return Success; } BOOL HookDeleteFileW( LPCWSTR lpFileName) { WCHAR FileNameBuf[FILENAMEBUF_SIZE]; + BOOL Success; PrepareFileName(lpFileName, FileNameBuf); - if (!OptResilient) - return DeleteFileW(FileNameBuf); - else - return ResilientDeleteFileW(FileNameBuf); + MaybeAdjustTraversePrivilege(FALSE); + Success = (OptResilient ? ResilientDeleteFileW : DeleteFileW)( + FileNameBuf); + MaybeAdjustTraversePrivilege(TRUE); + return Success; } BOOL HookRemoveDirectoryW( LPCWSTR lpPathName) { WCHAR FileNameBuf[FILENAMEBUF_SIZE]; + BOOL Success; PrepareFileName(lpPathName, FileNameBuf); - return RemoveDirectoryW(FileNameBuf); + MaybeAdjustTraversePrivilege(FALSE); + Success = RemoveDirectoryW(FileNameBuf); + MaybeAdjustTraversePrivilege(TRUE); + return Success; } BOOL HookMoveFileExW( @@ -222,11 +205,15 @@ BOOL HookMoveFileExW( { WCHAR OldFileNameBuf[FILENAMEBUF_SIZE]; WCHAR NewFileNameBuf[FILENAMEBUF_SIZE]; + BOOL Success; PrepareFileName(lpExistingFileName, OldFileNameBuf); PrepareFileName(lpNewFileName, NewFileNameBuf); - return MoveFileExW(OldFileNameBuf, NewFileNameBuf, dwFlags); + MaybeAdjustTraversePrivilege(FALSE); + Success = MoveFileExW(OldFileNameBuf, NewFileNameBuf, dwFlags); + MaybeAdjustTraversePrivilege(TRUE); + return Success; } HANDLE HookFindFirstFileW( @@ -234,8 +221,12 @@ HANDLE HookFindFirstFileW( LPWIN32_FIND_DATAW lpFindFileData) { WCHAR FileNameBuf[FILENAMEBUF_SIZE]; + HANDLE Handle; PrepareFileName(lpFileName, FileNameBuf); - return FindFirstFileW(FileNameBuf, lpFindFileData); + MaybeAdjustTraversePrivilege(FALSE); + Handle = FindFirstFileW(FileNameBuf, lpFindFileData); + MaybeAdjustTraversePrivilege(TRUE); + return Handle; } diff --git a/tst/winfsp-tests/info-test.c b/tst/winfsp-tests/info-test.c index 939c20bd..5371315f 100644 --- a/tst/winfsp-tests/info-test.c +++ b/tst/winfsp-tests/info-test.c @@ -215,16 +215,23 @@ void getfileinfo_name_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout) else ASSERT(0 == wcscmp(OrigPath, FinalPath)); /* don't use mywcscmp */ - Result = GetFinalPathNameByHandleW( - Handle, FinalPath, MAX_PATH - 1, VOLUME_NAME_NONE | FILE_NAME_NORMALIZED); - ASSERT(0 != Result && Result < MAX_PATH); - if (OptSharePrefixLength) + if (!OptNoTraverseToken || -1 != Flags) { - memmove(FinalPath, - FinalPath + OptSharePrefixLength / sizeof(WCHAR), - (wcslen(FinalPath) + 1) * sizeof(WCHAR) - OptSharePrefixLength); + /* + * FILE_NAME_NORMALIZED fails without Traverse privilege on NTFS. + * FILE_NAME_OPENED succeeds. Go figure! + */ + Result = GetFinalPathNameByHandleW( + Handle, FinalPath, MAX_PATH - 1, VOLUME_NAME_NONE | FILE_NAME_NORMALIZED); + ASSERT(0 != Result && Result < MAX_PATH); + if (OptSharePrefixLength) + { + memmove(FinalPath, + FinalPath + OptSharePrefixLength / sizeof(WCHAR), + (wcslen(FinalPath) + 1) * sizeof(WCHAR) - OptSharePrefixLength); + } + ASSERT(0 == wcscmp(OrigPath, FinalPath)); /* don't use mywcscmp */ } - ASSERT(0 == wcscmp(OrigPath, FinalPath)); /* don't use mywcscmp */ CloseHandle(Handle);