Repository navigation
Calls through a DFS link move the caller's tree, so later paths can hit the wrong share #20
Description
Context
Since #15, every path-taking SmbClient call follows a DFS link inside a share (a folder the server reports with STATUS_PATH_NOT_COVERED). They split into two groups:
- The streaming, handle, watch, and batch calls follow the link beside the caller's tree: the handle or item gets the target share, and the
Treethe caller passed stays on its own share. - The
&mut Treeconvenience calls (list_directory,read_file,write_file,stat,delete_file,rename,create_directory, and friends) still rewrite the caller'sTreein place to point at the link's target share, as they did before Follow DFS links in streaming, handle-opening, batch, and watch calls #15.
Problem
After one of those calls goes through a link, the caller's tree is the target share, so every later path on it is read relative to the target. A file manager that lists \\server\share\data (a link to \\fs02\files) and then goes back to the share root, or into a sibling folder, on the same tree sends those paths to files on fs02.
Usually that's a confusing NOT_FOUND on a folder that exists. When a same-named path exists on the target, it reads, overwrites, renames, or deletes the wrong file. The Docker test dfs_write_and_read_roundtrip relies on the current behavior: it deletes with the target-relative path after the redirect.
Solution
Make the &mut Tree calls follow links the way the rest now do: redirect beside the tree, never rewrite it. The caller's paths then always mean the same thing, and the referral cache keeps repeat calls through a link cheap (one refused CREATE, then a cache hit; see the follow-up issue on skipping that CREATE).
For the implementer
crates/smb2/src/client/mod.rs:on_treeis the wrapper that assigns*tree = moved_to;beside_treeis the one that doesn't. Moving the&mut Treemethods to thebeside_treebehavior is most of the change. Consider whether they still need&mut Treeafterwards (the reconnect pathrecover_treedoes use it).- Update
dfs_write_and_read_roundtripto use share-relative paths throughout, and add a Docker test againstsmb-dfs-rootthat lists the link folder, then lists the share root on the same tree and expects the root's entries. - Update
client/CLAUDE.md§ DFS (the contract) andCHANGELOG.md(behavior change, flagged as breaking for anyone who relied on the rewrite).
Open questions
- Is it OK to change this contract before 1.0? Anyone who relied on the tree moving (paths relative to the target after a first call) would break. I'd take the break: the current behavior is surprising and can hit the wrong file, and a consumer relying on it is unlikely (Cmdr doesn't).
Impact: Browsing back out of a DFS link on the same tree works, and can't read or change a same-named file on the target share · Severity: High (a same-named path on the target gets read, overwritten, or deleted) · Size: M (one wrapper change, a contract change, test updates)
Found while implementing #15.
Activity
chore(deps): smb2 0.27.0, so SMB on DFS namespaces and links uses the…
fix(client)!: a call through a DFS link leaves the caller's tree on i…