[PATCH] smbd: add reparse points at symlinks

Jeremy Allison jra at samba.org
Mon Nov 30 19:32:48 UTC 2015


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