Skip to content

Commit

Permalink
Fix DFS recurision for missing files (#239)
Browse files Browse the repository at this point in the history
The code that handles a missing path does not currently record existing
DFS target servers that have been tried resulting in a recursion error.
By ensuring a DFS target is only retried if it hasn't already it should
avoid this recursion problem.

Fixes: #228
  • Loading branch information
jborean93 authored Sep 5, 2023
1 parent 72eed28 commit b8c76d0
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Fix up pre authenticated session id lookups that were failing with Linux ksmbd
* Removes `logging.NullHandler()` being set in the root `smbprotocol` namespace
* Adds basic support for remote to local and vice versa file operations with `smbclient.shutil.copytree`
* Fixes DFS infinite recursion error when dealing with a file that does not exist on a DFS namespace

## 1.10.1 - 2022-11-14

Expand Down
9 changes: 9 additions & 0 deletions src/smbclient/_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ def __init__(self, raw):
self.raw = raw
self.results = None
self._actions = []
self._attempted_dfs_paths = set()

def __add__(self, other):
send_msg = other[0]
Expand Down Expand Up @@ -306,6 +307,14 @@ def commit(self):
if smb_open.tree_connect.share_name == self.raw.fd.tree_connect.share_name:
continue

# Ensure we don't continuously try the same DFS referral targets if it's already been attempted.
# https://github.com/jborean93/smbprotocol/issues/228
tested_path = f"{smb_open.tree_connect.share_name}{smb_open.file_name}".lower()
if tested_path in self._attempted_dfs_paths:
continue

self._attempted_dfs_paths.add(tested_path)

self.raw.fd = smb_open

# In case this is a transaction with an explicit open we want to reopen it with the new params
Expand Down
7 changes: 7 additions & 0 deletions tests/test_smbclient_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -2131,3 +2131,10 @@ def test_broken_dfs_path(smb_real):
# error and that it doesn't continuously loop.
with pytest.raises(SMBOSError):
smbclient.listdir(dfs_path, username=smb_real[0], password=smb_real[1], port=smb_real[3])


def test_dfs_nonexisting_path(smb_dfs_share):
fake_file = ntpath.join(smb_dfs_share, "missing file.txt")

with pytest.raises(SMBOSError):
smbclient.lstat(fake_file)

0 comments on commit b8c76d0

Please sign in to comment.