From df11a7d7ff15ac00352076ad2060d8023c1698d9 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Thu, 20 Oct 2016 18:32:01 -0700 Subject: [PATCH] dll: FspAccessCheckEx: fix traverse check problem with reparse points --- src/dll/security.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/src/dll/security.c b/src/dll/security.c index ef84e7cf..f1b0a598 100644 --- a/src/dll/security.c +++ b/src/dll/security.c @@ -119,7 +119,6 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, AllowTraverseCheck && !Request->Req.Create.HasTraversePrivilege && !(L'\\' == FileName[0] && L'\0' == FileName[1])/* no need to traverse check for root */) { - DEBUGLOG("TraverseCheck: Full=\"%S\"", FileName); Remain = FileName; for (;;) { @@ -132,16 +131,22 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, *Remain = L'\0'; Prefix = Remain > FileName ? FileName : TraverseCheckRoot; - DEBUGLOG("TraverseCheck: Part=\"%S\"", Prefix); FileAttributes = 0; Result = FspGetSecurityByName(FileSystem, Prefix, &FileAttributes, &SecurityDescriptor, &SecurityDescriptorSize); - /* compute the ReparsePointIndex and place it in FileAttributes now */ + /* + * We check to see if this is a reparse point and then compute the ReparsePointIndex + * and place it in FileAttributes. We do this check BEFORE the directory check, + * because contrary to NTFS we want to allow non-directory symlinks to directories. + */ if (NT_SUCCESS(Result) && STATUS_REPARSE != Result && (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) + { FileAttributes = FspPathSuffixIndex(Prefix); + Result = STATUS_REPARSE; + } *Remain = L'\\'; do @@ -156,27 +161,6 @@ FSP_API NTSTATUS FspAccessCheckEx(FSP_FILE_SYSTEM *FileSystem, goto exit; } - /* - * We check to see if this is a reparse point and then immediately return - * STATUS_REPARSE. We do this check BEFORE the directory check, because - * contrary to NTFS we want to allow non-directory symlinks to directories. - * - * Note that this effectively turns off traverse checking a path comprised of - * reparse points even when the originating process does not have the Traverse - * privilege. [I am not sure what NTFS does in this case, but POSIX symlinks - * behave similarly.] We will still traverse check the reparsed path when - * the FSD sends it back to us though! - * - * Now if the reparse points are not symlinks (or symlink-like) things - * get even more complicated. Argh! Windows! - */ - if (FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - { - /* ReparsePointIndex already computed after FspGetSecurityByName call above */ - Result = STATUS_REPARSE; - goto exit; - } - /* * Check if this is a directory, otherwise the path is invalid. */