Closed karan-lb closed 12 months ago
Sorry I'm not ignoring this, just haven't had time to look into it. Unfortunately DFS is a complex topic so might take some time to try and replicate and figure out where the problem is.
@jborean93 please let me know if you need any details about the setup. It was easy to repro this in-house using a 2 node setup with a fully replicated DFS namespace across both nodes.
Sorry for the delay getting to this issue, the PR https://github.com/jborean93/smbprotocol/pull/239 fixes the recursion problem by ensuring it won't retry a target that has already been tried. I was able to replicate the problem in my environment and I can confirm the changes in that PR ensure the correct exception is raised.
Hi, we have a 3 node DFS SMB server that we are trying to traverse. The DFS server exposes 4 namespaces that are fully replicated over all nodes. This means that every node holds all the files that are present in the namespace. When we try to lstat a file which exists, the code is working well and we don't see any issue. The DFS referrals are not involved there as all files do exist on each node.
Issue: When we try to lstat a file path that does not exist on the DFS server the smbclient gets into an infinite recursion. The trace for which looks as follows: Notice the frame repeats till we interrupt the process.
File "/usr/local/lib/python3.7/site-packages/smbclient/_io.py", line 335, in commit self.commit() [Previous line repeated 38 more times]
We notice that the referrals being returned by the server keep rotating between a couple of nodes and its gets into this infinite loop. Server A refers to Server B and then it refers back and so forth. Since the namespace does indeed exist on all three nodes that does make sense, but for deleted files there is no condition to make the recursion stop. (Ideally it should stop when we get to a node that we have already been referred before?)
Possible solution: We did notice that the
ClientConfig
does contain an optionskip_dfs
to avoid processing any referrals, but that option doesn't work for our case. We still see infinite recursion happening.If the skip_dfs option worked, it would solve the crash for our case as any single node of the DFS server is fully capable to serve all files in the server.
So, we notice in the method, we can return early if the tree connect is not a DFS share. So we plan to toggle the
is_dfs_share
capability returned by the server to False when ClientConfig hasskip_dfs
set to True by the client.We do the above by modifying the following code in
_pool.py
and in
tree.py
:This does help us in honoring the
skip_dfs
field, but we wanted to know