I've translated a Windows based DFS tree to a Samba based (3.0.23c)
one and it seems to work quite well from Windows Explorer and cmd.exe.
First off, I have a relatively big tree.
grep dfscmd /root/dfs.cmd | wc -l
1614
One issue I've noticed that tree enumeration and manipulation from a
Windows machine to a Samba based DFS root just doesn't work at all.
For instance dfscmd.exe (a long time friend):
dfscmd /view \\SERVER\dfs
\\SERVER\array
\\SERVER\dfs\ROOT_LINK
\\SERVER\\
\\SERVER\\
This is pretty interesting since first item is the 'other share' on
the machine (not the DFS share) which shouldn't be enumerated in the
output at all (AFAIK).
The second is the only link in the root of the dfs tree.
Not sure what to make of the tail two entries here.
As well I've written up a small tool to check each link in the DFS
tree (to detect broken links) using the Win32 API function NetDfsEnum.
Basically (this is going to get pretty mangled):
result = NetDfsEnum(argv[1],3,MAX_PREFERRED_LENGTH,(LPBYTE
*)&root,&numEntries,&hResume);
while(result==ERROR_SUCCESS) {
for(iterator=1;iterator<=numEntries;iterator++) {
info = dfsEntry->Storage;
for(numStorage=dfsEntry->NumberOfStorages;numStorage>0;numStorage--) {
swprintf_s(buffer,MAX_PATH,L"\\\\%s\\%s\\*",info->ServerName,info->ShareName);
hFind = FindFirstFile(buffer,&FindFileData); // If you can
list the contents of a UNC, odds are it isn't broken.
}
}
result = NetDfsEnum(argv[1],3,MAX_PREFERRED_LENGTH,(LPBYTE
*)&root,&numEntries,&hResume);
}
This obviously is not complete but basically this will run infinitely
because it will resolve the same output as dfscmd but if you noticed
the last two links are self referential so we've got a recursive
infinite loop going on. Taking out the while loop obviously fixes the
problem (and assuming NetDfsEnum will always return the entire tree on
the first invocation [not a valid assumption]) but still I can't
resolve the tree properly programatically since I get the same output
as dfscmd.exe.
Now I've figured out that the NetDfsEnum RPC call is returning this
stuff because most of my links are pretty deep. Meaning I have a
large tree of folders with DFS links being the leafs of the tree.
When Samba lists the dfs root it sees the 'root' folders and the one
DFS link (which could account for the trailing '\\SERVER\\' links
though there are more than 2 folders in the root).
ssh root@SERVER ls -l /home/dfs
total 20
drwxr-xr-x 10 nobody nogroup 512 Nov 26 09:52 .
drwxr-xr-x 5 root wheel 512 Nov 26 08:46 ..
drwxr-xr-x 5 root nogroup 512 Nov 26 09:52 A
drwxr-xr-x 5 root nogroup 512 Nov 26 09:52 B
drwxr-xr-x 4 root nogroup 512 Nov 26 09:52 C
drwxr-xr-x 4 root nogroup 512 Nov 26 09:52 D
lrwxr-xr-x 1 root nogroup 25 Nov 26 09:52 ROOT_LINK ->
msdfs:serverb\array
So it looks like the Samba NetDfsEnum handler doesn't recurse into
directories (understandable though annoying for me) nor results in any
usable enumeration of a hosted dfs tree.
So my question here is how do you suggest I enumerate the Samba hosted
DFS tree from a Windows machine reliably?
There doesn't seem to be a deterministic way of enumerating the leaf
nodes of the tree, which if there was then I can just make new or
update the tools I have to use that (ie. traverse the share tree
looking for DFS leaf nodes and return filtered result links).
As well I'm going to assume that NetDfsAdd* NetDfsMove* and
NetDfsRemove* will also not work as I can't use dfscmd.exe to map or
unmap anything in the Samba hosted tree (response is always 'Access is
denied', yet the DFS root folder and sub-folders are all owned by the
guest user).
--
Sean