dokan-dev / dokany

User mode file system library for windows with FUSE Wrapper
http://dokan-dev.github.io
5.2k stars 661 forks source link

Access denied, when using remote desktop #920

Closed martin5233 closed 4 years ago

martin5233 commented 4 years ago

Environment

Check List

Description

I have implemented a fuse-based filesystem, which works well on many machines, when logged in locally. However, if I run the same program via remote desktop or as a Jenkins job, Windows denies the access to the volume to each of the worker threads. I have passed the debug flag to the fuse implementation and got the following output, when running on a remote machine:

stderr:
Dokan: debug mode on
Dokan: use stderr
AllocationUnitSize: 512 SectorSize: 512
device opened
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
CreateMountPoint C:/temp/VD.281536/mnt -> \??\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}\ success
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
mounted: C:/temp/VD.281536/mnt -> \Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}
Mounted
Dokan Error: CreateFile failed \\.\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}: 5
Unmount

When doing the same logged in locally, the following output occurs and everything works as expected:

Dokan: debug mode on
Dokan: use stderr
AllocationUnitSize: 512 SectorSize: 512
device opened
CreateMountPoint C:/Users/<username deleted>/AppData/Local/Temp/VD.704801/mnt -> \??\Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}\ success
###QueryVolumeInfo -001
GetVolumeInformation
mounted: C:/Users/<username deleted>/AppData/Local/Temp/VD.704801/mnt -> \Volume{d6cc17c5-1734-4085-bce7-964f1e9f5de9}
Mounted
###Create 0000
CreateFile: \
    DesiredAccess: SYNCHRONIZE|FILE_READ_DATA
    ShareAccess: FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ
...

I have tried this on different machines with different OS levels varying from Windows Server 2012R2 up to Windows 10 V1903, but the result is always the same. From looking at the source code, I think the error occurs in DokanLoop, where each thread tries to access the volume via CreateFile in order to call DeviceIOControl afterwards, but for some reason Windows denies the access to the volume, if logged in remotely. I have tried to replicate this with the mirror example, but the mirror example does not build with Visual Studio, I cannot use cygwin for this.

Any idea what's going on here or how to circumvent this?

Liryna commented 4 years ago

@martin5233 Hi,

Have you tried with the mirror sample? I would imagine to fail too. Just wanna know what flags are you using here.

Have you tried with the mount manager option? It is /o for the mirror and dokan fuse also propose it but I can't remember exactly (in my phone now).

martin5233 commented 4 years ago

Hi Liryina,

thanks for your quick reply. I have tried the mirror sample, but there it works. Running "mirror.exe /r C:\temp \l C:\users\mal1\test \d \s" gives the following output:

## Attempting to add SE_SECURITY_NAME privilege to process token ##
  failed: Unable to adjust token privileges: 1300
[Mirror] Failed to add security privilege to process
        => GetFileSecurity/SetFileSecurity may not work properly
        => Please restart mirror sample with administrator rights to fix it
Dokan: debug mode on
Dokan: use stderr
AllocationUnitSize: 512 SectorSize: 512
device opened
CreateMountPoint C:\users\<user>\test -> \??\Volume{d6cc17c5-1727-4085-bce7-964f1e9f5de9}\ success
mounted: C:\users\<user>\test -> \Volume{d6cc17c5-1727-4085-bce7-964f1e9f5de9}
Mounted
###Create 0000
CreateFile : C:\temp\
  AccountName: mal1, DomainName: DSONE
        ShareMode = 0x3
        FILE_SHARE_READ
        FILE_SHARE_WRITE
        DesiredAccess = 0x100080
        FILE_READ_ATTRIBUTES
        SYNCHRONIZE
        FlagsAndAttributes = 0x0
        OPEN_EXISTING
...

I haven't tried the mount manager option yet, as I do not assume, that this is a bug, but rather a Windows permission problem somehow. What I don't understand is, why it works with the mirror example.

Liryna commented 4 years ago

@martin5233 That's surprising it is working. Was it running / started the same way as the fuse fs?

martin5233 commented 4 years ago

I have started the mirror executable from the command line by hand. For the other test I used 'ctest', which comes with CMake to run any tests. But I did this for both the successful local runs and the failing remote ones, so I don't think, that this has any influence.

Liryna commented 4 years ago

@martin5233 Are those machine freshly installed or there is anti-virus and other software running?

martin5233 commented 4 years ago

The machines are not freshly installed and there is anti-virus software running. But the thing is, that on exactly the same machine exactly the same program runs without problems, when logged in locally. I think there must some Windows setting, which removes certain permissions from a user, when logged in via remote desktop (which also applies, when a program is run on a Jenkins slave installed as a service). I will try with the mount manager as the next step.

martin5233 commented 4 years ago

@Liryna: I have now also checked using the mount manager option, but the result is the same as without the option.

Liryna commented 4 years ago

The disk is created with this SDDL https://github.com/dokan-dev/dokany/blob/f7161d7f760f8bf3597c0597066192363b4d470c/sys/dokan.h#L1104-L1105 Let me know if that would be the reason you get access denied in your running context and what exactly.

martin5233 commented 4 years ago

@Liryna: I dived into the realm of Windows access control and dumped out the security tokens in a debugger, immediately before issuing the first fuse call. I did this both for the local and the remote case and attached the generated information. As expected both differ slightly. The local output looks as follows:

Thread is not impersonating. using process token...
TS Session ID: 0x1
User: S-1-5-21-2455101938-2081098319-3243300316-652557 (User: <Domain>\<Username>)
User Groups:
 00 S-1-5-21-2455101938-2081098319-3243300316-513 (Group: <Domain>\Domain Users)
    Attributes - Mandatory Default Enabled
 01 S-1-1-0 (Well Known Group: localhost\Everyone)
    Attributes - Mandatory Default Enabled
 02 S-1-5-32-544 (Alias: BUILTIN\Administrators)
    Attributes - DenyOnly
 03 S-1-5-32-545 (Alias: BUILTIN\Users)
    Attributes - Mandatory Default Enabled
 04 S-1-5-32-559 (Alias: BUILTIN\Performance Log Users)
    Attributes - Mandatory Default Enabled
 05 S-1-5-4 (Well Known Group: NT AUTHORITY\INTERACTIVE)
    Attributes - Mandatory Default Enabled
 06 S-1-2-1 (Well Known Group: localhost\CONSOLE LOGON)
    Attributes - Mandatory Default Enabled
 07 S-1-5-11 (Well Known Group: NT AUTHORITY\Authenticated Users)
    Attributes - Mandatory Default Enabled
 08 S-1-5-15 (Well Known Group: NT AUTHORITY\This Organization)
    Attributes - Mandatory Default Enabled
 09 S-1-5-5-0-631282 Unrecognized SID    Attributes - Mandatory Default Enabled LogonId
 10 S-1-2-0 (Well Known Group: localhost\LOCAL)
Privs:
 00 0x000000013 SeShutdownPrivilege               Attributes -
 01 0x000000017 SeChangeNotifyPrivilege           Attributes - Enabled Default
 02 0x000000019 SeUndockPrivilege                 Attributes -
 03 0x000000021 SeIncreaseWorkingSetPrivilege     Attributes -
 04 0x000000022 SeTimeZonePrivilege               Attributes -
Auth ID: 0:9a771
Impersonation Level: Anonymous
TokenType: Primary
Is restricted token: no.
SandBoxInert: 0
Elevation Type: 3 (Limited)
Mandatory Policy: TOKEN_MANDATORY_POLICY_VALID_MASK
Integrity Level: S-1-16-8192 (Label: Mandatory Label\Medium Mandatory Level)
    Attributes - GroupIntegrity GroupIntegrityEnabled
Process Trust Level:   LocalDumpSid failed to dump Sid at addr 00000088f84988b8, 0xC0000078; try own SID dump.
s-1-0 ConvertSidToFriendlyName on failed with error code 0x80000057
    Attributes -
Token Virtualized: Disabled
UIAccess: 0
IsAppContainer: 0
Security Attributes Information:
 00 Attribute Name: TSA://ProcUnique
    Value Type  : TOKEN_SECURITY_ATTRIBUTE_TYPE_UINT64
    Value[0]    : 262
    Value[1]    : 508880315
Device Groups:

and the remote:

Thread is not impersonating. Using process token...
TS Session ID: 0x2
User: S-1-5-21-2455101938-2081098319-3243300316-652557 (User: <Domain>\<Username>)
User Groups:
 00 S-1-5-21-2455101938-2081098319-3243300316-513 (Group: <Domain>\Domain Users)
    Attributes - Mandatory Default Enabled
 01 S-1-1-0 (Well Known Group: localhost\Everyone)
    Attributes - Mandatory Default Enabled
 02 S-1-5-32-544 (Alias: BUILTIN\Administrators)
    Attributes - DenyOnly
 03 S-1-5-32-545 (Alias: BUILTIN\Users)
    Attributes - Mandatory Default Enabled
 04 S-1-5-14 (Well Known Group: NT AUTHORITY\REMOTE INTERACTIVE LOGON)
    Attributes - Mandatory Default Enabled
 05 S-1-5-4 (Well Known Group: NT AUTHORITY\INTERACTIVE)
    Attributes - Mandatory Default Enabled
 06 S-1-5-11 (Well Known Group: NT AUTHORITY\Authenticated Users)
    Attributes - Mandatory Default Enabled
 07 S-1-5-15 (Well Known Group: NT AUTHORITY\This Organization)
    Attributes - Mandatory Default Enabled
 08 S-1-5-5-0-613430 Unrecognized SID    Attributes - Mandatory Default Enabled LogonId
 09 S-1-2-0 (Well Known Group: localhost\LOCAL)
Attributes - Mandatory Default Enabled
 124 S-1-16-8192 (Label: Mandatory Label\Medium Mandatory Level)
    Attributes - GroupIntegrity GroupIntegrityEnabled
Primary Group: S-1-5-21-2455101938-2081098319-3243300316-513 (Group: <Domain>\Domain Users)
Privs:
 00 0x000000013 SeShutdownPrivilege               Attributes -
 01 0x000000017 SeChangeNotifyPrivilege           Attributes - Enabled Default
 02 0x000000019 SeUndockPrivilege                 Attributes -
 03 0x000000021 SeIncreaseWorkingSetPrivilege     Attributes -
 04 0x000000022 SeTimeZonePrivilege               Attributes -
Auth ID: 0:95e67
Impersonation Level: Anonymous
TokenType: Primary
Is restricted token: no.
SandBoxInert: 0
Elevation Type: 3 (Limited)
Mandatory Policy: TOKEN_MANDATORY_POLICY_VALID_MASK
Integrity Level: S-1-16-8192
Process Trust Level: (null)
Token Virtualized: Disabled
UIAccess: 0
IsAppContainer: 0
Device Groups:

But anyway as far as I understood the SDDL string, it grants generic access rights to the world, so I don't see, why an access should ever fail.

Liryna commented 4 years ago

OK that must an application that returns the failure and not the dokan driver. Why difference when rdp and local is used? Thats something they only have the answer.

You might be able to use procmon and find out in the stack who is answering this status.

martin5233 commented 4 years ago

@Liryna: I tried procmon before, but it seems, that it does not dump the file access of each worker thread at all. When I step through the code in a debugger, I can see the CreateFile call in DokanLoop failing, but this call never appears in procmon. The only thing I see in procmon, is that 10 threads are created, each of them tries to access the registry key HKLM\SOFTWARE\Policies\Microsoft\Windows\RemovableStorageDevices (which does not exist) and then the thread exits again. I can even see, that the registry access comes from within CreateFile from the stack trace, but the CreateFile is never recorded by procmon. I suspect, that procmon itself is susceptible to the same permission problem, which makes it rather useless. Do you know, if it's possible to use accesschk on volumes? I tried, but it always tells me, that it cannot find the object I passed for the volume.

martin5233 commented 4 years ago

@Liryna: I finally managed to reproduce the problem with the mirror example. It only occurs, if you pass it the /m option to mark the volume as a removable drive. This is always the case, if you use fuse and don't use a network drive. I assume, that generally remote users don't have the permission to access removable drives, so this is, why it works locally, but not remotely.

Liryna commented 4 years ago

@martin5233 Ah awesome that's a good news and we'll found! That's probably something that should be added to the API documentation.

martin5233 commented 4 years ago

@Liryna: You might also consider, if a fuse volume should automatically be marked as a removable volume, if it's not a network drive.

martin5233 commented 4 years ago

@Liryna: Just a final note: I could now get it to work via the fuse interface by marking the drive as a network drive. Thanks a lot for your great support!

Liryna commented 4 years ago

Thanks @martin5233 I will add some doc on the option. From https://github.com/dokan-dev/dokany/issues/843, seems like it is possible to use removable drive but from a service is that something you would try ?

Liryna commented 4 years ago

Duplicate of https://github.com/dokan-dev/dokany/issues/843 @martin5233 we can continue there if you would like.

martin5233 commented 4 years ago

@Liryna: For me using a network mount seems to be fine, using a service is not possible in the context I need.