Re: Visible symlinks under Windows - Samba

This is a discussion on Re: Visible symlinks under Windows - Samba ; Hi, On Feb 6 12:50, Volker Lendecke wrote: > On Wed, Feb 06, 2008 at 12:27:07PM +0100, Corinna Vinschen wrote: > > as Cygwin developer, it's sort of frustrating that there isn't a way to > > identify symlinks on ...

+ Reply to Thread
Results 1 to 3 of 3

Thread: Re: Visible symlinks under Windows

  1. Re: Visible symlinks under Windows

    Hi,

    On Feb 6 12:50, Volker Lendecke wrote:
    > On Wed, Feb 06, 2008 at 12:27:07PM +0100, Corinna Vinschen wrote:
    > > as Cygwin developer, it's sort of frustrating that there isn't a way to
    > > identify symlinks on Samba shares from a Windows user space application
    > > for what they really are.

    >
    > Well, why stop at symlinks? If you do those, why not the
    > whole set of posix inode types like devices, sockets and
    > other stuff also?
    >
    > This was the original purpose of the Unix extensions, but
    > nobody at that point thought about using that stuff from
    > Windows user space, so we carved our own number space in the
    > protocol. As hardly anybody uses SMB EAs these days, I would
    > say this could be a clever trick to pass information from
    > Windows user space into smbd and vice versa.


    I'd like to pick up this old thread from here. In the meantime I added
    support for Micosoft's NFS client to Cygwin (will be in the next major
    release). To do that I had to learn how the NFS client transfers the
    POSIXy information to native Windows clients. Unfortunately, the
    interface is not documented yet, so I tracked it down myself by debugging.

    The Microsoft NFS client uses the Extended Attribute API, too, as I
    proposed for symlinks in my posting which started this thread. As I
    said, the client side is already implemented in Cygwin and now I was
    wondering if there's interest to add the exact same interface (just the
    server side) to Samba as well. The advantage would be that there's only
    one common interface for Win32 clients to access the POSIXy file
    information, regardless of using NFS or SMB.

    Here's a description of the Microsoft NFS client interface from the
    Windows application perspective:

    When you open a file on the NFS share, the result depends on whether
    it's an ordinary file or directory, or, if it's a symlink, whether the
    NFS client can resolve the symlink target or not. If the target of the
    symlink points outside of the NFS share or is a dangling symlink, then
    opening the file results in getting a handle to the symlink itself.
    Win32 applications are usually lost here anyway. OTOH, if the target is
    a file on the share itself, the NFS client can resolve it and you get a
    handle to the target, which also dumb Win32 apps can use.

    If you want information about the symlink itself, rather than about the
    target of the symlink, you have to tell the NtCreateFile call that you
    want a handle to the symlink instead of to the target. You do this by
    giving a special EA called "NfsActOnLink" to the NtCreateFile call.
    Since you're writing an EA, you also have to specify the FILE_WRITE_EA
    access bit:

    ULONG ealen = sizeof (FILE_FULL_EA_INFORMATION)
    + sizeof ("NfsActOnLink");
    PFILE_FULL_EA_INFORMATION eaptr = (PFILE_FULL_EA_INFORMATION)
    alloca (ealen);
    eaptr->NextEntryOffset = eaptr->Flags eaptr->EaValueLength = 0;
    eaptr->EaNameLength = sizeof ("NfsActOnLink") - 1;
    strcpy (eaptr->EaName, "NfsActOnLink");
    status = NtCreateFile (&file_handle, GENERIC_READ, &object_attributes,
    &io_status_block, NULL, FILE_ATTRIBUTE_NORMAL,
    FILE_SHARE_VALID_FLAGS, FILE_OPEN, 0, eaptr, ealen);

    If the file is a symlink, you now have a handle to the symlink itself.
    Otherwise you just have a handle to the file as usual. It's save to use
    this EA also for normal files.

    To find out what that file you just opened is, you can now retrieve a
    struct stat like block by fetching another EA called "NfsV3Attributes":

    ULONG getlen = sizeof (FILE_GET_EA_INFORMATION)
    + sizeof ("NfsV3Attributes");
    PFILE_GET_EA_INFORMATION getptr = (PFILE_GET_EA_INFORMATION)
    alloca (getlen);
    ULONG ealen = sizeof (FILE_FULL_EA_INFORMATION)
    + sizeof ("NfsV3Attributes")
    + sizeof (struct fattr3); // See below
    PFILE_FULL_EA_INFORMATION eaptr = (PFILE_FULL_EA_INFORMATION)
    alloca (ealen);
    getptr->NextEntryOffset = 0;
    getptr->EaNameLength = sizeof ("NfsV3Attributes") - 1;
    strcpy (getptr->EaName, "NfsV3Attributes");
    status = NtQueryEaFile (file_handle, &io_status_block,
    eaptr, ealen, TRUE, getptr, getlen, TRUE);

    If this has gone well, the EA value in eaptr contains a struct
    fattr3 now, as defined in RFC 1813 (http://tools.ietf.org/html/rfc1813),
    with just a minor change. The structure returned by the above call has
    four extra bytes, apparently for alignment reasons. It boils down to
    this structure (compare with chapter 2.5/2.6 from RFC 1813):

    struct fattr3 {
    uint32_t type; // file type (NFS ftype3, see above RFC)
    uint32_t mode; // Mode bits rwxrwxrwx + suid/sgid/vtx
    uint32_t nlink;
    uint32_t uid; // owner id, original value from server
    uint32_t gid; // group id, original value from server
    uint32_t __dummy;
    uint64_t size; // file size
    uint64_t used; // allocation size
    struct
    {
    uint32_t specdata1;
    uint32_t specdata2;
    } rdev; // major/minor numbers for BLK/CHR devices
    uint64_t fsid; // file system device id
    uint64_t fileid; // inode number
    struct timespec atime; // last access, seconds since epoch
    struct timespec mtime; // last modify, seconds since epoch
    struct timespec ctime; // last change, seconds since epoch
    };

    If you want to know if the file is a symlink and if so, where it points to,
    fetch the EA called "NfsSymlinkTargetName":

    struct fattr3 *nfs_stat_p = (struct fattr3 *)
    (eaptr->EaName + eaptr->EaNameLength + 1);
    if (nfs_stat_p->type == NF3LNK) // NF3LNK == 5, see RFC 1813
    {
    ULONG getlen = sizeof (FILE_GET_EA_INFORMATION)
    + sizeof ("NfsSymlinkTargetName");
    PFILE_GET_EA_INFORMATION getptr = (PFILE_GET_EA_INFORMATION)
    alloca (getlen);
    ULONG ealen = 65536; // Max. size of a EA
    PFILE_FULL_EA_INFORMATION eaptr = (PFILE_FULL_EA_INFORMATION)
    alloca (ealen);
    getptr->NextEntryOffset = 0;
    getptr->EaNameLength = sizeof ("NfsSymlinkTargetName") - 1;
    strcpy (getptr->EaName, "NfsSymlinkTargetName");
    status = NtQueryEaFileA (file_handle, &io_status_block,
    eaptr, ealen, TRUE, getptr, getlen, TRUE);
    if (NT_SUCCESS (status))
    PWCHAR syml_target = (PWCHAR)
    (eaptr->EaName + eaptr->EaNameLength + 1);
    }

    Along the same lines you can create symlinks using a NfsSymlinkTargetName
    EA in a NtCreateFile, set correct mode bits using a NfsV3Attributes EA
    in a NtSetEaFile call or, when creating a file, in a NtCreateFile call.

    There's also an interesting difference when calling NtQueryDirectoryFile
    on the NFS shares in relation to symlinks. When you use the
    FileNamesInformation info class, then the NFS client lists all files,
    including dangling symlinks. Every other info class does not list
    dangling symlinks.

    Since *all* Win32 functions are based on using other info classes, you
    will typically not see dangling symlinks in Win32 applications,
    including Windows Explorer. Only applications which know to use the
    FileNamesInformation info class get *all* the information.

    For sake of completeness, the file names returned by
    NtQueryDirectoryFile(FileNamesInformation) are not mangled for Win32
    applications. They are returned and listed as is.


    Anybody still here? If so, does that sound as something worth to
    consider for Samba as well?


    Thanks for listening,
    Corinna


  2. Re: Visible symlinks under Windows

    On Mon, Jun 23, 2008 at 04:20:56PM +0200, Corinna Vinschen wrote:

    > Anybody still here? If so, does that sound as something worth to
    > consider for Samba as well?


    Yes, this sounds very, very interesting. Right now we're
    just very busy getting 3.2 shipped, so it might take until
    that's done before we can really look at that in depth. It
    will stay in my inbox :-)

    Volker

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.5 (GNU/Linux)

    iD8DBQFIX/vWUzqjrWwMRl0RAmK3AJ47CuzJhhPiDYuAMKrNfdXYczexBQCc Cqlv
    d/hVRugRHItvJQH5/N9jqQk=
    =LVXZ
    -----END PGP SIGNATURE-----


  3. Re: Visible symlinks under Windows

    Hi Volker,

    On Jun 23 21:39, Volker Lendecke wrote:
    > On Mon, Jun 23, 2008 at 04:20:56PM +0200, Corinna Vinschen wrote:
    >
    > > Anybody still here? If so, does that sound as something worth to
    > > consider for Samba as well?

    >
    > Yes, this sounds very, very interesting. Right now we're
    > just very busy getting 3.2 shipped, so it might take until
    > that's done before we can really look at that in depth. It
    > will stay in my inbox :-)


    I'm glad to read that and I'm looking forward to discuss this further.


    Thanks,
    Corinna


+ Reply to Thread