[PATCH] smbd: add reparse points at symlinks
Jacob Holtom
jacob at et.byu.edu
Wed Dec 2 18:28:49 UTC 2015
with follow symlinks and wide links enabled, they normally would just
see it as a continuation of the current path rather than a point to
another location
Sadly, the documentation on what the windows symlink filter driver does
is rather lacking, so the best I can do is make informed assumptions.
Now when they connect and encounter a reparse point with the
IO_REPARSE_TAG_SYMLINK they will interpret it as the start of a new path
and therefore re-evaluate everything (probably a new tree_connect at
that point) rather than inheriting everything above it. This is mostly
useful in the case of wide links, so that instead of inheriting the
original filesystems attributes, it goes and finds those of the target
filesystems.
Thanks!
Jacob
On 11/30/2015 12:32 PM, Jeremy Allison wrote:
> On Mon, Nov 30, 2015 at 11:42:49AM -0700, Jacob Holtom wrote:
>> Hi,
>>
>> This patch adds a reparse point at symlinks, with the correct
>> accompanying tag as defined by microsoft.
>> this may be better implemented with a compile time option of
>> smb.conf flag, review appreciated
>
> Interesting patch Jacob, thanks !
>
> What do Windows clients do when they see an smbd symlink
> as a reparse point ?
>
>> From 2175ed1fd6844eb5528b005f1694f68513746a99 Mon Sep 17 00:00:00 2001
>> From: Jacob Holtom <jacob at et.byu.edu>
>> Date: Mon, 30 Nov 2015 11:27:52 -0700
>> Subject: [PATCH] smbd: add reparse points at symlinks
>>
>> Signed-off-by: Jacob Holtom <jacob at et.byu.edu>
>> ---
>> source3/include/ntioctl.h | 2 +-
>> source3/smbd/dosmode.c | 9 ++++++++-
>> source3/smbd/trans2.c | 15 ++++++++++++---
>> 3 files changed, 21 insertions(+), 5 deletions(-)
>>
>> diff --git a/source3/include/ntioctl.h b/source3/include/ntioctl.h
>> index f9e6dd9..850e85f 100644
>> --- a/source3/include/ntioctl.h
>> +++ b/source3/include/ntioctl.h
>> @@ -27,7 +27,7 @@
>> #define IO_REPARSE_TAG_HSM 0xC0000004
>> #define IO_REPARSE_TAG_SIS 0x80000007
>> #define IO_REPARSE_TAG_DFS 0x8000000A
>> -
>> +#define IO_REPARSE_TAG_SYMLINK 0xA000000C
>>
>> /* For FSCTL_GET_SHADOW_COPY_DATA ...*/
>> typedef char SHADOW_COPY_LABEL[25];
>> diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
>> index 0f3eef0..e1e84ce 100644
>> --- a/source3/smbd/dosmode.c
>> +++ b/source3/smbd/dosmode.c
>> @@ -246,6 +246,8 @@ static uint32_t dos_mode_from_sbuf(connection_struct *conn,
>> result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY);
>>
>> result |= set_link_read_only_flag(&smb_fname->st);
>> + if(S_ISLNK(smb_fname->st.st_ex_mode))
>> + result |= FILE_ATTRIBUTE_REPARSE_POINT;
>>
>> dos_mode_debug_print(__func__, result);
>>
>> @@ -364,6 +366,8 @@ static bool get_ea_dos_attribute(connection_struct *conn,
>> if (S_ISDIR(smb_fname->st.st_ex_mode)) {
>> dosattr |= FILE_ATTRIBUTE_DIRECTORY;
>> }
>> + if(S_ISLNK(smb_fname->st.st_ex_mode))
>> + dosattr |= FILE_ATTRIBUTE_REPARSE_POINT;
>> /* FILE_ATTRIBUTE_SPARSE is valid on get but not on set. */
>> *pattr = (uint32_t)(dosattr & (SAMBA_ATTRIBUTES_MASK|FILE_ATTRIBUTE_SPARSE));
>>
>> @@ -633,7 +637,10 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
>> if (result == 0) {
>> result = FILE_ATTRIBUTE_NORMAL;
>> }
>> -
>> + //Add in reparse point if symlink
>> + if(S_ISLNK(smb_fname->st.st_ex_mode))
>> + result |= FILE_ATTRIBUTE_REPARSE_POINT;
>> + //End Additions
>> result = filter_mode_by_protocol(result);
>>
>> dos_mode_debug_print(__func__, result);
>> diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
>> index 11c97e8..fa3eba5 100644
>> --- a/source3/smbd/trans2.c
>> +++ b/source3/smbd/trans2.c
>> @@ -1864,7 +1864,10 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
>> SIVAL(p,0,mode); p += 4;
>> q = p; p += 4; /* q is placeholder for name length. */
>> if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
>> - SIVAL(p, 0, IO_REPARSE_TAG_DFS);
>> + if(S_ISLNK(mode))
>> + SIVAL(p,0,IO_REPARSE_TAG_SYMLINK);
>> + else
>> + SIVAL(p, 0, IO_REPARSE_TAG_DFS);
>> } else {
>> unsigned int ea_size = estimate_ea_size(conn, NULL,
>> smb_fname);
>> @@ -2058,7 +2061,10 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
>> SIVAL(p,0,mode); p += 4;
>> q = p; p += 4; /* q is placeholder for name length. */
>> if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
>> - SIVAL(p, 0, IO_REPARSE_TAG_DFS);
>> + if(S_ISLNK(mode))
>> + SIVAL(p,0,IO_REPARSE_TAG_SYMLINK);
>> + else
>> + SIVAL(p, 0, IO_REPARSE_TAG_DFS);
>> } else {
>> unsigned int ea_size = estimate_ea_size(conn, NULL,
>> smb_fname);
>> @@ -2109,7 +2115,10 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
>> SIVAL(p,0,mode); p += 4;
>> q = p; p += 4; /* q is placeholder for name length */
>> if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
>> - SIVAL(p, 0, IO_REPARSE_TAG_DFS);
>> + if(S_ISLNK(mode))
>> + SIVAL(p, 0, IO_REPARSE_TAG_SYMLINK);
>> + else
>> + SIVAL(p, 0, IO_REPARSE_TAG_DFS);
>> } else if (readdir_attr_data &&
>> readdir_attr_data->type == RDATTR_AAPL) {
>> /*
>> --
>> 2.6.2
>>
>
More information about the samba-technical
mailing list