jborean93 / smbprotocol

Python SMBv2 and v3 Client
MIT License
318 stars 73 forks source link

DFS namespace server #142

Closed malthe closed 2 years ago

malthe commented 2 years ago

In Microsoft's documentation on DFS Namespaces, there is a namespace server as the entrypoint:

image

In this situation, "Contoso" is just a namespace and not a server.

Meanwhile, when using a function such as smbclient.listdir on a namespace, the library code tries to connect to Contoso:445 which fails due to DNS resolution.

I don't have a complete picture of how DFS is supposed to work, but it seems to me that the namespace server should be the only machine that needs to be contacted at the outset. Then, if a target is requested (e.g. "Tools" or "Training Guides" in the figure above), then the namespace server resolves that to an actual server and actual share name.

Am I hitting limitations in the DFS support here?

jborean93 commented 2 years ago

Using \\Contoso\Public on Windows usually just works because the client already knows Contoso is a domain name rather than a hostname and it already knows a domain controller of the Contoso domain to query. This query asks the domain what would be the best namespace server to check for this DFS namespace. Internally it adjusts \\Contoso\Public to become \\dfs-server\Public and sends the SMB request to that server.

With smbprotocol it's a bit handicapped as it doesn't already know the domain information of the host so unless you've given that information it is always going to connect to the Contoso as you've requested. To fix this problem you can do

import smbclient

# User and Pass are optional if you've set up Kerberos auth, otherwise it's required
smbclient.ClientConfig(domain_controller='my-dc.contoso.com', username='user', password='pass')

smbclient.listdir(r'\\contoso\Public')

When you provide domain_controller as part of the ClientConfig it will send out the DFS namespace request to determine what namespaces are provided in the domain. Now that the client knows contoso is a DFS namespace when it sees a connection request to Contoso it will substitute that with the proper DFS server as part of the original query.

jborean93 commented 2 years ago

Closing, as per the above.