Open Sagar-Singari opened 3 years ago
Hi @bobsag,
Listing all shares is done using an RPC call and has been implemented in https://github.com/rapid7/smbj-rpc
Do note that this is pretty old, and does not work with the current master anymore.
It might be worth porting this into smbj, but I could definitely use some help there ;)
I'm asking this here because the last activity in smbj-rpc was 2 years ago.
smbj-rpc does work for me as long as I don't use encrypted SMB3. If I use SMB3 via the call config = SmbConfig.builder().withDialects(SMB2Dialect.SMB_3_1_1, SMB2Dialect.SMB_3_0_2, SMB2Dialect.SMB_3_0, SMB2Dialect.SMB_2_1, SMB2Dialect.SMB_2_0_2).withMultiProtocolNegotiate(true).build(); then I get VERY strange behaviour: To list shares, the client connects to IPC$ by sending SMB2_TREE_CONNECT, then SMB2_CREATE, then SMB2_IOCTL. The first two of these can be sent encrypted. But when I send the 3rd encrypted, I get back STATUS_INVALID_PARAMETER error (0XC000000D). When I send the first two encrypted and the last unencrypted by changing the function send(SMB2Packet packet) in Session.java from if (shouldEncryptData()) to if (shouldEncryptData() && !packet.getHeader().getMessage().equals(SMB2MessageCommandCode.SMB2_IOCTL)) then the RPC call goes through just fine, and I get the list of shares. Of course this doesn't work when I disallow unencrypted data on the server side via Powershell: $Set-SmbServerConfiguration -EncryptData $true
So does anyone have an idea why the SMB2_IOCTL packet cannot be sent encrypted? This doesn't make any sense to me.
For others who find this via google search, example of listing shares using the dcerpc module:
add dep
<dependency>
<groupId>com.rapid7.client</groupId>
<artifactId>dcerpc</artifactId>
<version>0.10.0</version>
</dependency>
Usage:
final SMBClient smbClient = new SMBClient();
try (final Connection smbConnection = smbClient.connect("www.yyy.xxx.zzz")) {
final AuthenticationContext smbAuthenticationContext = new AuthenticationContext("username", "password".toCharArray(), "domain");
final Session session = smbConnection.authenticate(smbAuthenticationContext);
final RPCTransport transport = SMBTransportFactories.SRVSVC.getTransport(session);
final ServerService serverService = new ServerService(transport);
final List<NetShareInfo0> shares = serverService.getShares();
for (final NetShareInfo0 share : shares) {
System.out.println(share);
}
}
Sounds like this issue should be closed, and a new Issue should be created about the SMB3 support.
smbj-rpc can list all file shares(or more),but it just support smbj 0.10.0. i don't know what's new in 0.11.1
i found that smbj-0.11.1 delete this method:Connection.getConfig and smbj-rpc use this method,it make this exception
smbj-rpc i have change some new api call in smbj-rpc to support smbj-0.11.1. i hope it can help others who find this via google search.
Dear hierynomus, Dear team,
i'a also struggle with problem discussed in this stream.. I am using a smb-server that uses DFS. When i use to protocol dialect 3.1.1 i always get a null-pointer exception when is try get access to an file that resides in the dfs shar. Everything works well when i change the smb dialect to 3.0.2. In my detail investigation i found out that the problem arises when the method DFSPathResolver.getReferral submits the IOCTL-Command in oder to resolve the referrer. The returned response packet always returns the status code INVALID_PARAMETER. As i mentioned before, everything works fine when using 3.0.2. I also tested to send the IOCT-Message unencrypted. Also this worked well.
On basis of this observations i started a deeper investigation of the problem. I had a look at the configuration, negotiation results and so on. The only difference that i found out is, that in 3.1.1 a individual encryption algorithm is used instead of the standard algorithm that is used when dealing with 3.0.2.
The behavior is still not clear to me, since the marshaling/unmarshaling is still the same independent of the dialect. Together with the above mention status code it think that the problem is somewhere around the encryption logic. I'am sorry but i was not able to figure out the problem completely.
Do you need any information to reproduce the problem?
I think that the problem is that dialect 3.1.1 has added a parameter or something to the ioctl. I need to dive into the spec to find that.
Dear hierynomus, Dear team,
i think i have found the problem with smb 3.1.1 and dfs. The reason is, that the getMaxPayloadSize() is not computed properly when an encrypted packet is sent. Due to the specification, the smb-server has to check the credits (if an IOCTL-Messsage is sent), which are based on the getMaxPayloadSize() of the transferred packet. In case when an encrypted packet was sent, the result for getMaxPayloadSize() of the wrapped packet was always SINGLE_CREDIT_PAYLOAD_SIZE since the method getMaxPayloadSize() was not overwritten. This lead to a wrong handling of the credits, which in consequence lead to an INVALID_PARAMETER when the IOCTL-Message was sent. If the getMaxPaloadSize is overwritten (the same is done in SignedPacketWarpper) the dfs-access with 3.1.1 works as expected:
You can see my changes in the following code fragment:
public class EncryptedPacketWrapper extends SMB2Packet {
@Override
public int getMaxPayloadSize() {
return packet.getMaxPayloadSize();
}}
The reason why it works ( as described by chrisgch ) is, that the packet is sent unencrypted. In this case. the SignedPacketWrapper is used to send the IOCTL-Messages. Since this class overwrites the getMaxPayloadSize() method as described above it works as expected.
I hope my diagnosis helps.
Best regards Bernd
Hi Bernd, Thanks for the analysis! I've just made a PR with the change in #683. If that builds OK, I will merge it and this should be fixed.
@hierynomus hierynomus Need to list all shares in a SMB location. It gives null pointer error when I try to do it.
Is the functionality implemented yet?
Thanks!