alphaleonis / AlphaFS

AlphaFS is a .NET library providing more complete Win32 file system functionality to the .NET platform than the standard System.IO classes.
http://alphafs.alphaleonis.com/
MIT License
563 stars 99 forks source link

UnauthorizedAccessException for Cygwin files with restrictive access rights #428

Closed shiek closed 6 years ago

shiek commented 6 years ago

Hi, I realized https://github.com/alphaleonis/AlphaVSS/issues/17 is a AlphaFS issue. Duplicati - 2.0.2.20_canary_2018-02-27 uses AlphaFS 2.1.3. I just compiled AlphaFS-master and reran my test case. The issue still persists.

What do you think about the problem?

Yomodo commented 6 years ago

The current AlphafS-master ís v2.1.3, you might want to try it with the latest dev, which will be the next v2.2.

shiek commented 6 years ago

Oh... I thought AlphaFS-master is almost in sync with AlphaFS-dev. It actually was some days ago but you reverted it all.

I get this error very early when using AlphaFS-dev:

Error reported while accessing file: C:\cygwin\
System.ArgumentException: Illegal characters: [?] in path.
Parametername: path
   bei Alphaleonis.Win32.Filesystem.Path.CheckInvalidPathChars(String path, Boolean checkAdditional, Boolean allowEmpty)
   bei Alphaleonis.Win32.Filesystem.Path.CheckSupportedPathFormat(String path, Boolean checkInvalidPathChars, Boolean checkAdditional)
   bei Alphaleonis.Win32.Filesystem.File.GetAttributesExCore[T](KernelTransaction transaction, String path, PathFormat pathFormat, Boolean returnErrorOnNotFound)
   bei Duplicati.Library.Snapshots.SystemIOWindows.GetFileAttributes(String path)
   bei Duplicati.Library.Snapshots.WindowsSnapshot.GetAttributes(String file)
   bei Duplicati.Library.Utility.Utility.<EnumerateFileSystemEntries>d__22.MoveNext()

I guess Duplicati is not ready for AlphaFS-dev yet.

Update: I guess "path" looks like this: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy13\cygwin\ Maybe it's actually a problem with AlphaFS?

Yomodo commented 6 years ago

I think method File.GetAttributes(string path) is used, which triggers path validation. To skip path validation, this should be used: File.GetAttributes(string path, PathFormat.LongFullPath) from Duplicati.

shiek commented 6 years ago

Thank you. I found a dirty workaround for the AlphaFS-dev issue:

--- "AlphaFS/Filesystem/File Class/File.Create.cs"     2018-03-05 01:47:48.000000000 +0100
+++ "AlphaFS/Filesystem/File Class/File.Create.cs"       2018-03-07 22:10:43.035875300 +0100
@@ -310,7 +310,7 @@
       {
          if (checkPath && pathFormat == PathFormat.RelativePath)

-            Path.CheckSupportedPathFormat(path, true, true);
+            Path.CheckSupportedPathFormat(path, false, false);

          // When isFile == null, we're working with a device.
--- "AlphaFS/Filesystem/File Class/File.GetAttributes.cs"      2018-03-05 01:47:48.000000000 +0100
+++ "AlphaFS/Filesystem/File Class/File.GetAttributes.cs"        2018-03-07 22:00:32.654817300 +0100
@@ -89,7 +89,7 @@
       internal static T GetAttributesExCore<T>(KernelTransaction transaction, string path, PathFormat pathFormat, bool returnErrorOnNotFound)
       {
          if (pathFormat == PathFormat.RelativePath)
-            Path.CheckSupportedPathFormat(path, true, true);
+            Path.CheckSupportedPathFormat(path, false, false);

          var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars);
shiek commented 6 years ago

After the workaround I get the old UnauthorizedAccessException I always had - now also with AlphaFS-dev:

System.UnauthorizedAccessException: (5) Zugriff verweigert: [\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy11\cygwin\home\user\.bash_history]
   bei Alphaleonis.Win32.NativeError.ThrowException(UInt32 errorCode, String readPath, String writePath)
   bei Alphaleonis.Win32.Filesystem.NativeMethods.IsValidHandle(SafeHandle handle, Int32 lastError, String path, Boolean throwException)
   bei Alphaleonis.Win32.Filesystem.File.CreateFileCore(KernelTransaction transaction, String path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, Boolean checkPath, Boolean continueOnException, PathFormat pathFormat)
   bei Alphaleonis.Win32.Filesystem.File.OpenCore(KernelTransaction transaction, String path, FileMode mode, FileSystemRights rights, FileShare share, ExtendedFileAttributes attributes, Nullable`1 bufferSize, FileSecurity security, PathFormat pathFormat)
   bei Duplicati.Library.Snapshots.SystemIOWindows.FileOpenRead(String path)
   bei Duplicati.Library.Snapshots.WindowsSnapshot.OpenRead(String file)
   bei Duplicati.Library.Main.Operation.BackupHandler.HandleFilesystemEntry(ISnapshotService snapshot, BackendManager backend, String path, FileAttributes attributes)

also similar:

System.UnauthorizedAccessException: (5) Zugriff verweigert: [\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy11\cygwin\home\user\.ssh]
   bei Alphaleonis.Win32.NativeError.ThrowException(UInt32 errorCode, String readPath, String writePath)
   bei Alphaleonis.Win32.Filesystem.FindFileSystemEntryInfo.ThrowPossibleException(UInt32 lastError, String pathLp)
   bei Alphaleonis.Win32.Filesystem.FindFileSystemEntryInfo.FindFirstFile(String pathLp, WIN32_FIND_DATA& win32FindData, Boolean suppressException)
   bei Alphaleonis.Win32.Filesystem.FindFileSystemEntryInfo.<Enumerate>d__84`1.MoveNext()
   bei System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   bei System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   bei Alphaleonis.Win32.Filesystem.Directory.GetDirectories(String path)
   bei Duplicati.Library.Snapshots.WindowsSnapshot.ListFolders(String folder)
   bei Duplicati.Library.Utility.Utility.<EnumerateFileSystemEntries>d__22.MoveNext()
Yomodo commented 6 years ago

Try another File.Open overload using the ExtendedFileAttributes.BackupSemantics to see if it makes a difference: https://github.com/alphaleonis/AlphaFS/blob/ee8c09c7a8d23c257259017024f70492b6623965/AlphaFS/Filesystem/File%20Class/File.Open.cs#L134

You don't get access denied on other file/folder items from those same paths?

shiek commented 6 years ago

Thank you Jeffrey - your comment pointed me into the right direction.

I have a working solution:

https://github.com/duplicati/duplicati/blob/96cd4dd72565c46633c17c7b516706cfd4e6774b/Duplicati/Library/Snapshots/SystemIOWindows.cs#L190

to

https://github.com/shiek/duplicati/blob/3dbe476da38faf197e234c09a607343dba74faab/Duplicati/Library/Snapshots/SystemIOWindows.cs#L190

and I added:

https://github.com/shiek/duplicati/blob/3dbe476da38faf197e234c09a607343dba74faab/Duplicati/Library/Main/Operation/BackupHandler.cs#L961

The process has the "SeBackupPrivilege" but the default is "Disabled".

In the end it's a tricky Cygwin + Windows + Duplicati issue.

Yomodo commented 6 years ago

Glad we could help!