xebialabs / overthere

Runs something "Over there"

Home Page:http://www.xebialabs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SmbFile.canRead returns STATUS_SHARING_VIOLATION or STATUS_ACCESS_DENIED exceptions when the file is locally opened

zerikv opened this issue · comments

The method SmbFile.canRead() throws the following exception, when the file is opened locally by another application.

com.hierynomus.mssmb2.SMBApiException: STATUS_SHARING_VIOLATION(3221225539/3221225539): Create failed for Temp\test.txt
	at com.hierynomus.smbj.share.Share.receive(Share.java:335)
	at com.hierynomus.smbj.share.Share.sendReceive(Share.java:319)
	at com.hierynomus.smbj.share.Share.createFile(Share.java:134)
	at com.hierynomus.smbj.share.DiskShare.open(DiskShare.java:55)
	at com.xebialabs.overthere.smb.SmbFile.getAccessMask(SmbFile.java:114)
	at com.xebialabs.overthere.smb.SmbFile.canRead(SmbFile.java:98)
	...

To test this case I launch a pending command "more" on the file in a window cmd.exe:

e:\Temp>more test.txt
....
-- Next (42%) --	

As reported by "handle.exe" (https://docs.microsoft.com/en-us/sysinternals/downloads/handle)
the file "E:\Temp\test.txt" is opened by the application more.com with a sharing access FILE_SHARE_READ + FILE_SHARE_WRITE:

------------------------------------------------------------------------------
more.com pid: 9972 DOMAIN\USER
   38: File  (RW-)   E:\Temp
   94: File  (R-D)   C:\Windows\System32\fr-FR\ulib.dll.mui
   9C: File  (RW-)   E:\Temp\test.txt

In this case the method SmbFile.canRead() should returns true.

In the method SmbFile.getAccessMask() the request access used for open the file is MAXIMUM_ALLOWED,
that seems to high, when requesting only with the access GENERIC_READ the file can be opened with success.

In the same way for the method SmbFile.canExecute() we have to request the access GENERIC_EXECUTE.

For the method SmbFile.canWrite() with the access GENERIC_WRITE we get an other exception:

com.hierynomus.mssmb2.SMBApiException: STATUS_ACCESS_DENIED(3221225506/3221225506): QueryInfo failed for SMB2FileId{persistentHandle=97 27 00 00 14 00 00 00}
	at com.hierynomus.smbj.share.Share.receive(Share.java:335)
	at com.hierynomus.smbj.share.Share.sendReceive(Share.java:319)
	at com.hierynomus.smbj.share.Share.queryInfo(Share.java:161)
	at com.hierynomus.smbj.share.DiskShare.getFileInformation(DiskShare.java:210)
	at com.hierynomus.smbj.share.DiskEntry.getFileInformation(DiskEntry.java:60)
	at com.hierynomus.smbj.share.DiskEntry.getFileInformation(DiskEntry.java:56)
	at com.xebialabs.overthere.smb.SmbFile.getAccessMask(SmbFile.java:117)
	at com.xebialabs.overthere.smb.SmbFile.canWrite(SmbFile.java:106)
    ....

The file has been successfully opened (with the SMB2 message CREATE) but the message QUERY_INFO failed.
I work out that the read access must be also requested in order that information about the file could be read.
So for SmbFile.canWrite we have to request the access: GENERIC_READ+ GENERIC_WRITE.

Other case, if the account has no right on the file, SbmFile.canRead cannot open the file and fails with the error STATUS_ACCESS_DENIED.
I think in this case it's better to catch the exception and return false.

I'm preparing a PR for these issues.

Eric

Makes sense, thanks @zerikv!

If you've got any comments for SMBJ, don't hesitate to let me know 👍