Bug 14169 - Renaming file on DFS root fails with NT_STATUS_OBJECT_PATH_NOT_FOUND
Summary: Renaming file on DFS root fails with NT_STATUS_OBJECT_PATH_NOT_FOUND
Status: ASSIGNED
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: libsmbclient (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Jeremy Allison
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-10-22 12:53 UTC by Christoph Ziebuhr
Modified: 2020-07-10 12:33 UTC (History)
0 users

See Also:


Attachments
Tree Connect Response (89.83 KB, image/png)
2019-10-23 08:57 UTC, Christoph Ziebuhr
no flags Details
SetInfo Request with SMB2_FILE_RENAME_INFO (88.82 KB, image/png)
2019-10-23 08:59 UTC, Christoph Ziebuhr
no flags Details
SetInfo Response (58.21 KB, image/png)
2019-10-23 09:00 UTC, Christoph Ziebuhr
no flags Details
pcap of failed rename to NetApp (10.12 KB, application/vnd.tcpdump.pcap)
2019-10-23 09:28 UTC, Christoph Ziebuhr
no flags Details
pcap of successful rename from windows 10 client to windows server (19.57 KB, application/vnd.tcpdump.pcap)
2019-10-23 09:44 UTC, Christoph Ziebuhr
no flags Details
git-am prototype fix for master. (5.07 KB, patch)
2019-10-23 12:16 UTC, Jeremy Allison
no flags Details
updated git-am fix for master. (5.83 KB, patch)
2019-10-23 14:04 UTC, Jeremy Allison
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Christoph Ziebuhr 2019-10-22 12:53:44 UTC
If a file is stored directly on a DFS enabled share, renaming fails with NT_STATUS_OBJECT_PATH_NOT_FOUND.
The usecase may sound unusual, but a customer is using NetApp ONTAP 9, which by default advertises DFS capabilities for all shares, and he cannot disable it for policy reasons.
I can also reproduce the issue with smbd and Windows Server 2012 R2 (haven't checked with other versions).

IMHO it is caused by:
- Not setting SMB2_HDR_FLAG_DFS when calling smb2cli_req_send() from smb2cli_set_info_send()
- cli_resolve_path() returning a full dfs path for the destination, which is then passed to cli_rename() to be used in SMB2_FILE_RENAME_INFO

After some patching and testing, I came to this conclusion:

Setting SMB2_HDR_FLAG_DFS solves the issue for smbd, but not for Windows Server and not for NetApp.
It seems that the file name in SMB2_FILE_RENAME_INFO must always be a non-dfs path and the header flag is ignored:
- A windows client uses a non-dfs path, but sets the header flag
- Linux kernel also uses a non-dfs path and doesn't set the header flag

This means, path handling for cli_rename() needs to be changed.
IMHO there are two possibilities:
- Extend cli_resolve_path() to be able to also return a non-dfs path
- Strip server/share from fname_dst in cli_rename(), e.g. with parse_dfs_path() from smbd
Comment 1 Christoph Ziebuhr 2019-10-23 08:57:55 UTC
Created attachment 15564 [details]
Tree Connect Response

DFS capability is advertised. NetApp doesn't set DFS share flags (which is also not required and out of scope for this report).
Comment 2 Christoph Ziebuhr 2019-10-23 08:59:44 UTC
Created attachment 15565 [details]
SetInfo Request with SMB2_FILE_RENAME_INFO

DFS flag is not set. Filename in SMB2_FILE_RENAME_INFO is a full dfs path.
Comment 3 Christoph Ziebuhr 2019-10-23 09:00:49 UTC
Created attachment 15566 [details]
SetInfo Response

Rename failed with STATUS_OBJECT_PATH_NOT_FOUND
Comment 4 Ralph Böhme 2019-10-23 09:03:34 UTC
Can you please also upload a trace showing the traffic between a Windows client and a Windows server, so we peek how exactly Windows does it? Thanks.
Comment 5 Christoph Ziebuhr 2019-10-23 09:28:04 UTC
Created attachment 15567 [details]
pcap of failed rename to NetApp
Comment 6 Christoph Ziebuhr 2019-10-23 09:44:45 UTC
Created attachment 15568 [details]
pcap of successful rename from windows 10 client to windows server
Comment 7 Jeremy Allison 2019-10-23 12:16:04 UTC
Created attachment 15569 [details]
git-am prototype fix for master.
Comment 8 Christoph Ziebuhr 2019-10-23 13:16:31 UTC
Works for me. Haven't checked with smb1 though.
The commit message for smb1/smb2 seems to be interchanged.
By the way: Found a function cli_ntrename() which is not called anywhere. Is it still required or just there for compability with older applications?
Comment 9 Jeremy Allison 2019-10-23 13:41:14 UTC
Thanks - this is a prototype patch so I'll fix that up and add a test (at least SMB2-only:-) before proposing this for an actual fix.

Thanks for confirming it fixes the issue against NetApp (I tested it locally against Samba but don't have access to a NetApp).
Comment 10 Jeremy Allison 2019-10-23 13:54:59 UTC
Yes, cli_ntrename() isn't used anywhere - it just maps onto cli_ntrename_internal() which is used by the hardlink code. I'll still add a fix for it into the patchset, it's easy enough to do. Thanks for testing !
Comment 11 Christoph Ziebuhr 2019-10-23 13:59:33 UTC
I now have another issue: if the destination already exists I get STATUS_OBJECT_PATH_SYNTAX_BAD (in version 4.5.16, haven't checked with master yet)
Comment 12 Jeremy Allison 2019-10-23 14:04:38 UTC
Created attachment 15570 [details]
updated git-am fix for master.
Comment 13 Jeremy Allison 2019-10-23 14:09:47 UTC
In 4.5.x cli_smb2_rename() doesn't use the 'replace' paramter - it's missing from the cli_rename() call.

In master it does, you add the '-f' parameter to force overwrite (cli_rename() takes an extra 'replace' parameter, set if you add -f to the command line in smbclient).
Comment 14 Christoph Ziebuhr 2019-10-23 16:27:52 UTC
Ignore comment #11. My local build- and test-environment was broken.