Skip to content

Commit

Permalink
Try to replace path for DFS renames
Browse files Browse the repository at this point in the history
  • Loading branch information
jborean93 committed Aug 22, 2022
1 parent db1f042 commit a4dd204
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/smbclient/_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -1109,9 +1109,11 @@ def _rename_information(src, dst, replace_if_exists=False, **kwargs):
# We open/close the dest (ignoring if the file does not exist) so we can resolve the DFS path and determine the
# filename src needs to be renamed to.
dst_raw = SMBRawIO(dst, desired_access=FilePipePrinterAccessMask.FILE_EXECUTE, **raw_args)
dst_open_failed = False
try:
SMBFileTransaction(dst_raw).commit()
except SMBOSError as err:
dst_open_failed = True
if err.errno != errno.ENOENT:
raise

Expand All @@ -1128,6 +1130,14 @@ def _rename_information(src, dst, replace_if_exists=False, **kwargs):
if src_guid != dst_guid or src_share.lower() != dst_share.lower():
raise ValueError("Cannot %s a file to a different root than the src." % verb)

dst_name = dst_raw.fd.file_name
dst_tree = dst_raw.fd.tree_connect
if dst_open_failed and dst_tree.is_dfs_share and dst_name.startswith(dst_tree.share_name[2:]):
# If the dst failed to open we can't rely on dst_raw.fd.file_name
# to have the correct path. It should theorectically work due to
# remote DFS normalisation but it seems like this is still needed.
dst_name = dst_name[len(dst_tree.share_name) - 1 :]

with SMBFileTransaction(src_raw) as transaction:
file_rename = FileRenameInformation()
file_rename["replace_if_exists"] = replace_if_exists
Expand Down

0 comments on commit a4dd204

Please # to comment.