Bug 4557 - smbc_stat or smbc_getxattr can't handle Vista symlinks.
Summary: smbc_stat or smbc_getxattr can't handle Vista symlinks.
Status: NEW
Alias: None
Product: Samba 3.0
Classification: Unclassified
Component: libsmbclient (show other bugs)
Version: 3.0.25
Hardware: x86 Other
: P3 normal
Target Milestone: none
Assignee: Derrell Lipman
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-04-26 04:52 UTC by Henrik (dead mail address)
Modified: 2007-12-20 04:16 UTC (History)
1 user (show)

See Also:


Attachments
Vista-Vista dir command showing junction (8.77 KB, text/plain)
2007-12-07 09:29 UTC, Henrik (dead mail address)
no flags Details
Followed a junction in Explorer when mounting a Vista share from Vista (7.90 KB, text/plain)
2007-12-07 09:30 UTC, Henrik (dead mail address)
no flags Details
Listing folder through explorer on a vista machine when connected to another vista machine (6.82 KB, text/plain)
2007-12-07 09:31 UTC, Henrik (dead mail address)
no flags Details
WIn XP to Vista dir command showing a junction. (2.32 KB, text/plain)
2007-12-10 04:27 UTC, Henrik (dead mail address)
no flags Details
Dump of traffic showing use of FCTL_GET_REPARSE_POINT over SMB v1 (162.91 KB, text/plain)
2007-12-19 03:18 UTC, Henrik (dead mail address)
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Henrik (dead mail address) 2007-04-26 04:52:16 UTC
We are not able to tell if a file is a symlink or junction when run against a Vista client.
This causes quite a bit of problem as smbc_open/smbc_read will throw a lot of errors going through a directory structure on a Vista client with a lot of symlinks/junctions.

Below are our tests and findings.

C:\Users\Administrator\Documents>mkdir mydir

C:\Users\Administrator\Documents>mklink /j myjunction mydir
Junction created for myjunction <<===>> mydir

C:\Users\Administrator\Documents>mklink /d mysymlink mydir
symbolic link created for mysymlink <<===>> mydir

C:\Users\Administrator\Documents>dir
 Volume in drive C has no label.
 Volume Serial Number is 0256-B10C

 Directory of C:\Users\Administrator\Documents

2007-04-26  09:44    <DIR>          .
2007-04-26  09:44    <DIR>          ..
2007-04-26  09:41    <DIR>          mydir
2007-04-26  09:40    <JUNCTION>     myjunction [C:\Users\Administrator\Documents\mydir]
2007-04-26  09:40    <SYMLINKD>     mysymlink [mydir]
               0 File(s)              0 bytes
               5 Dir(s)  139 957 547 008 bytes free


mydir
    stat: mode 0x41ed
getxattr: mode   0x10


mysymlink
    stat: mode 0x41ed
getxattr: mode (9) EBADF


myjunction
    stat: mode 0x41ed
getxattr: mode  0x410


//Henrik
Comment 1 Henrik (dead mail address) 2007-12-07 09:29:52 UTC
Created attachment 3027 [details]
Vista-Vista dir command showing junction

I did a connect from a vista machine to another vista machine and executed a dir command on the remote share.
Comment 2 Henrik (dead mail address) 2007-12-07 09:30:43 UTC
Created attachment 3028 [details]
Followed a junction in Explorer  when mounting a Vista share from Vista
Comment 3 Henrik (dead mail address) 2007-12-07 09:31:26 UTC
Created attachment 3029 [details]
Listing folder through explorer on a vista machine when connected to another vista machine
Comment 4 Volker Lendecke 2007-12-07 15:35:28 UTC
Can you repeat the same traces with Vista against W2k3, XP or some Windows version that is *not* Vista? What you sent is smb2 traffic which Samba does not yet support.

Thanks,

Volker
Comment 5 Henrik (dead mail address) 2007-12-10 04:27:47 UTC
Created attachment 3035 [details]
WIn XP to Vista dir command showing a junction.

XP machine mounted a Vista share and did a dir /a. I can see that it identifies the junction as a Reparse Point but with the difference that there is no information to where the junctions points. Maybe we need SMB2 for that?
Comment 6 Derrell Lipman 2007-12-12 20:52:18 UTC
Henrik, 

I've been researching this topic.  Reparse points predate Vista, so SMB2 should not be required.  However, to read a reparse point (which it seems is a junction), the required library function is DeviceIoControl() using FSCTL_GET_REPARSE_POINT.  The documentation subtree worth reviewing appears to be:

  http://msdn2.microsoft.com/en-us/library/aa365503.aspx

I'm not sure that DeviceIoControl can be used over the network, although I'd be a bit surprised if it could not be.  If you can provide me with a packet trace that shows returning what the reparse point points to (using XP or W2K, not Vista), I may be able to add that functionality.  You may be able to obtain that using Windows commands or by writing an application which uses DeviceIoControl().

Derrell
Comment 7 Henrik (dead mail address) 2007-12-18 04:49:05 UTC
Hi Derrell,

I've been trying to get a pre-vista machine to issue a FCTL_GET_REPARSE_POINT call but I can't I suppose its not due to the limitation of the SMB protocol but rather there is no utility out there that uses FCTL_GET_REPARSE_POINT. Maybe you can use the information on the technet article you showed me together with the trace from Vista-Vista where the FCTL_GET_REPARSE_POINT is used?

I'll keep trying!

Cheers,
Henrik
Comment 8 Derrell Lipman 2007-12-18 08:16:05 UTC
The previous traces were all SMB2 traffic.  I don't think we're quite ready to add SMB2 to Samba3.  (Samba4 supports it in some fashion, although to what extent I'm not sure.)

> I'll keep trying!

Cool. :-)

There's got to be some application that uses it, but if not, if you can figure out the semantics of the ioctl or library call, you should be able to write a small app that issues the request and receives the response...  Yes?

Derrell
Comment 9 Henrik (dead mail address) 2007-12-19 03:18:12 UTC
Created attachment 3054 [details]
Dump of traffic showing use of FCTL_GET_REPARSE_POINT over SMB v1

Derrell,

Today is you lucky day! ( and mine =) )

I succeeded to issue a FCTL_GET_REPARSE_POINT over the SMB protocol! :)

Now work your magic! :D

Cheers,
Henrik
Comment 10 Derrell Lipman 2007-12-19 13:02:33 UTC
Cool!

Ok, after spending the morning doing more researching...  Here are a couple of pretty good developer-oriented background articles:

  http://www.codeproject.com/KB/vista/ReparsePointID.aspx
  http://www.flexhex.com/docs/articles/hard-links.phtml

It seems possible to add handling of reparse points in the internal Samba library.  It's less obvious how to map it to the POSIX-like interface of libsmbclient.  In particular, how would one distinguish between a Junction (which can only be on a directory) and a Symbolic Link if the latter is on a directory?  

If I were to just return the Junction or SymLink data on a newly-created smbc_lstat() call (ignoring the previous issue), I'd also want to create an smbc_symlink() to create them...

I could possibly use the /??/ "unparse" header to distinguish between a Junction and a SymLink by always returning that from smbc_lstat()... and then similarly create a Juncion if the provided path begins with /??/ and a SymLink otherwise.

And furthermore, if smbc_lstat() returns what a reparse point points to, then what must smbc_stat() now do?  Follow the reparse point?  (I'm getting a headache.)  I don't think I can follow it without breaking backward compatibility unless I add an option specifying which procedure to use...  

(What about a MountPoint reparse point?  I suppose that would be done with a smbc_mount() function which I don't plan to implement now.)

Still thinking, and open to suggestions.

Derrell
Comment 11 Henrik (dead mail address) 2007-12-20 04:16:30 UTC
Good links! I found some other nice links regarding reparse points on codeproject also.

To distinguish between junction and symlink I suppose the header is the only way but I haven't looked that thoroughly on the SMB traffic regarding that yet.

I believe all these issues need to be looked at different angles to really get a complete view on how to handle it but the most important features to start with is.

a) Return a SMBC_LINK type OR a new type (SMBC_REPARSE_POINT?) when we come upon a reparse point.

b) Implement a smbc_lstat function that can retrieve the target of the reparse point and also type of reparse point (symlink/junction) if we don't do it directly.

If we just know these things the programmer can determine what he/she wants to do with it. I don't think we need to worry about following these reparse points for starters. If a programmer wants to issue a smbc_stat on the target then he should call a smbc_lstat first to determine the target.

Of course it would be great if we could handle them the same way we handle the POSIX links but I guess we need more research to determine that. As always windows has done a poor job implementing links functionality in their filesystem.

Creating junctions/symlinks would be a really nice features also. I really don't have any creative input on how yet but I think it would be quite straight forward.

Thats my input for now. I'll keep thinking about it and give you any input I come up with. You can message me directly on my e-mail if you want some more feedback outside the bugreport.

Cheers,
Henrik