jordanlytle / SmbAbstraction

Implements the System.IO.Abstractions interfaces for interacting with the filesystem, and adds support for interacting with UNC or SMB paths
MIT License
6 stars 8 forks source link

SmbAbstraction requires having access at all levels #36

Open fayilt opened 4 years ago

fayilt commented 4 years ago

Hi,

Looks like SmbAbstraction doesn't work in situations when the user has access to a folder, but no access to one of the higher level folders. For example, if I'm accessing this file: \server1\share1$\folder1\subfolder1\file1.txt

When you create SMBFileInfo, it'll also try to create IDirectoryInfo by calling FromDirectoryName for the folder where the file is. That call will also try to get the parent folder info etc.. if you don't have access at any of the levels, it'll fail with STATUS_ACCESS_DENIED error. This is the line in SMBDirectoryInfoFactory that's not working (line 86):

status = fileStore.CreateFile(out handle, out FileStatus fileStatus, relativePath, AccessMask.GENERIC_READ, 0, ShareAccess.Read, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, null);

It works ok if we just use SMBLibrary (or SMBLibraryLight). Is there any reason why it needs to recursively get information about every level in the path?

jordanlytle commented 4 years ago

I believe IFileInfo needs to store information about its parent directory which is why it needs access. I can look into it some more later and double check.

fayilt commented 4 years ago

Thanks @jordanlytle , would be nice to change this so it doesn't require access to all the levels

jordanlytle commented 4 years ago

Looking into it further, I was correct. It needs access because the IFileInfo interface is expected to contain information about the parent directory.

From https://github.com/System-IO-Abstractions/System.IO.Abstractions/blob/master/System.IO.Abstractions/IFileInfo.cs#L45-L48

/// <inheritdoc cref="FileInfo.Directory"/>
IDirectoryInfo Directory { get; }
/// <inheritdoc cref="FileInfo.DirectoryName"/>
string DirectoryName { get; }

In theory, we could change it to set it up with empty values, but that seems like it could hide genuine errors. I'm also not sure what the use case is that would necessitate having access only to a file but not to any of the parent folders. Can you provide any more information as to why that might be needed?

fayilt commented 4 years ago

Thanks for checking.

In our case IFileInfo requiring info about the holding folder isn't a problem (although it might be if you have access only to the file, but not the folder - it's possible in theory I think).

The problem for us is that IDirectoryInfo requires info about its parent. I think the properties (IFileInfo.Directory, IDirectoryInfo.Parent & IDirectoryInfo.Root) should return values on demand, and they shouldn't recursively populate all these properties when initialising. How about a Lazy<> implementation? This would improve performance too. Please let me know what you think.

fayilt commented 4 years ago

You also asked for more information as to why this is needed. The answer is simple, in our company (and others I worked for too) it is possible to have access to a folder, without having access to one of its parents. That's the current setup and I'm not able to use SmbAbstraction because of this. I can't possibly ask them to give me access at the top level because the library I want to use requires this.

jordanlytle commented 4 years ago

Hmm, sounds like this behavior is due to the Bypass Traverse Checking right, which I was unaware of. I'll have to do some more testing to see how this is handled by the System.IO.Abstractions implementation of IFileSystem from a Windows client so that we can mirror that as closely as possible.

I'm hesitant to implement any kind of lazy loading since the credential that was provided when the initial call was made may no longer exist when the consumer tries to access those properties, but that could be an option.

Can you provide any more information as to what permissions the user has to the parent folders / share and what permissions they have to the folder they are trying to access? That would help me to reproduce this scenario more quickly.

jogibaeratvega commented 3 years ago

Hi @jordanlytle,

we try to realize a file-share access (write files to a windows file-share) from an API running in Docker. You library seemed to be a good solution but we came up with the same issues like @fayilt mentioned. We got a user with read/write access to the folder but not on the file-share-server itself. When I try it with my credentials (admin), I'm able to read/write to the file-share.

I wanted to ask, whether you got some news or if you still need Information about the permissions of the user on the file-share?

EDIT: Okay it seems like it's not the same problem as fayilt mentioned. I receive an STATUS_LOGON_FAILURE for that user.

jordanlytle commented 3 years ago

@jj707 I think you are correct about your problem being different from the one being discussed here. It sounds like an incorrect username or password. As long as the user you login as has access to the share you shouldn't run into this issue.