Repository navigation
List the DFS namespaces a domain hosts #13
Description
Context
SmbClient::connect_share opens a domain-based DFS namespace like \\example.com\namespace when the caller already
knows its name. SmbClient::list_shares (IPC$ + the srvsvc pipe, NetShareEnumAll) is how a caller discovers what
exists on a server, and against a domain name it legitimately returns zero disk shares: namespaces aren't shares.
MS-DFSC, the referral protocol this crate speaks, has no operation that lists namespaces. That lives in a different
protocol, MS-DFSNM (DFS namespace management), as NetrDfsEnumEx over the netdfs named pipe. The crate already has a
small DCE/RPC layer (crates/smb2/src/rpc/) that does exactly this dance for srvsvc.
crates/smb2/README.md § Limitations lists this as unsupported.
Problem
A person browsing a network in a file manager types \\example.com, sees nothing, and has no way to find out that
\\example.com\projects exists unless someone tells them. Windows Explorer lists a domain's namespaces when you browse
the domain name. This is the exact shape of the first field report that led to namespace-root support: the domain answered, listed no
shares, and the consumer concluded there was nothing there.
Solution
Add a netdfs RPC client beside srvsvc and a public call that returns the namespaces a domain (or a standalone
namespace server) hosts.
For the implementer
- Fetch the spec first:
MS-DFSNMvia thecurlrecipe inAGENTS.md§ "Spec files". ReadNetrDfsEnumEx(the
method list in § 3.1.4 gives its opnum), theDFS_INFO_*levels it returns (§ 2.2.4), and the interface UUID in
§ 1.9. Level 200 (DFS_INFO_200, the namespace name only) is enough to list domain-based namespaces; level 300 adds
standalone ones. crates/smb2/src/rpc/: addnetdfs.rsnext tosrvsvc.rs, reusingmod.rs's BIND / REQUEST / RESPONSE framing and
the fragment reassembly inclient/shares.rs(read_pipe_message,parse_response_fragment). Plain NDR only, as
rpc/CLAUDE.mdexplains.crates/smb2/src/client/: anamespaces.rsmirroringshares.rs(connect IPC$, opennetdfs, bind, call, close),
and a publicSmbClientmethod. Reuse the connection's cached IPC$ tree the wayclient/dfs.rs::get_dfs_referral
does.- For a domain,
NetrDfsEnumExis answered by a DC; the connection to the domain name normally lands on one already, the same
way the root referral does. - Tests: known-bytes NDR tests for the request and a captured response; a mock-transport flow test in the new module.
Samba implementsnetdfsonly partially, so check whethersmb-dfs-namespace(crates/smb2/tests/docker/internal/)
answersNetrDfsEnumExbefore promising a Docker test; the real proof is the Windows setup from the "Verify DFS
namespace roots against a real Windows domain" issue. - Update
README.md§ Limitations,client/CLAUDE.md§ DFS, andrpc/CLAUDE.md.
Open questions
- Where should the namespaces show up in the API? (a) A separate
SmbClient::list_dfs_namespaces()returning
names. (b) Fold them intolist_shares()as entries with a newShareInfokind. (a) keepslist_shareshonest
(it meansNetShareEnumAll, which consumers already understand) and lets a consumer decide when to pay for the
second RPC; (b) is less work for a consumer that only wants "what can I open here?". I'd go with (a) and let Cmdr
merge the two lists in its own UI. - Is this worth doing before the Windows verification lands? It can't be tested for real without a Windows DC, so
I'd sequence it after that issue.
Impact: Makes domain DFS namespaces discoverable instead of only reachable by name · Size: L (a new RPC
interface, NDR encoding for its structures, and a Windows test run)
Origin: DFS namespace root plan § Follow-up work, deliberately out of scope
Activity