[PATCH] Final removal of lp_posix_pathnames() from the smbd server main code paths.

Jeremy Allison jra at samba.org
Wed Mar 23 16:13:27 UTC 2016


On Tue, Mar 22, 2016 at 08:47:15AM -0700, Jeremy Allison wrote:
> On Sun, Mar 20, 2016 at 09:31:40PM -0700, Jeremy Allison wrote:
> > This is the final removal of all the
> > lp_posix_pathnames() globals from the
> > SMB1/2/3 server code paths (except for
> > the per-request lookup in the SMB1 server).
> > 
> > After this patchset we should be able
> > to add per-handle based unix extensions
> > to the SMB2 server without running into
> > any issues with the lp_posix_pathnames() global.
> > 
> > Passes local make test.
> > 
> > Patset is:
> > 
> > 1). Fix vfs_afsacl.c module build (missing struct
> > smb_filename conversion).
> > 
> > 2). vfs_afsacl.c - move to using STAT directly
> > (if it was a symlink path, we already refused it).
> > 
> > 3). Move lp_posix_pathnames() out of ea_list_has_invalid_name()
> > utility function.
> > 
> > 4). Add uint32_t flags field to struct smb_filename. Only
> > defined field currently is SMB_FILENAME_POSIX_PATH.
> > 
> > 5). Add uint32_t flags parameter to synthetic_smb_fname().
> > Touches a lot of files but is mostly boilerplate, copying
> > the 'flags' field from an available smb_filename struct.
> > 
> > 6). Remove use of lp_posix_pathnames() below the VFS.
> > Removes an optimization if it's done on a symlink.
> > 
> > 7). posix_acls.c - move to using STAT directly
> > (if it was a symlink path, we already refused it).
> > 
> > 8). Remove unneeded lp_posix_pathnames() check in
> >  SMB2 create.
> > 
> > 9). Remove many common uses of lp_posix_pathnames().
> > We can check smb_fname->flags now.
> > 
> > 10). vfs_recycle.c - Remove use of vfs_stat_smb_basename().
> > 
> > 11). vfs_acl_tdb.c - Remove use of vfs_stat_smb_basename().
> > 
> > 12). Modify vfs_stat_smb_basename() to take a
> >  const struct smb_filename *. Allows last use of
> > lp_posix_pathnames() below the VFS to be removed.
> > 
> > 13). Remove lp_posix_pathnames() from msdfs code.
> > Last lp_posix_pathnames() in the SMB1/2/3 code paths.
> > 
> > 14). torture. Remove spurious lp_posix_pathnames().
> > Cut-and-paste error from long ago.
> > 
> > Please review and push if happy !
> 
> Updated version containing the flag definition
> change requested by Ralph.
> 
> The flags really are different things though,
> as they apply to different objects within the
> core server - so the names should be different.
> But at least the values are now consistent.

I know people are really busy with other More.Important.Things. :-(
right now.

But for those who aren't, it'd be really great to get this in
as then I can start prototyping the SMB2 unix extensions !

Cheers,

Jeremy.

> From 3e04d9c7e64334b708095e26c69a223b4dda4a26 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Thu, 17 Mar 2016 16:44:50 -0700
> Subject: [PATCH 01/14] s3:smbd: Fix build for vfs_afsacl.c.
> 
> Missed conversion of get_nt_acl_fn from const char *
> to const struct smb_filename *.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/modules/vfs_afsacl.c | 19 ++++++-------------
>  1 file changed, 6 insertions(+), 13 deletions(-)
> 
> diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c
> index aa8de9a..feca54f 100644
> --- a/source3/modules/vfs_afsacl.c
> +++ b/source3/modules/vfs_afsacl.c
> @@ -1031,31 +1031,24 @@ static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle,
>  }
>  
>  static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle,
> -				  const char *name, uint32_t security_info,
> -				  TALLOC_CTX *mem_ctx,
> -				  struct security_descriptor **ppdesc)
> +				const struct smb_filename *smb_fname,
> +				uint32_t security_info,
> +				TALLOC_CTX *mem_ctx,
> +				struct security_descriptor **ppdesc)
>  {
>  	struct afs_acl acl;
>  	size_t sd_size;
> -	struct smb_filename *smb_fname = NULL;
>  
> -	DEBUG(5, ("afsacl_get_nt_acl: %s\n", name));
> +	DEBUG(5, ("afsacl_get_nt_acl: %s\n", smb_fname->base_name));
>  
>  	sidpts = lp_parm_bool(SNUM(handle->conn), "afsacl", "sidpts", false);
>  
> -	if (!afs_get_afs_acl(name, &acl)) {
> +	if (!afs_get_afs_acl(smb_fname->base_name, &acl)) {
>  		return NT_STATUS_ACCESS_DENIED;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(), name, NULL, NULL);
> -	if (smb_fname == NULL) {
> -		free_afs_acl(&acl);
> -		return NT_STATUS_NO_MEMORY;
> -	}
> -
>  	sd_size = afs_to_nt_acl(&acl, handle->conn, smb_fname, security_info,
>  				mem_ctx, ppdesc);
> -	TALLOC_FREE(smb_fname);
>  
>  	free_afs_acl(&acl);
>  
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 156adb3b19c0d8834dd826077a07c5486bd3c981 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 15 Mar 2016 11:46:58 -0700
> Subject: [PATCH 02/14] s3: vfs: vfs_afsacl. refuse_symlink() means we can
>  always use STAT here.
> 
> For a posix acl call on a symlink, we've already refused it.
> For a Windows acl mapped call on a symlink, we want to follow
> it.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/modules/vfs_afsacl.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c
> index feca54f..5838fd0 100644
> --- a/source3/modules/vfs_afsacl.c
> +++ b/source3/modules/vfs_afsacl.c
> @@ -666,12 +666,14 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl,
>  {
>  	int ret;
>  
> +	/*
> +	 * We can directly use SMB_VFS_STAT here, as if this was a
> +	 * POSIX call on a symlink, we've already refused it.
> +	 * For a Windows acl mapped call on a symlink, we want to follow
> +	 * it.
> +	 */
>  	/* Get the stat struct for the owner info. */
> -	if (lp_posix_pathnames()) {
> -		ret = SMB_VFS_LSTAT(conn, smb_fname);
> -	} else {
> -		ret = SMB_VFS_STAT(conn, smb_fname);
> -	}
> +	ret = SMB_VFS_STAT(conn, smb_fname);
>  	if (ret == -1) {
>  		return 0;
>  	}
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 5d13ef8f610bb37d9fd0cd183694f3c400270578 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Tue, 15 Mar 2016 11:43:32 -0700
> Subject: [PATCH 03/14] s3:smbd: Move lp_posix_pathnames() out of
>  ea_list_has_invalid_name().
> 
> External uses will be replaced by checks on struct smb_filename flags.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/lib/filename_util.c | 4 ----
>  source3/smbd/nttrans.c      | 3 ++-
>  source3/smbd/smb2_create.c  | 3 ++-
>  source3/smbd/trans2.c       | 5 +++--
>  4 files changed, 7 insertions(+), 8 deletions(-)
> 
> diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c
> index 6ee91ec..61a5f01 100644
> --- a/source3/lib/filename_util.c
> +++ b/source3/lib/filename_util.c
> @@ -267,10 +267,6 @@ bool is_invalid_windows_ea_name(const char *name)
>  
>  bool ea_list_has_invalid_name(struct ea_list *ea_list)
>  {
> -	if (lp_posix_pathnames()) {
> -		return false;
> -	}
> -
>  	for (;ea_list; ea_list = ea_list->next) {
>  		if (is_invalid_windows_ea_name(ea_list->ea.name)) {
>  			return true;
> diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
> index 0951280..be5994a 100644
> --- a/source3/smbd/nttrans.c
> +++ b/source3/smbd/nttrans.c
> @@ -1178,7 +1178,8 @@ static void call_nt_transact_create(connection_struct *conn,
>  			goto out;
>  		}
>  
> -		if (ea_list_has_invalid_name(ea_list)) {
> +		if (!lp_posix_pathnames() &&
> +				ea_list_has_invalid_name(ea_list)) {
>  			/* Realloc the size of parameters and data we will return */
>  			if (flags & EXTENDED_RESPONSE_REQUIRED) {
>  				/* Extended response is 32 more byyes. */
> diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
> index 9dbed68..ab37be0 100644
> --- a/source3/smbd/smb2_create.c
> +++ b/source3/smbd/smb2_create.c
> @@ -716,7 +716,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
>  				return tevent_req_post(req, ev);
>  			}
>  
> -			if (ea_list_has_invalid_name(ea_list)) {
> +			if (!lp_posix_pathnames() &&
> +					ea_list_has_invalid_name(ea_list)) {
>  				tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
>  				return tevent_req_post(req, ev);
>  			}
> diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
> index 9c77a67..e23b893 100644
> --- a/source3/smbd/trans2.c
> +++ b/source3/smbd/trans2.c
> @@ -717,7 +717,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
>  	 * we set *any* of them.
>  	 */
>  
> -	if (ea_list_has_invalid_name(ea_list)) {
> +	if (!lp_posix_pathnames() && ea_list_has_invalid_name(ea_list)) {
>  		return STATUS_INVALID_EA_NAME;
>  	}
>  
> @@ -1297,7 +1297,8 @@ static void call_trans2open(connection_struct *conn,
>  			goto out;
>  		}
>  
> -		if (ea_list_has_invalid_name(ea_list)) {
> +		if (!lp_posix_pathnames() &&
> +				ea_list_has_invalid_name(ea_list)) {
>  			int param_len = 30;
>  			*pparams = (char *)SMB_REALLOC(*pparams, param_len);
>  			if(*pparams == NULL ) {
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From c72f400e9bf40f33481c7a064960c2d5b2c80201 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Thu, 17 Mar 2016 16:20:17 -0700
> Subject: [PATCH 04/14] s3: smbd: Add uint32_t flags field to struct
>  smb_filename.
> 
> Only one defined flag for now, SMB_FILENAME_POSIX_PATH.
> Define as the same as FSP_POSIX_FLAGS_PATHNAMES to keep
> the value consistent.
> 
> Set this inside unix_convert() when a posix path parse
> is selected.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/include/vfs.h         | 9 +++++++++
>  source3/lib/filename_util.c   | 1 +
>  source3/modules/vfs_default.c | 1 +
>  source3/smbd/filename.c       | 2 ++
>  4 files changed, 13 insertions(+)
> 
> diff --git a/source3/include/vfs.h b/source3/include/vfs.h
> index 1c6bc2f..3a86c62 100644
> --- a/source3/include/vfs.h
> +++ b/source3/include/vfs.h
> @@ -190,6 +190,7 @@
>  		const struct smb_filename * */
>  /* Version 35 - Change streaminfo from const char *, to
>  		const struct smb_filename * */
> +/* Version 35 - Add uint32_t flags to struct smb_filename */
>  
>  #define SMB_VFS_INTERFACE_VERSION 35
>  
> @@ -514,9 +515,17 @@ struct smb_filename {
>  	char *base_name;
>  	char *stream_name;
>  	char *original_lcomp;
> +	uint32_t flags;
>  	SMB_STRUCT_STAT st;
>  };
>  
> +/*
> + * smb_filename flags. Define in terms of the FSP_POSIX_FLAGS_XX
> + * to keep the numeric values consistent.
> + */
> +
> +#define SMB_FILENAME_POSIX_PATH		FSP_POSIX_FLAGS_PATHNAMES
> +
>  #define VFS_FIND(__fn__) while (handle->fns->__fn__##_fn==NULL) { \
>  				handle = handle->next; \
>  			 }
> diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c
> index 61a5f01..c2beae1 100644
> --- a/source3/lib/filename_util.c
> +++ b/source3/lib/filename_util.c
> @@ -212,6 +212,7 @@ struct smb_filename *cp_smb_filename(TALLOC_CTX *mem_ctx,
>  		talloc_set_name_const(out->original_lcomp,
>  				      out->original_lcomp);
>  	}
> +	out->flags = in->flags;
>  	out->st = in->st;
>  	return out;
>  }
> diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
> index ea7dc2c..23df640 100644
> --- a/source3/modules/vfs_default.c
> +++ b/source3/modules/vfs_default.c
> @@ -2211,6 +2211,7 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
>  		ZERO_STRUCT(smb_fname_cp);
>  		smb_fname_cp.base_name = discard_const_p(char,
>  					smb_fname->base_name);
> +		smb_fname_cp.flags = smb_fname->flags;
>  
>  		if (lp_posix_pathnames()) {
>  			ret = SMB_VFS_LSTAT(handle->conn, &smb_fname_cp);
> diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
> index dffa71d..a1920c3 100644
> --- a/source3/smbd/filename.c
> +++ b/source3/smbd/filename.c
> @@ -273,6 +273,8 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
>  		goto done;
>  	}
>  
> +	smb_fname->flags = posix_pathnames ? SMB_FILENAME_POSIX_PATH : 0;
> +
>  	DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path));
>  
>  	/*
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 327c2724d4e0bd7a29ac939e0f6fcb0fb70b711b Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Fri, 18 Mar 2016 21:19:38 -0700
> Subject: [PATCH 05/14] s3: Filenames: Add uint32_t flags parameter to
>  synthetic_smb_fname().
> 
> Get it from parent/deriving smb_filename if present.
> Use 0 (as usually this a Windows-style lookup) if
> not.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/include/proto.h                |  3 +-
>  source3/lib/filename_util.c            | 12 ++++--
>  source3/modules/non_posix_acls.c       |  2 +-
>  source3/modules/vfs_cap.c              | 21 ++++++----
>  source3/modules/vfs_catia.c            | 27 ++++++++-----
>  source3/modules/vfs_default.c          |  2 +-
>  source3/modules/vfs_fake_acls.c        |  2 +-
>  source3/modules/vfs_fruit.c            | 22 ++++++++---
>  source3/modules/vfs_gpfs.c             |  2 +-
>  source3/modules/vfs_hpuxacl.c          |  2 +-
>  source3/modules/vfs_media_harmony.c    |  6 ++-
>  source3/modules/vfs_nfs4acl_xattr.c    |  2 +-
>  source3/modules/vfs_recycle.c          | 10 +++--
>  source3/modules/vfs_shadow_copy.c      |  3 +-
>  source3/modules/vfs_shadow_copy2.c     | 27 ++++++++-----
>  source3/modules/vfs_snapper.c          | 24 ++++++++----
>  source3/modules/vfs_streams_depot.c    | 71 +++++++++++++++++++++++++---------
>  source3/modules/vfs_streams_xattr.c    | 14 +++++--
>  source3/modules/vfs_unityed_media.c    |  6 ++-
>  source3/modules/vfs_vxfs.c             |  2 +-
>  source3/modules/vfs_xattr_tdb.c        |  2 +-
>  source3/printing/nt_printing.c         |  2 +-
>  source3/printing/printspoolss.c        |  2 +-
>  source3/rpc_server/fss/srv_fss_agent.c |  2 +-
>  source3/smbd/close.c                   | 17 +++++---
>  source3/smbd/dir.c                     | 14 +++++--
>  source3/smbd/dosmode.c                 | 14 +++++--
>  source3/smbd/durable.c                 |  7 +++-
>  source3/smbd/file_access.c             |  9 ++++-
>  source3/smbd/filename.c                |  3 +-
>  source3/smbd/files.c                   |  2 +-
>  source3/smbd/msdfs.c                   | 19 ++++++---
>  source3/smbd/open.c                    | 38 ++++++++++++------
>  source3/smbd/pipes.c                   |  2 +-
>  source3/smbd/posix_acls.c              |  5 ++-
>  source3/smbd/pysmbd.c                  | 12 ++++--
>  source3/smbd/reply.c                   | 12 ++++--
>  source3/smbd/service.c                 |  7 +++-
>  source3/smbd/trans2.c                  | 37 ++++++++++++------
>  source3/smbd/vfs.c                     |  9 +++--
>  source3/torture/cmd_vfs.c              | 29 ++++++++++----
>  41 files changed, 347 insertions(+), 157 deletions(-)
> 
> diff --git a/source3/include/proto.h b/source3/include/proto.h
> index dc8fee9..8cdbadf 100644
> --- a/source3/include/proto.h
> +++ b/source3/include/proto.h
> @@ -1139,7 +1139,8 @@ NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_f
>  struct smb_filename *synthetic_smb_fname(TALLOC_CTX *mem_ctx,
>  					 const char *base_name,
>  					 const char *stream_name,
> -					 const SMB_STRUCT_STAT *psbuf);
> +					 const SMB_STRUCT_STAT *psbuf,
> +					 uint32_t flags);
>  struct smb_filename *synthetic_smb_fname_split(TALLOC_CTX *ctx,
>  						const char *fname,
>  						bool posix_path);
> diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c
> index c2beae1..78bfc70 100644
> --- a/source3/lib/filename_util.c
> +++ b/source3/lib/filename_util.c
> @@ -53,13 +53,15 @@ NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx,
>  struct smb_filename *synthetic_smb_fname(TALLOC_CTX *mem_ctx,
>  					 const char *base_name,
>  					 const char *stream_name,
> -					 const SMB_STRUCT_STAT *psbuf)
> +					 const SMB_STRUCT_STAT *psbuf,
> +					 uint32_t flags)
>  {
>  	struct smb_filename smb_fname_loc = { 0, };
>  
>  	/* Setup the base_name/stream_name. */
>  	smb_fname_loc.base_name = discard_const_p(char, base_name);
>  	smb_fname_loc.stream_name = discard_const_p(char, stream_name);
> +	smb_fname_loc.flags = flags;
>  
>  	/* Copy the psbuf if one was given. */
>  	if (psbuf)
> @@ -83,7 +85,11 @@ struct smb_filename *synthetic_smb_fname_split(TALLOC_CTX *ctx,
>  
>  	if (posix_path) {
>  		/* No stream name looked for. */
> -		return synthetic_smb_fname(ctx, fname, NULL, NULL);
> +		return synthetic_smb_fname(ctx,
> +				fname,
> +				NULL,
> +				NULL,
> +				SMB_FILENAME_POSIX_PATH);
>  	}
>  
>  	ok = split_stream_filename(ctx,
> @@ -94,7 +100,7 @@ struct smb_filename *synthetic_smb_fname_split(TALLOC_CTX *ctx,
>  		return NULL;
>  	}
>  
> -	ret = synthetic_smb_fname(ctx, base_name, stream_name, NULL);
> +	ret = synthetic_smb_fname(ctx, base_name, stream_name, NULL, 0);
>  	TALLOC_FREE(base_name);
>  	TALLOC_FREE(stream_name);
>  	return ret;
> diff --git a/source3/modules/non_posix_acls.c b/source3/modules/non_posix_acls.c
> index fca9979..8d3be72 100644
> --- a/source3/modules/non_posix_acls.c
> +++ b/source3/modules/non_posix_acls.c
> @@ -32,7 +32,7 @@ int non_posix_sys_acl_blob_get_file_helper(vfs_handle_struct *handle,
>  	struct xattr_sys_acl_hash_wrapper acl_wrapper = {};
>  	struct smb_filename *smb_fname;
>  
> -	smb_fname = synthetic_smb_fname(frame, path_p, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(frame, path_p, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(frame);
>  		errno = ENOMEM;
> diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
> index 42b4b8d..eece198 100644
> --- a/source3/modules/vfs_cap.c
> +++ b/source3/modules/vfs_cap.c
> @@ -69,7 +69,8 @@ static DIR *cap_opendir(vfs_handle_struct *handle,
>  	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					capname,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (cap_smb_fname == NULL) {
>  		TALLOC_FREE(capname);
>  		errno = ENOMEM;
> @@ -125,7 +126,8 @@ static int cap_mkdir(vfs_handle_struct *handle,
>  	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					cappath,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (cap_smb_fname == NULL) {
>  		TALLOC_FREE(cappath);
>  		errno = ENOMEM;
> @@ -149,7 +151,8 @@ static int cap_rmdir(vfs_handle_struct *handle,
>  	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					cappath,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (cap_smb_fname == NULL) {
>  		TALLOC_FREE(cappath);
>  		errno = ENOMEM;
> @@ -321,7 +324,8 @@ static int cap_chmod(vfs_handle_struct *handle,
>  	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					cappath,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (cap_smb_fname == NULL) {
>  		TALLOC_FREE(cappath);
>  		errno = ENOMEM;
> @@ -354,7 +358,8 @@ static int cap_chown(vfs_handle_struct *handle,
>  	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					cappath,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (cap_smb_fname == NULL) {
>  		TALLOC_FREE(cappath);
>  		errno = ENOMEM;
> @@ -387,7 +392,8 @@ static int cap_lchown(vfs_handle_struct *handle,
>  	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					cappath,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (cap_smb_fname == NULL) {
>  		TALLOC_FREE(cappath);
>  		errno = ENOMEM;
> @@ -522,7 +528,8 @@ static int cap_chmod_acl(vfs_handle_struct *handle,
>  	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					cappath,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (cap_smb_fname == NULL) {
>  		TALLOC_FREE(cappath);
>  		errno = ENOMEM;
> diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
> index e2b4eb5..c5d2b6a 100644
> --- a/source3/modules/vfs_catia.c
> +++ b/source3/modules/vfs_catia.c
> @@ -290,7 +290,8 @@ static DIR *catia_opendir(vfs_handle_struct *handle,
>  	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
>  				name_mapped,
>  				NULL,
> -				NULL);
> +				NULL,
> +				smb_fname->flags);
>  	if (mapped_smb_fname == NULL) {
>  		TALLOC_FREE(mapped_smb_fname);
>  		errno = ENOMEM;
> @@ -543,7 +544,8 @@ static int catia_chown(vfs_handle_struct *handle,
>  	catia_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					name,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (catia_smb_fname == NULL) {
>  		TALLOC_FREE(name);
>  		errno = ENOMEM;
> @@ -580,7 +582,8 @@ static int catia_lchown(vfs_handle_struct *handle,
>  	catia_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					name,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (catia_smb_fname == NULL) {
>  		TALLOC_FREE(name);
>  		errno = ENOMEM;
> @@ -616,7 +619,8 @@ static int catia_chmod(vfs_handle_struct *handle,
>  	catia_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					name,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (catia_smb_fname == NULL) {
>  		TALLOC_FREE(name);
>  		errno = ENOMEM;
> @@ -650,7 +654,8 @@ static int catia_rmdir(vfs_handle_struct *handle,
>  	catia_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					name,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (catia_smb_fname == NULL) {
>  		TALLOC_FREE(name);
>  		errno = ENOMEM;
> @@ -684,7 +689,8 @@ static int catia_mkdir(vfs_handle_struct *handle,
>  	catia_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					name,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (catia_smb_fname == NULL) {
>  		TALLOC_FREE(name);
>  		errno = ENOMEM;
> @@ -819,7 +825,8 @@ catia_streaminfo(struct vfs_handle_struct *handle,
>  	catia_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					mapped_name,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (catia_smb_fname == NULL) {
>  		TALLOC_FREE(mapped_name);
>  		return NT_STATUS_NO_MEMORY;
> @@ -898,7 +905,8 @@ catia_get_nt_acl(struct vfs_handle_struct *handle,
>  	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					mapped_name,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (mapped_smb_fname == NULL) {
>  		TALLOC_FREE(mapped_name);
>  		return NT_STATUS_NO_MEMORY;
> @@ -935,7 +943,8 @@ catia_chmod_acl(vfs_handle_struct *handle,
>  	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					mapped_name,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (mapped_smb_fname == NULL) {
>  		TALLOC_FREE(mapped_name);
>  		errno = ENOMEM;
> diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
> index 23df640..65a14df 100644
> --- a/source3/modules/vfs_default.c
> +++ b/source3/modules/vfs_default.c
> @@ -133,7 +133,7 @@ static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
>  	 * use when setting a timestamp. */
>  
>  	smb_fname_cpath = synthetic_smb_fname(talloc_tos(), conn->connectpath,
> -					      NULL, NULL);
> +					      NULL, NULL, 0);
>  	if (smb_fname_cpath == NULL) {
>  		return caps;
>  	}
> diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
> index 491e1ac..55ff7db 100644
> --- a/source3/modules/vfs_fake_acls.c
> +++ b/source3/modules/vfs_fake_acls.c
> @@ -364,7 +364,7 @@ static int fake_acls_sys_acl_delete_def_file(vfs_handle_struct *handle, const ch
>  	TALLOC_CTX *frame = talloc_stackframe();
>  	struct smb_filename *smb_fname;
>  
> -	smb_fname = synthetic_smb_fname(frame, path, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(frame, path, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(frame);
>  		errno = ENOMEM;
> diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
> index 0c74286..492c174 100644
> --- a/source3/modules/vfs_fruit.c
> +++ b/source3/modules/vfs_fruit.c
> @@ -2132,7 +2132,10 @@ static int fruit_open_meta(vfs_handle_struct *handle,
>  
>  	/* Create an smb_filename with stream_name == NULL. */
>  	smb_fname_base = synthetic_smb_fname(talloc_tos(),
> -					     smb_fname->base_name, NULL, NULL);
> +					smb_fname->base_name,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  
>  	if (smb_fname_base == NULL) {
>  		errno = ENOMEM;
> @@ -2281,7 +2284,10 @@ static int fruit_open_rsrc(vfs_handle_struct *handle,
>  
>  	/* Create an smb_filename with stream_name == NULL. */
>  	smb_fname_base = synthetic_smb_fname(talloc_tos(),
> -					     adpath, NULL, NULL);
> +					adpath,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  	if (smb_fname_base == NULL) {
>  		errno = ENOMEM;
>  		rc = -1;
> @@ -2527,7 +2533,8 @@ static int fruit_chmod(vfs_handle_struct *handle,
>  	smb_fname_adp = synthetic_smb_fname(talloc_tos(),
>  					adp,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (smb_fname_adp == NULL) {
>  		TALLOC_FREE(adp);
>  		errno = ENOMEM;
> @@ -2583,7 +2590,8 @@ static int fruit_chown(vfs_handle_struct *handle,
>  	adp_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					adp,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (adp_smb_fname == NULL) {
>  		errno = ENOMEM;
>  		rc = -1;
> @@ -3802,7 +3810,8 @@ static void fruit_copy_chunk_done(struct tevent_req *subreq)
>  			req,
>  			state->src_fsp->fsp_name->base_name,
>  			streams[i].name,
> -			NULL);
> +			NULL,
> +			state->src_fsp->fsp_name->flags);
>  		if (tevent_req_nomem(src_fname_tmp, req)) {
>  			return;
>  		}
> @@ -3816,7 +3825,8 @@ static void fruit_copy_chunk_done(struct tevent_req *subreq)
>  			req,
>  			state->dst_fsp->fsp_name->base_name,
>  			streams[i].name,
> -			NULL);
> +			NULL,
> +			state->src_fsp->fsp_name->flags);
>  		if (tevent_req_nomem(dst_fname_tmp, req)) {
>  			TALLOC_FREE(src_fname_tmp);
>  			return;
> diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
> index 09e37fa..04d89f4 100644
> --- a/source3/modules/vfs_gpfs.c
> +++ b/source3/modules/vfs_gpfs.c
> @@ -1380,7 +1380,7 @@ static int gpfsacl_emu_chmod(vfs_handle_struct *handle,
>  
>  	/* don't add complementary DENY ACEs here */
>  	fake_fsp.fsp_name = synthetic_smb_fname(
> -		frame, path, NULL, NULL);
> +		frame, path, NULL, NULL, 0);
>  	if (fake_fsp.fsp_name == NULL) {
>  		errno = ENOMEM;
>  		TALLOC_FREE(frame);
> diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c
> index 55a6894..df27c89 100644
> --- a/source3/modules/vfs_hpuxacl.c
> +++ b/source3/modules/vfs_hpuxacl.c
> @@ -221,7 +221,7 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
>  	DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n",
>  		   name));
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(), name, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(talloc_tos(), name, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		status = NT_STATUS_NO_MEMORY;
>  		goto done;
> diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
> index 2ae6c4a..8f80221 100644
> --- a/source3/modules/vfs_media_harmony.c
> +++ b/source3/modules/vfs_media_harmony.c
> @@ -783,7 +783,8 @@ static DIR *mh_opendir(vfs_handle_struct *handle,
>  				synthetic_smb_fname(talloc_tos(),
>  					dirInfo->clientPath,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  		if (smb_fname_clientpath == NULL) {
>  			goto err;
>  		}
> @@ -2045,7 +2046,8 @@ static NTSTATUS mh_get_nt_acl(vfs_handle_struct *handle,
>  	client_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					clientPath,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (client_smb_fname == NULL) {
>  		TALLOC_FREE(clientPath);
>  		return NT_STATUS_NO_MEMORY;
> diff --git a/source3/modules/vfs_nfs4acl_xattr.c b/source3/modules/vfs_nfs4acl_xattr.c
> index af84b8b..9ab7238 100644
> --- a/source3/modules/vfs_nfs4acl_xattr.c
> +++ b/source3/modules/vfs_nfs4acl_xattr.c
> @@ -417,7 +417,7 @@ static struct SMB4ACL_T *nfs4acls_inheritacl(vfs_handle_struct *handle,
>  	TALLOC_CTX *frame = talloc_stackframe();
>  
>  	DEBUG(10, ("nfs4acls_inheritacl invoked for %s\n", path));
> -	smb_fname = synthetic_smb_fname(frame, path, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(frame, path, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(frame);
>  		errno = ENOMEM;
> diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c
> index 4981f55..ca3fc2e 100644
> --- a/source3/modules/vfs_recycle.c
> +++ b/source3/modules/vfs_recycle.c
> @@ -299,7 +299,8 @@ static bool recycle_create_dir(vfs_handle_struct *handle, const char *dname)
>  			smb_fname = synthetic_smb_fname(talloc_tos(),
>  						new_dir,
>  						NULL,
> -						NULL);
> +						NULL,
> +						0);
>  			if (smb_fname == NULL) {
>  				goto done;
>  			}
> @@ -587,8 +588,11 @@ static int recycle_unlink(vfs_handle_struct *handle,
>  	}
>  
>  	/* Create smb_fname with final base name and orig stream name. */
> -	smb_fname_final = synthetic_smb_fname(talloc_tos(), final_name,
> -					      smb_fname->stream_name, NULL);
> +	smb_fname_final = synthetic_smb_fname(talloc_tos(),
> +					final_name,
> +					smb_fname->stream_name,
> +					NULL,
> +					smb_fname->flags);
>  	if (smb_fname_final == NULL) {
>  		rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
>  		goto done;
> diff --git a/source3/modules/vfs_shadow_copy.c b/source3/modules/vfs_shadow_copy.c
> index 77dc163..9b43e85 100644
> --- a/source3/modules/vfs_shadow_copy.c
> +++ b/source3/modules/vfs_shadow_copy.c
> @@ -230,7 +230,8 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle,
>  	struct smb_filename *smb_fname = synthetic_smb_fname(talloc_tos(),
>  						fsp->conn->connectpath,
>  						NULL,
> -						NULL);
> +						NULL,
> +						0);
>  	if (smb_fname == NULL) {
>  		errno = ENOMEM;
>  		return -1;
> diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
> index c63d676..43bc89d 100644
> --- a/source3/modules/vfs_shadow_copy2.c
> +++ b/source3/modules/vfs_shadow_copy2.c
> @@ -719,7 +719,8 @@ static DIR *shadow_copy2_opendir(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		return NULL;
> @@ -998,7 +999,8 @@ static int shadow_copy2_chmod(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		errno = ENOMEM;
> @@ -1042,7 +1044,8 @@ static int shadow_copy2_chown(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		errno = ENOMEM;
> @@ -1442,7 +1445,8 @@ static int shadow_copy2_get_shadow_copy_data(
>  	snapdir_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					snapdir,
>  					NULL,
> -					NULL);
> +					NULL,
> +					fsp->fsp_name->flags);
>  	if (snapdir_smb_fname == NULL) {
>  		errno = ENOMEM;
>  		talloc_free(tmp_ctx);
> @@ -1543,7 +1547,8 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					fsp->fsp_name->flags);
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		return NT_STATUS_NO_MEMORY;
> @@ -1587,7 +1592,8 @@ static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		return NT_STATUS_NO_MEMORY;
> @@ -1627,7 +1633,8 @@ static int shadow_copy2_mkdir(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		return -1;
> @@ -1667,7 +1674,8 @@ static int shadow_copy2_rmdir(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		return -1;
> @@ -1853,7 +1861,8 @@ static int shadow_copy2_chmod_acl(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		errno = ENOMEM;
> diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
> index 11a99d9..64a83bd 100644
> --- a/source3/modules/vfs_snapper.c
> +++ b/source3/modules/vfs_snapper.c
> @@ -1972,7 +1972,8 @@ static DIR *snapper_gmt_opendir(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		errno = ENOMEM;
> @@ -2244,7 +2245,8 @@ static int snapper_gmt_chmod(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		errno = ENOMEM;
> @@ -2289,7 +2291,8 @@ static int snapper_gmt_chown(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		errno = ENOMEM;
> @@ -2485,7 +2488,8 @@ static NTSTATUS snapper_gmt_fget_nt_acl(vfs_handle_struct *handle,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					fsp->fsp_name->flags);
>  	TALLOC_FREE(conv);
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
> @@ -2525,7 +2529,8 @@ static NTSTATUS snapper_gmt_get_nt_acl(vfs_handle_struct *handle,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					fname->flags);
>  	TALLOC_FREE(conv);
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
> @@ -2562,7 +2567,8 @@ static int snapper_gmt_mkdir(vfs_handle_struct *handle,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					fname->flags);
>  	TALLOC_FREE(conv);
>  	if (smb_fname == NULL) {
>  		errno = ENOMEM;
> @@ -2600,7 +2606,8 @@ static int snapper_gmt_rmdir(vfs_handle_struct *handle,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					fname->flags);
>  	TALLOC_FREE(conv);
>  	if (smb_fname == NULL) {
>  		errno = ENOMEM;
> @@ -2786,7 +2793,8 @@ static int snapper_gmt_chmod_acl(vfs_handle_struct *handle,
>  	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					conv,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (conv_smb_fname == NULL) {
>  		TALLOC_FREE(conv);
>  		errno = ENOMEM;
> diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
> index 5a97444..2b80b9d 100644
> --- a/source3/modules/vfs_streams_depot.c
> +++ b/source3/modules/vfs_streams_depot.c
> @@ -148,7 +148,8 @@ static char *stream_dir(vfs_handle_struct *handle,
>  	rootdir_fname = synthetic_smb_fname(talloc_tos(),
>  					rootdir,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (rootdir_fname == NULL) {
>  		errno = ENOMEM;
>  		goto fail;
> @@ -159,7 +160,11 @@ static char *stream_dir(vfs_handle_struct *handle,
>  		struct smb_filename *smb_fname_base;
>  
>  		smb_fname_base = synthetic_smb_fname(
> -			talloc_tos(), smb_fname->base_name, NULL, NULL);
> +					talloc_tos(),
> +					smb_fname->base_name,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  		if (smb_fname_base == NULL) {
>  			errno = ENOMEM;
>  			goto fail;
> @@ -200,7 +205,11 @@ static char *stream_dir(vfs_handle_struct *handle,
>  		return NULL;
>  	}
>  
> -	smb_fname_hash = synthetic_smb_fname(talloc_tos(), result, NULL, NULL);
> +	smb_fname_hash = synthetic_smb_fname(talloc_tos(),
> +					result,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  	if (smb_fname_hash == NULL) {
>  		errno = ENOMEM;
>  		goto fail;
> @@ -251,7 +260,11 @@ static char *stream_dir(vfs_handle_struct *handle,
>  			}
>  
>  			smb_fname_new = synthetic_smb_fname(
> -				talloc_tos(), newname, NULL, NULL);
> +						talloc_tos(),
> +						newname,
> +						NULL,
> +						NULL,
> +						smb_fname->flags);
>  			TALLOC_FREE(newname);
>  			if (smb_fname_new == NULL) {
>  				errno = ENOMEM;
> @@ -287,7 +300,11 @@ static char *stream_dir(vfs_handle_struct *handle,
>  		goto fail;
>  	}
>  
> -	tmp_fname = synthetic_smb_fname(talloc_tos(), tmp, NULL, NULL);
> +	tmp_fname = synthetic_smb_fname(talloc_tos(),
> +					tmp,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  	if (tmp_fname == NULL) {
>  		errno = ENOMEM;
>  		goto fail;
> @@ -308,7 +325,11 @@ static char *stream_dir(vfs_handle_struct *handle,
>  		goto fail;
>  	}
>  
> -	tmp_fname = synthetic_smb_fname(talloc_tos(), tmp, NULL, NULL);
> +	tmp_fname = synthetic_smb_fname(talloc_tos(),
> +					tmp,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  	if (tmp_fname == NULL) {
>  		errno = ENOMEM;
>  		goto fail;
> @@ -403,8 +424,11 @@ static NTSTATUS stream_smb_fname(vfs_handle_struct *handle,
>  	DEBUG(10, ("stream filename = %s\n", stream_fname));
>  
>  	/* Create an smb_filename with stream_name == NULL. */
> -	*smb_fname_out = synthetic_smb_fname(
> -		talloc_tos(), stream_fname, NULL, NULL);
> +	*smb_fname_out = synthetic_smb_fname(talloc_tos(),
> +					stream_fname,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  	if (*smb_fname_out == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> @@ -449,7 +473,8 @@ static NTSTATUS walk_streams(vfs_handle_struct *handle,
>  	dir_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					dirname,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname_base->flags);
>  	if (dir_smb_fname == NULL) {
>  		TALLOC_FREE(dirname);
>  		return NT_STATUS_NO_MEMORY;
> @@ -615,8 +640,11 @@ static int streams_depot_open(vfs_handle_struct *handle,
>  	}
>  
>  	/* Ensure the base file still exists. */
> -	smb_fname_base = synthetic_smb_fname(
> -		talloc_tos(), smb_fname->base_name, NULL, NULL);
> +	smb_fname_base = synthetic_smb_fname(talloc_tos(),
> +					smb_fname->base_name,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  	if (smb_fname_base == NULL) {
>  		ret = -1;
>  		errno = ENOMEM;
> @@ -676,8 +704,11 @@ static int streams_depot_unlink(vfs_handle_struct *handle,
>  	 * We potentially need to delete the per-inode streams directory
>  	 */
>  
> -	smb_fname_base = synthetic_smb_fname(
> -		talloc_tos(), smb_fname->base_name, NULL, NULL);
> +	smb_fname_base = synthetic_smb_fname(talloc_tos(),
> +					smb_fname->base_name,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  	if (smb_fname_base == NULL) {
>  		errno = ENOMEM;
>  		return -1;
> @@ -704,7 +735,8 @@ static int streams_depot_unlink(vfs_handle_struct *handle,
>  				synthetic_smb_fname(talloc_tos(),
>  						dirname,
>  						NULL,
> -						NULL);
> +						NULL,
> +						smb_fname->flags);
>  			if (smb_fname_dir == NULL) {
>  				TALLOC_FREE(smb_fname_base);
>  				TALLOC_FREE(dirname);
> @@ -737,7 +769,8 @@ static int streams_depot_rmdir(vfs_handle_struct *handle,
>  	smb_fname_base = synthetic_smb_fname(talloc_tos(),
>  				smb_fname->base_name,
>  				NULL,
> -				NULL);
> +				NULL,
> +				smb_fname->flags);
>  	if (smb_fname_base == NULL) {
>  		errno = ENOMEM;
>  		return -1;
> @@ -764,7 +797,8 @@ static int streams_depot_rmdir(vfs_handle_struct *handle,
>  				synthetic_smb_fname(talloc_tos(),
>  						dirname,
>  						NULL,
> -						NULL);
> +						NULL,
> +						smb_fname->flags);
>  			if (smb_fname_dir == NULL) {
>  				TALLOC_FREE(smb_fname_base);
>  				TALLOC_FREE(dirname);
> @@ -884,7 +918,7 @@ static bool collect_one_stream(const char *dirname,
>  		goto out;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(), sname, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(talloc_tos(), sname, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		state->status = NT_STATUS_NO_MEMORY;
>  		ret = false;
> @@ -930,7 +964,8 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
>  	smb_fname_base = synthetic_smb_fname(talloc_tos(),
>  					smb_fname->base_name,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (smb_fname_base == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
> index 0d54734..b3b8002 100644
> --- a/source3/modules/vfs_streams_xattr.c
> +++ b/source3/modules/vfs_streams_xattr.c
> @@ -242,8 +242,11 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
>  	}
>  
>  	/* Create an smb_filename with stream_name == NULL. */
> -	smb_fname_base = synthetic_smb_fname(talloc_tos(), io->base,
> -					     NULL, NULL);
> +	smb_fname_base = synthetic_smb_fname(talloc_tos(),
> +					io->base,
> +					NULL,
> +					NULL,
> +					fsp->fsp_name->flags);
>  	if (smb_fname_base == NULL) {
>  		errno = ENOMEM;
>  		return -1;
> @@ -427,8 +430,11 @@ static int streams_xattr_open(vfs_handle_struct *handle,
>  	}
>  
>  	/* Create an smb_filename with stream_name == NULL. */
> -	smb_fname_base = synthetic_smb_fname(
> -		talloc_tos(), smb_fname->base_name, NULL, NULL);
> +	smb_fname_base = synthetic_smb_fname(talloc_tos(),
> +				smb_fname->base_name,
> +				NULL,
> +				NULL,
> +				smb_fname->flags);
>  	if (smb_fname_base == NULL) {
>  		errno = ENOMEM;
>  		goto fail;
> diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
> index 4bbb8fb..3b3493d 100644
> --- a/source3/modules/vfs_unityed_media.c
> +++ b/source3/modules/vfs_unityed_media.c
> @@ -571,7 +571,8 @@ static DIR *um_opendir(vfs_handle_struct *handle,
>  			synthetic_smb_fname(talloc_tos(),
>  					dirInfo->clientPath,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  		if (client_smb_fname == NULL) {
>  			goto err;
>  		}
> @@ -1561,7 +1562,8 @@ static NTSTATUS um_get_nt_acl(vfs_handle_struct *handle,
>  	client_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					client_path,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  	if (client_smb_fname == NULL) {
>  		TALLOC_FREE(client_path);
>  		return NT_STATUS_NO_MEMORY;
> diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c
> index 4bfbef3..bcd7ae3 100644
> --- a/source3/modules/vfs_vxfs.c
> +++ b/source3/modules/vfs_vxfs.c
> @@ -421,7 +421,7 @@ static bool vxfs_compare(connection_struct *conn, char *name, SMB_ACL_T the_acl,
>  		goto out;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(mem_ctx, name, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(mem_ctx, name, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		DEBUG(10, ("vfs_vxfs: Failed to create smb_fname\n"));
>  		goto out;
> diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
> index a22192b..aac8245 100644
> --- a/source3/modules/vfs_xattr_tdb.c
> +++ b/source3/modules/vfs_xattr_tdb.c
> @@ -37,7 +37,7 @@ static int xattr_tdb_get_file_id(struct vfs_handle_struct *handle,
>  	TALLOC_CTX *frame = talloc_stackframe();
>  	struct smb_filename *smb_fname;
>  
> -	smb_fname = synthetic_smb_fname(frame, path, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(frame, path, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(frame);
>  		errno = ENOMEM;
> diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
> index 3d6cfb1..36e7324 100644
> --- a/source3/printing/nt_printing.c
> +++ b/source3/printing/nt_printing.c
> @@ -1585,7 +1585,7 @@ static NTSTATUS driver_unlink_internals(connection_struct *conn,
>  		goto err_out;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(tmp_ctx, print_dlr_path, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(tmp_ctx, print_dlr_path, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		goto err_out;
>  	}
> diff --git a/source3/printing/printspoolss.c b/source3/printing/printspoolss.c
> index 883e81f..ebf6d39 100644
> --- a/source3/printing/printspoolss.c
> +++ b/source3/printing/printspoolss.c
> @@ -212,7 +212,7 @@ NTSTATUS print_spool_open(files_struct *fsp,
>  	}
>  
>  	/* setup a full fsp */
> -	fsp->fsp_name = synthetic_smb_fname(fsp, pf->filename, NULL, NULL);
> +	fsp->fsp_name = synthetic_smb_fname(fsp, pf->filename, NULL, NULL, 0);
>  	if (fsp->fsp_name == NULL) {
>  		status = NT_STATUS_NO_MEMORY;
>  		goto done;
> diff --git a/source3/rpc_server/fss/srv_fss_agent.c b/source3/rpc_server/fss/srv_fss_agent.c
> index 68a5143..2a1f770 100644
> --- a/source3/rpc_server/fss/srv_fss_agent.c
> +++ b/source3/rpc_server/fss/srv_fss_agent.c
> @@ -173,7 +173,7 @@ static bool snap_path_exists(TALLOC_CTX *ctx, struct messaging_context *msg_ctx,
>  		goto out;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(service, sc->sc_path, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(service, sc->sc_path, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		goto out;
>  	}
> diff --git a/source3/smbd/close.c b/source3/smbd/close.c
> index 3b887c8..0302c67 100644
> --- a/source3/smbd/close.c
> +++ b/source3/smbd/close.c
> @@ -204,7 +204,8 @@ NTSTATUS delete_all_streams(connection_struct *conn,
>  		smb_fname_stream = synthetic_smb_fname(talloc_tos(),
>  					smb_fname->base_name,
>  					stream_info[i].name,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  
>  		if (smb_fname_stream == NULL) {
>  			DEBUG(0, ("talloc_aprintf failed\n"));
> @@ -833,8 +834,11 @@ bool recursive_rmdir(TALLOC_CTX *ctx,
>  			goto err_break;
>  		}
>  
> -		smb_dname_full = synthetic_smb_fname(talloc_tos(), fullname,
> -						     NULL, NULL);
> +		smb_dname_full = synthetic_smb_fname(talloc_tos(),
> +						fullname,
> +						NULL,
> +						NULL,
> +						smb_dname->flags);
>  		if (smb_dname_full == NULL) {
>  			errno = ENOMEM;
>  			goto err_break;
> @@ -984,8 +988,11 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
>  				goto err_break;
>  			}
>  
> -			smb_dname_full = synthetic_smb_fname(
> -				talloc_tos(), fullname, NULL, NULL);
> +			smb_dname_full = synthetic_smb_fname(talloc_tos(),
> +							fullname,
> +							NULL,
> +							NULL,
> +							smb_dname->flags);
>  			if (smb_dname_full == NULL) {
>  				errno = ENOMEM;
>  				goto err_break;
> diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
> index 82841eb..3c6f000 100644
> --- a/source3/smbd/dir.c
> +++ b/source3/smbd/dir.c
> @@ -413,8 +413,11 @@ static struct smb_Dir *open_dir_with_privilege(connection_struct *conn,
>  	}
>  
>  	/* Now check the stat value is the same. */
> -	smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
> -
> +	smb_fname_cwd = synthetic_smb_fname(talloc_tos(),
> +					".",
> +					NULL,
> +					NULL,
> +					smb_dname->flags);
>  	if (smb_fname_cwd == NULL) {
>  		goto out;
>  	}
> @@ -1545,8 +1548,11 @@ bool is_visible_file(connection_struct *conn, const char *dir_path,
>  		}
>  
>  		/* Create an smb_filename with stream_name == NULL. */
> -		smb_fname_base = synthetic_smb_fname(talloc_tos(), entry, NULL,
> -						     pst);
> +		smb_fname_base = synthetic_smb_fname(talloc_tos(),
> +						entry,
> +						NULL,
> +						pst,
> +						0);
>  		if (smb_fname_base == NULL) {
>  			ret = false;
>  			goto out;
> diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
> index 60761c2..7a15bae 100644
> --- a/source3/smbd/dosmode.c
> +++ b/source3/smbd/dosmode.c
> @@ -135,8 +135,11 @@ mode_t unix_mode(connection_struct *conn, int dosmode,
>  			  smb_fname_str_dbg(smb_fname),
>  			  inherit_from_dir));
>  
> -		smb_fname_parent = synthetic_smb_fname(
> -			talloc_tos(), inherit_from_dir, NULL, NULL);
> +		smb_fname_parent = synthetic_smb_fname(talloc_tos(),
> +					inherit_from_dir,
> +					NULL,
> +					NULL,
> +					smb_fname->flags);
>  		if (smb_fname_parent == NULL) {
>  			DEBUG(1,("unix_mode(%s) failed, [dir %s]: No memory\n",
>  				 smb_fname_str_dbg(smb_fname),
> @@ -1022,8 +1025,11 @@ NTSTATUS set_create_timespec_ea(connection_struct *conn,
>  		return NT_STATUS_OK;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(), psmb_fname->base_name,
> -					NULL, &psmb_fname->st);
> +	smb_fname = synthetic_smb_fname(talloc_tos(),
> +					psmb_fname->base_name,
> +					NULL,
> +					&psmb_fname->st,
> +					psmb_fname->flags);
>  
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
> diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c
> index d9b88a8..f39a365 100644
> --- a/source3/smbd/durable.c
> +++ b/source3/smbd/durable.c
> @@ -598,8 +598,11 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
>  	}
>  
>  	/* Create an smb_filename with stream_name == NULL. */
> -	smb_fname = synthetic_smb_fname(talloc_tos(), cookie.base_name,
> -					NULL, NULL);
> +	smb_fname = synthetic_smb_fname(talloc_tos(),
> +					cookie.base_name,
> +					NULL,
> +					NULL,
> +					0);
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
> index 0a6d6b1..66c9ed3 100644
> --- a/source3/smbd/file_access.c
> +++ b/source3/smbd/file_access.c
> @@ -54,7 +54,11 @@ bool can_delete_file_in_directory(connection_struct *conn,
>  		return False;
>  	}
>  
> -	smb_fname_parent = synthetic_smb_fname(ctx, dname, NULL, NULL);
> +	smb_fname_parent = synthetic_smb_fname(ctx,
> +				dname,
> +				NULL,
> +				NULL,
> +				smb_fname->flags);
>  	if (smb_fname_parent == NULL) {
>  		ret = false;
>  		goto out;
> @@ -155,7 +159,8 @@ bool directory_has_default_acl(connection_struct *conn, const char *fname)
>  	struct smb_filename *smb_fname = synthetic_smb_fname(talloc_tos(),
>  						fname,
>  						NULL,
> -						NULL);
> +						NULL,
> +						0);
>  
>  	if (smb_fname == NULL) {
>  		return false;
> diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
> index a1920c3..7271466 100644
> --- a/source3/smbd/filename.c
> +++ b/source3/smbd/filename.c
> @@ -1202,7 +1202,8 @@ static int get_real_filename_full_scan(connection_struct *conn,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					path,
>  					NULL,
> -					NULL);
> +					NULL,
> +					0);
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(unmangled_name);
>  		return -1;
> diff --git a/source3/smbd/files.c b/source3/smbd/files.c
> index 3e2b3d7..a3cce13 100644
> --- a/source3/smbd/files.c
> +++ b/source3/smbd/files.c
> @@ -118,7 +118,7 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
>  	 * few NULL checks, so make sure it's initialized with something. to
>  	 * be safe until an audit can be done.
>  	 */
> -	fsp->fsp_name = synthetic_smb_fname(fsp, "", NULL, NULL);
> +	fsp->fsp_name = synthetic_smb_fname(fsp, "", NULL, NULL, 0);
>  	if (fsp->fsp_name == NULL) {
>  		file_free(NULL, fsp);
>  		return NT_STATUS_NO_MEMORY;
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index fe95877..647ac3b 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -1311,8 +1311,11 @@ bool create_msdfs_link(const struct junction_map *jucn)
>  		if (errno == EEXIST) {
>  			struct smb_filename *smb_fname;
>  
> -			smb_fname = synthetic_smb_fname(talloc_tos(), path,
> -							NULL, NULL);
> +			smb_fname = synthetic_smb_fname(talloc_tos(),
> +						path,
> +						NULL,
> +						NULL,
> +						0);
>  			if (smb_fname == NULL) {
>  				errno = ENOMEM;
>  				goto out;
> @@ -1353,7 +1356,11 @@ bool remove_msdfs_link(const struct junction_map *jucn)
>  		return false;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(), path, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(talloc_tos(),
> +					path,
> +					NULL,
> +					NULL,
> +					0);
>  	if (smb_fname == NULL) {
>  		errno = ENOMEM;
>  		return false;
> @@ -1417,7 +1424,8 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					".",
>  					NULL,
> -					NULL);
> +					NULL,
> +					0);
>  	if (smb_fname == NULL) {
>  		goto out;
>  	}
> @@ -1534,7 +1542,8 @@ static int form_junctions(TALLOC_CTX *ctx,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					".",
>  					NULL,
> -					NULL);
> +					NULL,
> +					0);
>  	if (smb_fname == NULL) {
>  		goto out;
>  	}
> diff --git a/source3/smbd/open.c b/source3/smbd/open.c
> index e5503f5..d111254 100644
> --- a/source3/smbd/open.c
> +++ b/source3/smbd/open.c
> @@ -255,7 +255,8 @@ static NTSTATUS check_parent_access(struct connection_struct *conn,
>  	parent_smb_fname = synthetic_smb_fname(talloc_tos(),
>  				parent_dir,
>  				NULL,
> -				NULL);
> +				NULL,
> +				smb_fname->flags);
>  	if (parent_smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> @@ -457,8 +458,11 @@ void change_file_owner_to_parent(connection_struct *conn,
>  	struct smb_filename *smb_fname_parent;
>  	int ret;
>  
> -	smb_fname_parent = synthetic_smb_fname(talloc_tos(), inherit_from_dir,
> -					       NULL, NULL);
> +	smb_fname_parent = synthetic_smb_fname(talloc_tos(),
> +					inherit_from_dir,
> +					NULL,
> +					NULL,
> +					0);
>  	if (smb_fname_parent == NULL) {
>  		return;
>  	}
> @@ -515,8 +519,11 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
>  	NTSTATUS status = NT_STATUS_OK;
>  	int ret;
>  
> -	smb_fname_parent = synthetic_smb_fname(ctx, inherit_from_dir,
> -					       NULL, NULL);
> +	smb_fname_parent = synthetic_smb_fname(ctx,
> +					inherit_from_dir,
> +					NULL,
> +					NULL,
> +					0);
>  	if (smb_fname_parent == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> @@ -556,7 +563,7 @@ NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
>  		goto chdir;
>  	}
>  
> -	smb_fname_cwd = synthetic_smb_fname(ctx, ".", NULL, NULL);
> +	smb_fname_cwd = synthetic_smb_fname(ctx, ".", NULL, NULL, 0);
>  	if (smb_fname_cwd == NULL) {
>  		status = NT_STATUS_NO_MEMORY;
>  		goto chdir;
> @@ -3812,8 +3819,11 @@ void msg_file_was_renamed(struct messaging_context *msg,
>  		stream_name = NULL;
>  	}
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(), base_name,
> -					stream_name, NULL);
> +	smb_fname = synthetic_smb_fname(talloc_tos(),
> +					base_name,
> +					stream_name,
> +					NULL,
> +					0);
>  	if (smb_fname == NULL) {
>  		return;
>  	}
> @@ -3911,7 +3921,8 @@ static NTSTATUS open_streams_for_delete(connection_struct *conn,
>  		smb_fname_cp = synthetic_smb_fname(talloc_tos(),
>  					smb_fname->base_name,
>  					stream_info[i].name,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  		if (smb_fname_cp == NULL) {
>  			status = NT_STATUS_NO_MEMORY;
>  			goto fail;
> @@ -4009,7 +4020,8 @@ static NTSTATUS inherit_new_acl(files_struct *fsp)
>  	parent_smb_fname = synthetic_smb_fname(talloc_tos(),
>  						parent_name,
>  						NULL,
> -						NULL);
> +						NULL,
> +						fsp->fsp_name->flags);
>  
>  	if (parent_smb_fname == NULL) {
>  		TALLOC_FREE(frame);
> @@ -4564,8 +4576,10 @@ static NTSTATUS create_file_unixpath(connection_struct *conn,
>  
>  		/* Create an smb_filename with stream_name == NULL. */
>  		smb_fname_base = synthetic_smb_fname(talloc_tos(),
> -						     smb_fname->base_name,
> -						     NULL, NULL);
> +						smb_fname->base_name,
> +						NULL,
> +						NULL,
> +						smb_fname->flags);
>  		if (smb_fname_base == NULL) {
>  			status = NT_STATUS_NO_MEMORY;
>  			goto fail;
> diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
> index 455dbf0..2c9516d 100644
> --- a/source3/smbd/pipes.c
> +++ b/source3/smbd/pipes.c
> @@ -51,7 +51,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
>  	fsp->can_lock = false;
>  	fsp->access_mask = FILE_READ_DATA | FILE_WRITE_DATA;
>  
> -	smb_fname = synthetic_smb_fname(talloc_tos(), name, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(talloc_tos(), name, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		file_free(smb_req, fsp);
>  		return NT_STATUS_NO_MEMORY;
> diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
> index c4eeb9c..8fc7cba 100644
> --- a/source3/smbd/posix_acls.c
> +++ b/source3/smbd/posix_acls.c
> @@ -4642,7 +4642,8 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
>  	struct smb_filename *smb_fname = synthetic_smb_fname(talloc_tos(),
>  						fname,
>  						NULL,
> -						NULL);
> +						NULL,
> +						0);
>  
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(frame);
> @@ -4809,7 +4810,7 @@ int posix_sys_acl_blob_get_file(vfs_handle_struct *handle,
>  	};
>  	struct smb_filename *smb_fname;
>  
> -	smb_fname = synthetic_smb_fname(frame, path_p, NULL, NULL);
> +	smb_fname = synthetic_smb_fname(frame, path_p, NULL, NULL, 0);
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(frame);
>  		errno = ENOMEM;
> diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
> index 4d95bcf..fca8f10 100644
> --- a/source3/smbd/pysmbd.c
> +++ b/source3/smbd/pysmbd.c
> @@ -199,9 +199,11 @@ static NTSTATUS get_nt_acl_conn(TALLOC_CTX *mem_ctx,
>  	TALLOC_CTX *frame = talloc_stackframe();
>  	NTSTATUS status;
>  	struct smb_filename *smb_fname = synthetic_smb_fname(talloc_tos(),
> -						fname,
> -						NULL,
> -						NULL);
> +					fname,
> +					NULL,
> +					NULL,
> +					lp_posix_pathnames() ?
> +						SMB_FILENAME_POSIX_PATH : 0);
>  
>  	if (smb_fname == NULL) {
>  		TALLOC_FREE(frame);
> @@ -398,7 +400,9 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs)
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					fname,
>  					NULL,
> -					NULL);
> +					NULL,
> +					lp_posix_pathnames() ?
> +						SMB_FILENAME_POSIX_PATH : 0);
>  	if (smb_fname == NULL) {
>  		umask(saved_umask);
>  		TALLOC_FREE(frame);
> diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
> index c18eb38..cbe15a3 100644
> --- a/source3/smbd/reply.c
> +++ b/source3/smbd/reply.c
> @@ -1825,7 +1825,8 @@ void reply_search(struct smb_request *req)
>  		smb_dname = synthetic_smb_fname(talloc_tos(),
>  					directory,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  		if (smb_dname == NULL) {
>  			reply_nterror(req, NT_STATUS_NO_MEMORY);
>  			goto out;
> @@ -3088,7 +3089,8 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
>  		smb_fname_dir = synthetic_smb_fname(talloc_tos(),
>  					fname_dir,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname->flags);
>  		if (smb_fname_dir == NULL) {
>  			status = NT_STATUS_NO_MEMORY;
>  			goto out;
> @@ -7064,7 +7066,8 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
>  	smb_fname_src_dir = synthetic_smb_fname(talloc_tos(),
>  				fname_src_dir,
>  				NULL,
> -				NULL);
> +				NULL,
> +				smb_fname_src->flags);
>  	if (smb_fname_src_dir == NULL) {
>  		status = NT_STATUS_NO_MEMORY;
>  		goto out;
> @@ -7779,7 +7782,8 @@ void reply_copy(struct smb_request *req)
>  		smb_fname_src_dir = synthetic_smb_fname(talloc_tos(),
>  					fname_src_dir,
>  					NULL,
> -					NULL);
> +					NULL,
> +					smb_fname_src->flags);
>  		if (smb_fname_src_dir == NULL) {
>  			reply_nterror(req, NT_STATUS_NO_MEMORY);
>  			goto out;
> diff --git a/source3/smbd/service.c b/source3/smbd/service.c
> index ba8946d..2777a09 100644
> --- a/source3/smbd/service.c
> +++ b/source3/smbd/service.c
> @@ -814,8 +814,11 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
>  		set_namearray( &conn->aio_write_behind_list,
>  				lp_aio_write_behind(talloc_tos(), snum));
>  	}
> -	smb_fname_cpath = synthetic_smb_fname(talloc_tos(), conn->connectpath,
> -					      NULL, NULL);
> +	smb_fname_cpath = synthetic_smb_fname(talloc_tos(),
> +					conn->connectpath,
> +					NULL,
> +					NULL,
> +					0);
>  	if (smb_fname_cpath == NULL) {
>  		status = NT_STATUS_NO_MEMORY;
>  		goto err_root_exit;
> diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
> index e23b893..a76b2df 100644
> --- a/source3/smbd/trans2.c
> +++ b/source3/smbd/trans2.c
> @@ -5764,8 +5764,11 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
>  
>  			/* Create an smb_filename with stream_name == NULL. */
>  			smb_fname_base = synthetic_smb_fname(
> -				talloc_tos(), smb_fname->base_name,
> -				NULL, NULL);
> +						talloc_tos(),
> +						smb_fname->base_name,
> +						NULL,
> +						NULL,
> +						smb_fname->flags);
>  			if (smb_fname_base == NULL) {
>  				reply_nterror(req, NT_STATUS_NO_MEMORY);
>  				return;
> @@ -6163,8 +6166,11 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
>  	}
>  
>  	/* Always operate on the base_name, even if a stream was passed in. */
> -	smb_fname_base = synthetic_smb_fname(
> -		talloc_tos(), smb_fname->base_name, NULL, &smb_fname->st);
> +	smb_fname_base = synthetic_smb_fname(talloc_tos(),
> +					smb_fname->base_name,
> +					NULL,
> +					&smb_fname->st,
> +					smb_fname->flags);
>  	if (smb_fname_base == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> @@ -6666,9 +6672,11 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn,
>  		}
>  
>  		/* Create an smb_fname to call rename_internals_fsp() with. */
> -		smb_fname_dst = synthetic_smb_fname(
> -			talloc_tos(), fsp->base_fsp->fsp_name->base_name,
> -			newname, NULL);
> +		smb_fname_dst = synthetic_smb_fname(talloc_tos(),
> +					fsp->base_fsp->fsp_name->base_name,
> +					newname,
> +					NULL,
> +					fsp->base_fsp->fsp_name->flags);
>  		if (smb_fname_dst == NULL) {
>  			status = NT_STATUS_NO_MEMORY;
>  			goto out;
> @@ -6872,9 +6880,11 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
>  		}
>  
>  		/* Create an smb_fname to call rename_internals_fsp() with. */
> -		smb_fname_dst = synthetic_smb_fname(
> -			talloc_tos(), fsp->base_fsp->fsp_name->base_name,
> -			newname, NULL);
> +		smb_fname_dst = synthetic_smb_fname(talloc_tos(),
> +					fsp->base_fsp->fsp_name->base_name,
> +					newname,
> +					NULL,
> +					fsp->base_fsp->fsp_name->flags);
>  		if (smb_fname_dst == NULL) {
>  			status = NT_STATUS_NO_MEMORY;
>  			goto out;
> @@ -6944,8 +6954,11 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
>  				goto out;
>  			}
>  			/* Create an smb_fname to call rename_internals_fsp() */
> -			smb_fname_dst = synthetic_smb_fname(
> -				ctx, base_name, NULL, NULL);
> +			smb_fname_dst = synthetic_smb_fname(ctx,
> +						base_name,
> +						NULL,
> +						NULL,
> +						smb_fname_src->flags);
>  			if (smb_fname_dst == NULL) {
>  				status = NT_STATUS_NO_MEMORY;
>  				goto out;
> diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
> index a1154ae..972cea4 100644
> --- a/source3/smbd/vfs.c
> +++ b/source3/smbd/vfs.c
> @@ -876,7 +876,7 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
>  		goto nocache;
>  	}
>  
> -	smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL);
> +	smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL, 0);
>  	if (smb_fname_dot == NULL) {
>  		errno = ENOMEM;
>  		goto out;
> @@ -904,7 +904,7 @@ char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
>  		   && (cache_value.data[cache_value.length-1] == '\0'));
>  
>  	smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
> -					     NULL, NULL);
> +					     NULL, NULL, 0);
>  	if (smb_fname_full == NULL) {
>  		errno = ENOMEM;
>  		goto out;
> @@ -1044,7 +1044,7 @@ NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
>  		resolved_name));
>  
>  	/* Now check the stat value is the same. */
> -	smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
> +	smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, 0);
>  	if (smb_fname_cwd == NULL) {
>  		status = NT_STATUS_NO_MEMORY;
>  		goto err;
> @@ -1968,7 +1968,8 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
>  		local_smb_fname = synthetic_smb_fname(talloc_tos(),
>  					final_component,
>  					NULL,
> -					NULL);
> +					NULL,
> +					fsp->fsp_name->flags);
>  		if (local_smb_fname == NULL) {
>  			status = NT_STATUS_NO_MEMORY;
>  			goto out;
> diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
> index 7c49ce7..12610cf 100644
> --- a/source3/torture/cmd_vfs.c
> +++ b/source3/torture/cmd_vfs.c
> @@ -30,6 +30,11 @@
>  
>  static const char *null_string = "";
>  
> +static uint32_t ssf_flags(void)
> +{
> +	return lp_posix_pathnames() ? SMB_FILENAME_POSIX_PATH : 0;
> +}
> +
>  static NTSTATUS cmd_load_module(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
>  {
>  	int i;
> @@ -139,7 +144,8 @@ static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					argv[1],
>  					NULL,
> -					NULL);
> +					NULL,
> +					ssf_flags());
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> @@ -222,7 +228,8 @@ static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					argv[1],
>  					NULL,
> -					NULL);
> +					NULL,
> +					ssf_flags());
>  
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
> @@ -424,7 +431,8 @@ static NTSTATUS cmd_pathfunc(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					argv[1],
>  					NULL,
> -					NULL);
> +					NULL,
> +					ssf_flags());
>  
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
> @@ -859,7 +867,8 @@ static NTSTATUS cmd_chmod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					argv[1],
>  					NULL,
> -					NULL);
> +					NULL,
> +					ssf_flags());
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> @@ -918,7 +927,8 @@ static NTSTATUS cmd_chmod_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					argv[1],
>  					NULL,
> -					NULL);
> +					NULL,
> +					ssf_flags());
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> @@ -979,7 +989,8 @@ static NTSTATUS cmd_chown(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					argv[1],
>  					NULL,
> -					NULL);
> +					NULL,
> +					ssf_flags());
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> @@ -1459,7 +1470,8 @@ static NTSTATUS cmd_get_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					argv[1],
>  					NULL,
> -					NULL);
> +					NULL,
> +					ssf_flags());
>  
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
> @@ -1796,7 +1808,8 @@ static NTSTATUS cmd_translate_name(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
>  	smb_fname = synthetic_smb_fname(talloc_tos(),
>  					".",
>  					NULL,
> -					NULL);
> +					NULL,
> +					ssf_flags());
>  	if (smb_fname == NULL) {
>  		return NT_STATUS_NO_MEMORY;
>  	}
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From f61fe7021bb55d4b3e6a4d46d6ee5d4600e10cd8 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Fri, 18 Mar 2016 21:31:22 -0700
> Subject: [PATCH 06/14] s3: vfs: Remove use of lp_posix_pathnames() below the
>  VFS.
> 
> We don't have access to a struct smb_filename here and
> can't get one, so simply always set AT_SYMLINK_NOFOLLOW
> and remove the optimization if we ended up fstatat()'ing
> a symlink, as we don't know if the caller wanted a link
> stat or not.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/modules/vfs_default.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
> index 65a14df..a7004a0 100644
> --- a/source3/modules/vfs_default.c
> +++ b/source3/modules/vfs_default.c
> @@ -419,13 +419,20 @@ static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
>  		if (result != NULL) {
>  			/* See if we can efficiently return this. */
>  			struct stat st;
> -			int flags = (lp_posix_pathnames() ?
> -				AT_SYMLINK_NOFOLLOW : 0);
> +			int flags = AT_SYMLINK_NOFOLLOW;
>  			int ret = fstatat(dirfd(dirp),
>  					result->d_name,
>  					&st,
>  					flags);
> -			if (ret == 0) {
> +			/*
> +			 * As this is an optimization,
> +			 * ignore it if we stat'ed a
> +			 * symlink. Make the caller
> +			 * do it again as we don't
> +			 * know if they wanted the link
> +			 * info, or its target info.
> +			 */
> +			if ((ret == 0) && (!S_ISLNK(st.st_mode))) {
>  				init_stat_ex_from_stat(sbuf,
>  					&st,
>  					lp_fake_directory_create_times(
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 400f7d1a8a9fc8bc985b8bec1ebf2b64555fcec3 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Fri, 18 Mar 2016 21:50:15 -0700
> Subject: [PATCH 07/14] s3: posix_acls. Always use STAT, not LSTAT here.
> 
> We have already refused acls on a symlink.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/smbd/posix_acls.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
> index 8fc7cba..2bb90c4 100644
> --- a/source3/smbd/posix_acls.c
> +++ b/source3/smbd/posix_acls.c
> @@ -3566,11 +3566,13 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn,
>  	}
>  
>  	/* Get the stat struct for the owner info. */
> -	if (lp_posix_pathnames()) {
> -		ret = SMB_VFS_LSTAT(conn, smb_fname);
> -	} else {
> -		ret = SMB_VFS_STAT(conn, smb_fname);
> -	}
> +	/*
> +	 * We can directly use SMB_VFS_STAT here, as if this was a
> +	 * POSIX call on a symlink, we've already refused it.
> +	 * For a Windows acl mapped call on a symlink, we want to follow
> +	 * it.
> +	 */
> +	ret = SMB_VFS_STAT(conn, smb_fname);
>  
>  	if (ret == -1) {
>  		TALLOC_FREE(frame);
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From c9d37f511ca430bcf0c2bd4f046101d16729a8a9 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Fri, 18 Mar 2016 21:55:05 -0700
> Subject: [PATCH 08/14] s3: smbd: Remove unneeded lp_posix_pathnames() check in
>  SMB2 create.
> 
> Add a comment reminding me to re-add the check when SMB2
> unix extensions are re-added.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/smbd/smb2_create.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
> index ab37be0..4c1b81d 100644
> --- a/source3/smbd/smb2_create.c
> +++ b/source3/smbd/smb2_create.c
> @@ -716,8 +716,13 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
>  				return tevent_req_post(req, ev);
>  			}
>  
> -			if (!lp_posix_pathnames() &&
> -					ea_list_has_invalid_name(ea_list)) {
> +			/*
> +			 * NB. When SMB2+ unix extensions are added,
> +			 * we need to relax this check in invalid
> +			 * names - we used to not do this if
> +			 * lp_posix_pathnames() was false.
> +			 */
> +			if (ea_list_has_invalid_name(ea_list)) {
>  				tevent_req_nterror(req, STATUS_INVALID_EA_NAME);
>  				return tevent_req_post(req, ev);
>  			}
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 9176c7ffcb466fb086a26d80475e2f6788131665 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Fri, 18 Mar 2016 21:58:20 -0700
> Subject: [PATCH 09/14] s3: smbd: Remove many common uses of
>  lp_posix_pathnames().
> 
> Check the smb_filename->flags field, or req->posix_pathnames
> instead, depending on what is available.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/lib/filename_util.c         |  2 +-
>  source3/modules/vfs_acl_common.c    |  4 ++--
>  source3/modules/vfs_acl_tdb.c       |  2 +-
>  source3/modules/vfs_default.c       |  2 +-
>  source3/modules/vfs_posix_eadb.c    |  2 +-
>  source3/modules/vfs_streams_depot.c |  6 +++---
>  source3/modules/vfs_streams_xattr.c |  2 +-
>  source3/modules/vfs_xattr_tdb.c     |  2 +-
>  source3/smbd/nttrans.c              |  2 +-
>  source3/smbd/trans2.c               | 22 +++++++++++++++++++---
>  10 files changed, 31 insertions(+), 15 deletions(-)
> 
> diff --git a/source3/lib/filename_util.c b/source3/lib/filename_util.c
> index 78bfc70..3983aaa 100644
> --- a/source3/lib/filename_util.c
> +++ b/source3/lib/filename_util.c
> @@ -233,7 +233,7 @@ bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
>  		SMB_ASSERT(smb_fname->stream_name[0] != '\0');
>  	}
>  
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
>  		return false;
>  	}
>  
> diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
> index c8c0650..888b320 100644
> --- a/source3/modules/vfs_acl_common.c
> +++ b/source3/modules/vfs_acl_common.c
> @@ -1087,7 +1087,7 @@ static int chmod_acl_module_common(struct vfs_handle_struct *handle,
>  			const struct smb_filename *smb_fname,
>  			mode_t mode)
>  {
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
>  		/* Only allow this on POSIX pathnames. */
>  		return SMB_VFS_NEXT_CHMOD(handle, smb_fname, mode);
>  	}
> @@ -1108,7 +1108,7 @@ static int chmod_acl_acl_module_common(struct vfs_handle_struct *handle,
>  			const struct smb_filename *smb_fname,
>  			mode_t mode)
>  {
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
>  		/* Only allow this on POSIX pathnames. */
>  		return SMB_VFS_NEXT_CHMOD_ACL(handle, smb_fname, mode);
>  	}
> diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
> index 1bc5973..eee4d89 100644
> --- a/source3/modules/vfs_acl_tdb.c
> +++ b/source3/modules/vfs_acl_tdb.c
> @@ -252,7 +252,7 @@ static int unlink_acl_tdb(vfs_handle_struct *handle,
>  		goto out;
>  	}
>  
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname_tmp->flags & SMB_FILENAME_POSIX_PATH) {
>  		ret = SMB_VFS_LSTAT(handle->conn, smb_fname_tmp);
>  	} else {
>  		ret = SMB_VFS_STAT(handle->conn, smb_fname_tmp);
> diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
> index a7004a0..41e443e 100644
> --- a/source3/modules/vfs_default.c
> +++ b/source3/modules/vfs_default.c
> @@ -2220,7 +2220,7 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
>  					smb_fname->base_name);
>  		smb_fname_cp.flags = smb_fname->flags;
>  
> -		if (lp_posix_pathnames()) {
> +		if (smb_fname_cp.flags & SMB_FILENAME_POSIX_PATH) {
>  			ret = SMB_VFS_LSTAT(handle->conn, &smb_fname_cp);
>  		} else {
>  			ret = SMB_VFS_STAT(handle->conn, &smb_fname_cp);
> diff --git a/source3/modules/vfs_posix_eadb.c b/source3/modules/vfs_posix_eadb.c
> index 1d16529..2c7717a 100644
> --- a/source3/modules/vfs_posix_eadb.c
> +++ b/source3/modules/vfs_posix_eadb.c
> @@ -296,7 +296,7 @@ static int posix_eadb_unlink(vfs_handle_struct *handle,
>  		return -1;
>  	}
>  
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
>  		ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_tmp);
>  	} else {
>  		ret = SMB_VFS_NEXT_STAT(handle, smb_fname_tmp);
> diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
> index 2b80b9d..83c9d97 100644
> --- a/source3/modules/vfs_streams_depot.c
> +++ b/source3/modules/vfs_streams_depot.c
> @@ -714,7 +714,7 @@ static int streams_depot_unlink(vfs_handle_struct *handle,
>  		return -1;
>  	}
>  
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname_base->flags & SMB_FILENAME_POSIX_PATH) {
>  		ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_base);
>  	} else {
>  		ret = SMB_VFS_NEXT_STAT(handle, smb_fname_base);
> @@ -776,7 +776,7 @@ static int streams_depot_rmdir(vfs_handle_struct *handle,
>  		return -1;
>  	}
>  
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname_base->flags & SMB_FILENAME_POSIX_PATH) {
>  		ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_base);
>  	} else {
>  		ret = SMB_VFS_NEXT_STAT(handle, smb_fname_base);
> @@ -974,7 +974,7 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
>  		ret = SMB_VFS_NEXT_FSTAT(handle, fsp, &smb_fname_base->st);
>  	}
>  	else {
> -		if (lp_posix_pathnames()) {
> +		if (smb_fname_base->flags & SMB_FILENAME_POSIX_PATH) {
>  			ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_base);
>  		} else {
>  			ret = SMB_VFS_NEXT_STAT(handle, smb_fname_base);
> diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
> index b3b8002..8313464 100644
> --- a/source3/modules/vfs_streams_xattr.c
> +++ b/source3/modules/vfs_streams_xattr.c
> @@ -252,7 +252,7 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
>  		return -1;
>  	}
>  
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname_base->flags & SMB_FILENAME_POSIX_PATH) {
>  		ret = SMB_VFS_LSTAT(handle->conn, smb_fname_base);
>  	} else {
>  		ret = SMB_VFS_STAT(handle->conn, smb_fname_base);
> diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
> index aac8245..aa3bd82 100644
> --- a/source3/modules/vfs_xattr_tdb.c
> +++ b/source3/modules/vfs_xattr_tdb.c
> @@ -364,7 +364,7 @@ static int xattr_tdb_unlink(vfs_handle_struct *handle,
>  		return -1;
>  	}
>  
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname_tmp->flags & SMB_FILENAME_POSIX_PATH) {
>  		ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_tmp);
>  	} else {
>  		ret = SMB_VFS_NEXT_STAT(handle, smb_fname_tmp);
> diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
> index be5994a..3a2c35f 100644
> --- a/source3/smbd/nttrans.c
> +++ b/source3/smbd/nttrans.c
> @@ -1178,7 +1178,7 @@ static void call_nt_transact_create(connection_struct *conn,
>  			goto out;
>  		}
>  
> -		if (!lp_posix_pathnames() &&
> +		if (!req->posix_pathnames &&
>  				ea_list_has_invalid_name(ea_list)) {
>  			/* Realloc the size of parameters and data we will return */
>  			if (flags & EXTENDED_RESPONSE_REQUIRED) {
> diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
> index a76b2df..65c2cb0 100644
> --- a/source3/smbd/trans2.c
> +++ b/source3/smbd/trans2.c
> @@ -371,11 +371,19 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
>  	size_t i, num_names;
>  	char **names;
>  	struct ea_list *ea_list_head = NULL;
> +	bool posix_pathnames = false;
>  	NTSTATUS status;
>  
>  	*pea_total_len = 0;
>  	*ea_list = NULL;
>  
> +	if (fsp) {
> +		posix_pathnames =
> +			(fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
> +	} else {
> +		posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
> +	}
> +
>  	status = get_ea_names_from_file(talloc_tos(),
>  				conn,
>  				fsp,
> @@ -404,7 +412,7 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
>  		 * Filter out any underlying POSIX EA names
>  		 * that a Windows client can't handle.
>  		 */
> -		if (!lp_posix_pathnames() &&
> +		if (!posix_pathnames &&
>  				is_invalid_windows_ea_name(names[i])) {
>  			continue;
>  		}
> @@ -692,11 +700,19 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
>  		const struct smb_filename *smb_fname, struct ea_list *ea_list)
>  {
>  	NTSTATUS status;
> +	bool posix_pathnames = false;
>  
>  	if (!lp_ea_support(SNUM(conn))) {
>  		return NT_STATUS_EAS_NOT_SUPPORTED;
>  	}
>  
> +	if (fsp) {
> +		posix_pathnames =
> +			(fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
> +	} else {
> +		posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
> +	}
> +
>  	status = refuse_symlink(conn, fsp, smb_fname);
>  	if (!NT_STATUS_IS_OK(status)) {
>  		return status;
> @@ -717,7 +733,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
>  	 * we set *any* of them.
>  	 */
>  
> -	if (!lp_posix_pathnames() && ea_list_has_invalid_name(ea_list)) {
> +	if (!posix_pathnames && ea_list_has_invalid_name(ea_list)) {
>  		return STATUS_INVALID_EA_NAME;
>  	}
>  
> @@ -1297,7 +1313,7 @@ static void call_trans2open(connection_struct *conn,
>  			goto out;
>  		}
>  
> -		if (!lp_posix_pathnames() &&
> +		if (!req->posix_pathnames &&
>  				ea_list_has_invalid_name(ea_list)) {
>  			int param_len = 30;
>  			*pparams = (char *)SMB_REALLOC(*pparams, param_len);
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 1426aa4727b36aca54f7835bb57f39dc77f4a702 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Fri, 18 Mar 2016 22:10:34 -0700
> Subject: [PATCH 10/14] s3: vfs: recycle. Remove use of
>  vfs_stat_smb_basename().
> 
> We only need a basic STAT here.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/modules/vfs_recycle.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c
> index ca3fc2e..dfc3b9c 100644
> --- a/source3/modules/vfs_recycle.c
> +++ b/source3/modules/vfs_recycle.c
> @@ -186,10 +186,12 @@ static mode_t recycle_subdir_mode(vfs_handle_struct *handle)
>  
>  static bool recycle_directory_exist(vfs_handle_struct *handle, const char *dname)
>  {
> -	SMB_STRUCT_STAT st;
> +	struct smb_filename smb_fname = {
> +			.base_name = discard_const_p(char, dname)
> +	};
>  
> -	if (vfs_stat_smb_basename(handle->conn, dname, &st) == 0) {
> -		if (S_ISDIR(st.st_ex_mode)) {
> +	if (SMB_VFS_STAT(handle->conn, &smb_fname) == 0) {
> +		if (S_ISDIR(smb_fname.st.st_ex_mode)) {
>  			return True;
>  		}
>  	}
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 85bc087568975a367030baf79775fd0caeaeae16 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Fri, 18 Mar 2016 22:15:12 -0700
> Subject: [PATCH 11/14] s3: vfs: vfs_acl_tdb. Remove use of
>  vfs_stat_smb_basename().
> 
> We only need a basic STAT here.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/modules/vfs_acl_tdb.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
> index eee4d89..e2d0cb8 100644
> --- a/source3/modules/vfs_acl_tdb.c
> +++ b/source3/modules/vfs_acl_tdb.c
> @@ -341,11 +341,13 @@ static int sys_acl_set_file_tdb(vfs_handle_struct *handle,
>                                SMB_ACL_TYPE_T type,
>                                SMB_ACL_T theacl)
>  {
> -	SMB_STRUCT_STAT sbuf;
>  	struct db_context *db = acl_db;
>  	int ret = -1;
> +	struct smb_filename smb_fname = {
> +		.base_name = discard_const_p(char, path)
> +	};
>  
> -	ret = vfs_stat_smb_basename(handle->conn, path, &sbuf);
> +	ret = SMB_VFS_STAT(handle->conn, &smb_fname);
>  	if (ret == -1) {
>  		return -1;
>  	}
> @@ -358,7 +360,7 @@ static int sys_acl_set_file_tdb(vfs_handle_struct *handle,
>  		return -1;
>  	}
>  
> -	acl_tdb_delete(handle, db, &sbuf);
> +	acl_tdb_delete(handle, db, &smb_fname.st);
>  	return 0;
>  }
>  
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 5ee631618974cfa40812770253ed904ba02726c4 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Fri, 18 Mar 2016 22:17:30 -0700
> Subject: [PATCH 12/14] s3: smbd: Modify vfs_stat_smb_basename() to take a
>  const struct smb_filename * instead of const char *.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/modules/nfs4_acls.c         |  2 +-
>  source3/modules/vfs_acl_common.c    |  2 +-
>  source3/modules/vfs_acl_tdb.c       |  4 ++--
>  source3/modules/vfs_streams_xattr.c |  2 +-
>  source3/modules/vfs_xattr_tdb.c     |  2 +-
>  source3/smbd/proto.h                |  3 ++-
>  source3/smbd/trans2.c               |  2 +-
>  source3/smbd/vfs.c                  | 10 ++++++----
>  8 files changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
> index 349b26b..8756285 100644
> --- a/source3/modules/nfs4_acls.c
> +++ b/source3/modules/nfs4_acls.c
> @@ -274,7 +274,7 @@ static int smbacl4_GetFileOwner(struct connection_struct *conn,
>  	ZERO_STRUCTP(psbuf);
>  
>  	/* Get the stat struct for the owner info. */
> -	if (vfs_stat_smb_basename(conn, smb_fname->base_name, psbuf) != 0)
> +	if (vfs_stat_smb_basename(conn, smb_fname, psbuf) != 0)
>  	{
>  		DEBUG(8, ("vfs_stat_smb_basename failed with error %s\n",
>  			strerror(errno)));
> diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
> index 888b320..93b7e49 100644
> --- a/source3/modules/vfs_acl_common.c
> +++ b/source3/modules/vfs_acl_common.c
> @@ -641,7 +641,7 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
>  			 * is fully plumbed through the VFS.
>  			 */
>  			int ret = vfs_stat_smb_basename(handle->conn,
> -						smb_fname->base_name,
> +						smb_fname,
>  						&sbuf);
>  			if (ret == -1) {
>  				TALLOC_FREE(frame);
> diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
> index e2d0cb8..e4c8462 100644
> --- a/source3/modules/vfs_acl_tdb.c
> +++ b/source3/modules/vfs_acl_tdb.c
> @@ -160,7 +160,7 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
>  		sbuf = fsp->fsp_name->st;
>  	} else {
>  		int ret = vfs_stat_smb_basename(handle->conn,
> -				smb_fname->base_name,
> +				smb_fname,
>  				&sbuf);
>  		if (ret == -1) {
>  			status = map_nt_error_from_unix(errno);
> @@ -285,7 +285,7 @@ static int rmdir_acl_tdb(vfs_handle_struct *handle,
>  	struct db_context *db = acl_db;
>  	int ret = -1;
>  
> -	ret = vfs_stat_smb_basename(handle->conn, smb_fname->base_name, &sbuf);
> +	ret = vfs_stat_smb_basename(handle->conn, smb_fname, &sbuf);
>  	if (ret == -1) {
>  		return -1;
>  	}
> diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
> index 8313464..d9eb2e1 100644
> --- a/source3/modules/vfs_streams_xattr.c
> +++ b/source3/modules/vfs_streams_xattr.c
> @@ -842,7 +842,7 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle,
>  		ret = SMB_VFS_FSTAT(fsp, &sbuf);
>  	} else {
>  		ret = vfs_stat_smb_basename(handle->conn,
> -				smb_fname->base_name,
> +				smb_fname,
>  				&sbuf);
>  	}
>  
> diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
> index aa3bd82..c40f1e1 100644
> --- a/source3/modules/vfs_xattr_tdb.c
> +++ b/source3/modules/vfs_xattr_tdb.c
> @@ -416,7 +416,7 @@ static int xattr_tdb_rmdir(vfs_handle_struct *handle,
>  				});
>  
>  	if (vfs_stat_smb_basename(handle->conn,
> -				smb_fname->base_name,
> +				smb_fname,
>  				&sbuf) == -1) {
>  		TALLOC_FREE(frame);
>  		return -1;
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 776e91d..6f402ab 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -1213,7 +1213,8 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname);
>  NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
>  			const char *fname,
>  			struct smb_request *smbreq);
> -int vfs_stat_smb_basename(struct connection_struct *conn, const char *fname,
> +int vfs_stat_smb_basename(struct connection_struct *conn,
> +			const struct smb_filename *smb_fname_in,
>  			SMB_STRUCT_STAT *psbuf);
>  NTSTATUS vfs_stat_fsp(files_struct *fsp);
>  NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid);
> diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
> index 65c2cb0..69276f5 100644
> --- a/source3/smbd/trans2.c
> +++ b/source3/smbd/trans2.c
> @@ -69,7 +69,7 @@ static NTSTATUS refuse_symlink(connection_struct *conn,
>  		pst = &fsp->fsp_name->st;
>  	} else {
>  		int ret = vfs_stat_smb_basename(conn,
> -				smb_fname->base_name,
> +				smb_fname,
>  				&sbuf);
>  		if (ret == -1) {
>  			return map_nt_error_from_unix(errno);
> diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
> index 972cea4..b58becc 100644
> --- a/source3/smbd/vfs.c
> +++ b/source3/smbd/vfs.c
> @@ -1315,15 +1315,17 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
>   *
>   * Called when we know stream name parsing has already been done.
>   */
> -int vfs_stat_smb_basename(struct connection_struct *conn, const char *fname,
> -		       SMB_STRUCT_STAT *psbuf)
> +int vfs_stat_smb_basename(struct connection_struct *conn,
> +			const struct smb_filename *smb_fname_in,
> +			SMB_STRUCT_STAT *psbuf)
>  {
>  	struct smb_filename smb_fname = {
> -			.base_name = discard_const_p(char, fname)
> +		.base_name = discard_const_p(char, smb_fname_in->base_name),
> +		.flags = smb_fname_in->flags
>  	};
>  	int ret;
>  
> -	if (lp_posix_pathnames()) {
> +	if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
>  		ret = SMB_VFS_LSTAT(conn, &smb_fname);
>  	} else {
>  		ret = SMB_VFS_STAT(conn, &smb_fname);
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 39c399a8d5876d4a9f0b138f361f6df1dc0c2711 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Sat, 19 Mar 2016 21:04:09 -0700
> Subject: [PATCH 13/14] s3: smbd: Remove the last lp_posix_pathnames() from the
>  SMB1/2/3 code paths.
> 
> lp_posix_pathnames() is only used in one place in SMB1
> processing, and not at all in SMB2/3.
> 
> *NOW* we can start on SMB2/3 unix extentions !
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/smbd/msdfs.c | 23 ++++++++++++++++++-----
>  1 file changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
> index 647ac3b..9a0b14b 100644
> --- a/source3/smbd/msdfs.c
> +++ b/source3/smbd/msdfs.c
> @@ -82,9 +82,12 @@ static NTSTATUS parse_dfs_path(connection_struct *conn,
>  	eos_ptr = &pathname_local[strlen(pathname_local)];
>  	p = temp = pathname_local;
>  
> -	pdp->posix_path = (lp_posix_pathnames() && *pathname == '/');
> -
> -	sepchar = pdp->posix_path ? '/' : '\\';
> +	if (*pathname == '/') {
> +		pdp->posix_path = true;
> +		sepchar = '/';
> +	} else {
> +		sepchar = '\\';
> +	}
>  
>  	if (allow_broken_path && (*pathname != sepchar)) {
>  		DEBUG(10,("parse_dfs_path: path %s doesn't start with %c\n",
> @@ -94,11 +97,21 @@ static NTSTATUS parse_dfs_path(connection_struct *conn,
>  		 * Try and convert to a local path.
>  		 */
>  
> +		/*
> +		 * If the path contains a '/' character,
> +		 * assume it's a local posix path as this
> +		 * isn't expected in Windows pathnames
> +		 * (although it's allowed, which makes
> +		 * this a heuristic, not an absolute rule).
> +		 */
> +		if (strchr_m(temp, '/') != NULL) {
> +			pdp->posix_path = true;
> +			sepchar = '/';
> +		}
> +
>  		pdp->hostname = eos_ptr; /* "" */
>  		pdp->servicename = eos_ptr; /* "" */
>  
> -		/* We've got no info about separators. */
> -		pdp->posix_path = lp_posix_pathnames();
>  		p = temp;
>  		DEBUG(10,("parse_dfs_path: trying to convert %s to a "
>  			"local path\n",
> -- 
> 2.8.0.rc3.226.g39d4020
> 
> 
> From 246e5521365312bbd5c3d22988abbd63cdf6f7a1 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at samba.org>
> Date: Sat, 19 Mar 2016 21:07:01 -0700
> Subject: [PATCH 14/14] s3: torture. Remove spurious lp_posix_pathnames()
>  included by cut-and-paste error.
> 
> Signed-off-by: Jeremy Allison <jra at samba.org>
> ---
>  source3/torture/torture.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/source3/torture/torture.c b/source3/torture/torture.c
> index 349527f..8b8dbe9 100644
> --- a/source3/torture/torture.c
> +++ b/source3/torture/torture.c
> @@ -9158,7 +9158,7 @@ static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
>  
>  	sname = strchr_m(fname, ':');
>  
> -	if (lp_posix_pathnames() || (sname == NULL)) {
> +	if (sname == NULL) {
>  		if (pbase != NULL) {
>  			base = talloc_strdup(mem_ctx, fname);
>  			NT_STATUS_HAVE_NO_MEMORY(base);
> -- 
> 2.8.0.rc3.226.g39d4020
> 




More information about the samba-technical mailing list