[PATCH] Moving the VFS to struct smb_filename.

Ralph Böhme slow at samba.org
Tue May 30 07:59:36 UTC 2017


On Mon, May 29, 2017 at 09:47:13PM +0200, Ralph Böhme wrote:
> On Fri, May 26, 2017 at 04:05:22PM -0700, Jeremy Allison wrote:
> > Hi all,
> > 
> > As promised, this is the first set of patches
> > that will be migrating *ALL* VFS calls from
> > 'const char *' -> 'const struct smb_filename *'
> > for Samba 4.7 (or Samba-5, whatever we decide :-).
> > 
> > This first set changes the low-level sys_acl_XXXX()
> > calls, followed by the XXXattr() calls.
> > 
> > It actually cleans up quite a bit of the internal
> > code now we can simply pass const struct smb_filename
> > pointers around rather than converting to and
> > from char * -> struct * and back all the time,
> > so for each hunk you might see some modification
> > of some of the calling functions to change from
> > const char *' -> 'const struct smb_filename * also
> > if it makes them cleaner.
> > 
> > The patch is split into one hunk per VFS
> > call, so there are currently 8 of them covering:
> > 
> > 1). SMB_VFS_SYS_ACL_DELETE_DEF_FILE
> > 2). SMB_VFS_SYS_ACL_GET_FILE
> > 3). SMB_VFS_SYS_ACL_BLOB_GET_FILE
> > 4). SMB_VFS_SYS_ACL_SET_FILE
> > 5). SMB_VFS_LISTXATTR
> > 6). SMB_VFS_REMOVEXATTR
> > 7). SMB_VFS_SETXATTR
> > 8). SMB_VFS_GETXATTR
> > 
> > in turn. Passes local make test. Please
> > review and push if happy ! Once these
> > are in I'll start making my way up to
> > the more complex calls.
> 
> processing...

found a few issues, all fixed in the attached patchset:

sys_acl_set_file_tdb: not freeing smb_fname from talloc_tos
solarisacl_sys_acl_set_file: struct smb_filename smb_fname not declared as pointer variable
vxfs_remove_xattr: missing declaration of struct smb_filename *smb_fname
vxfs_remove_xattr: use after free of smb_fname when calling vxfs_removexattr_path
vxfs_set_xattr: use after free of smb_fname when calling SMB_VFS_NEXT_REMOVEXATTR
vfs_gluster_setxattr: calling glfs_setxattr with smb_fname instead of smb_fname->base_name
vxfs_set_xattr: call to vxfs_setxattr_path still uses path instead of smb_fname_in->base_name

Please push if you're happy with the changes.

-slow
-------------- next part --------------
From 1bea7b0a5379920b22d9e0c4c79477381f01c023 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Tue, 23 May 2017 15:33:31 -0700
Subject: [PATCH 1/8] s3: VFS: Change SMB_VFS_SYS_ACL_DELETE_DEF_FILE to use
 const struct smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c          |  2 +-
 examples/VFS/skel_transparent.c     |  4 ++--
 source3/include/smb_acls.h          |  3 ++-
 source3/include/vfs.h               |  7 +++++--
 source3/include/vfs_macros.h        |  8 ++++----
 source3/lib/sysacls.c               | 22 +++++++++++-----------
 source3/modules/posixacl_xattr.c    |  6 ++++--
 source3/modules/posixacl_xattr.h    |  2 +-
 source3/modules/vfs_aixacl.c        |  2 +-
 source3/modules/vfs_aixacl2.c       |  2 +-
 source3/modules/vfs_cap.c           | 29 ++++++++++++++++++++++++++---
 source3/modules/vfs_catia.c         | 28 ++++++++++++++++++++++++----
 source3/modules/vfs_default.c       |  5 +++--
 source3/modules/vfs_fake_acls.c     |  9 +++++----
 source3/modules/vfs_full_audit.c    |  7 +++----
 source3/modules/vfs_gpfs.c          |  4 ++--
 source3/modules/vfs_hpuxacl.c       |  7 ++++---
 source3/modules/vfs_hpuxacl.h       |  2 +-
 source3/modules/vfs_media_harmony.c | 27 +++++++++++----------------
 source3/modules/vfs_nfs4acl_xattr.c |  2 +-
 source3/modules/vfs_posixacl.c      |  4 ++--
 source3/modules/vfs_posixacl.h      |  2 +-
 source3/modules/vfs_solarisacl.c    |  6 +++---
 source3/modules/vfs_solarisacl.h    |  2 +-
 source3/modules/vfs_time_audit.c    |  7 ++++---
 source3/modules/vfs_tru64acl.c      |  4 ++--
 source3/modules/vfs_tru64acl.h      |  2 +-
 source3/modules/vfs_unityed_media.c | 26 ++++++++++++++++++--------
 source3/modules/vfs_zfsacl.c        |  2 +-
 source3/smbd/posix_acls.c           | 28 +++++++++++++++++-----------
 source3/smbd/proto.h                |  4 ++--
 source3/smbd/trans2.c               |  2 +-
 source3/smbd/vfs.c                  |  4 ++--
 source3/torture/cmd_vfs.c           | 14 +++++++++++++-
 34 files changed, 180 insertions(+), 105 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index af119f3..801012a 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -787,7 +787,7 @@ static int skel_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static int skel_sys_acl_delete_def_file(vfs_handle_struct *handle,
-					const char *path)
+					const struct smb_filename *smb_fname)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index e974529..0404a2e 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -923,9 +923,9 @@ static int skel_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static int skel_sys_acl_delete_def_file(vfs_handle_struct *handle,
-					const char *path)
+					const struct smb_filename *smb_fname)
 {
-	return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path);
+	return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, smb_fname);
 }
 
 static ssize_t skel_getxattr(vfs_handle_struct *handle, const char *path,
diff --git a/source3/include/smb_acls.h b/source3/include/smb_acls.h
index 3ac23db..6a41e19 100644
--- a/source3/include/smb_acls.h
+++ b/source3/include/smb_acls.h
@@ -24,6 +24,7 @@
 
 struct vfs_handle_struct;
 struct files_struct;
+struct smb_filename;
 
 typedef int			SMB_ACL_TYPE_T;
 typedef mode_t			*SMB_ACL_PERMSET_T;
@@ -61,7 +62,7 @@ int sys_acl_set_file(struct vfs_handle_struct *handle,
 int sys_acl_set_fd(struct vfs_handle_struct *handle, struct files_struct *fsp,
 		   SMB_ACL_T acl_d);
 int sys_acl_delete_def_file(struct vfs_handle_struct *handle,
-			    const char *path);
+			const struct smb_filename *smb_fname);
 int no_acl_syscall_error(int err);
 
 #endif /* _SMB_ACLS_H */
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 7908980..8fe5536 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -197,6 +197,8 @@
 /* Version 36 - Remove is_offline and set_offline */
 /* Version 37 - Module init functions now take a TALLOC_CTX * parameter. */
 /* Version 37 - Add vfs_copy_chunk_flags for DUP_EXTENTS_TO_FILE */
+/* Version 37 - Change sys_acl_delete_def_file from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -872,7 +874,8 @@ struct vfs_fn_pointers {
 				      DATA_BLOB *blob);
 	int (*sys_acl_set_file_fn)(struct vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
 	int (*sys_acl_set_fd_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_ACL_T theacl);
-	int (*sys_acl_delete_def_file_fn)(struct vfs_handle_struct *handle, const char *path);
+	int (*sys_acl_delete_def_file_fn)(struct vfs_handle_struct *handle,
+					const struct smb_filename *smb_fname);
 
 	/* EA operations. */
 	ssize_t (*getxattr_fn)(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size);
@@ -1333,7 +1336,7 @@ int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
 				struct files_struct *fsp, SMB_ACL_T theacl);
 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
-					 const char *path);
+				const struct smb_filename *smb_fname);
 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
 			      const char *path, const char *name, void *value,
 			      size_t size);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 0cbcf89..43dfe92 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -510,10 +510,10 @@
 #define SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl) \
 	smb_vfs_call_sys_acl_set_fd((handle)->next, (fsp), (theacl))
 
-#define SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, path) \
-	smb_vfs_call_sys_acl_delete_def_file((conn)->vfs_handles, (path))
-#define SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path) \
-	smb_vfs_call_sys_acl_delete_def_file((handle)->next, (path))
+#define SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, smb_fname) \
+	smb_vfs_call_sys_acl_delete_def_file((conn)->vfs_handles, (smb_fname))
+#define SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, smb_fname) \
+	smb_vfs_call_sys_acl_delete_def_file((handle)->next, (smb_fname))
 
 #define SMB_VFS_GETXATTR(conn,path,name,value,size) \
 	smb_vfs_call_getxattr((conn)->vfs_handles,(path),(name),(value),(size))
diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c
index 7cff488..b75c981 100644
--- a/source3/lib/sysacls.c
+++ b/source3/lib/sysacls.c
@@ -385,9 +385,9 @@ int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_delete_def_file(vfs_handle_struct *handle,
-			    const char *path)
+			const struct smb_filename *smb_fname)
 {
-	return posixacl_sys_acl_delete_def_file(handle, path);
+	return posixacl_sys_acl_delete_def_file(handle, smb_fname);
 }
 
 #elif defined(HAVE_AIX_ACLS)
@@ -418,9 +418,9 @@ int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_delete_def_file(vfs_handle_struct *handle,
-			    const char *path)
+				const struct smb_filename *smb_fname)
 {
-	return aixacl_sys_acl_delete_def_file(handle, path);
+	return aixacl_sys_acl_delete_def_file(handle, smb_fname);
 }
 
 #elif defined(HAVE_TRU64_ACLS)
@@ -452,9 +452,9 @@ int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_delete_def_file(vfs_handle_struct *handle,
-			    const char *path)
+				const struct smb_filename *smb_fname)
 {
-	return tru64acl_sys_acl_delete_def_file(handle, path);
+	return tru64acl_sys_acl_delete_def_file(handle, smb_fname);
 }
 
 #elif defined(HAVE_SOLARIS_UNIXWARE_ACLS)
@@ -487,9 +487,9 @@ int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_delete_def_file(vfs_handle_struct *handle,
-			    const char *path)
+				const struct smb_filename *smb_fname)
 {
-	return solarisacl_sys_acl_delete_def_file(handle, path);
+	return solarisacl_sys_acl_delete_def_file(handle, smb_fname);
 }
 
 #elif defined(HAVE_HPUX_ACLS)
@@ -520,9 +520,9 @@ int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_delete_def_file(vfs_handle_struct *handle,
-			    const char *path)
+				const struct smb_filename *smb_fname)
 {
-	return hpuxacl_sys_acl_delete_def_file(handle, path);
+	return hpuxacl_sys_acl_delete_def_file(handle, smb_fname);
 }
 
 #else /* No ACLs. */
@@ -573,7 +573,7 @@ int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_delete_def_file(vfs_handle_struct *handle,
-			    const char *path)
+				const struct smb_filename *smb_fname)
 {
 #ifdef ENOTSUP
 	errno = ENOTSUP;
diff --git a/source3/modules/posixacl_xattr.c b/source3/modules/posixacl_xattr.c
index 652a2ee..871aa66 100644
--- a/source3/modules/posixacl_xattr.c
+++ b/source3/modules/posixacl_xattr.c
@@ -498,7 +498,9 @@ int posixacl_xattr_acl_set_fd(vfs_handle_struct *handle,
 }
 
 int posixacl_xattr_acl_delete_def_file(vfs_handle_struct *handle,
-				       const char *path_p)
+				const struct smb_filename *smb_fname)
 {
-	return SMB_VFS_REMOVEXATTR(handle->conn, path_p, ACL_EA_DEFAULT);
+	return SMB_VFS_REMOVEXATTR(handle->conn,
+			smb_fname->base_name,
+			ACL_EA_DEFAULT);
 }
diff --git a/source3/modules/posixacl_xattr.h b/source3/modules/posixacl_xattr.h
index 9e0aa58..6f6316a 100644
--- a/source3/modules/posixacl_xattr.h
+++ b/source3/modules/posixacl_xattr.h
@@ -40,5 +40,5 @@ int posixacl_xattr_acl_set_fd(vfs_handle_struct *handle,
 			      SMB_ACL_T theacl);
 
 int posixacl_xattr_acl_delete_def_file(vfs_handle_struct *handle,
-				       const char *path);
+				const struct smb_filename *smb_fname);
 #endif
diff --git a/source3/modules/vfs_aixacl.c b/source3/modules/vfs_aixacl.c
index 169058f..c25c249 100644
--- a/source3/modules/vfs_aixacl.c
+++ b/source3/modules/vfs_aixacl.c
@@ -174,7 +174,7 @@ int aixacl_sys_acl_set_fd(vfs_handle_struct *handle,
 }
 
 int aixacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				     const char *path)
+				const struct smb_filename *smb_fname)
 {
 	return 0; /* otherwise you can't set acl at upper level */
 }
diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c
index aaf6e293..e46e502 100644
--- a/source3/modules/vfs_aixacl2.c
+++ b/source3/modules/vfs_aixacl2.c
@@ -538,7 +538,7 @@ int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle,
 }
 
 int aixjfs2_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				     const char *path)
+				const struct smb_filename *smb_fname)
 {
 	/* Not available under AIXC ACL */
 	/* Don't report here any error otherwise */
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 0360830..4179926 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -568,15 +568,38 @@ static int cap_sys_acl_set_file(vfs_handle_struct *handle, const char *path, SMB
 	return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cappath, acltype, theacl);
 }
 
-static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
+static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	struct smb_filename *cap_smb_fname = NULL;
+	char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+	int ret;
+	int saved_errno = 0;
 
 	if (!cappath) {
 		errno = ENOMEM;
 		return -1;
 	}
-	return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cappath);
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					cappath,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(cappath);
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cap_smb_fname);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(cappath);
+	TALLOC_FREE(cap_smb_fname);
+	if (saved_errno) {
+		errno = saved_errno;
+	}
+	return ret;
 }
 
 static ssize_t cap_getxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size)
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 972f51a..7ed531a 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -1292,22 +1292,42 @@ catia_sys_acl_set_file(vfs_handle_struct *handle,
 
 static int
 catia_sys_acl_delete_def_file(vfs_handle_struct *handle,
-			      const char *path)
+				const struct smb_filename *smb_fname)
 {
+	struct smb_filename *mapped_smb_fname = NULL;
+	int saved_errno = 0;
 	char *mapped_name = NULL;
 	NTSTATUS status;
 	int ret;
 
 	status = catia_string_replace_allocate(handle->conn,
-				path, &mapped_name, vfs_translate_to_unix);
+				smb_fname->base_name,
+				&mapped_name,
+				vfs_translate_to_unix);
 	if (!NT_STATUS_IS_OK(status)) {
 		errno = map_errno_from_nt_status(status);
 		return -1;
 	}
 
-	ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, mapped_name);
+	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
+					mapped_name,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (mapped_smb_fname == NULL) {
+		TALLOC_FREE(mapped_name);
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, mapped_smb_fname);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(mapped_smb_fname);
 	TALLOC_FREE(mapped_name);
-
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index fa89f7f..9b3fdf1 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2732,9 +2732,10 @@ static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 	return sys_acl_set_fd(handle, fsp, theacl);
 }
 
-static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
+static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname)
 {
-	return sys_acl_delete_def_file(handle, path);
+	return sys_acl_delete_def_file(handle, smb_fname);
 }
 
 /****************************************************************
diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
index 62b53b6..4b52bf5 100644
--- a/source3/modules/vfs_fake_acls.c
+++ b/source3/modules/vfs_fake_acls.c
@@ -357,14 +357,15 @@ static int fake_acls_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp
 	return ret;
 }
 
-static int fake_acls_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
+static int fake_acls_sys_acl_delete_def_file(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname_in)
 {
 	int ret;
 	const char *name = FAKE_ACL_DEFAULT_XATTR;
 	TALLOC_CTX *frame = talloc_stackframe();
-	struct smb_filename *smb_fname;
+	struct smb_filename *smb_fname = cp_smb_filename(talloc_tos(),
+						smb_fname_in);
 
-	smb_fname = synthetic_smb_fname(frame, path, NULL, NULL, 0);
 	if (smb_fname == NULL) {
 		TALLOC_FREE(frame);
 		errno = ENOMEM;
@@ -383,7 +384,7 @@ static int fake_acls_sys_acl_delete_def_file(vfs_handle_struct *handle, const ch
 		return -1;
 	}
 
-	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
+	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname->base_name, name);
 	if (ret == -1 && errno == ENOATTR) {
 		ret = 0;
 		errno = 0;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 4c2eb87..e6ee577 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2241,15 +2241,14 @@ static int smb_full_audit_sys_acl_set_fd(vfs_handle_struct *handle, files_struct
 }
 
 static int smb_full_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
-
-					 const char *path)
+				const struct smb_filename *smb_fname)
 {
 	int result;
 
-	result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path);
+	result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, smb_fname);
 
 	do_log(SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, (result >= 0), handle,
-	       "%s", path);
+	       "%s", smb_fname->base_name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index d1d59ce..fa2664e 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -1279,7 +1279,7 @@ static int gpfsacl_sys_acl_set_fd(vfs_handle_struct *handle,
 }
 
 static int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-					   const char *path)
+				const struct smb_filename *smb_fname)
 {
 	struct gpfs_config_data *config;
 
@@ -1288,7 +1288,7 @@ static int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
 				return -1);
 
 	if (!config->acl) {
-		return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path);
+		return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, smb_fname);
 	}
 
 	errno = ENOTSUP;
diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c
index d91657a..f666a5e 100644
--- a/source3/modules/vfs_hpuxacl.c
+++ b/source3/modules/vfs_hpuxacl.c
@@ -358,7 +358,7 @@ int hpuxacl_sys_acl_set_fd(vfs_handle_struct *handle,
  * check is considered unnecessary. --- Agreed? XXX
  */
 int hpuxacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				    const char *path)
+				const struct smb_filename *smb_fname)
 {
 	SMB_ACL_T smb_acl;
 	int ret = -1;
@@ -367,7 +367,7 @@ int hpuxacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
 
 	DEBUG(10, ("entering hpuxacl_sys_acl_delete_def_file.\n"));
 
-	smb_acl = hpuxacl_sys_acl_get_file(handle, path, 
+	smb_acl = hpuxacl_sys_acl_get_file(handle, smb_fname->base_name,
 					   SMB_ACL_TYPE_ACCESS);
 	if (smb_acl == NULL) {
 		DEBUG(10, ("getting file acl failed!\n"));
@@ -383,7 +383,8 @@ int hpuxacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
 		DEBUG(10, ("resulting acl is not valid!\n"));
 		goto done;
 	}
-	ret = acl(discard_const_p(char, path), ACL_SET, count, hpux_acl);
+	ret = acl(discard_const_p(char, smb_fname->base_name),
+				ACL_SET, count, hpux_acl);
 	if (ret != 0) {
 		DEBUG(10, ("settinge file acl failed!\n"));
 	}
diff --git a/source3/modules/vfs_hpuxacl.h b/source3/modules/vfs_hpuxacl.h
index 07b32d6..df30e17 100644
--- a/source3/modules/vfs_hpuxacl.h
+++ b/source3/modules/vfs_hpuxacl.h
@@ -50,7 +50,7 @@ int hpuxacl_sys_acl_set_fd(vfs_handle_struct *handle,
 			   SMB_ACL_T theacl);
 
 int hpuxacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				    const char *path);
+			const struct smb_filename *smb_fname);
 
 NTSTATUS vfs_hpuxacl_init(void);
 
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index 794644e..9a5b99d 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -2179,33 +2179,28 @@ out:
  * Failure: set errno, return -1
  */
 static int mh_sys_acl_delete_def_file(vfs_handle_struct *handle,
-		const char *path)
+			const struct smb_filename *smb_fname)
 {
 	int status;
-	char *clientPath;
-	TALLOC_CTX *ctx;
+	struct smb_filename *clientFname = NULL;
 
 	DEBUG(MH_INFO_DEBUG, ("Entering mh_sys_acl_delete_def_file\n"));
-	if (!is_in_media_files(path))
-	{
+	if (!is_in_media_files(smb_fname->base_name)) {
 		status = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle,
-				path);
+				smb_fname);
 		goto out;
 	}
 
-	clientPath = NULL;
-	ctx = talloc_tos();
-
-	if ((status = alloc_get_client_path(handle, ctx,
-				path,
-				&clientPath)))
-	{
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&clientFname);
+	if (status != 0) {
 		goto err;
 	}
-
-	status = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, clientPath);
+	status = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, clientFname);
 err:
-	TALLOC_FREE(clientPath);
+	TALLOC_FREE(clientFname);
 out:
 	return status;
 }
diff --git a/source3/modules/vfs_nfs4acl_xattr.c b/source3/modules/vfs_nfs4acl_xattr.c
index a22ae7f..cae3e7b 100644
--- a/source3/modules/vfs_nfs4acl_xattr.c
+++ b/source3/modules/vfs_nfs4acl_xattr.c
@@ -615,7 +615,7 @@ static int nfs4acl_xattr_fail__sys_acl_set_fd(vfs_handle_struct *handle,
 }
 
 static int nfs4acl_xattr_fail__sys_acl_delete_def_file(vfs_handle_struct *handle,
-						const char *path)
+			const struct smb_filename *smb_fname)
 {
 	return -1;
 }
diff --git a/source3/modules/vfs_posixacl.c b/source3/modules/vfs_posixacl.c
index 85d84a5..ed8f1ba 100644
--- a/source3/modules/vfs_posixacl.c
+++ b/source3/modules/vfs_posixacl.c
@@ -129,9 +129,9 @@ int posixacl_sys_acl_set_fd(vfs_handle_struct *handle,
 }
 
 int posixacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				     const char *path)
+				const struct smb_filename *smb_fname)
 {
-	return acl_delete_def_file(path);
+	return acl_delete_def_file(smb_fname->base_name);
 }
 
 
diff --git a/source3/modules/vfs_posixacl.h b/source3/modules/vfs_posixacl.h
index 59d3dc9..b64bdb2 100644
--- a/source3/modules/vfs_posixacl.h
+++ b/source3/modules/vfs_posixacl.h
@@ -40,7 +40,7 @@ int posixacl_sys_acl_set_fd(vfs_handle_struct *handle,
 			    SMB_ACL_T theacl);
 
 int posixacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				     const char *path);
+				const struct smb_filename *smb_fname);
 
 NTSTATUS vfs_posixacl_init(TALLOC_CTX *);
 
diff --git a/source3/modules/vfs_solarisacl.c b/source3/modules/vfs_solarisacl.c
index e5a581c..48305c5 100644
--- a/source3/modules/vfs_solarisacl.c
+++ b/source3/modules/vfs_solarisacl.c
@@ -298,7 +298,7 @@ int solarisacl_sys_acl_set_fd(vfs_handle_struct *handle,
  * check is considered unnecessary. --- Agreed? XXX
  */
 int solarisacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				       const char *path)
+				struct smb_filename *smb_fname)
 {
 	SMB_ACL_T smb_acl;
 	int ret = -1;
@@ -307,7 +307,7 @@ int solarisacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
 
 	DEBUG(10, ("entering solarisacl_sys_acl_delete_def_file.\n"));
 	
-	smb_acl = solarisacl_sys_acl_get_file(handle, path, 
+	smb_acl = solarisacl_sys_acl_get_file(handle, smb_fname->base_name,
 					      SMB_ACL_TYPE_ACCESS, talloc_tos());
 	if (smb_acl == NULL) {
 		DEBUG(10, ("getting file acl failed!\n"));
@@ -323,7 +323,7 @@ int solarisacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
 		DEBUG(10, ("resulting acl is not valid!\n"));
 		goto done;
 	}
-	ret = acl(path, SETACL, count, solaris_acl);
+	ret = acl(smb_fname->base_name, SETACL, count, solaris_acl);
 	if (ret != 0) {
 		DEBUG(10, ("settinge file acl failed!\n"));
 	}
diff --git a/source3/modules/vfs_solarisacl.h b/source3/modules/vfs_solarisacl.h
index 20f1051..941f766 100644
--- a/source3/modules/vfs_solarisacl.h
+++ b/source3/modules/vfs_solarisacl.h
@@ -39,7 +39,7 @@ int solarisacl_sys_acl_set_fd(vfs_handle_struct *handle,
 			      SMB_ACL_T theacl);
 
 int solarisacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				       const char *path);
+				const struct smb_filename *smb_fname);
 
 NTSTATUS vfs_solarisacl_init(void);
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 52bd00e..c86f0df 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -2297,19 +2297,20 @@ static int smb_time_audit_sys_acl_set_fd(vfs_handle_struct *handle,
 }
 
 static int smb_time_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
-						  const char *path)
+				const struct smb_filename *smb_fname)
 {
 	int result;
 	struct timespec ts1,ts2;
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path);
+	result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, smb_fname);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("sys_acl_delete_def_file", timediff, path);
+		smb_time_audit_log_fname("sys_acl_delete_def_file", timediff,
+			smb_fname->base_name);
 	}
 
 	return result;
diff --git a/source3/modules/vfs_tru64acl.c b/source3/modules/vfs_tru64acl.c
index 83edc15..83f3289 100644
--- a/source3/modules/vfs_tru64acl.c
+++ b/source3/modules/vfs_tru64acl.c
@@ -148,9 +148,9 @@ int tru64acl_sys_acl_set_fd(vfs_handle_struct *handle,
 }
 
 int tru64acl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				     const char *path)
+				const struct smb_filename *smb_fname)
 {
-	return acl_delete_def_file((char *)path);
+	return acl_delete_def_file((char *)smb_fname->base_name);
 }
 
 
diff --git a/source3/modules/vfs_tru64acl.h b/source3/modules/vfs_tru64acl.h
index af79e2f..3825be0 100644
--- a/source3/modules/vfs_tru64acl.h
+++ b/source3/modules/vfs_tru64acl.h
@@ -37,7 +37,7 @@ int tru64acl_sys_acl_set_fd(vfs_handle_struct *handle,
 			    SMB_ACL_T theacl);
 
 int tru64acl_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				     const char *path);
+				const struct smb_filename *smb_fname);
 
 NTSTATUS vfs_tru64acl_init(void);
 
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index ccafb88..bbccb66 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1668,27 +1668,37 @@ err:
 }
 
 static int um_sys_acl_delete_def_file(vfs_handle_struct *handle,
-				      const char *path)
+				const struct smb_filename *smb_fname)
 {
 	int status;
-	char *client_path = NULL;
+	int saved_errno = 0;
+	struct smb_filename *client_fname = NULL;
 
 	DEBUG(10, ("Entering um_sys_acl_delete_def_file\n"));
 
-	if (!is_in_media_files(path)) {
-		return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle,
+				smb_fname);
 	}
 
-	status = alloc_get_client_path(handle, talloc_tos(),
-					    path, &client_path);
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&client_fname);
 	if (status != 0) {
 		goto err;
 	}
 
-	status = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, client_path);
+	status = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, client_fname);
 
 err:
-	TALLOC_FREE(client_path);
+	if (status == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(client_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return status;
 }
 
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index 6eadf42..c59a910 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -314,7 +314,7 @@ static int zfsacl_fail__sys_acl_set_fd(vfs_handle_struct *handle,
 }
 
 static int zfsacl_fail__sys_acl_delete_def_file(vfs_handle_struct *handle,
-						const char *path)
+			const struct smb_filename *smb_fname)
 {
 	return -1;
 }
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 72bb9fe..c02331d 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -3927,7 +3927,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32_t security_info_sent, const struct
 				become_root();
 			}
 			sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn,
-			    fsp->fsp_name->base_name);
+			    fsp->fsp_name);
 			if (set_acl_as_root) {
 				unbecome_root();
 			}
@@ -3943,7 +3943,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32_t security_info_sent, const struct
 					sret =
 					    SMB_VFS_SYS_ACL_DELETE_DEF_FILE(
 						    conn,
-						    fsp->fsp_name->base_name);
+						    fsp->fsp_name);
 					unbecome_root();
 				}
 
@@ -4410,14 +4410,18 @@ static SMB_ACL_T create_posix_acl_from_wire(connection_struct *conn,
  on the directory.
 ****************************************************************************/
 
-bool set_unix_posix_default_acl(connection_struct *conn, const char *fname, const SMB_STRUCT_STAT *psbuf,
-				uint16_t num_def_acls, const char *pdata)
+bool set_unix_posix_default_acl(connection_struct *conn,
+				const struct smb_filename *smb_fname,
+				uint16_t num_def_acls,
+				const char *pdata)
 {
 	SMB_ACL_T def_acl = NULL;
 
-	if (!S_ISDIR(psbuf->st_ex_mode)) {
+	if (!S_ISDIR(smb_fname->st.st_ex_mode)) {
 		if (num_def_acls) {
-			DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname ));
+			DEBUG(5,("set_unix_posix_default_acl: Can't "
+				"set default ACL on non-directory file %s\n",
+				smb_fname->base_name ));
 			errno = EISDIR;
 			return False;
 		} else {
@@ -4427,9 +4431,9 @@ bool set_unix_posix_default_acl(connection_struct *conn, const char *fname, cons
 
 	if (!num_def_acls) {
 		/* Remove the default ACL. */
-		if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fname) == -1) {
+		if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, smb_fname) == -1) {
 			DEBUG(5,("set_unix_posix_default_acl: acl_delete_def_file failed on directory %s (%s)\n",
-				fname, strerror(errno) ));
+				smb_fname->base_name, strerror(errno) ));
 			return False;
 		}
 		return True;
@@ -4441,14 +4445,16 @@ bool set_unix_posix_default_acl(connection_struct *conn, const char *fname, cons
 		return False;
 	}
 
-	if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT, def_acl) == -1) {
+	if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname->base_name,
+				SMB_ACL_TYPE_DEFAULT, def_acl) == -1) {
 		DEBUG(5,("set_unix_posix_default_acl: acl_set_file failed on directory %s (%s)\n",
-			fname, strerror(errno) ));
+			smb_fname->base_name, strerror(errno) ));
 	        TALLOC_FREE(def_acl);
 		return False;
 	}
 
-	DEBUG(10,("set_unix_posix_default_acl: set default acl for file %s\n", fname ));
+	DEBUG(10,("set_unix_posix_default_acl: set default acl for file %s\n",
+		smb_fname->base_name ));
 	TALLOC_FREE(def_acl);
 	return True;
 }
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 0be2a49..d101686 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -781,8 +781,8 @@ int chmod_acl(connection_struct *conn, const char *name, mode_t mode);
 int inherit_access_posix_acl(connection_struct *conn, const char *inherit_from_dir,
 		       const char *name, mode_t mode);
 int fchmod_acl(files_struct *fsp, mode_t mode);
-bool set_unix_posix_default_acl(connection_struct *conn, const char *fname,
-				const SMB_STRUCT_STAT *psbuf,
+bool set_unix_posix_default_acl(connection_struct *conn,
+				const struct smb_filename *smb_fname,
 				uint16_t num_def_acls, const char *pdata);
 bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char *fname, uint16_t num_acls, const char *pdata);
 NTSTATUS get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname,
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 5155abb..f11dcd1 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -7157,7 +7157,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
 	}
 
 	if (valid_def_acls && !set_unix_posix_default_acl(conn,
-		smb_fname->base_name, &smb_fname->st, num_def_acls,
+		smb_fname, num_def_acls,
 		pdata + SMB_POSIX_ACL_HEADER_SIZE +
 		(num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
 		return map_nt_error_from_unix(errno);
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 560c4b2..a4aeffe 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2493,10 +2493,10 @@ int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
 }
 
 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
-					 const char *path)
+				const struct smb_filename *smb_fname)
 {
 	VFS_FIND(sys_acl_delete_def_file);
-	return handle->fns->sys_acl_delete_def_file_fn(handle, path);
+	return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
 }
 
 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index b57a061..c22b5d2 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -1778,17 +1778,29 @@ static NTSTATUS cmd_sys_acl_delete_def_file(struct vfs_state *vfs, TALLOC_CTX *m
 					    int argc, const char **argv)
 {
 	int ret;
+	struct smb_filename *smb_fname = NULL;
 
 	if (argc != 2) {
 		printf("Usage: sys_acl_delete_def_file <path>\n");
 		return NT_STATUS_OK;
 	}
 
-	ret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(vfs->conn, argv[1]);
+	smb_fname = synthetic_smb_fname(talloc_tos(),
+					argv[1],
+					NULL,
+					NULL,
+					ssf_flags());
+
+	if (smb_fname == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	ret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(vfs->conn, smb_fname);
 	if (ret == -1) {
 		printf("sys_acl_delete_def_file failed (%s)\n", strerror(errno));
+		TALLOC_FREE(smb_fname);
 		return NT_STATUS_UNSUCCESSFUL;
 	}
+	TALLOC_FREE(smb_fname);
 	return NT_STATUS_OK;
 }
 
-- 
2.9.3


From 9ab91a5285e2518c5313389cac6fd36ccef312ba Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Tue, 23 May 2017 17:11:18 -0700
Subject: [PATCH 2/8] s3: VFS: Change SMB_VFS_SYS_ACL_GET_FILE to use const
 struct smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Requires a few extra cleanups in calling code.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c          |  2 +-
 examples/VFS/skel_transparent.c     |  4 +-
 source3/include/smb_acls.h          |  5 ++-
 source3/include/vfs.h               |  6 ++-
 source3/include/vfs_macros.h        |  8 ++--
 source3/lib/sysacls.c               | 39 +++++++++++--------
 source3/modules/posixacl_xattr.c    | 20 +++++-----
 source3/modules/posixacl_xattr.h    |  2 +-
 source3/modules/vfs_aixacl.c        |  3 +-
 source3/modules/vfs_aixacl2.c       |  9 +++--
 source3/modules/vfs_cap.c           | 32 ++++++++++++++--
 source3/modules/vfs_catia.c         | 36 ++++++++++++++----
 source3/modules/vfs_default.c       |  6 +--
 source3/modules/vfs_fake_acls.c     |  7 ++--
 source3/modules/vfs_full_audit.c    | 11 +++---
 source3/modules/vfs_gpfs.c          |  6 +--
 source3/modules/vfs_hpuxacl.c       |  7 ++--
 source3/modules/vfs_hpuxacl.h       |  2 +-
 source3/modules/vfs_media_harmony.c | 34 ++++++++---------
 source3/modules/vfs_nfs4acl_xattr.c |  6 +--
 source3/modules/vfs_posixacl.c      |  8 ++--
 source3/modules/vfs_posixacl.h      |  2 +-
 source3/modules/vfs_solarisacl.c    |  6 ++-
 source3/modules/vfs_solarisacl.h    |  6 +--
 source3/modules/vfs_time_audit.c    | 12 +++---
 source3/modules/vfs_tru64acl.c      |  8 ++--
 source3/modules/vfs_tru64acl.h      |  4 +-
 source3/modules/vfs_unityed_media.c | 32 ++++++++++------
 source3/modules/vfs_vxfs.c          | 15 ++++----
 source3/modules/vfs_zfsacl.c        |  6 +--
 source3/smbd/dosmode.c              |  4 +-
 source3/smbd/open.c                 |  4 +-
 source3/smbd/posix_acls.c           | 76 ++++++++++++++++++++++++++-----------
 source3/smbd/proto.h                | 19 +++++++---
 source3/smbd/pysmbd.c               | 12 +++++-
 source3/smbd/trans2.c               | 10 ++---
 source3/smbd/vfs.c                  |  4 +-
 source3/torture/cmd_vfs.c           | 11 +++++-
 38 files changed, 309 insertions(+), 175 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 801012a..b0be73c 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -741,7 +741,7 @@ static int skel_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle,
-				       const char *path_p,
+				       const struct smb_filename *smb_fname,
 				       SMB_ACL_TYPE_T type,
 				       TALLOC_CTX *mem_ctx)
 {
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 0404a2e..d103695 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -881,11 +881,11 @@ static int skel_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle,
-				       const char *path_p,
+				       const struct smb_filename *smb_fname,
 				       SMB_ACL_TYPE_T type,
 				       TALLOC_CTX *mem_ctx)
 {
-	return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx);
+	return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, smb_fname, type, mem_ctx);
 }
 
 static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle,
diff --git a/source3/include/smb_acls.h b/source3/include/smb_acls.h
index 6a41e19..f5603f3 100644
--- a/source3/include/smb_acls.h
+++ b/source3/include/smb_acls.h
@@ -53,8 +53,9 @@ int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d);
 int sys_acl_free_text(char *text);
 int sys_acl_valid(SMB_ACL_T acl_d);
 SMB_ACL_T sys_acl_get_file(struct vfs_handle_struct *handle,
-			   const char *path_p, SMB_ACL_TYPE_T type,
-			   TALLOC_CTX *mem_ctx);
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			TALLOC_CTX *mem_ctx);
 SMB_ACL_T sys_acl_get_fd(struct vfs_handle_struct *handle, struct files_struct *fsp,
 			 TALLOC_CTX *mem_ctx);
 int sys_acl_set_file(struct vfs_handle_struct *handle,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 8fe5536..330a819 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -199,6 +199,8 @@
 /* Version 37 - Add vfs_copy_chunk_flags for DUP_EXTENTS_TO_FILE */
 /* Version 37 - Change sys_acl_delete_def_file from const char *
 		to const struct smb_filename * */
+/* Version 37 - Change sys_acl_get_file from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -858,7 +860,7 @@ struct vfs_fn_pointers {
 	int (*fchmod_acl_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, mode_t mode);
 
 	SMB_ACL_T (*sys_acl_get_file_fn)(struct vfs_handle_struct *handle,
-					 const char *path_p,
+					 const struct smb_filename *smb_fname,
 					 SMB_ACL_TYPE_T type,
 					 TALLOC_CTX *mem_ctx);
 	SMB_ACL_T (*sys_acl_get_fd_fn)(struct vfs_handle_struct *handle,
@@ -1314,7 +1316,7 @@ int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle,
 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
 			    struct files_struct *fsp, mode_t mode);
 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
-					const char *path_p,
+					const struct smb_filename *smb_fname,
 					SMB_ACL_TYPE_T type,
 					TALLOC_CTX *mem_ctx);
 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 43dfe92..6858181 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -480,10 +480,10 @@
 #define SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode) \
 	smb_vfs_call_fchmod_acl((handle)->next, (fsp), (mode))
 
-#define SMB_VFS_SYS_ACL_GET_FILE(conn, path_p, type, mem_ctx)		\
-	smb_vfs_call_sys_acl_get_file((conn)->vfs_handles, (path_p), (type), (mem_ctx))
-#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx)		\
-	smb_vfs_call_sys_acl_get_file((handle)->next, (path_p), (type), (mem_ctx))
+#define SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname, type, mem_ctx)		\
+	smb_vfs_call_sys_acl_get_file((conn)->vfs_handles, (smb_fname), (type), (mem_ctx))
+#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, smb_fname, type, mem_ctx)		\
+	smb_vfs_call_sys_acl_get_file((handle)->next, (smb_fname), (type), (mem_ctx))
 
 #define SMB_VFS_SYS_ACL_GET_FD(fsp, mem_ctx) \
 	smb_vfs_call_sys_acl_get_fd((fsp)->conn->vfs_handles, (fsp), (mem_ctx))
diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c
index b75c981..8016773 100644
--- a/source3/lib/sysacls.c
+++ b/source3/lib/sysacls.c
@@ -362,9 +362,11 @@ int sys_acl_valid(SMB_ACL_T acl_d)
 #if defined(HAVE_POSIX_ACLS)
 
 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
-			   const char *path_p, SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			TALLOC_CTX *mem_ctx)
 {
-	return posixacl_sys_acl_get_file(handle, path_p, type, mem_ctx);
+	return posixacl_sys_acl_get_file(handle, smb_fname, type, mem_ctx);
 }
 
 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, TALLOC_CTX *mem_ctx)
@@ -393,10 +395,11 @@ int sys_acl_delete_def_file(vfs_handle_struct *handle,
 #elif defined(HAVE_AIX_ACLS)
 
 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
-			   const char *path_p, SMB_ACL_TYPE_T type,
-			   TALLOC_CTX *mem_ctx)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			TALLOC_CTX *mem_ctx)
 {
-	return aixacl_sys_acl_get_file(handle, path_p, type, mem_ctx);
+	return aixacl_sys_acl_get_file(handle, smb_fname, type, mem_ctx);
 }
 
 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp,
@@ -426,10 +429,11 @@ int sys_acl_delete_def_file(vfs_handle_struct *handle,
 #elif defined(HAVE_TRU64_ACLS)
 
 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
-			   const char *path_p, SMB_ACL_TYPE_T type,
-			   TALLOC_CTX *mem_ctx)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			TALLOC_CTX *mem_ctx)
 {
-	return tru64acl_sys_acl_get_file(handle, path_p, type,
+	return tru64acl_sys_acl_get_file(handle, smb_fname, type,
 					 mem_ctx);
 }
 
@@ -460,10 +464,11 @@ int sys_acl_delete_def_file(vfs_handle_struct *handle,
 #elif defined(HAVE_SOLARIS_UNIXWARE_ACLS)
 
 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
-			   const char *path_p, SMB_ACL_TYPE_T type,
-			   TALLOC_CTX *mem_ctx)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			TALLOC_CTX *mem_ctx)
 {
-	return solarisacl_sys_acl_get_file(handle, path_p, type,
+	return solarisacl_sys_acl_get_file(handle, smb_fname, type,
 					   mem_ctx);
 }
 
@@ -495,10 +500,11 @@ int sys_acl_delete_def_file(vfs_handle_struct *handle,
 #elif defined(HAVE_HPUX_ACLS)
 
 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
-			   const char *path_p, SMB_ACL_TYPE_T type,
-			   TALLOC_CTX *mem_ctx)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			TALLOC_CTX *mem_ctx)
 {
-	return hpuxacl_sys_acl_get_file(handle, path_p, type, mem_ctx);
+	return hpuxacl_sys_acl_get_file(handle, smb_fname, type, mem_ctx);
 }
 
 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp,
@@ -528,8 +534,9 @@ int sys_acl_delete_def_file(vfs_handle_struct *handle,
 #else /* No ACLs. */
 
 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
-			   const char *path_p, SMB_ACL_TYPE_T type,
-			   TALLOC_CTX *mem_ctx)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			TALLOC_CTX *mem_ctx)
 {
 #ifdef ENOTSUP
 	errno = ENOTSUP;
diff --git a/source3/modules/posixacl_xattr.c b/source3/modules/posixacl_xattr.c
index 871aa66..c0117c9 100644
--- a/source3/modules/posixacl_xattr.c
+++ b/source3/modules/posixacl_xattr.c
@@ -336,7 +336,7 @@ static int smb_acl_to_posixacl_xattr(SMB_ACL_T theacl, char *buf, size_t len)
 }
 
 SMB_ACL_T posixacl_xattr_acl_get_file(vfs_handle_struct *handle,
-				      const char *path_p,
+				      const struct smb_filename *smb_fname,
 				      SMB_ACL_TYPE_T type,
 				      TALLOC_CTX *mem_ctx)
 {
@@ -360,16 +360,18 @@ SMB_ACL_T posixacl_xattr_acl_get_file(vfs_handle_struct *handle,
 		return NULL;
 	}
 
-	ret = SMB_VFS_GETXATTR(handle->conn, path_p, name, buf, size);
+	ret = SMB_VFS_GETXATTR(handle->conn, smb_fname->base_name,
+				name, buf, size);
 	if (ret < 0 && errno == ERANGE) {
-		size = SMB_VFS_GETXATTR(handle->conn, path_p, name,
-					NULL, 0);
+		size = SMB_VFS_GETXATTR(handle->conn, smb_fname->base_name,
+					name, NULL, 0);
 		if (size > 0) {
 			buf = alloca(size);
 			if (!buf) {
 				return NULL;
 			}
-			ret = SMB_VFS_GETXATTR(handle->conn, path_p, name,
+			ret = SMB_VFS_GETXATTR(handle->conn,
+						smb_fname->base_name, name,
 						buf, size);
 		}
 	}
@@ -380,15 +382,15 @@ SMB_ACL_T posixacl_xattr_acl_get_file(vfs_handle_struct *handle,
 	if (ret == 0 || errno == ENOATTR || errno == ENODATA) {
 		mode_t mode = 0;
 		TALLOC_CTX *frame = talloc_stackframe();
-		struct smb_filename *smb_fname =
-			synthetic_smb_fname(frame, path_p, NULL, NULL, 0);
+		struct smb_filename *smb_fname_tmp =
+			cp_smb_filename(frame, smb_fname);
 		if (smb_fname == NULL) {
 			errno = ENOMEM;
 			ret = -1;
 		} else {
-			ret = SMB_VFS_STAT(handle->conn, smb_fname);
+			ret = SMB_VFS_STAT(handle->conn, smb_fname_tmp);
 			if (ret == 0) {
-				mode = smb_fname->st.st_ex_mode;
+				mode = smb_fname_tmp->st.st_ex_mode;
 			}
 		}
 		TALLOC_FREE(frame);
diff --git a/source3/modules/posixacl_xattr.h b/source3/modules/posixacl_xattr.h
index 6f6316a..8751692 100644
--- a/source3/modules/posixacl_xattr.h
+++ b/source3/modules/posixacl_xattr.h
@@ -22,7 +22,7 @@
 #define __POSIXACL_XATTR_H__
 
 SMB_ACL_T posixacl_xattr_acl_get_file(vfs_handle_struct *handle,
-				      const char *path_p,
+				      const struct smb_filename *smb_fname,
 				      SMB_ACL_TYPE_T type,
 				      TALLOC_CTX *mem_ctx);
 
diff --git a/source3/modules/vfs_aixacl.c b/source3/modules/vfs_aixacl.c
index c25c249..024c9aa 100644
--- a/source3/modules/vfs_aixacl.c
+++ b/source3/modules/vfs_aixacl.c
@@ -23,10 +23,11 @@
 #include "vfs_aixacl_util.h"
 
 SMB_ACL_T aixacl_sys_acl_get_file(vfs_handle_struct *handle,
-				  const char *path_p,
+				  const struct smb_filename *smb_fname,
 				  SMB_ACL_TYPE_T type,
 				  TALLOC_CTX *mem_ctx)
 {
+	const char *path_p = smb_fname->base_name;
 	struct acl *file_acl = (struct acl *)NULL;
 	struct smb_acl_t *result = (struct smb_acl_t *)NULL;
 	
diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c
index e46e502..de5b333 100644
--- a/source3/modules/vfs_aixacl2.c
+++ b/source3/modules/vfs_aixacl2.c
@@ -291,9 +291,9 @@ static SMB_ACL_T aixjfs2_get_posix_acl(const char *path, acl_type_t type, TALLOC
 }
 
 SMB_ACL_T aixjfs2_sys_acl_get_file(vfs_handle_struct *handle,
-                                    const char *path_p,
-				   SMB_ACL_TYPE_T type,
-				   TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
         acl_type_t aixjfs2_type;
 
@@ -309,7 +309,8 @@ SMB_ACL_T aixjfs2_sys_acl_get_file(vfs_handle_struct *handle,
                 smb_panic("exiting");
         }
 
-        return aixjfs2_get_posix_acl(path_p, aixjfs2_type, mem_ctx);
+        return aixjfs2_get_posix_acl(smb_fname->base_name,
+			aixjfs2_type, mem_ctx);
 }
 
 SMB_ACL_T aixjfs2_sys_acl_get_fd(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 4179926..8aba431 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -545,16 +545,40 @@ static int cap_chmod_acl(vfs_handle_struct *handle,
 }
 
 static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle,
-				      const char *path, SMB_ACL_TYPE_T type,
-				      TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	struct smb_filename *cap_smb_fname = NULL;
+	char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+	SMB_ACL_T ret;
+	int saved_errno = 0;
 
 	if (!cappath) {
 		errno = ENOMEM;
 		return (SMB_ACL_T)NULL;
 	}
-	return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cappath, type, mem_ctx);
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					cappath,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(cappath);
+		errno = ENOMEM;
+		return (SMB_ACL_T)NULL;
+	}
+	ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cap_smb_fname,
+				type, mem_ctx);
+	if (ret == NULL) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(cappath);
+	TALLOC_FREE(cap_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
+	return ret;
 }
 
 static int cap_sys_acl_set_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 7ed531a..62f03c8 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -1246,24 +1246,46 @@ catia_chmod_acl(vfs_handle_struct *handle,
 
 static SMB_ACL_T
 catia_sys_acl_get_file(vfs_handle_struct *handle,
-		       const char *path,
-		       SMB_ACL_TYPE_T type,
-		       TALLOC_CTX *mem_ctx)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			TALLOC_CTX *mem_ctx)
 {
 	char *mapped_name = NULL;
+	struct smb_filename *mapped_smb_fname = NULL;
 	NTSTATUS status;
 	SMB_ACL_T ret;
+	int saved_errno;
 
 	status = catia_string_replace_allocate(handle->conn,
-				path, &mapped_name, vfs_translate_to_unix);
+				smb_fname->base_name,
+				&mapped_name,
+				vfs_translate_to_unix);
 	if (!NT_STATUS_IS_OK(status)) {
 		errno = map_errno_from_nt_status(status);
-		return NULL;
+		return (SMB_ACL_T)NULL;
 	}
 
-	ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_name, type, mem_ctx);
-	TALLOC_FREE(mapped_name);
+	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
+					mapped_name,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (mapped_smb_fname == NULL) {
+		TALLOC_FREE(mapped_name);
+		errno = ENOMEM;
+		return (SMB_ACL_T)NULL;
+	}
 
+	ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_smb_fname,
+			type, mem_ctx);
+	if (ret == (SMB_ACL_T)NULL) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(mapped_smb_fname);
+	TALLOC_FREE(mapped_name);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 9b3fdf1..91e4912 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2686,7 +2686,7 @@ static int vfswrap_chmod_acl(vfs_handle_struct *handle,
 	int result;
 
 	START_PROFILE(chmod_acl);
-	result = chmod_acl(handle->conn, smb_fname->base_name, mode);
+	result = chmod_acl(handle->conn, smb_fname, mode);
 	END_PROFILE(chmod_acl);
 	return result;
 #endif
@@ -2708,11 +2708,11 @@ static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode
 }
 
 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle,
-					  const char *path_p,
+					  const struct smb_filename *smb_fname,
 					  SMB_ACL_TYPE_T type,
 					  TALLOC_CTX *mem_ctx)
 {
-	return sys_acl_get_file(handle, path_p, type, mem_ctx);
+	return sys_acl_get_file(handle, smb_fname, type, mem_ctx);
 }
 
 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
index 4b52bf5..be8a2f3 100644
--- a/source3/modules/vfs_fake_acls.c
+++ b/source3/modules/vfs_fake_acls.c
@@ -242,14 +242,15 @@ static DATA_BLOB fake_acls_acl2blob(TALLOC_CTX *mem_ctx, SMB_ACL_T acl)
 }
 
 static SMB_ACL_T fake_acls_sys_acl_get_file(struct vfs_handle_struct *handle,
-					    const char *path,
-					    SMB_ACL_TYPE_T type,
-					    TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
 	DATA_BLOB blob = data_blob_null;
 	ssize_t length;
 	const char *name = NULL;
 	struct smb_acl_t *acl = NULL;
+	const char *path = smb_fname->base_name;
 	TALLOC_CTX *frame = talloc_stackframe();
 	switch (type) {
 	case SMB_ACL_TYPE_ACCESS:
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index e6ee577..932dbf8 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2152,16 +2152,17 @@ static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fs
 }
 
 static SMB_ACL_T smb_full_audit_sys_acl_get_file(vfs_handle_struct *handle,
-					const char *path_p,
-						 SMB_ACL_TYPE_T type,
-						 TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
 	SMB_ACL_T result;
 
-	result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx);
+	result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, smb_fname,
+				type, mem_ctx);
 
 	do_log(SMB_VFS_OP_SYS_ACL_GET_FILE, (result != NULL), handle,
-	       "%s", path_p);
+	       "%s", smb_fname->base_name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index fa2664e..37568ab 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -961,7 +961,7 @@ static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type,
 }
 
 static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
-					  const char *path_p,
+					  const struct smb_filename *smb_fname,
 					  SMB_ACL_TYPE_T type,
 					  TALLOC_CTX *mem_ctx)
 {
@@ -973,7 +973,7 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
 				return NULL);
 
 	if (!config->acl) {
-		return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p,
+		return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, smb_fname,
 						     type, mem_ctx);
 	}
 
@@ -989,7 +989,7 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
 		smb_panic("exiting");
 	}
 
-	return gpfsacl_get_posix_acl(path_p, gpfs_type, mem_ctx);
+	return gpfsacl_get_posix_acl(smb_fname->base_name, gpfs_type, mem_ctx);
 }
 
 static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c
index f666a5e..c344cb9 100644
--- a/source3/modules/vfs_hpuxacl.c
+++ b/source3/modules/vfs_hpuxacl.c
@@ -139,13 +139,14 @@ static bool hpux_aclsort_call_present(void);
 /* public functions - the api */
 
 SMB_ACL_T hpuxacl_sys_acl_get_file(vfs_handle_struct *handle,
-				      const char *path_p,
-				   SMB_ACL_TYPE_T type,
-				   TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
 	SMB_ACL_T result = NULL;
 	int count;
 	HPUX_ACL_T hpux_acl = NULL;
+	const char *path_p = smb_fname->base_name;
 
 	DEBUG(10, ("hpuxacl_sys_acl_get_file called for file '%s'.\n", 
 		   path_p));
diff --git a/source3/modules/vfs_hpuxacl.h b/source3/modules/vfs_hpuxacl.h
index df30e17..b629c7d 100644
--- a/source3/modules/vfs_hpuxacl.h
+++ b/source3/modules/vfs_hpuxacl.h
@@ -34,7 +34,7 @@
 #define __VFS_HPUXACL_H__
 
 SMB_ACL_T hpuxacl_sys_acl_get_file(vfs_handle_struct *handle,
-				   const char *path_p,
+				   const struct smb_filename *smb_fname,
 				   SMB_ACL_TYPE_T type);
 
 SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index 9a5b99d..cad3d9f 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -2101,35 +2101,33 @@ out:
  * Failure: set errno, return NULL
  */
 static SMB_ACL_T mh_sys_acl_get_file(vfs_handle_struct *handle,
-				     const char *path_p,
-				     SMB_ACL_TYPE_T type,
-				     TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
 	SMB_ACL_T ret;
-	char *clientPath;
-	TALLOC_CTX *ctx;
+	int status;
+	struct smb_filename *clientFname = NULL;
 
 	DEBUG(MH_INFO_DEBUG, ("Entering mh_sys_acl_get_file\n"));
-	if (!is_in_media_files(path_p))
-	{
-		ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, smb_fname,
+				type, mem_ctx);
 		goto out;
 	}
 
-	clientPath = NULL;
-	ctx = talloc_tos();
-
-	if (alloc_get_client_path(handle, ctx,
-				path_p,
-				&clientPath))
-	{
-		ret = NULL;
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&clientFname);
+	if (status != 0) {
+		ret = (SMB_ACL_T)NULL;
 		goto err;
 	}
 
-	ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, clientPath, type, mem_ctx);
+	ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, clientFname, type, mem_ctx);
 err:
-	TALLOC_FREE(clientPath);
+	TALLOC_FREE(clientFname);
 out:
 	return ret;
 }
diff --git a/source3/modules/vfs_nfs4acl_xattr.c b/source3/modules/vfs_nfs4acl_xattr.c
index cae3e7b..3975f80 100644
--- a/source3/modules/vfs_nfs4acl_xattr.c
+++ b/source3/modules/vfs_nfs4acl_xattr.c
@@ -585,9 +585,9 @@ static NTSTATUS nfs4acl_xattr_fset_nt_acl(vfs_handle_struct *handle,
 */
 
 static SMB_ACL_T nfs4acl_xattr_fail__sys_acl_get_file(vfs_handle_struct *handle,
-						      const char *path_p,
-						      SMB_ACL_TYPE_T type,
-						      TALLOC_CTX *mem_ctx)
+					const struct smb_filename *smb_fname,
+					SMB_ACL_TYPE_T type,
+					TALLOC_CTX *mem_ctx)
 {
 	return (SMB_ACL_T)NULL;
 }
diff --git a/source3/modules/vfs_posixacl.c b/source3/modules/vfs_posixacl.c
index ed8f1ba..d99f538 100644
--- a/source3/modules/vfs_posixacl.c
+++ b/source3/modules/vfs_posixacl.c
@@ -34,9 +34,9 @@ static acl_t smb_acl_to_posix(const struct smb_acl_t *acl);
 /* public functions - the api */
 
 SMB_ACL_T posixacl_sys_acl_get_file(vfs_handle_struct *handle,
-				    const char *path_p,
-				    SMB_ACL_TYPE_T type,
-				    TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
 	struct smb_acl_t *result;
 	acl_type_t acl_type;
@@ -54,7 +54,7 @@ SMB_ACL_T posixacl_sys_acl_get_file(vfs_handle_struct *handle,
 		return NULL;
 	}
 
-	acl = acl_get_file(path_p, acl_type);
+	acl = acl_get_file(smb_fname->base_name, acl_type);
 
 	if (acl == NULL) {
 		return NULL;
diff --git a/source3/modules/vfs_posixacl.h b/source3/modules/vfs_posixacl.h
index b64bdb2..8dd138e 100644
--- a/source3/modules/vfs_posixacl.h
+++ b/source3/modules/vfs_posixacl.h
@@ -22,7 +22,7 @@
 #define __VFS_POSIXACL_H__
 
 SMB_ACL_T posixacl_sys_acl_get_file(vfs_handle_struct *handle,
-				    const char *path_p,
+				    const struct smb_filename *smb_fname,
 				    SMB_ACL_TYPE_T type,
 				    TALLOC_CTX *mem_ctx);
 
diff --git a/source3/modules/vfs_solarisacl.c b/source3/modules/vfs_solarisacl.c
index 48305c5..4506274 100644
--- a/source3/modules/vfs_solarisacl.c
+++ b/source3/modules/vfs_solarisacl.c
@@ -63,12 +63,14 @@ static bool solaris_acl_check(SOLARIS_ACL_T solaris_acl, int count);
 /* public functions - the api */
 
 SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle,
-				      const char *path_p,
-				      SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
 	SMB_ACL_T result = NULL;
 	int count;
 	SOLARIS_ACL_T solaris_acl = NULL;
+	const char *path_p = smb_fname->base_name;
 	
 	DEBUG(10, ("solarisacl_sys_acl_get_file called for file '%s'.\n", 
 		   path_p));
diff --git a/source3/modules/vfs_solarisacl.h b/source3/modules/vfs_solarisacl.h
index 941f766..0ee4fa3 100644
--- a/source3/modules/vfs_solarisacl.h
+++ b/source3/modules/vfs_solarisacl.h
@@ -21,9 +21,9 @@
 #define __VFS_SOLARISACL_H__
 
 SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle,
-				      const char *path_p,
-				      SMB_ACL_TYPE_T type, 
-				      TALLOC_CTX *mem_ctx);
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx);
 
 SMB_ACL_T solarisacl_sys_acl_get_fd(vfs_handle_struct *handle,
 				    files_struct *fsp, 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index c86f0df..033dabe 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -2169,21 +2169,23 @@ static int smb_time_audit_fchmod_acl(vfs_handle_struct *handle,
 }
 
 static SMB_ACL_T smb_time_audit_sys_acl_get_file(vfs_handle_struct *handle,
-						 const char *path_p,
-						 SMB_ACL_TYPE_T type,
-						 TALLOC_CTX *mem_ctx)
+					const struct smb_filename *smb_fname,
+					SMB_ACL_TYPE_T type,
+					TALLOC_CTX *mem_ctx)
 {
 	SMB_ACL_T result;
 	struct timespec ts1,ts2;
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx);
+	result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, smb_fname,
+				type, mem_ctx);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("sys_acl_get_file", timediff, path_p);
+		smb_time_audit_log_fname("sys_acl_get_file", timediff,
+			smb_fname->base_name);
 	}
 
 	return result;
diff --git a/source3/modules/vfs_tru64acl.c b/source3/modules/vfs_tru64acl.c
index 83f3289..69e5dfc 100644
--- a/source3/modules/vfs_tru64acl.c
+++ b/source3/modules/vfs_tru64acl.c
@@ -38,9 +38,9 @@ static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset);
 /* public functions - the api */
 
 SMB_ACL_T tru64acl_sys_acl_get_file(vfs_handle_struct *handle,
-				    const char *path_p,
-				    SMB_ACL_TYPE_T type,
-				    TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
         struct smb_acl_t *result;
         acl_type_t the_acl_type;
@@ -60,7 +60,7 @@ SMB_ACL_T tru64acl_sys_acl_get_file(vfs_handle_struct *handle,
                 return NULL;
         }
 
-        tru64_acl = acl_get_file((char *)path_p, the_acl_type);
+        tru64_acl = acl_get_file((char *)smb_fname->base_name, the_acl_type);
 
         if (tru64_acl == NULL) {
                 return NULL;
diff --git a/source3/modules/vfs_tru64acl.h b/source3/modules/vfs_tru64acl.h
index 3825be0..0af0930 100644
--- a/source3/modules/vfs_tru64acl.h
+++ b/source3/modules/vfs_tru64acl.h
@@ -21,8 +21,8 @@
 #define __VFS_TRU64ACL_H__
 
 SMB_ACL_T tru64acl_sys_acl_get_file(vfs_handle_struct *handle,
-				    const char *path_p,
-				    SMB_ACL_TYPE_T type);
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type);
 
 SMB_ACL_T tru64acl_sys_acl_get_fd(vfs_handle_struct *handle,
 				  files_struct *fsp);
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index bbccb66..93d9ce6 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1609,32 +1609,42 @@ err:
 }
 
 static SMB_ACL_T um_sys_acl_get_file(vfs_handle_struct *handle,
-				     const char *path_p,
-				     SMB_ACL_TYPE_T type,
-				     TALLOC_CTX *mem_ctx)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				TALLOC_CTX *mem_ctx)
 {
 	SMB_ACL_T ret;
-	char *client_path = NULL;
+	int saved_errno = 0;
+	struct smb_filename *client_fname = NULL;
 	int status;
 
 	DEBUG(10, ("Entering um_sys_acl_get_file\n"));
 
-	if (!is_in_media_files(path_p)) {
-		return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p,
+	if (!is_in_media_files(smb_fname->base_name)) {
+		return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, smb_fname,
 						     type, mem_ctx);
 	}
 
-	status = alloc_get_client_path(handle, talloc_tos(),
-				       path_p, &client_path);
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&client_fname);
 	if (status != 0) {
-		ret = NULL;
+		ret = (SMB_ACL_T)NULL;
 		goto err;
 	}
 
-	ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, client_path, type, mem_ctx);
+	ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, client_fname,
+				type, mem_ctx);
 
 err:
-	TALLOC_FREE(client_path);
+	if (ret == (SMB_ACL_T)NULL) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(client_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c
index f8b0dfa..6586494 100644
--- a/source3/modules/vfs_vxfs.c
+++ b/source3/modules/vfs_vxfs.c
@@ -408,7 +408,14 @@ static bool vxfs_compare(connection_struct *conn, char *name, SMB_ACL_T the_acl,
 	int status;
 
 	DEBUG(10, ("vfs_vxfs: Getting existing ACL for %s\n", name));
-	existing_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, the_acl_type,
+
+	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;
+	}
+
+	existing_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname, the_acl_type,
 						mem_ctx);
 	if (existing_acl == NULL) {
 		DEBUG(10, ("vfs_vxfs: Failed to get ACL\n"));
@@ -423,12 +430,6 @@ 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, 0);
-	if (smb_fname == NULL) {
-		DEBUG(10, ("vfs_vxfs: Failed to create smb_fname\n"));
-		goto out;
-	}
-
 	status = SMB_VFS_STAT(conn, smb_fname);
 	if (status == -1) {
 		DEBUG(10, ("vfs_vxfs: stat failed!\n"));
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index c59a910..57e4182 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -284,9 +284,9 @@ static NTSTATUS zfsacl_fset_nt_acl(vfs_handle_struct *handle,
 */
 
 static SMB_ACL_T zfsacl_fail__sys_acl_get_file(vfs_handle_struct *handle,
-					       const char *path_p,
-					       SMB_ACL_TYPE_T type,
-					       TALLOC_CTX *mem_ctx)
+					const struct smb_filename *smb_fname,
+					SMB_ACL_TYPE_T type,
+					TALLOC_CTX *mem_ctx)
 {
 	return (SMB_ACL_T)NULL;
 }
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 1789b55..3c6d47b 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -679,8 +679,8 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
 
 	unixmode = smb_fname->st.st_ex_mode;
 
-	get_acl_group_bits(conn, smb_fname->base_name,
-			   &smb_fname->st.st_ex_mode);
+	get_acl_group_bits(conn, smb_fname,
+			&smb_fname->st.st_ex_mode);
 
 	if (S_ISDIR(smb_fname->st.st_ex_mode))
 		dosmode |= FILE_ATTRIBUTE_DIRECTORY;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 49932e9..8fdc963 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1224,7 +1224,7 @@ static NTSTATUS open_file(files_struct *fsp,
 			/* Inherit the ACL if required */
 			if (lp_inherit_permissions(SNUM(conn))) {
 				inherit_access_posix_acl(conn, parent_dir,
-							 smb_fname->base_name,
+							 smb_fname,
 							 unx_mode);
 				need_re_stat = true;
 			}
@@ -3832,7 +3832,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
 
 	if (lp_inherit_permissions(SNUM(conn))) {
 		inherit_access_posix_acl(conn, parent_dir,
-					 smb_dname->base_name, mode);
+					 smb_dname, mode);
 		need_re_stat = true;
 	}
 
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index c02331d..4f0540b 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -3583,12 +3583,12 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn,
 	}
 
 	/* Get the ACL from the path. */
-	posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname->base_name,
+	posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname,
 					     SMB_ACL_TYPE_ACCESS, frame);
 
 	/* If it's a directory get the default POSIX ACL. */
 	if(S_ISDIR(smb_fname->st.st_ex_mode)) {
-		def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname->base_name,
+		def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname,
 						   SMB_ACL_TYPE_DEFAULT, frame);
 		def_acl = free_empty_sys_acl(conn, def_acl);
 	}
@@ -4044,14 +4044,16 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32_t security_info_sent, const struct
  the mask bits, not the real group bits, for a file with an ACL.
 ****************************************************************************/
 
-int get_acl_group_bits( connection_struct *conn, const char *fname, mode_t *mode )
+int get_acl_group_bits( connection_struct *conn,
+			const struct smb_filename *smb_fname,
+			mode_t *mode )
 {
 	int entry_id = SMB_ACL_FIRST_ENTRY;
 	SMB_ACL_ENTRY_T entry;
 	SMB_ACL_T posix_acl;
 	int result = -1;
 
-	posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname,
+	posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname,
 					     SMB_ACL_TYPE_ACCESS, talloc_tos());
 	if (posix_acl == (SMB_ACL_T)NULL)
 		return -1;
@@ -4155,12 +4157,15 @@ static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mo
  resulting ACL on TO.  Note that name is in UNIX character set.
 ****************************************************************************/
 
-static int copy_access_posix_acl(connection_struct *conn, const char *from, const char *to, mode_t mode)
+static int copy_access_posix_acl(connection_struct *conn,
+				const struct smb_filename *smb_fname_from,
+				const struct smb_filename *smb_fname_to,
+				mode_t mode)
 {
 	SMB_ACL_T posix_acl = NULL;
 	int ret = -1;
 
-	if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, from,
+	if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname_from,
 						  SMB_ACL_TYPE_ACCESS,
 						  talloc_tos())) == NULL)
 		return -1;
@@ -4168,7 +4173,8 @@ static int copy_access_posix_acl(connection_struct *conn, const char *from, cons
 	if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
 		goto done;
 
-	ret = SMB_VFS_SYS_ACL_SET_FILE(conn, to, SMB_ACL_TYPE_ACCESS, posix_acl);
+	ret = SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname_to->base_name,
+			SMB_ACL_TYPE_ACCESS, posix_acl);
 
  done:
 
@@ -4182,18 +4188,21 @@ static int copy_access_posix_acl(connection_struct *conn, const char *from, cons
  Note that name is in UNIX character set.
 ****************************************************************************/
 
-int chmod_acl(connection_struct *conn, const char *name, mode_t mode)
+int chmod_acl(connection_struct *conn,
+			const struct smb_filename *smb_fname,
+			mode_t mode)
 {
-	return copy_access_posix_acl(conn, name, name, mode);
+	return copy_access_posix_acl(conn, smb_fname, smb_fname, mode);
 }
 
 /****************************************************************************
  Check for an existing default POSIX ACL on a directory.
 ****************************************************************************/
 
-static bool directory_has_default_posix_acl(connection_struct *conn, const char *fname)
+static bool directory_has_default_posix_acl(connection_struct *conn,
+			const struct smb_filename *smb_fname)
 {
-	SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname,
+	SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname,
 						     SMB_ACL_TYPE_DEFAULT,
 						     talloc_tos());
 	bool has_acl = False;
@@ -4214,13 +4223,25 @@ static bool directory_has_default_posix_acl(connection_struct *conn, const char
  inherit this Access ACL to file name.
 ****************************************************************************/
 
-int inherit_access_posix_acl(connection_struct *conn, const char *inherit_from_dir,
-		       const char *name, mode_t mode)
+int inherit_access_posix_acl(connection_struct *conn,
+			const char *inherit_from_dir,
+			const struct smb_filename *smb_fname,
+			mode_t mode)
 {
-	if (directory_has_default_posix_acl(conn, inherit_from_dir))
+	struct smb_filename *inherit_from_fname =
+			synthetic_smb_fname(talloc_tos(),
+				smb_fname->base_name,
+				NULL,
+				NULL,
+				smb_fname->flags);
+	if (inherit_from_fname == NULL) {
+		return-1;
+	}
+
+	if (directory_has_default_posix_acl(conn, inherit_from_fname))
 		return 0;
 
-	return copy_access_posix_acl(conn, inherit_from_dir, name, mode);
+	return copy_access_posix_acl(conn, inherit_from_fname, smb_fname, mode);
 }
 
 /****************************************************************************
@@ -4467,12 +4488,15 @@ bool set_unix_posix_default_acl(connection_struct *conn,
  FIXME ! How does the share mask/mode fit into this.... ?
 ****************************************************************************/
 
-static bool remove_posix_acl(connection_struct *conn, files_struct *fsp, const char *fname)
+static bool remove_posix_acl(connection_struct *conn,
+			files_struct *fsp,
+			const struct smb_filename *smb_fname)
 {
 	SMB_ACL_T file_acl = NULL;
 	int entry_id = SMB_ACL_FIRST_ENTRY;
 	SMB_ACL_ENTRY_T entry;
 	bool ret = False;
+	const char *fname = smb_fname->base_name;
 	/* Create a new ACL with only 3 entries, u/g/w. */
 	SMB_ACL_T new_file_acl = sys_acl_init(talloc_tos());
 	SMB_ACL_ENTRY_T user_ent = NULL;
@@ -4522,7 +4546,7 @@ static bool remove_posix_acl(connection_struct *conn, files_struct *fsp, const c
 	if (fsp && fsp->fh->fd != -1) {
 		file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, talloc_tos());
 	} else {
-		file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname,
+		file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname,
 						    SMB_ACL_TYPE_ACCESS,
 						    talloc_tos());
 	}
@@ -4605,13 +4629,17 @@ static bool remove_posix_acl(connection_struct *conn, files_struct *fsp, const c
  except SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER.
 ****************************************************************************/
 
-bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char *fname, uint16_t num_acls, const char *pdata)
+bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp,
+			const struct smb_filename *smb_fname,
+			uint16_t num_acls,
+			const char *pdata)
 {
 	SMB_ACL_T file_acl = NULL;
+	const char *fname = smb_fname->base_name;
 
 	if (!num_acls) {
 		/* Remove the ACL from the file. */
-		return remove_posix_acl(conn, fsp, fname);
+		return remove_posix_acl(conn, fsp, smb_fname);
 	}
 
 	if ((file_acl = create_posix_acl_from_wire(conn, num_acls,
@@ -4728,7 +4756,7 @@ int posix_sys_acl_blob_get_file(vfs_handle_struct *handle,
 
 	acl_wrapper.access_acl
 		= smb_vfs_call_sys_acl_get_file(handle,
-						path_p,
+						smb_fname,
 						SMB_ACL_TYPE_ACCESS,
 						frame);
 
@@ -4741,7 +4769,7 @@ int posix_sys_acl_blob_get_file(vfs_handle_struct *handle,
 	if (S_ISDIR(smb_fname->st.st_ex_mode)) {
 		acl_wrapper.default_acl
 			= smb_vfs_call_sys_acl_get_file(handle,
-							path_p,
+							smb_fname,
 							SMB_ACL_TYPE_DEFAULT,
 							frame);
 	}
@@ -4789,8 +4817,10 @@ int posix_sys_acl_blob_get_fd(vfs_handle_struct *handle,
 
 	acl_wrapper.default_acl = NULL;
 
-	acl_wrapper.access_acl = smb_vfs_call_sys_acl_get_file(handle, fsp->fsp_name->base_name,
-							       SMB_ACL_TYPE_ACCESS, frame);
+	acl_wrapper.access_acl = smb_vfs_call_sys_acl_get_file(handle,
+					fsp->fsp_name,
+					SMB_ACL_TYPE_ACCESS,
+					frame);
 
 	ret = smb_vfs_call_fstat(handle, fsp, &sbuf);
 	if (ret == -1) {
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index d101686..e1c01bc 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -776,15 +776,24 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn,
 			struct security_descriptor **ppdesc);
 NTSTATUS try_chown(files_struct *fsp, uid_t uid, gid_t gid);
 NTSTATUS set_nt_acl(files_struct *fsp, uint32_t security_info_sent, const struct security_descriptor *psd);
-int get_acl_group_bits( connection_struct *conn, const char *fname, mode_t *mode );
-int chmod_acl(connection_struct *conn, const char *name, mode_t mode);
-int inherit_access_posix_acl(connection_struct *conn, const char *inherit_from_dir,
-		       const char *name, mode_t mode);
+int get_acl_group_bits( connection_struct *conn,
+			const struct smb_filename *smb_fname,
+			mode_t *mode);
+int chmod_acl(connection_struct *conn,
+			const struct smb_filename *smb_fname,
+			mode_t mode);
+int inherit_access_posix_acl(connection_struct *conn,
+			const char *inherit_from_dir,
+			const struct smb_filename *smb_fname,
+			mode_t mode);
 int fchmod_acl(files_struct *fsp, mode_t mode);
 bool set_unix_posix_default_acl(connection_struct *conn,
 				const struct smb_filename *smb_fname,
 				uint16_t num_def_acls, const char *pdata);
-bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char *fname, uint16_t num_acls, const char *pdata);
+bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp,
+				const struct smb_filename *smb_fname,
+				uint16_t num_acls,
+				const char *pdata);
 NTSTATUS get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname,
 			     uint32_t security_info_wanted,
 			     struct security_descriptor **sd);
diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index fca8f10..df6ab18 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -622,6 +622,8 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args, PyObject *k
 	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
 	connection_struct *conn;
 	char *service = NULL;
+	struct smb_filename *smb_fname = NULL;
+
 	if (!tmp_ctx) {
 		PyErr_NoMemory();
 		return NULL;
@@ -642,7 +644,15 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args, PyObject *k
 		return NULL;
 	}
 
-	acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, acl_type, tmp_ctx);
+	smb_fname = synthetic_smb_fname_split(frame,
+					fname,
+					lp_posix_pathnames());
+	if (smb_fname == NULL) {
+		TALLOC_FREE(frame);
+		TALLOC_FREE(tmp_ctx);
+		return NULL;
+	}
+	acl = SMB_VFS_SYS_ACL_GET_FILE( conn, smb_fname, acl_type, tmp_ctx);
 	if (!acl) {
 		TALLOC_FREE(frame);
 		TALLOC_FREE(tmp_ctx);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index f11dcd1..a44de7e 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -5519,7 +5519,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
 				} else {
 					file_acl =
 					    SMB_VFS_SYS_ACL_GET_FILE(conn,
-						smb_fname->base_name,
+						smb_fname,
 						SMB_ACL_TYPE_ACCESS,
 						talloc_tos());
 				}
@@ -5537,14 +5537,14 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
 						def_acl =
 						    SMB_VFS_SYS_ACL_GET_FILE(
 							    conn,
-							    fsp->fsp_name->base_name,
+							    fsp->fsp_name,
 							    SMB_ACL_TYPE_DEFAULT,
 							    talloc_tos());
 					} else {
 						def_acl =
 						    SMB_VFS_SYS_ACL_GET_FILE(
 							    conn,
-							    smb_fname->base_name,
+							    smb_fname,
 							    SMB_ACL_TYPE_DEFAULT,
 							    talloc_tos());
 					}
@@ -7151,7 +7151,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
 		(unsigned int)num_def_acls));
 
 	if (valid_file_acls && !set_unix_posix_acl(conn, fsp,
-		smb_fname->base_name, num_file_acls,
+		smb_fname, num_file_acls,
 		pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
 		return map_nt_error_from_unix(errno);
 	}
@@ -7590,7 +7590,7 @@ static NTSTATUS smb_unix_mknod(connection_struct *conn,
 				    &parent, NULL)) {
 			return NT_STATUS_NO_MEMORY;
 		}
-		inherit_access_posix_acl(conn, parent, smb_fname->base_name,
+		inherit_access_posix_acl(conn, parent, smb_fname,
 					 unixmode);
 		TALLOC_FREE(parent);
 	}
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index a4aeffe..82d0485 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2441,12 +2441,12 @@ int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
 }
 
 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
-					const char *path_p,
+					const struct smb_filename *smb_fname,
 					SMB_ACL_TYPE_T type,
 					TALLOC_CTX *mem_ctx)
 {
 	VFS_FIND(sys_acl_get_file);
-	return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
+	return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
 }
 
 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index c22b5d2..390cffa 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -1683,13 +1683,22 @@ static NTSTATUS cmd_sys_acl_get_file(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 	SMB_ACL_T acl;
 	char *acl_text;
 	int type;
+	struct smb_filename *smb_fname = NULL;
+
 	if (argc != 3) {
 		printf("Usage: sys_acl_get_file <path> <type>\n");
 		return NT_STATUS_OK;
 	}
 
+	smb_fname = synthetic_smb_fname_split(talloc_tos(),
+					argv[1],
+					lp_posix_pathnames());
+	if (smb_fname == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
 	type = atoi(argv[2]);
-	acl = SMB_VFS_SYS_ACL_GET_FILE(vfs->conn, argv[1], type, talloc_tos());
+	acl = SMB_VFS_SYS_ACL_GET_FILE(vfs->conn, smb_fname,
+				type, talloc_tos());
 	if (!acl) {
 		printf("sys_acl_get_file failed (%s)\n", strerror(errno));
 		return NT_STATUS_UNSUCCESSFUL;
-- 
2.9.3


From 2446df60f721e5a1e90fc24f9620f80a32b14de3 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Tue, 23 May 2017 17:35:59 -0700
Subject: [PATCH 3/8] s3: VFS: Change SMB_VFS_SYS_ACL_BLOB_GET_FILE to use
 const struct smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c          |  6 ++++--
 examples/VFS/skel_transparent.c     |  8 +++++---
 source3/include/vfs.h               |  6 ++++--
 source3/include/vfs_macros.h        |  8 ++++----
 source3/modules/non_posix_acls.c    | 18 +++++-------------
 source3/modules/non_posix_acls.h    |  2 +-
 source3/modules/vfs_acl_common.c    |  2 +-
 source3/modules/vfs_afsacl.c        |  6 +++++-
 source3/modules/vfs_aixacl2.c       |  9 +++++++--
 source3/modules/vfs_full_audit.c    | 13 +++++++------
 source3/modules/vfs_gpfs.c          |  9 +++++----
 source3/modules/vfs_nfs4acl_xattr.c |  6 +++++-
 source3/modules/vfs_time_audit.c    | 11 ++++++-----
 source3/modules/vfs_zfsacl.c        |  6 +++++-
 source3/smbd/posix_acls.c           | 14 ++++++++------
 source3/smbd/proto.h                |  2 +-
 source3/smbd/vfs.c                  | 11 ++++++-----
 source3/torture/cmd_vfs.c           |  9 ++++++++-
 18 files changed, 87 insertions(+), 59 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index b0be73c..8ecd0be 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -757,8 +757,10 @@ static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 static int skel_sys_acl_blob_get_file(vfs_handle_struct *handle,
-				      const char *path_p, TALLOC_CTX *mem_ctx,
-				      char **blob_description, DATA_BLOB *blob)
+				const struct smb_filename *smb_fname,
+				TALLOC_CTX *mem_ctx,
+				char **blob_description,
+				DATA_BLOB *blob)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index d103695..82d3c37 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -895,10 +895,12 @@ static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 static int skel_sys_acl_blob_get_file(vfs_handle_struct *handle,
-				      const char *path_p, TALLOC_CTX *mem_ctx,
-				      char **blob_description, DATA_BLOB *blob)
+				const struct smb_filename *smb_fname,
+				TALLOC_CTX *mem_ctx,
+				char **blob_description,
+				DATA_BLOB *blob)
 {
-	return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, mem_ctx,
+	return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, smb_fname, mem_ctx,
 						  blob_description, blob);
 }
 
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 330a819..e32952a 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -201,6 +201,8 @@
 		to const struct smb_filename * */
 /* Version 37 - Change sys_acl_get_file from const char *
 		to const struct smb_filename * */
+/* Version 37 - Change sys_acl_blob_get_file from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -867,7 +869,7 @@ struct vfs_fn_pointers {
 				       struct files_struct *fsp,
 				       TALLOC_CTX *mem_ctx);
 	int (*sys_acl_blob_get_file_fn)(struct vfs_handle_struct *handle,
-					const char *path_p,
+					const struct smb_filename *smb_fname,
 					TALLOC_CTX *mem_ctx,
 					char **blob_description,
 					DATA_BLOB *blob);
@@ -1323,7 +1325,7 @@ SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
 				      struct files_struct *fsp,
 				      TALLOC_CTX *mem_ctx);
 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
-				       const char *path_p,
+				       const struct smb_filename *smb_fname,
 				       TALLOC_CTX *mem_ctx,
 				       char **blob_description,
 				       DATA_BLOB *blob);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 6858181..0ca601a 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -490,10 +490,10 @@
 #define SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx) \
 	smb_vfs_call_sys_acl_get_fd((handle)->next, (fsp), (mem_ctx))
 
-#define SMB_VFS_SYS_ACL_BLOB_GET_FILE(conn, path_p, mem_ctx, blob_description, blob)	\
-	smb_vfs_call_sys_acl_blob_get_file((conn)->vfs_handles, (path_p), (mem_ctx), (blob_description), (blob))
-#define SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, mem_ctx, blob_description, blob) \
-	smb_vfs_call_sys_acl_blob_get_file((handle)->next, (path_p), (mem_ctx), (blob_description), (blob))
+#define SMB_VFS_SYS_ACL_BLOB_GET_FILE(conn, smb_fname, mem_ctx, blob_description, blob)	\
+	smb_vfs_call_sys_acl_blob_get_file((conn)->vfs_handles, (smb_fname), (mem_ctx), (blob_description), (blob))
+#define SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, smb_fname, mem_ctx, blob_description, blob) \
+	smb_vfs_call_sys_acl_blob_get_file((handle)->next, (smb_fname), (mem_ctx), (blob_description), (blob))
 
 #define SMB_VFS_SYS_ACL_BLOB_GET_FD(fsp, mem_ctx, blob_description, blob)			\
 	smb_vfs_call_sys_acl_blob_get_fd((fsp)->conn->vfs_handles, (fsp), (mem_ctx), (blob_description), (blob))
diff --git a/source3/modules/non_posix_acls.c b/source3/modules/non_posix_acls.c
index 8d3be72..d753ef2 100644
--- a/source3/modules/non_posix_acls.c
+++ b/source3/modules/non_posix_acls.c
@@ -22,23 +22,15 @@
 #include "modules/non_posix_acls.h"
 
 int non_posix_sys_acl_blob_get_file_helper(vfs_handle_struct *handle,
-					   const char *path_p,
-					   DATA_BLOB acl_as_blob,
-					   TALLOC_CTX *mem_ctx,
-					   DATA_BLOB *blob)
+				   const struct smb_filename *smb_fname_in,
+				   DATA_BLOB acl_as_blob,
+				   TALLOC_CTX *mem_ctx,
+				   DATA_BLOB *blob)
 {
 	int ret;
 	TALLOC_CTX *frame = talloc_stackframe();
 	struct xattr_sys_acl_hash_wrapper acl_wrapper = {};
-	struct smb_filename *smb_fname;
-
-	smb_fname = synthetic_smb_fname(frame, path_p, NULL, NULL, 0);
-	if (smb_fname == NULL) {
-		TALLOC_FREE(frame);
-		errno = ENOMEM;
-		return -1;
-	}
-
+	struct smb_filename *smb_fname = cp_smb_filename(frame, smb_fname_in);
 	acl_wrapper.acl_as_blob = acl_as_blob;
 
 	ret = smb_vfs_call_stat(handle, smb_fname);
diff --git a/source3/modules/non_posix_acls.h b/source3/modules/non_posix_acls.h
index 6567a31..8924810 100644
--- a/source3/modules/non_posix_acls.h
+++ b/source3/modules/non_posix_acls.h
@@ -18,7 +18,7 @@
 */
 
 int non_posix_sys_acl_blob_get_file_helper(vfs_handle_struct *handle,
-					   const char *path_p,
+					   const struct smb_filename *smb_fname,
 					   DATA_BLOB acl_as_blob,
 					   TALLOC_CTX *mem_ctx,
 					   DATA_BLOB *blob);
diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
index fa65fd1..bd1d755 100644
--- a/source3/modules/vfs_acl_common.c
+++ b/source3/modules/vfs_acl_common.c
@@ -711,7 +711,7 @@ static NTSTATUS validate_nt_acl_blob(TALLOC_CTX *mem_ctx,
 		} else {
 			/* Get the full underlying sd, then hash. */
 			ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle,
-						 smb_fname->base_name,
+						 smb_fname,
 						 mem_ctx,
 						 &sys_acl_blob_description,
 						 &sys_acl_blob);
diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c
index f34495b..ce789f0 100644
--- a/source3/modules/vfs_afsacl.c
+++ b/source3/modules/vfs_afsacl.c
@@ -1085,7 +1085,11 @@ static int afsacl_connect(vfs_handle_struct *handle,
 }
 
 /* We don't have a linear form of the AFS ACL yet */
-static int afsacl_sys_acl_blob_get_file(vfs_handle_struct *handle, const char *path_p, TALLOC_CTX *mem_ctx, char **blob_description, DATA_BLOB *blob)
+static int afsacl_sys_acl_blob_get_file(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			TALLOC_CTX *mem_ctx,
+			char **blob_description,
+			DATA_BLOB *blob)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c
index de5b333..8613b59 100644
--- a/source3/modules/vfs_aixacl2.c
+++ b/source3/modules/vfs_aixacl2.c
@@ -221,16 +221,21 @@ static NTSTATUS aixjfs2_get_nt_acl(vfs_handle_struct *handle,
 				pacl);
 }
 
-static int aixjfs2_sys_acl_blob_get_file(vfs_handle_struct *handle, const char *path_p, TALLOC_CTX *mem_ctx, char **blob_description, DATA_BLOB *blob)
+static int aixjfs2_sys_acl_blob_get_file(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			TALLOC_CTX *mem_ctx,
+			char **blob_description,
+			DATA_BLOB *blob)
 {
 	struct SMB4ACL_T *pacl = NULL;
+	const char *path_p = smb_fname->base_name;
 	bool	result;
 	bool	retryPosix = False;
 
 	result = aixjfs2_get_nfs4_acl(mem_ctx, path_p, &pacl, &retryPosix);
 	if (retryPosix)
 	{
-		return posix_sys_acl_blob_get_file(handle, path_p, mem_ctx,
+		return posix_sys_acl_blob_get_file(handle, smb_fname, mem_ctx,
 						   blob_description, blob);
 	}
 	/* Now way to linarlise NFS4 ACLs at the moment, but the NT ACL is pretty close in this case */
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 932dbf8..6d281d8 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2181,17 +2181,18 @@ static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 static int smb_full_audit_sys_acl_blob_get_file(vfs_handle_struct *handle,
-						const char *path_p,
-						TALLOC_CTX *mem_ctx,
-						char **blob_description,
-						DATA_BLOB *blob)
+				const struct smb_filename *smb_fname,
+				TALLOC_CTX *mem_ctx,
+				char **blob_description,
+				DATA_BLOB *blob)
 {
 	int result;
 
-	result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, mem_ctx, blob_description, blob);
+	result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, smb_fname,
+			mem_ctx, blob_description, blob);
 
 	do_log(SMB_VFS_OP_SYS_ACL_BLOB_GET_FILE, (result >= 0), handle,
-	       "%s", path_p);
+	       "%s", smb_fname->base_name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 37568ab..87ddf5d 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -1011,7 +1011,7 @@ static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 static int gpfsacl_sys_acl_blob_get_file(vfs_handle_struct *handle,
-				      const char *path_p,
+				      const struct smb_filename *smb_fname,
 				      TALLOC_CTX *mem_ctx,
 				      char **blob_description,
 				      DATA_BLOB *blob)
@@ -1020,13 +1020,14 @@ static int gpfsacl_sys_acl_blob_get_file(vfs_handle_struct *handle,
 	struct gpfs_opaque_acl *acl = NULL;
 	DATA_BLOB aclblob;
 	int result;
+	const char *path_p = smb_fname->base_name;
 
 	SMB_VFS_HANDLE_GET_DATA(handle, config,
 				struct gpfs_config_data,
 				return -1);
 
 	if (!config->acl) {
-		return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p,
+		return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, smb_fname,
 							  mem_ctx,
 							  blob_description,
 							  blob);
@@ -1068,7 +1069,7 @@ static int gpfsacl_sys_acl_blob_get_file(vfs_handle_struct *handle,
 			return -1;
 		}
 
-		result = non_posix_sys_acl_blob_get_file_helper(handle, path_p,
+		result = non_posix_sys_acl_blob_get_file_helper(handle, smb_fname,
 								aclblob,
 								mem_ctx, blob);
 
@@ -1077,7 +1078,7 @@ static int gpfsacl_sys_acl_blob_get_file(vfs_handle_struct *handle,
 	}
 
 	/* fall back to POSIX ACL */
-	return posix_sys_acl_blob_get_file(handle, path_p, mem_ctx,
+	return posix_sys_acl_blob_get_file(handle, smb_fname, mem_ctx,
 					   blob_description, blob);
 }
 
diff --git a/source3/modules/vfs_nfs4acl_xattr.c b/source3/modules/vfs_nfs4acl_xattr.c
index 3975f80..a0c4af7 100644
--- a/source3/modules/vfs_nfs4acl_xattr.c
+++ b/source3/modules/vfs_nfs4acl_xattr.c
@@ -620,7 +620,11 @@ static int nfs4acl_xattr_fail__sys_acl_delete_def_file(vfs_handle_struct *handle
 	return -1;
 }
 
-static int nfs4acl_xattr_fail__sys_acl_blob_get_file(vfs_handle_struct *handle, const char *path_p, TALLOC_CTX *mem_ctx, char **blob_description, DATA_BLOB *blob)
+static int nfs4acl_xattr_fail__sys_acl_blob_get_file(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			TALLOC_CTX *mem_ctx,
+			char **blob_description,
+			DATA_BLOB *blob)
 {
 	return -1;
 }
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 033dabe..d62df37 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -2213,17 +2213,18 @@ static SMB_ACL_T smb_time_audit_sys_acl_get_fd(vfs_handle_struct *handle,
 
 
 static int smb_time_audit_sys_acl_blob_get_file(vfs_handle_struct *handle,
-						const char *path_p,
-						TALLOC_CTX *mem_ctx, 
-						char **blob_description,
-						DATA_BLOB *blob)
+				const struct smb_filename *smb_fname,
+				TALLOC_CTX *mem_ctx,
+				char **blob_description,
+				DATA_BLOB *blob)
 {
 	int result;
 	struct timespec ts1,ts2;
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, mem_ctx, blob_description, blob);
+	result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, smb_fname,
+				mem_ctx, blob_description, blob);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index 57e4182..cf341da 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -319,7 +319,11 @@ static int zfsacl_fail__sys_acl_delete_def_file(vfs_handle_struct *handle,
 	return -1;
 }
 
-static int zfsacl_fail__sys_acl_blob_get_file(vfs_handle_struct *handle, const char *path_p, TALLOC_CTX *mem_ctx, char **blob_description, DATA_BLOB *blob)
+static int zfsacl_fail__sys_acl_blob_get_file(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			TALLOC_CTX *mem_ctx,
+			char **blob_description,
+			DATA_BLOB *blob)
 {
 	return -1;
 }
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 4f0540b..8a5d579 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -4734,7 +4734,7 @@ NTSTATUS get_nt_acl_no_snum(TALLOC_CTX *ctx, const char *fname,
 }
 
 int posix_sys_acl_blob_get_file(vfs_handle_struct *handle,
-				const char *path_p,
+				const struct smb_filename *smb_fname_in,
 				TALLOC_CTX *mem_ctx,
 				char **blob_description,
 				DATA_BLOB *blob)
@@ -4745,9 +4745,8 @@ int posix_sys_acl_blob_get_file(vfs_handle_struct *handle,
 	struct smb_acl_wrapper acl_wrapper = {
 		NULL
 	};
-	struct smb_filename *smb_fname;
-
-	smb_fname = synthetic_smb_fname(frame, path_p, NULL, NULL, 0);
+	struct smb_filename *smb_fname = cp_smb_filename(frame,
+						smb_fname_in);
 	if (smb_fname == NULL) {
 		TALLOC_FREE(frame);
 		errno = ENOMEM;
@@ -4810,8 +4809,11 @@ int posix_sys_acl_blob_get_fd(vfs_handle_struct *handle,
 
 	/* This ensures that we also consider the default ACL */
 	if (fsp->is_directory ||  fsp->fh->fd == -1) {
-		return posix_sys_acl_blob_get_file(handle, fsp->fsp_name->base_name,
-						   mem_ctx, blob_description, blob);
+		return posix_sys_acl_blob_get_file(handle,
+						fsp->fsp_name,
+						mem_ctx,
+						blob_description,
+						blob);
 	}
 	frame = talloc_stackframe();
 
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index e1c01bc..34feed1 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -798,7 +798,7 @@ NTSTATUS get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname,
 			     uint32_t security_info_wanted,
 			     struct security_descriptor **sd);
 int posix_sys_acl_blob_get_file(vfs_handle_struct *handle,
-				const char *path_p,
+				const struct smb_filename *smb_fname,
 				TALLOC_CTX *mem_ctx,
 				char **blob_description,
 				DATA_BLOB *blob);
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 82d0485..8dd84a2 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2458,13 +2458,14 @@ SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
 }
 
 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
-				       const char *path_p,
-				       TALLOC_CTX *mem_ctx, 
-				       char **blob_description,
-				       DATA_BLOB *blob)
+				const struct smb_filename *smb_fname,
+				TALLOC_CTX *mem_ctx,
+				char **blob_description,
+				DATA_BLOB *blob)
 {
 	VFS_FIND(sys_acl_blob_get_file);
-	return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
+	return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
+			mem_ctx, blob_description, blob);
 }
 
 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 390cffa..0bb2903 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -1718,13 +1718,20 @@ static NTSTATUS cmd_sys_acl_blob_get_file(struct vfs_state *vfs,
 	DATA_BLOB blob;
 	int ret;
 	size_t i;
+	struct smb_filename *smb_fname = NULL;
 
 	if (argc != 2) {
 		printf("Usage: sys_acl_get_file <path>\n");
 		return NT_STATUS_OK;
 	}
 
-	ret = SMB_VFS_SYS_ACL_BLOB_GET_FILE(vfs->conn, argv[1], talloc_tos(),
+	smb_fname = synthetic_smb_fname_split(talloc_tos(),
+					argv[1],
+					lp_posix_pathnames());
+	if (smb_fname == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	ret = SMB_VFS_SYS_ACL_BLOB_GET_FILE(vfs->conn, smb_fname, talloc_tos(),
 					    &description, &blob);
 	if (ret != 0) {
 		printf("sys_acl_blob_get_file failed (%s)\n", strerror(errno));
-- 
2.9.3


From bbc3c4cf91d062e3da7c3c5d67de67f7fa283133 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 24 May 2017 10:47:46 -0700
Subject: [PATCH 4/8] s3: VFS: Change SMB_VFS_SYS_ACL_SET_FILE to use const
 struct smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c          |  6 ++++--
 examples/VFS/skel_transparent.c     |  9 ++++++---
 source3/include/smb_acls.h          |  4 +++-
 source3/include/vfs.h               | 12 +++++++++---
 source3/include/vfs_macros.h        |  8 ++++----
 source3/lib/sysacls.c               | 34 +++++++++++++++++++++++-----------
 source3/modules/posixacl_xattr.c    |  5 +++--
 source3/modules/posixacl_xattr.h    |  2 +-
 source3/modules/vfs_acl_tdb.c       | 35 ++++++++++++++++++++++++-----------
 source3/modules/vfs_acl_xattr.c     | 11 ++++++-----
 source3/modules/vfs_aixacl.c        |  8 ++++----
 source3/modules/vfs_aixacl2.c       | 11 ++++++-----
 source3/modules/vfs_cap.c           | 32 +++++++++++++++++++++++++++++---
 source3/modules/vfs_catia.c         | 34 ++++++++++++++++++++++++++++------
 source3/modules/vfs_default.c       |  7 +++++--
 source3/modules/vfs_fake_acls.c     |  8 ++++++--
 source3/modules/vfs_full_audit.c    | 10 +++++-----
 source3/modules/vfs_gpfs.c          |  7 ++++---
 source3/modules/vfs_hpuxacl.c       |  4 ++--
 source3/modules/vfs_hpuxacl.h       |  2 +-
 source3/modules/vfs_media_harmony.c | 26 +++++++++++---------------
 source3/modules/vfs_nfs4acl_xattr.c |  2 +-
 source3/modules/vfs_posixacl.c      |  8 +++++---
 source3/modules/vfs_posixacl.h      |  2 +-
 source3/modules/vfs_solarisacl.c    | 26 ++++++++++++++++----------
 source3/modules/vfs_solarisacl.h    |  2 +-
 source3/modules/vfs_time_audit.c    |  7 ++++---
 source3/modules/vfs_tru64acl.c      |  7 ++++---
 source3/modules/vfs_tru64acl.h      |  2 +-
 source3/modules/vfs_unityed_media.c | 25 +++++++++++++++++--------
 source3/modules/vfs_vxfs.c          | 12 ++++++++----
 source3/modules/vfs_zfsacl.c        |  2 +-
 source3/smbd/posix_acls.c           | 16 ++++++++++------
 source3/smbd/pysmbd.c               | 12 +++++++++++-
 source3/smbd/vfs.c                  |  8 +++++---
 35 files changed, 269 insertions(+), 137 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 8ecd0be..e715820 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -774,8 +774,10 @@ static int skel_sys_acl_blob_get_fd(vfs_handle_struct *handle,
 	return -1;
 }
 
-static int skel_sys_acl_set_file(vfs_handle_struct *handle, const char *name,
-				 SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+static int skel_sys_acl_set_file(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T acltype,
+				SMB_ACL_T theacl)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 82d3c37..05d6723 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -912,10 +912,13 @@ static int skel_sys_acl_blob_get_fd(vfs_handle_struct *handle,
 						blob_description, blob);
 }
 
-static int skel_sys_acl_set_file(vfs_handle_struct *handle, const char *name,
-				 SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+static int skel_sys_acl_set_file(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T acltype,
+				SMB_ACL_T theacl)
 {
-	return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype, theacl);
+	return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, smb_fname,
+			acltype, theacl);
 }
 
 static int skel_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
diff --git a/source3/include/smb_acls.h b/source3/include/smb_acls.h
index f5603f3..73b67af 100644
--- a/source3/include/smb_acls.h
+++ b/source3/include/smb_acls.h
@@ -59,7 +59,9 @@ SMB_ACL_T sys_acl_get_file(struct vfs_handle_struct *handle,
 SMB_ACL_T sys_acl_get_fd(struct vfs_handle_struct *handle, struct files_struct *fsp,
 			 TALLOC_CTX *mem_ctx);
 int sys_acl_set_file(struct vfs_handle_struct *handle,
-		     const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d);
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T acl_d);
 int sys_acl_set_fd(struct vfs_handle_struct *handle, struct files_struct *fsp,
 		   SMB_ACL_T acl_d);
 int sys_acl_delete_def_file(struct vfs_handle_struct *handle,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index e32952a..f3a0b32 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -203,6 +203,8 @@
 		to const struct smb_filename * */
 /* Version 37 - Change sys_acl_blob_get_file from const char *
 		to const struct smb_filename * */
+/* Version 37 - Change sys_acl_set_file from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -876,7 +878,10 @@ struct vfs_fn_pointers {
 	int (*sys_acl_blob_get_fd_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp,
 				      TALLOC_CTX *mem_ctx, char **blob_description,
 				      DATA_BLOB *blob);
-	int (*sys_acl_set_file_fn)(struct vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+	int (*sys_acl_set_file_fn)(struct vfs_handle_struct *handle,
+					const struct smb_filename *smb_fname,
+					SMB_ACL_TYPE_T acltype,
+					SMB_ACL_T theacl);
 	int (*sys_acl_set_fd_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_ACL_T theacl);
 	int (*sys_acl_delete_def_file_fn)(struct vfs_handle_struct *handle,
 					const struct smb_filename *smb_fname);
@@ -1335,8 +1340,9 @@ int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
 				     char **blob_description,
 				     DATA_BLOB *blob);
 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
-				  const char *name, SMB_ACL_TYPE_T acltype,
-				  SMB_ACL_T theacl);
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T acltype,
+				SMB_ACL_T theacl);
 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
 				struct files_struct *fsp, SMB_ACL_T theacl);
 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 0ca601a..ac04093 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -500,10 +500,10 @@
 #define SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, blob_description, blob)	\
 	smb_vfs_call_sys_acl_blob_get_fd((handle)->next, (fsp), mem_ctx, (blob_description), (blob))
 
-#define SMB_VFS_SYS_ACL_SET_FILE(conn, name, acltype, theacl) \
-	smb_vfs_call_sys_acl_set_file((conn)->vfs_handles, (name), (acltype), (theacl))
-#define SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype, theacl) \
-	smb_vfs_call_sys_acl_set_file((handle)->next, (name), (acltype), (theacl))
+#define SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname, acltype, theacl) \
+	smb_vfs_call_sys_acl_set_file((conn)->vfs_handles, (smb_fname), (acltype), (theacl))
+#define SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, smb_fname, acltype, theacl) \
+	smb_vfs_call_sys_acl_set_file((handle)->next, (smb_fname), (acltype), (theacl))
 
 #define SMB_VFS_SYS_ACL_SET_FD(fsp, theacl) \
 	smb_vfs_call_sys_acl_set_fd((fsp)->conn->vfs_handles, (fsp), (theacl))
diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c
index 8016773..0bf3c37 100644
--- a/source3/lib/sysacls.c
+++ b/source3/lib/sysacls.c
@@ -375,9 +375,11 @@ SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, TALLOC_CT
 }
 
 int sys_acl_set_file(vfs_handle_struct *handle,
-		     const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T acl_d)
 {
-	return posixacl_sys_acl_set_file(handle, name, type, acl_d);
+	return posixacl_sys_acl_set_file(handle, smb_fname, type, acl_d);
 }
 
 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
@@ -409,9 +411,11 @@ SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_set_file(vfs_handle_struct *handle,
-		     const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T acl_d)
 {
-	return aixacl_sys_acl_set_file(handle, name, type, acl_d);
+	return aixacl_sys_acl_set_file(handle, smb_fname, type, acl_d);
 }
 
 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
@@ -444,9 +448,11 @@ SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_set_file(vfs_handle_struct *handle,
-		     const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T acl_d)
 {
-	return tru64acl_sys_acl_set_file(handle, name, type, acl_d);
+	return tru64acl_sys_acl_set_file(handle, smb_fname, type, acl_d);
 }
 
 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
@@ -480,9 +486,11 @@ SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_set_file(vfs_handle_struct *handle,
-		     const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T acl_d)
 {
-	return solarisacl_sys_acl_set_file(handle, name, type, acl_d);
+	return solarisacl_sys_acl_set_file(handle, smb_fname, type, acl_d);
 }
 
 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
@@ -514,9 +522,11 @@ SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_set_file(vfs_handle_struct *handle,
-		     const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T acl_d)
 {
-	return hpuxacl_sys_acl_set_file(handle, name, type, acl_d);
+	return hpuxacl_sys_acl_set_file(handle, smb_fname, type, acl_d);
 }
 
 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
@@ -558,7 +568,9 @@ SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 int sys_acl_set_file(vfs_handle_struct *handle,
-		     const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T acl_d)
 {
 #ifdef ENOTSUP
 	errno = ENOTSUP;
diff --git a/source3/modules/posixacl_xattr.c b/source3/modules/posixacl_xattr.c
index c0117c9..e7e3f5d 100644
--- a/source3/modules/posixacl_xattr.c
+++ b/source3/modules/posixacl_xattr.c
@@ -444,7 +444,7 @@ SMB_ACL_T posixacl_xattr_acl_get_fd(vfs_handle_struct *handle,
 }
 
 int posixacl_xattr_acl_set_file(vfs_handle_struct *handle,
-				const char *path_p,
+				const struct smb_filename *smb_fname,
 				SMB_ACL_TYPE_T type,
 				SMB_ACL_T theacl)
 {
@@ -474,7 +474,8 @@ int posixacl_xattr_acl_set_file(vfs_handle_struct *handle,
 		return -1;
 	}
 
-	return SMB_VFS_SETXATTR(handle->conn, path_p, name, buf, size, 0);
+	return SMB_VFS_SETXATTR(handle->conn, smb_fname->base_name,
+			name, buf, size, 0);
 }
 
 int posixacl_xattr_acl_set_fd(vfs_handle_struct *handle,
diff --git a/source3/modules/posixacl_xattr.h b/source3/modules/posixacl_xattr.h
index 8751692..70962dd 100644
--- a/source3/modules/posixacl_xattr.h
+++ b/source3/modules/posixacl_xattr.h
@@ -31,7 +31,7 @@ SMB_ACL_T posixacl_xattr_acl_get_fd(vfs_handle_struct *handle,
 				    TALLOC_CTX *mem_ctx);
 
 int posixacl_xattr_acl_set_file(vfs_handle_struct *handle,
-				const char *name,
+				const struct smb_filename *smb_fname,
 				SMB_ACL_TYPE_T type,
 				SMB_ACL_T theacl);
 
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index 68abc33..847096f 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -383,31 +383,44 @@ static int connect_acl_tdb(struct vfs_handle_struct *handle,
 *********************************************************************/
 
 static int sys_acl_set_file_tdb(vfs_handle_struct *handle,
-                              const char *path,
-                              SMB_ACL_TYPE_T type,
-                              SMB_ACL_T theacl)
+			const struct smb_filename *smb_fname_in,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T theacl)
 {
 	struct db_context *db = acl_db;
 	int ret = -1;
-	struct smb_filename smb_fname = {
-		.base_name = discard_const_p(char, path)
+	int saved_errno = 0;
+	struct smb_filename *smb_fname = NULL;
+
+	smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
+	if (smb_fname == NULL) {
+		return -1;
 	};
 
-	ret = SMB_VFS_STAT(handle->conn, &smb_fname);
+	ret = SMB_VFS_STAT(handle->conn, smb_fname);
 	if (ret == -1) {
-		return -1;
+		saved_errno = errno;
+		goto fail;
 	}
 
 	ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle,
-						path,
+						smb_fname,
 						type,
 						theacl);
 	if (ret == -1) {
-		return -1;
+		saved_errno = errno;
+		goto fail;
 	}
 
-	acl_tdb_delete(handle, db, &smb_fname.st);
-	return 0;
+	acl_tdb_delete(handle, db, &smb_fname->st);
+
+fail:
+	TALLOC_FREE(smb_fname);
+
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
+	return ret;
 }
 
 /*********************************************************************
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 96bd016..1dc7082 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -168,12 +168,12 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
 *********************************************************************/
 
 static int sys_acl_set_file_xattr(vfs_handle_struct *handle,
-                              const char *name,
-                              SMB_ACL_TYPE_T type,
-                              SMB_ACL_T theacl)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				SMB_ACL_T theacl)
 {
 	int ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle,
-						name,
+						smb_fname,
 						type,
 						theacl);
 	if (ret == -1) {
@@ -181,7 +181,8 @@ static int sys_acl_set_file_xattr(vfs_handle_struct *handle,
 	}
 
 	become_root();
-	SMB_VFS_REMOVEXATTR(handle->conn, name, XATTR_NTACL_NAME);
+	SMB_VFS_REMOVEXATTR(handle->conn, smb_fname->base_name,
+			XATTR_NTACL_NAME);
 	unbecome_root();
 
 	return ret;
diff --git a/source3/modules/vfs_aixacl.c b/source3/modules/vfs_aixacl.c
index 024c9aa..f6c42cb 100644
--- a/source3/modules/vfs_aixacl.c
+++ b/source3/modules/vfs_aixacl.c
@@ -134,9 +134,9 @@ SMB_ACL_T aixacl_sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 int aixacl_sys_acl_set_file(vfs_handle_struct *handle,
-			      const char *name,
-			      SMB_ACL_TYPE_T type,
-			      SMB_ACL_T theacl)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T theacl)
 {
 	struct acl *file_acl = NULL;
 	unsigned int rc;
@@ -145,7 +145,7 @@ int aixacl_sys_acl_set_file(vfs_handle_struct *handle,
 	if (!file_acl)
 		return -1;
 
-	rc = chacl((char *)name,file_acl,file_acl->acl_len);
+	rc = chacl((char *)smb_fname->base_name,file_acl,file_acl->acl_len);
 	DEBUG(10,("errno is %d\n",errno));
 	DEBUG(10,("return code is %d\n",rc));
 	SAFE_FREE(file_acl);
diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c
index 8613b59..2e4b61e 100644
--- a/source3/modules/vfs_aixacl2.c
+++ b/source3/modules/vfs_aixacl2.c
@@ -468,9 +468,9 @@ NTSTATUS aixjfs2_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint3
 }
 
 int aixjfs2_sys_acl_set_file(vfs_handle_struct *handle,
-			      const char *name,
-			      SMB_ACL_TYPE_T type,
-			      SMB_ACL_T theacl)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T type,
+				SMB_ACL_T theacl)
 {
 	struct acl	*acl_aixc;
 	acl_type_t	acl_type_info;
@@ -478,7 +478,8 @@ int aixjfs2_sys_acl_set_file(vfs_handle_struct *handle,
 
 	DEBUG(10, ("aixjfs2_sys_acl_set_file invoked for %s", name));
 
-	rc = aixjfs2_query_acl_support((char *)name, ACL_AIXC, &acl_type_info);
+	rc = aixjfs2_query_acl_support((char *)smb_fname->base_name,
+			ACL_AIXC, &acl_type_info);
 	if (rc) {
 		DEBUG(8, ("jfs2_set_nt_acl: AIXC support not found\n"));
 		return -1;
@@ -498,7 +499,7 @@ int aixjfs2_sys_acl_set_file(vfs_handle_struct *handle,
 	);
 	if (rc) {
 		DEBUG(2, ("aclx_put failed with %s for %s\n",
-			strerror(errno), name));
+			strerror(errno), smb_fname->base_name));
 		return -1;
 	}
 
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 8aba431..8d621cc 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -581,15 +581,41 @@ static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle,
 	return ret;
 }
 
-static int cap_sys_acl_set_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+static int cap_sys_acl_set_file(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T acltype,
+			SMB_ACL_T theacl)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	struct smb_filename *cap_smb_fname = NULL;
+	char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+	int ret;
+	int saved_errno = 0;
 
 	if (!cappath) {
 		errno = ENOMEM;
 		return -1;
 	}
-	return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cappath, acltype, theacl);
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					cappath,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(cappath);
+		errno = ENOMEM;
+		return -1;
+	}
+	ret =  SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cap_smb_fname,
+				acltype, theacl);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(cappath);
+	TALLOC_FREE(cap_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
+	return ret;
 }
 
 static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 62f03c8..bb4b8f5 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -1291,24 +1291,46 @@ catia_sys_acl_get_file(vfs_handle_struct *handle,
 
 static int
 catia_sys_acl_set_file(vfs_handle_struct *handle,
-		       const char *path,
-		       SMB_ACL_TYPE_T type,
-		       SMB_ACL_T theacl)
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T type,
+			SMB_ACL_T theacl)
 {
+	struct smb_filename *mapped_smb_fname = NULL;
+	int saved_errno = 0;
 	char *mapped_name = NULL;
 	NTSTATUS status;
 	int ret;
 
 	status = catia_string_replace_allocate(handle->conn,
-				path, &mapped_name, vfs_translate_to_unix);
+				smb_fname->base_name,
+				&mapped_name,
+				vfs_translate_to_unix);
 	if (!NT_STATUS_IS_OK(status)) {
 		errno = map_errno_from_nt_status(status);
 		return -1;
 	}
 
-	ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, mapped_name, type, theacl);
-	TALLOC_FREE(mapped_name);
+	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
+					mapped_name,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (mapped_smb_fname == NULL) {
+		TALLOC_FREE(mapped_name);
+		errno = ENOMEM;
+		return -1;
+	}
 
+	ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, mapped_smb_fname,
+			type, theacl);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(mapped_smb_fname);
+	TALLOC_FREE(mapped_name);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 91e4912..ece4463 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2722,9 +2722,12 @@ static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle,
 	return sys_acl_get_fd(handle, fsp, mem_ctx);
 }
 
-static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T acltype,
+				SMB_ACL_T theacl)
 {
-	return sys_acl_set_file(handle, name, acltype, theacl);
+	return sys_acl_set_file(handle, smb_fname, acltype, theacl);
 }
 
 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
index be8a2f3..a52e840 100644
--- a/source3/modules/vfs_fake_acls.c
+++ b/source3/modules/vfs_fake_acls.c
@@ -316,7 +316,10 @@ static SMB_ACL_T fake_acls_sys_acl_get_fd(struct vfs_handle_struct *handle,
 }
 
 
-static int fake_acls_sys_acl_set_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+static int fake_acls_sys_acl_set_file(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			SMB_ACL_TYPE_T acltype,
+			SMB_ACL_T theacl)
 {
 	int ret;
 	const char *name = NULL;
@@ -336,7 +339,8 @@ static int fake_acls_sys_acl_set_file(vfs_handle_struct *handle, const char *pat
 		name = FAKE_ACL_DEFAULT_XATTR;
 		break;
 	}
-	ret = SMB_VFS_NEXT_SETXATTR(handle, path, name, blob.data, blob.length, 0);
+	ret = SMB_VFS_NEXT_SETXATTR(handle, smb_fname->base_name,
+			name, blob.data, blob.length, 0);
 	TALLOC_FREE(frame);
 	return ret;
 }
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 6d281d8..07f01c2 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2214,17 +2214,17 @@ static int smb_full_audit_sys_acl_blob_get_fd(vfs_handle_struct *handle,
 }
 
 static int smb_full_audit_sys_acl_set_file(vfs_handle_struct *handle,
-
-				  const char *name, SMB_ACL_TYPE_T acltype,
-				  SMB_ACL_T theacl)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T acltype,
+				SMB_ACL_T theacl)
 {
 	int result;
 
-	result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype,
+	result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, smb_fname, acltype,
 					       theacl);
 
 	do_log(SMB_VFS_OP_SYS_ACL_SET_FILE, (result >= 0), handle,
-	       "%s", name);
+	       "%s", smb_fname->base_name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 87ddf5d..4dc9f76 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -1233,7 +1233,7 @@ static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl,
 }
 
 static int gpfsacl_sys_acl_set_file(vfs_handle_struct *handle,
-				    const char *name,
+				    const struct smb_filename *smb_fname,
 				    SMB_ACL_TYPE_T type,
 				    SMB_ACL_T theacl)
 {
@@ -1246,7 +1246,8 @@ static int gpfsacl_sys_acl_set_file(vfs_handle_struct *handle,
 				return -1);
 
 	if (!config->acl) {
-		return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, type, theacl);
+		return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, smb_fname,
+				type, theacl);
 	}
 
 	gpfs_acl = smb2gpfs_acl(theacl, type);
@@ -1254,7 +1255,7 @@ static int gpfsacl_sys_acl_set_file(vfs_handle_struct *handle,
 		return -1;
 	}
 
-	result = gpfswrap_putacl(discard_const_p(char, name),
+	result = gpfswrap_putacl(discard_const_p(char, smb_fname->base_name),
 				 GPFS_PUTACL_STRUCT|GPFS_ACL_SAMBA, gpfs_acl);
 
 	SAFE_FREE(gpfs_acl);
diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c
index c344cb9..53e0ad6 100644
--- a/source3/modules/vfs_hpuxacl.c
+++ b/source3/modules/vfs_hpuxacl.c
@@ -209,7 +209,7 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
 
 
 int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
-			     const char *name,
+			     const struct smb_filename *smb_fname_in,
 			     SMB_ACL_TYPE_T type,
 			     SMB_ACL_T theacl)
 {
@@ -222,7 +222,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, 0);
+	smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
 	if (smb_fname == NULL) {
 		status = NT_STATUS_NO_MEMORY;
 		goto done;
diff --git a/source3/modules/vfs_hpuxacl.h b/source3/modules/vfs_hpuxacl.h
index b629c7d..b1b9ec3 100644
--- a/source3/modules/vfs_hpuxacl.h
+++ b/source3/modules/vfs_hpuxacl.h
@@ -41,7 +41,7 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
 				 files_struct *fsp);
 
 int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
-			     const char *name,
+			     const struct smb_filename *smb_fname,
 			     SMB_ACL_TYPE_T type,
 			     SMB_ACL_T theacl);
 
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index cad3d9f..6915fb0 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -2138,36 +2138,32 @@ out:
  * In this case, "name" is a path.
  */
 static int mh_sys_acl_set_file(vfs_handle_struct *handle,
-		const char *name,
+		const struct smb_filename *smb_fname,
 		SMB_ACL_TYPE_T acltype,
 		SMB_ACL_T theacl)
 {
 	int status;
-	char *clientPath;
-	TALLOC_CTX *ctx;
+	struct smb_filename *clientFname = NULL;
 
 	DEBUG(MH_INFO_DEBUG, ("Entering mh_sys_acl_set_file\n"));
-	if (!is_in_media_files(name))
-	{
-		status = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name,
+	if (!is_in_media_files(smb_fname->base_name)) {
+		status = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, smb_fname,
 				acltype, theacl);
 		goto out;
 	}
 
-	clientPath = NULL;
-	ctx = talloc_tos();
-
-	if ((status = alloc_get_client_path(handle, ctx,
-				name,
-				&clientPath)))
-	{
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&clientFname);
+	if (status != 0) {
 		goto err;
 	}
 
-	status = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, clientPath,
+	status = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, clientFname,
 			acltype, theacl);
 err:
-	TALLOC_FREE(clientPath);
+	TALLOC_FREE(clientFname);
 out:
 	return status;
 }
diff --git a/source3/modules/vfs_nfs4acl_xattr.c b/source3/modules/vfs_nfs4acl_xattr.c
index a0c4af7..faf9f9b 100644
--- a/source3/modules/vfs_nfs4acl_xattr.c
+++ b/source3/modules/vfs_nfs4acl_xattr.c
@@ -600,7 +600,7 @@ static SMB_ACL_T nfs4acl_xattr_fail__sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 static int nfs4acl_xattr_fail__sys_acl_set_file(vfs_handle_struct *handle,
-					 const char *name,
+					 const struct smb_filename *smb_fname,
 					 SMB_ACL_TYPE_T type,
 					 SMB_ACL_T theacl)
 {
diff --git a/source3/modules/vfs_posixacl.c b/source3/modules/vfs_posixacl.c
index d99f538..0cad9b6 100644
--- a/source3/modules/vfs_posixacl.c
+++ b/source3/modules/vfs_posixacl.c
@@ -81,7 +81,7 @@ SMB_ACL_T posixacl_sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 int posixacl_sys_acl_set_file(vfs_handle_struct *handle,
-			      const char *name,
+			      const struct smb_filename *smb_fname,
 			      SMB_ACL_TYPE_T type,
 			      SMB_ACL_T theacl)
 {
@@ -89,7 +89,9 @@ int posixacl_sys_acl_set_file(vfs_handle_struct *handle,
 	acl_type_t acl_type;
 	acl_t acl;
 
-	DEBUG(10, ("Calling acl_set_file: %s, %d\n", name, type));
+	DEBUG(10, ("Calling acl_set_file: %s, %d\n",
+			smb_fname->base_name,
+			type));
 
 	switch(type) {
 	case SMB_ACL_TYPE_ACCESS:
@@ -106,7 +108,7 @@ int posixacl_sys_acl_set_file(vfs_handle_struct *handle,
 	if ((acl = smb_acl_to_posix(theacl)) == NULL) {
 		return -1;
 	}
-	res = acl_set_file(name, acl_type, acl);
+	res = acl_set_file(smb_fname->base_name, acl_type, acl);
 	if (res != 0) {
 		DEBUG(10, ("acl_set_file failed: %s\n", strerror(errno)));
 	}
diff --git a/source3/modules/vfs_posixacl.h b/source3/modules/vfs_posixacl.h
index 8dd138e..9cd3160 100644
--- a/source3/modules/vfs_posixacl.h
+++ b/source3/modules/vfs_posixacl.h
@@ -31,7 +31,7 @@ SMB_ACL_T posixacl_sys_acl_get_fd(vfs_handle_struct *handle,
 				  TALLOC_CTX *mem_ctx);
 
 int posixacl_sys_acl_set_file(vfs_handle_struct *handle,
-			      const char *name,
+			      const struct smb_filename *smb_fname,
 			      SMB_ACL_TYPE_T type,
 			      SMB_ACL_T theacl);
 
diff --git a/source3/modules/vfs_solarisacl.c b/source3/modules/vfs_solarisacl.c
index 4506274..ca2aa56 100644
--- a/source3/modules/vfs_solarisacl.c
+++ b/source3/modules/vfs_solarisacl.c
@@ -136,19 +136,23 @@ SMB_ACL_T solarisacl_sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 int solarisacl_sys_acl_set_file(vfs_handle_struct *handle,
-				const char *name,
+				const struct smb_filename *smb_fname_in,
 				SMB_ACL_TYPE_T type,
 				SMB_ACL_T theacl)
 {
 	int ret = -1;
 	SOLARIS_ACL_T solaris_acl = NULL;
 	int count;
-	struct smb_filename smb_fname = {
-		.base_name = discard_const_p(char, name)
-	};
+	struct smb_filename *smb_fname = NULL;
+
+	smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
+	if (smb_fname == NULL) {
+		errno = ENOMEM;
+		goto done;
+	}
 
 	DEBUG(10, ("solarisacl_sys_acl_set_file called for file '%s'\n",
-		   name));
+		   smb_fname->base_name));
 
 	if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT)) {
 		errno = EINVAL;
@@ -176,12 +180,12 @@ int solarisacl_sys_acl_set_file(vfs_handle_struct *handle,
 	 * For a Windows acl mapped call on a symlink, we want to follow
 	 * it.
 	 */
-	ret = SMB_VFS_STAT(handle->conn, &smb_fname);
+	ret = SMB_VFS_STAT(handle->conn, smb_fname);
 	if (ret != 0) {
 		DEBUG(10, ("Error in stat call: %s\n", strerror(errno)));
 		goto done;
 	}
-	if (S_ISDIR(smb_fname.st.st_ex_mode)) {
+	if (S_ISDIR(smb_fname->st.st_ex_mode)) {
 		SOLARIS_ACL_T other_acl = NULL;
 		int other_count;
 		SMB_ACL_TYPE_T other_type;
@@ -190,7 +194,8 @@ int solarisacl_sys_acl_set_file(vfs_handle_struct *handle,
 			? SMB_ACL_TYPE_DEFAULT
 			: SMB_ACL_TYPE_ACCESS;
 		DEBUGADD(10, ("getting acl from filesystem\n"));
-		if (!solaris_acl_get_file(name, &other_acl, &other_count)) {
+		if (!solaris_acl_get_file(smb_fname->base_name,
+					&other_acl, &other_count)) {
 			DEBUG(10, ("error getting acl from directory\n"));
 			goto done;
 		}
@@ -217,12 +222,13 @@ int solarisacl_sys_acl_set_file(vfs_handle_struct *handle,
 		goto done;
 	}
 
-	ret = acl(name, SETACL, count, solaris_acl);
-	
+	ret = acl(smb_fname->base_name, SETACL, count, solaris_acl);
+
  done:
 	DEBUG(10, ("solarisacl_sys_acl_set_file %s.\n",
 		   ((ret != 0) ? "failed" : "succeeded")));
 	SAFE_FREE(solaris_acl);
+	TALLOC_FREE(smb_fname);
 	return ret;
 }
 
diff --git a/source3/modules/vfs_solarisacl.h b/source3/modules/vfs_solarisacl.h
index 0ee4fa3..02bd371 100644
--- a/source3/modules/vfs_solarisacl.h
+++ b/source3/modules/vfs_solarisacl.h
@@ -30,7 +30,7 @@ SMB_ACL_T solarisacl_sys_acl_get_fd(vfs_handle_struct *handle,
 				    TALLOC_CTX *mem_ctx);
 
 int solarisacl_sys_acl_set_file(vfs_handle_struct *handle,
-				const char *name,
+				const struct smb_filename *smb_fname,
 				SMB_ACL_TYPE_T type,
 				SMB_ACL_T theacl);
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index d62df37..2a2f084 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -2258,7 +2258,7 @@ static int smb_time_audit_sys_acl_blob_get_fd(vfs_handle_struct *handle,
 }
 
 static int smb_time_audit_sys_acl_set_file(vfs_handle_struct *handle,
-					   const char *name,
+					   const struct smb_filename *smb_fname,
 					   SMB_ACL_TYPE_T acltype,
 					   SMB_ACL_T theacl)
 {
@@ -2267,13 +2267,14 @@ static int smb_time_audit_sys_acl_set_file(vfs_handle_struct *handle,
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype,
+	result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, smb_fname, acltype,
 					       theacl);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("sys_acl_set_file", timediff, name);
+		smb_time_audit_log_fname("sys_acl_set_file", timediff,
+			smb_fname->base_name);
 	}
 
 	return result;
diff --git a/source3/modules/vfs_tru64acl.c b/source3/modules/vfs_tru64acl.c
index 69e5dfc..d44e56a 100644
--- a/source3/modules/vfs_tru64acl.c
+++ b/source3/modules/vfs_tru64acl.c
@@ -88,7 +88,7 @@ SMB_ACL_T tru64acl_sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 int tru64acl_sys_acl_set_file(vfs_handle_struct *handle,
-			      const char *name,
+			      const struct smb_filename *smb_fname,
 			      SMB_ACL_TYPE_T type,
 			      SMB_ACL_T theacl)
 {
@@ -97,7 +97,7 @@ int tru64acl_sys_acl_set_file(vfs_handle_struct *handle,
         acl_t tru64_acl;
 
         DEBUG(10, ("tru64acl_sys_acl_set_file called with name %s, type %d\n", 
-			name, type));
+			smb_fname->base_name, type));
 
         switch(type) {
         case SMB_ACL_TYPE_ACCESS:
@@ -120,7 +120,8 @@ int tru64acl_sys_acl_set_file(vfs_handle_struct *handle,
                 goto fail;
         }
 	DEBUG(10, ("got tru64 acl...\n"));
-        res = acl_set_file((char *)name, the_acl_type, tru64_acl);
+        res = acl_set_file((char *)smb_fname->base_name,
+				the_acl_type, tru64_acl);
         acl_free(tru64_acl);
         if (res != 0) {
                 DEBUG(10, ("acl_set_file failed: %s\n", strerror(errno)));
diff --git a/source3/modules/vfs_tru64acl.h b/source3/modules/vfs_tru64acl.h
index 0af0930..8dab1f0 100644
--- a/source3/modules/vfs_tru64acl.h
+++ b/source3/modules/vfs_tru64acl.h
@@ -28,7 +28,7 @@ SMB_ACL_T tru64acl_sys_acl_get_fd(vfs_handle_struct *handle,
 				  files_struct *fsp);
 
 int tru64acl_sys_acl_set_file(vfs_handle_struct *handle,
-			      const char *name,
+			      const struct smb_filename *smb_fname,
 			      SMB_ACL_TYPE_T type,
 			      SMB_ACL_T theacl);
 
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index 93d9ce6..21d5416 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1649,31 +1649,40 @@ err:
 }
 
 static int um_sys_acl_set_file(vfs_handle_struct *handle,
-			       const char *name,
+			       const struct smb_filename *smb_fname,
 			       SMB_ACL_TYPE_T acltype,
 			       SMB_ACL_T theacl)
 {
 	int status;
-	char *client_path = NULL;
+	int saved_errno = 0;
+	struct smb_filename *client_fname = NULL;
 
 	DEBUG(10, ("Entering um_sys_acl_set_file\n"));
 
-	if (!is_in_media_files(name)) {
-		return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name,
+	if (!is_in_media_files(smb_fname->base_name)) {
+		return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, smb_fname,
 						     acltype, theacl);
 	}
 
-	status = alloc_get_client_path(handle, talloc_tos(),
-				       name, &client_path);
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&client_fname);
 	if (status != 0) {
 		goto err;
 	}
 
-	status = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, client_path,
+	status = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, client_fname,
 					       acltype, theacl);
 
 err:
-	TALLOC_FREE(client_path);
+	if (status == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(client_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return status;
 }
 
diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c
index 6586494..5dc9ba2 100644
--- a/source3/modules/vfs_vxfs.c
+++ b/source3/modules/vfs_vxfs.c
@@ -499,14 +499,18 @@ static int vxfs_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
 	return SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
 }
 
-static int vxfs_sys_acl_set_file(vfs_handle_struct *handle,  const char *name,
-				 SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+static int vxfs_sys_acl_set_file(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T acltype,
+				SMB_ACL_T theacl)
 {
-	if (vxfs_compare(handle->conn, (char *)name, theacl, acltype)) {
+	if (vxfs_compare(handle->conn, (char *)smb_fname->base_name,
+			theacl, acltype)) {
 		return 0;
 	}
 
-	return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype, theacl);
+	return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, smb_fname,
+			acltype, theacl);
 }
 
 static int vxfs_set_xattr(struct vfs_handle_struct *handle,  const char *path,
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index cf341da..76cf528 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -299,7 +299,7 @@ static SMB_ACL_T zfsacl_fail__sys_acl_get_fd(vfs_handle_struct *handle,
 }
 
 static int zfsacl_fail__sys_acl_set_file(vfs_handle_struct *handle,
-					 const char *name,
+					 const struct smb_filename *smb_fname,
 					 SMB_ACL_TYPE_T type,
 					 SMB_ACL_T theacl)
 {
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 8a5d579..53aebfa 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2970,7 +2970,7 @@ static bool set_canon_ace_list(files_struct *fsp,
 	 */
 
 	if(default_ace || fsp->is_directory || fsp->fh->fd == -1) {
-		if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name->base_name,
+		if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name,
 					     the_acl_type, the_acl) == -1) {
 			/*
 			 * Some systems allow all the above calls and only fail with no ACL support
@@ -2990,7 +2990,7 @@ static bool set_canon_ace_list(files_struct *fsp,
 
 				become_root();
 				sret = SMB_VFS_SYS_ACL_SET_FILE(conn,
-				    fsp->fsp_name->base_name, the_acl_type,
+				    fsp->fsp_name, the_acl_type,
 				    the_acl);
 				unbecome_root();
 				if (sret == 0) {
@@ -4173,7 +4173,7 @@ static int copy_access_posix_acl(connection_struct *conn,
 	if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1)
 		goto done;
 
-	ret = SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname_to->base_name,
+	ret = SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname_to,
 			SMB_ACL_TYPE_ACCESS, posix_acl);
 
  done:
@@ -4466,7 +4466,7 @@ bool set_unix_posix_default_acl(connection_struct *conn,
 		return False;
 	}
 
-	if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname->base_name,
+	if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname,
 				SMB_ACL_TYPE_DEFAULT, def_acl) == -1) {
 		DEBUG(5,("set_unix_posix_default_acl: acl_set_file failed on directory %s (%s)\n",
 			smb_fname->base_name, strerror(errno) ));
@@ -4603,7 +4603,10 @@ static bool remove_posix_acl(connection_struct *conn,
 			goto done;
 		}
 	} else {
-		if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS, new_file_acl) == -1) {
+		if (SMB_VFS_SYS_ACL_SET_FILE(conn,
+					smb_fname,
+					SMB_ACL_TYPE_ACCESS,
+					new_file_acl) == -1) {
 			DEBUG(5,("remove_posix_acl: acl_set_file failed on %s (%s)\n",
 				fname, strerror(errno) ));
 			goto done;
@@ -4657,7 +4660,8 @@ bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp,
 			return False;
 		}
 	} else {
-		if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS, file_acl) == -1) {
+		if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname,
+					SMB_ACL_TYPE_ACCESS, file_acl) == -1) {
 			DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
 				fname, strerror(errno) ));
 		        TALLOC_FREE(file_acl);
diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c
index df6ab18..63fc5d6 100644
--- a/source3/smbd/pysmbd.c
+++ b/source3/smbd/pysmbd.c
@@ -81,6 +81,7 @@ static int set_sys_acl_conn(const char *fname,
 				 SMB_ACL_T theacl, connection_struct *conn)
 {
 	int ret;
+	struct smb_filename *smb_fname = NULL;
 	mode_t saved_umask;
 
 	TALLOC_CTX *frame = talloc_stackframe();
@@ -89,7 +90,16 @@ static int set_sys_acl_conn(const char *fname,
 	   so set our umask to 0 */
 	saved_umask = umask(0);
 
-	ret = SMB_VFS_SYS_ACL_SET_FILE( conn, fname, acltype, theacl);
+	smb_fname = synthetic_smb_fname_split(frame,
+					fname,
+					lp_posix_pathnames());
+	if (smb_fname == NULL) {
+		TALLOC_FREE(frame);
+		umask(saved_umask);
+		return -1;
+	}
+
+	ret = SMB_VFS_SYS_ACL_SET_FILE( conn, smb_fname, acltype, theacl);
 
 	umask(saved_umask);
 
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 8dd84a2..fc0a519 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2479,11 +2479,13 @@ int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
 }
 
 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
-				  const char *name, SMB_ACL_TYPE_T acltype,
-				  SMB_ACL_T theacl)
+				const struct smb_filename *smb_fname,
+				SMB_ACL_TYPE_T acltype,
+				SMB_ACL_T theacl)
 {
 	VFS_FIND(sys_acl_set_file);
-	return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
+	return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
+				acltype, theacl);
 }
 
 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
-- 
2.9.3


From f22207f864f557c2ce1dae4452c0d1283a6cc4c5 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Tue, 23 May 2017 13:12:29 -0700
Subject: [PATCH 5/8] s3: VFS: Change SMB_VFS_LISTXATTR to use const struct
 smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c          |  6 ++++--
 examples/VFS/skel_transparent.c     |  8 +++++---
 source3/include/vfs.h               | 11 ++++++++--
 source3/include/vfs_macros.h        |  8 ++++----
 source3/modules/vfs_cap.c           | 31 +++++++++++++++++++++++++---
 source3/modules/vfs_catia.c         | 28 ++++++++++++++++++++++---
 source3/modules/vfs_ceph.c          | 10 ++++++---
 source3/modules/vfs_default.c       |  7 +++++--
 source3/modules/vfs_full_audit.c    |  9 +++++---
 source3/modules/vfs_glusterfs.c     |  6 ++++--
 source3/modules/vfs_media_harmony.c | 27 +++++++++++-------------
 source3/modules/vfs_posix_eadb.c    |  6 ++++--
 source3/modules/vfs_shadow_copy2.c  | 24 +++++++++++++++++-----
 source3/modules/vfs_snapper.c       | 41 +++++++++++++++++++++++++++----------
 source3/modules/vfs_time_audit.c    |  8 +++++---
 source3/modules/vfs_unityed_media.c | 18 ++++++++--------
 source3/modules/vfs_vxfs.c          | 10 +++++----
 source3/modules/vfs_xattr_tdb.c     |  6 ++++--
 source3/smbd/trans2.c               |  4 ++--
 source3/smbd/vfs.c                  |  6 ++++--
 source3/torture/cmd_vfs.c           | 13 ++++++++++--
 21 files changed, 204 insertions(+), 83 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index e715820..981bfbf 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -812,8 +812,10 @@ static ssize_t skel_fgetxattr(vfs_handle_struct *handle,
 	return -1;
 }
 
-static ssize_t skel_listxattr(vfs_handle_struct *handle, const char *path,
-			      char *list, size_t size)
+static ssize_t skel_listxattr(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 05d6723..ec7a9f1 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -946,10 +946,12 @@ static ssize_t skel_fgetxattr(vfs_handle_struct *handle,
 	return SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size);
 }
 
-static ssize_t skel_listxattr(vfs_handle_struct *handle, const char *path,
-			      char *list, size_t size)
+static ssize_t skel_listxattr(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size)
 {
-	return SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
+	return SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
 }
 
 static ssize_t skel_flistxattr(vfs_handle_struct *handle,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index f3a0b32..7046513 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -205,6 +205,8 @@
 		to const struct smb_filename * */
 /* Version 37 - Change sys_acl_set_file from const char *
 		to const struct smb_filename * */
+/* Version 37 - Change listxattr from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -889,7 +891,10 @@ struct vfs_fn_pointers {
 	/* EA operations. */
 	ssize_t (*getxattr_fn)(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size);
 	ssize_t (*fgetxattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size);
-	ssize_t (*listxattr_fn)(struct vfs_handle_struct *handle, const char *path, char *list, size_t size);
+	ssize_t (*listxattr_fn)(struct vfs_handle_struct *handle,
+					const struct smb_filename *smb_fname,
+					char *list,
+					size_t size);
 	ssize_t (*flistxattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size);
 	int (*removexattr_fn)(struct vfs_handle_struct *handle, const char *path, const char *name);
 	int (*fremovexattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name);
@@ -1354,7 +1359,9 @@ ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
 			       struct files_struct *fsp, const char *name,
 			       void *value, size_t size);
 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
-			       const char *path, char *list, size_t size);
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size);
 ssize_t smb_vfs_call_llistxattr(struct vfs_handle_struct *handle,
 				const char *path, char *list, size_t size);
 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index ac04093..f5c0332 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -525,10 +525,10 @@
 #define SMB_VFS_NEXT_FGETXATTR(handle,fsp,name,value,size) \
 	smb_vfs_call_fgetxattr((handle)->next,(fsp),(name),(value),(size))
 
-#define SMB_VFS_LISTXATTR(conn,path,list,size) \
-	smb_vfs_call_listxattr((conn)->vfs_handles,(path),(list),(size))
-#define SMB_VFS_NEXT_LISTXATTR(handle,path,list,size) \
-	smb_vfs_call_listxattr((handle)->next,(path),(list),(size))
+#define SMB_VFS_LISTXATTR(conn,smb_fname,list,size) \
+	smb_vfs_call_listxattr((conn)->vfs_handles,(smb_fname),(list),(size))
+#define SMB_VFS_NEXT_LISTXATTR(handle,smb_fname,list,size) \
+	smb_vfs_call_listxattr((handle)->next,(smb_fname),(list),(size))
 
 #define SMB_VFS_FLISTXATTR(fsp,list,size) \
 	smb_vfs_call_flistxattr((fsp)->conn->vfs_handles, (fsp), (list),(size))
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 8d621cc..91f624e 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -675,15 +675,40 @@ static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp
         return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
 }
 
-static ssize_t cap_listxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size)
+static ssize_t cap_listxattr(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	struct smb_filename *cap_smb_fname = NULL;
+	char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+	ssize_t ret;
+	int saved_errno = 0;
 
 	if (!cappath) {
 		errno = ENOMEM;
 		return -1;
 	}
-        return SMB_VFS_NEXT_LISTXATTR(handle, cappath, list, size);
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					cappath,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(cappath);
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_LISTXATTR(handle, cap_smb_fname, list, size);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(cappath);
+	TALLOC_FREE(cap_smb_fname);
+	if (saved_errno) {
+		errno = saved_errno;
+	}
+	return ret;
 }
 
 static int cap_removexattr(vfs_handle_struct *handle, const char *path, const char *name)
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index bb4b8f5..20f68a1 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -1408,23 +1408,45 @@ catia_getxattr(vfs_handle_struct *handle, const char *path,
 }
 
 static ssize_t
-catia_listxattr(vfs_handle_struct *handle, const char *path,
+catia_listxattr(vfs_handle_struct *handle,
+		const struct smb_filename *smb_fname,
 		char *list, size_t size)
 {
+	struct smb_filename *mapped_smb_fname = NULL;
 	char *mapped_name = NULL;
 	NTSTATUS status;
 	ssize_t ret;
+	int saved_errno = 0;
 
 	status = catia_string_replace_allocate(handle->conn,
-				path, &mapped_name, vfs_translate_to_unix);
+				smb_fname->base_name,
+				&mapped_name,
+				vfs_translate_to_unix);
 	if (!NT_STATUS_IS_OK(status)) {
 		errno = map_errno_from_nt_status(status);
 		return -1;
 	}
 
+	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
+					mapped_name,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (mapped_smb_fname == NULL) {
+		TALLOC_FREE(mapped_name);
+		errno = ENOMEM;
+		return -1;
+	}
 
-	ret = SMB_VFS_NEXT_LISTXATTR(handle, mapped_name, list, size);
+	ret = SMB_VFS_NEXT_LISTXATTR(handle, mapped_smb_fname, list, size);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
 	TALLOC_FREE(mapped_name);
+	TALLOC_FREE(mapped_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 
 	return ret;
 }
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index d819fe1..874bd40 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1247,11 +1247,15 @@ static ssize_t cephwrap_fgetxattr(struct vfs_handle_struct *handle, struct files
 	}
 }
 
-static ssize_t cephwrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
+static ssize_t cephwrap_listxattr(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			char *list,
+			size_t size)
 {
 	int ret;
-	DBG_DEBUG("[CEPH] listxattr(%p, %s, %p, %llu)\n", handle, path, list, llu(size));
-	ret = ceph_listxattr(handle->data, path, list, size);
+	DBG_DEBUG("[CEPH] listxattr(%p, %s, %p, %llu)\n", handle,
+			smb_fname->base_name, list, llu(size));
+	ret = ceph_listxattr(handle->data, smb_fname->base_name, list, size);
 	DBG_DEBUG("[CEPH] listxattr(...) = %d\n", ret);
 	if (ret < 0) {
 		WRAP_RETURN(ret);
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index ece4463..fb8864e 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2755,9 +2755,12 @@ static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_
 	return fgetxattr(fsp->fh->fd, name, value, size);
 }
 
-static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
+static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			char *list,
+			size_t size)
 {
-	return listxattr(path, list, size);
+	return listxattr(smb_fname->base_name, list, size);
 }
 
 static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 07f01c2..f50f24d 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2284,13 +2284,16 @@ static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle,
 }
 
 static ssize_t smb_full_audit_listxattr(struct vfs_handle_struct *handle,
-			       const char *path, char *list, size_t size)
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size)
 {
 	ssize_t result;
 
-	result = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
+	result = SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
 
-	do_log(SMB_VFS_OP_LISTXATTR, (result >= 0), handle, "%s", path);
+	do_log(SMB_VFS_OP_LISTXATTR, (result >= 0), handle, "%s",
+			smb_fname->base_name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index 628dea7..30629b8 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -1316,9 +1316,11 @@ static ssize_t vfs_gluster_fgetxattr(struct vfs_handle_struct *handle,
 }
 
 static ssize_t vfs_gluster_listxattr(struct vfs_handle_struct *handle,
-				     const char *path, char *list, size_t size)
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size)
 {
-	return glfs_listxattr(handle->data, path, list, size);
+	return glfs_listxattr(handle->data, smb_fname->base_name, list, size);
 }
 
 static ssize_t vfs_gluster_flistxattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index 6915fb0..2113e03 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -2245,35 +2245,32 @@ out:
  * Failure: set errno, return -1
  */
 static ssize_t mh_listxattr(struct vfs_handle_struct *handle,
-		const char *path,
+		const struct smb_filename *smb_fname,
 		char *list,
 		size_t size)
 {
 	ssize_t ret;
-	char *clientPath;
-	TALLOC_CTX *ctx;
+	struct smb_filename *clientFname = NULL;
+	int status;
 
 	DEBUG(MH_INFO_DEBUG, ("Entering mh_listxattr\n"));
-	if (!is_in_media_files(path))
-	{
-		ret = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		ret = SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
 		goto out;
 	}
 
-	clientPath = NULL;
-	ctx = talloc_tos();
-
-	if (alloc_get_client_path(handle, ctx,
-				path,
-				&clientPath))
-	{
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&clientFname);
+	if (status != 0) {
 		ret = -1;
 		goto err;
 	}
 
-	ret = SMB_VFS_NEXT_LISTXATTR(handle, clientPath, list, size);
+	ret = SMB_VFS_NEXT_LISTXATTR(handle, clientFname, list, size);
 err:
-	TALLOC_FREE(clientPath);
+	TALLOC_FREE(clientFname);
 out:
 	return ret;
 }
diff --git a/source3/modules/vfs_posix_eadb.c b/source3/modules/vfs_posix_eadb.c
index 129f072..b5f92df 100644
--- a/source3/modules/vfs_posix_eadb.c
+++ b/source3/modules/vfs_posix_eadb.c
@@ -179,13 +179,15 @@ static ssize_t posix_eadb_listattr(struct tdb_wrap *db_ctx,
 }
 
 static ssize_t posix_eadb_listxattr(struct vfs_handle_struct *handle,
-				   const char *path, char *list, size_t size)
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size)
 {
 	struct tdb_wrap *db;
 
 	SMB_VFS_HANDLE_GET_DATA(handle, db, struct tdb_wrap, return -1);
 
-	return posix_eadb_listattr(db, path, -1, list, size);
+	return posix_eadb_listattr(db, smb_fname->base_name, -1, list, size);
 }
 
 static ssize_t posix_eadb_flistxattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 6777d7a..7417679 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -2367,7 +2367,7 @@ static ssize_t shadow_copy2_getxattr(vfs_handle_struct *handle,
 }
 
 static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle,
-				      const char *fname,
+				      const struct smb_filename *smb_fname,
 				      char *list, size_t size)
 {
 	time_t timestamp = 0;
@@ -2375,23 +2375,37 @@ static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle,
 	ssize_t ret;
 	int saved_errno = 0;
 	char *conv;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-					 &timestamp, &stripped)) {
+	if (!shadow_copy2_strip_snapshot(talloc_tos(),
+				handle,
+				smb_fname->base_name,
+				&timestamp,
+				&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_LISTXATTR(handle, fname, list, size);
+		return SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
 	}
 	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_LISTXATTR(handle, conv, list, size);
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (conv_smb_fname == NULL) {
+		TALLOC_FREE(conv);
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_LISTXATTR(handle, conv_smb_fname, list, size);
 	if (ret == -1) {
 		saved_errno = errno;
 	}
+	TALLOC_FREE(conv_smb_fname);
 	TALLOC_FREE(conv);
 	if (saved_errno != 0) {
 		errno = saved_errno;
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index 69e2ab9..a67ec1c 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -2699,31 +2699,50 @@ static ssize_t snapper_gmt_getxattr(vfs_handle_struct *handle,
 }
 
 static ssize_t snapper_gmt_listxattr(struct vfs_handle_struct *handle,
-				     const char *fname,
+				     const struct smb_filename *smb_fname,
 				     char *list, size_t size)
 {
-	time_t timestamp;
-	char *stripped;
+	time_t timestamp = 0;
+	char *stripped = NULL;
 	ssize_t ret;
-	int saved_errno;
-	char *conv;
+	int saved_errno = 0;
+	char *conv = NULL;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname,
-					&timestamp, &stripped)) {
+	if (!snapper_gmt_strip_snapshot(talloc_tos(),
+					handle,
+					smb_fname->base_name,
+					&timestamp,
+					&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_LISTXATTR(handle, fname, list, size);
+		return SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
 	}
 	conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_LISTXATTR(handle, conv, list, size);
-	saved_errno = errno;
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					fname->flags);
 	TALLOC_FREE(conv);
-	errno = saved_errno;
+	if (conv_smb_fname == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_LISTXATTR(handle, conv_smb_fname, list, size);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(conv_smb_fname);
+	TALLOC_FREE(conv);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 2a2f084..e260c47 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -2362,7 +2362,8 @@ static ssize_t smb_time_audit_fgetxattr(struct vfs_handle_struct *handle,
 }
 
 static ssize_t smb_time_audit_listxattr(struct vfs_handle_struct *handle,
-					const char *path, char *list,
+					const struct smb_filename *smb_fname,
+					char *list,
 					size_t size)
 {
 	ssize_t result;
@@ -2370,12 +2371,13 @@ static ssize_t smb_time_audit_listxattr(struct vfs_handle_struct *handle,
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
+	result = SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("listxattr", timediff, path);
+		smb_time_audit_log_fname("listxattr", timediff,
+				smb_fname->base_name);
 	}
 
 	return result;
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index 21d5416..7b60856 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1750,31 +1750,33 @@ err:
 }
 
 static ssize_t um_listxattr(struct vfs_handle_struct *handle,
-			    const char *path,
+			    const struct smb_filename *smb_fname,
 			    char *list,
 			    size_t size)
 {
 	ssize_t ret;
-	char *client_path = NULL;
+	struct smb_filename *client_fname = NULL;
 	int status;
 
 	DEBUG(10, ("Entering um_listxattr\n"));
 
-	if (!is_in_media_files(path)) {
-		return SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		return SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
 	}
 
-	status = alloc_get_client_path(handle, talloc_tos(),
-				       path, &client_path);
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&client_fname);
 	if (status != 0) {
 		ret = -1;
 		goto err;
 	}
 
-	ret = SMB_VFS_NEXT_LISTXATTR(handle, client_path, list, size);
+	ret = SMB_VFS_NEXT_LISTXATTR(handle, client_fname, list, size);
 
 err:
-	TALLOC_FREE(client_path);
+	TALLOC_FREE(client_fname);
 	return ret;
 }
 
diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c
index 5dc9ba2..c678636 100644
--- a/source3/modules/vfs_vxfs.c
+++ b/source3/modules/vfs_vxfs.c
@@ -752,17 +752,19 @@ static size_t vxfs_filter_list(char *list, size_t size)
 	return size;
 }
 
-static ssize_t vxfs_listxattr(vfs_handle_struct *handle, const char *path,
-                              char *list, size_t size)
+static ssize_t vxfs_listxattr(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size)
 {
 	ssize_t result;
 
-	result = vxfs_listxattr_path(path, list, size);
+	result = vxfs_listxattr_path(smb_fname->base_name, list, size);
 	if (result >= 0 || ((errno != ENOTSUP) && (errno != ENOSYS))) {
 		return result;
 	}
 
-	result = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
+	result = SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
 
 	if (result <= 0) {
 		return result;
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
index 12ccbca..a4f80b2 100644
--- a/source3/modules/vfs_xattr_tdb.c
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -204,7 +204,9 @@ static int xattr_tdb_fsetxattr(struct vfs_handle_struct *handle,
 }
 
 static ssize_t xattr_tdb_listxattr(struct vfs_handle_struct *handle,
-				   const char *path, char *list, size_t size)
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size)
 {
 	struct file_id id;
 	struct db_context *db;
@@ -217,7 +219,7 @@ static ssize_t xattr_tdb_listxattr(struct vfs_handle_struct *handle,
 					TALLOC_FREE(frame); return -1;
 				});
 
-	ret = xattr_tdb_get_file_id(handle, path, &id);
+	ret = xattr_tdb_get_file_id(handle, smb_fname->base_name, &id);
 	if (ret == -1) {
 		TALLOC_FREE(frame);
 		return -1;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index a44de7e..8c1190b 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -289,7 +289,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
 					     ea_namelist_size);
 	} else {
 		sizeret = SMB_VFS_LISTXATTR(conn,
-					    smb_fname->base_name,
+					    smb_fname,
 					    ea_namelist,
 					    ea_namelist_size);
 	}
@@ -307,7 +307,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
 						     ea_namelist_size);
 		} else {
 			sizeret = SMB_VFS_LISTXATTR(conn,
-						    smb_fname->base_name,
+						    smb_fname,
 						    ea_namelist,
 						    ea_namelist_size);
 		}
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index fc0a519..d27ab39 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2519,10 +2519,12 @@ ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
 }
 
 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
-			       const char *path, char *list, size_t size)
+				const struct smb_filename *smb_fname,
+				char *list,
+				size_t size)
 {
 	VFS_FIND(listxattr);
-	return handle->fns->listxattr_fn(handle, path, list, size);
+	return handle->fns->listxattr_fn(handle, smb_fname, list, size);
 }
 
 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 0bb2903..7155ac3 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -1344,6 +1344,7 @@ static NTSTATUS cmd_listxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 {
 	char *buf, *p;
 	ssize_t ret;
+	struct smb_filename *smb_fname = NULL;
 
 	if (argc != 2) {
 		printf("Usage: listxattr <path>\n");
@@ -1352,7 +1353,14 @@ static NTSTATUS cmd_listxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 
 	buf = NULL;
 
-	ret = SMB_VFS_LISTXATTR(vfs->conn, argv[1], buf, talloc_get_size(buf));
+	smb_fname = synthetic_smb_fname_split(mem_ctx,
+					argv[1],
+					lp_posix_pathnames());
+	if (smb_fname == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	ret = SMB_VFS_LISTXATTR(vfs->conn, smb_fname,
+				buf, talloc_get_size(buf));
 	if (ret == -1) {
 		int err = errno;
 		printf("listxattr returned (%s)\n", strerror(err));
@@ -1362,7 +1370,8 @@ static NTSTATUS cmd_listxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 	if (buf == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
-	ret = SMB_VFS_LISTXATTR(vfs->conn, argv[1], buf, talloc_get_size(buf));
+	ret = SMB_VFS_LISTXATTR(vfs->conn, smb_fname,
+				buf, talloc_get_size(buf));
 	if (ret == -1) {
 		int err = errno;
 		printf("listxattr returned (%s)\n", strerror(err));
-- 
2.9.3


From 3f0b79149f417cb449623013cb0037f65a3845e1 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Wed, 24 May 2017 11:35:50 -0700
Subject: [PATCH 6/8] s3: VFS: Change SMB_VFS_REMOVEXATTR to use const struct
 smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c          |  5 +++--
 examples/VFS/skel_transparent.c     |  7 +++---
 source3/include/vfs.h               |  9 ++++++--
 source3/include/vfs_macros.h        |  8 +++----
 source3/modules/posixacl_xattr.c    |  2 +-
 source3/modules/vfs_acl_xattr.c     |  2 +-
 source3/modules/vfs_cap.c           | 32 ++++++++++++++++++++++++---
 source3/modules/vfs_catia.c         | 33 ++++++++++++++++++++++++----
 source3/modules/vfs_ceph.c          |  9 +++++---
 source3/modules/vfs_default.c       |  6 ++++--
 source3/modules/vfs_fake_acls.c     |  2 +-
 source3/modules/vfs_fruit.c         |  4 ++--
 source3/modules/vfs_full_audit.c    |  6 +++---
 source3/modules/vfs_glusterfs.c     |  5 +++--
 source3/modules/vfs_media_harmony.c | 27 ++++++++++-------------
 source3/modules/vfs_posix_eadb.c    |  5 +++--
 source3/modules/vfs_shadow_copy2.c  | 25 ++++++++++++++++-----
 source3/modules/vfs_snapper.c       | 43 +++++++++++++++++++++++++++----------
 source3/modules/vfs_streams_xattr.c |  4 ++--
 source3/modules/vfs_time_audit.c    |  8 ++++---
 source3/modules/vfs_unityed_media.c | 18 +++++++++-------
 source3/modules/vfs_vxfs.c          | 35 ++++++++++++++++++------------
 source3/modules/vfs_xattr_tdb.c     |  5 +++--
 source3/smbd/trans2.c               |  2 +-
 source3/smbd/vfs.c                  |  5 +++--
 source3/torture/cmd_vfs.c           | 13 ++++++++++-
 26 files changed, 220 insertions(+), 100 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 981bfbf..ea66742 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -829,8 +829,9 @@ static ssize_t skel_flistxattr(vfs_handle_struct *handle,
 	return -1;
 }
 
-static int skel_removexattr(vfs_handle_struct *handle, const char *path,
-			    const char *name)
+static int skel_removexattr(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index ec7a9f1..e72edbc 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -961,10 +961,11 @@ static ssize_t skel_flistxattr(vfs_handle_struct *handle,
 	return SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
 }
 
-static int skel_removexattr(vfs_handle_struct *handle, const char *path,
-			    const char *name)
+static int skel_removexattr(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name)
 {
-	return SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
+	return SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
 }
 
 static int skel_fremovexattr(vfs_handle_struct *handle,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 7046513..56c3f5d 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -207,6 +207,8 @@
 		to const struct smb_filename * */
 /* Version 37 - Change listxattr from const char *
 		to const struct smb_filename * */
+/* Version 37 - Change removexattr from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -896,7 +898,9 @@ struct vfs_fn_pointers {
 					char *list,
 					size_t size);
 	ssize_t (*flistxattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size);
-	int (*removexattr_fn)(struct vfs_handle_struct *handle, const char *path, const char *name);
+	int (*removexattr_fn)(struct vfs_handle_struct *handle,
+					const struct smb_filename *smb_fname,
+					const char *name);
 	int (*fremovexattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name);
 	int (*setxattr_fn)(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags);
 	int (*fsetxattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags);
@@ -1368,7 +1372,8 @@ ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
 				struct files_struct *fsp, char *list,
 				size_t size);
 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
-			     const char *path, const char *name);
+				const struct smb_filename *smb_fname,
+				const char *name);
 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
 			      struct files_struct *fsp, const char *name);
 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index f5c0332..e1a9ba0 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -535,10 +535,10 @@
 #define SMB_VFS_NEXT_FLISTXATTR(handle,fsp,list,size) \
 	smb_vfs_call_flistxattr((handle)->next,(fsp),(list),(size))
 
-#define SMB_VFS_REMOVEXATTR(conn,path,name) \
-	smb_vfs_call_removexattr((conn)->vfs_handles,(path),(name))
-#define SMB_VFS_NEXT_REMOVEXATTR(handle,path,name) \
-	smb_vfs_call_removexattr((handle)->next,(path),(name))
+#define SMB_VFS_REMOVEXATTR(conn,smb_fname,name) \
+	smb_vfs_call_removexattr((conn)->vfs_handles,(smb_fname),(name))
+#define SMB_VFS_NEXT_REMOVEXATTR(handle,smb_fname,name) \
+	smb_vfs_call_removexattr((handle)->next,(smb_fname),(name))
 
 #define SMB_VFS_FREMOVEXATTR(fsp,name) \
 	smb_vfs_call_fremovexattr((fsp)->conn->vfs_handles, (fsp), (name))
diff --git a/source3/modules/posixacl_xattr.c b/source3/modules/posixacl_xattr.c
index e7e3f5d..780f68a 100644
--- a/source3/modules/posixacl_xattr.c
+++ b/source3/modules/posixacl_xattr.c
@@ -504,6 +504,6 @@ int posixacl_xattr_acl_delete_def_file(vfs_handle_struct *handle,
 				const struct smb_filename *smb_fname)
 {
 	return SMB_VFS_REMOVEXATTR(handle->conn,
-			smb_fname->base_name,
+			smb_fname,
 			ACL_EA_DEFAULT);
 }
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 1dc7082..b21207b 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -181,7 +181,7 @@ static int sys_acl_set_file_xattr(vfs_handle_struct *handle,
 	}
 
 	become_root();
-	SMB_VFS_REMOVEXATTR(handle->conn, smb_fname->base_name,
+	SMB_VFS_REMOVEXATTR(handle->conn, smb_fname,
 			XATTR_NTACL_NAME);
 	unbecome_root();
 
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 91f624e..fe70d78 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -711,16 +711,42 @@ static ssize_t cap_listxattr(vfs_handle_struct *handle,
 	return ret;
 }
 
-static int cap_removexattr(vfs_handle_struct *handle, const char *path, const char *name)
+static int cap_removexattr(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				const char *name)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	struct smb_filename *cap_smb_fname = NULL;
+	char *cappath = capencode(talloc_tos(), smb_fname->base_name);
 	char *capname = capencode(talloc_tos(), name);
+	int ret;
+	int saved_errno = 0;
 
 	if (!cappath || !capname) {
 		errno = ENOMEM;
 		return -1;
 	}
-        return SMB_VFS_NEXT_REMOVEXATTR(handle, cappath, capname);
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					cappath,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(cappath);
+		TALLOC_FREE(capname);
+		errno = ENOMEM;
+		return -1;
+	}
+        ret = SMB_VFS_NEXT_REMOVEXATTR(handle, cap_smb_fname, capname);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(cappath);
+	TALLOC_FREE(capname);
+	TALLOC_FREE(cap_smb_fname);
+	if (saved_errno) {
+		errno = saved_errno;
+	}
+	return ret;
 }
 
 static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 20f68a1..3266d95 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -1452,16 +1452,21 @@ catia_listxattr(vfs_handle_struct *handle,
 }
 
 static int
-catia_removexattr(vfs_handle_struct *handle, const char *path,
-		  const char *name)
+catia_removexattr(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name)
 {
+	struct smb_filename *mapped_smb_fname = NULL;
 	char *mapped_name = NULL;
 	char *mapped_ea_name = NULL;
 	NTSTATUS status;
 	ssize_t ret;
+	int saved_errno = 0;
 
 	status = catia_string_replace_allocate(handle->conn,
-				path, &mapped_name, vfs_translate_to_unix);
+				smb_fname->base_name,
+				&mapped_name,
+				vfs_translate_to_unix);
 	if (!NT_STATUS_IS_OK(status)) {
 		errno = map_errno_from_nt_status(status);
 		return -1;
@@ -1475,9 +1480,29 @@ catia_removexattr(vfs_handle_struct *handle, const char *path,
 		return -1;
 	}
 
-	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, mapped_name, mapped_ea_name);
+	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
+					mapped_name,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (mapped_smb_fname == NULL) {
+		TALLOC_FREE(mapped_name);
+		TALLOC_FREE(mapped_ea_name);
+		errno = ENOMEM;
+		return -1;
+	}
+
+	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, mapped_smb_fname,
+				mapped_ea_name);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
 	TALLOC_FREE(mapped_name);
 	TALLOC_FREE(mapped_ea_name);
+	TALLOC_FREE(mapped_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 
 	return ret;
 }
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 874bd40..825df00 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1296,11 +1296,14 @@ static ssize_t cephwrap_flistxattr(struct vfs_handle_struct *handle, struct file
 	}
 }
 
-static int cephwrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
+static int cephwrap_removexattr(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				const char *name)
 {
 	int ret;
-	DBG_DEBUG("[CEPH] removexattr(%p, %s, %s)\n", handle, path, name);
-	ret = ceph_removexattr(handle->data, path, name);
+	DBG_DEBUG("[CEPH] removexattr(%p, %s, %s)\n", handle,
+			smb_fname->base_name, name);
+	ret = ceph_removexattr(handle->data, smb_fname->base_name, name);
 	DBG_DEBUG("[CEPH] removexattr(...) = %d\n", ret);
 	WRAP_RETURN(ret);
 }
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index fb8864e..9b6e70d 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2768,9 +2768,11 @@ static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files
 	return flistxattr(fsp->fh->fd, list, size);
 }
 
-static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
+static int vfswrap_removexattr(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				const char *name)
 {
-	return removexattr(path, name);
+	return removexattr(smb_fname->base_name, name);
 }
 
 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
index a52e840..529064b 100644
--- a/source3/modules/vfs_fake_acls.c
+++ b/source3/modules/vfs_fake_acls.c
@@ -389,7 +389,7 @@ static int fake_acls_sys_acl_delete_def_file(vfs_handle_struct *handle,
 		return -1;
 	}
 
-	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname->base_name, name);
+	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
 	if (ret == -1 && errno == ENOATTR) {
 		ret = 0;
 		errno = 0;
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 7bc259b..b6d4f9b 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -3150,7 +3150,7 @@ static int fruit_unlink_meta_netatalk(vfs_handle_struct *handle,
 				      const struct smb_filename *smb_fname)
 {
 	return SMB_VFS_REMOVEXATTR(handle->conn,
-				   smb_fname->base_name,
+				   smb_fname,
 				   AFPINFO_EA_NETATALK);
 }
 
@@ -3870,7 +3870,7 @@ static ssize_t fruit_pwrite_meta_netatalk(vfs_handle_struct *handle,
 
 	if (ai_empty_finderinfo(ai)) {
 		ret = SMB_VFS_REMOVEXATTR(handle->conn,
-					  fsp->fsp_name->base_name,
+					  fsp->fsp_name,
 					  AFPINFO_EA_NETATALK);
 
 		if (ret != 0 && errno != ENOENT && errno != ENOATTR) {
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index f50f24d..905d573 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2313,15 +2313,15 @@ static ssize_t smb_full_audit_flistxattr(struct vfs_handle_struct *handle,
 }
 
 static int smb_full_audit_removexattr(struct vfs_handle_struct *handle,
-			     const char *path,
+			     const struct smb_filename *smb_fname,
 			     const char *name)
 {
 	int result;
 
-	result = SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
+	result = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
 
 	do_log(SMB_VFS_OP_REMOVEXATTR, (result >= 0), handle,
-	       "%s|%s", path, name);
+	       "%s|%s", smb_fname->base_name, name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index 30629b8..8784232 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -1331,9 +1331,10 @@ static ssize_t vfs_gluster_flistxattr(struct vfs_handle_struct *handle,
 }
 
 static int vfs_gluster_removexattr(struct vfs_handle_struct *handle,
-				   const char *path, const char *name)
+				const struct smb_filename *smb_fname,
+				const char *name)
 {
-	return glfs_removexattr(handle->data, path, name);
+	return glfs_removexattr(handle->data, smb_fname->base_name, name);
 }
 
 static int vfs_gluster_fremovexattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index 2113e03..3c33020 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -2281,33 +2281,28 @@ out:
  * In this case, "name" is an attr name.
  */
 static int mh_removexattr(struct vfs_handle_struct *handle,
-		const char *path,
+		const struct smb_filename *smb_fname,
 		const char *name)
 {
 	int status;
-	char *clientPath;
-	TALLOC_CTX *ctx;
+	struct smb_filename *clientFname = NULL;
 
 	DEBUG(MH_INFO_DEBUG, ("Entering mh_removexattr\n"));
-	if (!is_in_media_files(path))
-	{
-		status = SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		status = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
 		goto out;
 	}
 
-	clientPath = NULL;
-	ctx = talloc_tos();
-
-	if ((status = alloc_get_client_path(handle, ctx,
-				path,
-				&clientPath)))
-	{
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&clientFname);
+	if (status != 0) {
 		goto err;
 	}
-
-	status = SMB_VFS_NEXT_REMOVEXATTR(handle, clientPath, name);
+	status = SMB_VFS_NEXT_REMOVEXATTR(handle, clientFname, name);
 err:
-	TALLOC_FREE(clientPath);
+	TALLOC_FREE(clientFname);
 out:
 	return status;
 }
diff --git a/source3/modules/vfs_posix_eadb.c b/source3/modules/vfs_posix_eadb.c
index b5f92df..add0446 100644
--- a/source3/modules/vfs_posix_eadb.c
+++ b/source3/modules/vfs_posix_eadb.c
@@ -221,13 +221,14 @@ static int posix_eadb_removeattr(struct tdb_wrap *db_ctx,
 }
 
 static int posix_eadb_removexattr(struct vfs_handle_struct *handle,
-				 const char *path, const char *name)
+				const struct smb_filename *smb_fname,
+				const char *name)
 {
 	struct tdb_wrap *db;
 
 	SMB_VFS_HANDLE_GET_DATA(handle, db, struct tdb_wrap, return -1);
 
-	return posix_eadb_removeattr(db, path, -1, name);
+	return posix_eadb_removeattr(db, smb_fname->base_name, -1, name);
 }
 
 static int posix_eadb_fremovexattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 7417679..4500801 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -2414,30 +2414,45 @@ static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle,
 }
 
 static int shadow_copy2_removexattr(vfs_handle_struct *handle,
-				    const char *fname, const char *aname)
+				const struct smb_filename *smb_fname,
+				const char *aname)
 {
 	time_t timestamp = 0;
 	char *stripped = NULL;
 	int saved_errno = 0;
 	int ret;
 	char *conv;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-					 &timestamp, &stripped)) {
+	if (!shadow_copy2_strip_snapshot(talloc_tos(),
+				handle,
+				smb_fname->base_name,
+				&timestamp,
+				&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_REMOVEXATTR(handle, fname, aname);
+		return SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, aname);
 	}
 	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, conv, aname);
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (conv_smb_fname == NULL) {
+		TALLOC_FREE(conv);
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, conv_smb_fname, aname);
 	if (ret == -1) {
 		saved_errno = errno;
 	}
+	TALLOC_FREE(conv_smb_fname);
 	TALLOC_FREE(conv);
 	if (saved_errno != 0) {
 		errno = saved_errno;
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index a67ec1c..e618951 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -2747,29 +2747,50 @@ static ssize_t snapper_gmt_listxattr(struct vfs_handle_struct *handle,
 }
 
 static int snapper_gmt_removexattr(vfs_handle_struct *handle,
-				   const char *fname, const char *aname)
+				const stuct smb_filename *smb_fname,
+				const char *aname)
 {
-	time_t timestamp;
-	char *stripped;
-	int ret, saved_errno;
-	char *conv;
+	time_t timestamp = 0;
+	char *stripped = NULL;
+	ssize_t ret;
+	int saved_errno = 0;
+	char *conv = NULL;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname,
-					&timestamp, &stripped)) {
+	if (!snapper_gmt_strip_snapshot(talloc_tos(),
+					handle,
+					smb_fname->base_name,
+					&timestamp,
+					&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_REMOVEXATTR(handle, fname, aname);
+		return SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, aname);
 	}
 	conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, conv, aname);
-	saved_errno = errno;
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					fname->flags);
 	TALLOC_FREE(conv);
-	errno = saved_errno;
+	if (conv_smb_fname == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_REMOVEXATTR(handle, conv_smb_fname, aname);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(conv_smb_fname);
+	TALLOC_FREE(conv);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index f481f27..0f4050e 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -588,7 +588,7 @@ static int streams_xattr_unlink(vfs_handle_struct *handle,
 		goto fail;
 	}
 
-	ret = SMB_VFS_REMOVEXATTR(handle->conn, smb_fname->base_name, xattr_name);
+	ret = SMB_VFS_REMOVEXATTR(handle->conn, smb_fname, xattr_name);
 
 	if ((ret == -1) && (errno == ENOATTR)) {
 		errno = ENOENT;
@@ -672,7 +672,7 @@ static int streams_xattr_rename(vfs_handle_struct *handle,
 	}
 
 	/* remove the old stream */
-	oret = SMB_VFS_REMOVEXATTR(handle->conn, smb_fname_src->base_name,
+	oret = SMB_VFS_REMOVEXATTR(handle->conn, smb_fname_src,
 				   src_xattr_name);
 	if (oret < 0) {
 		if (errno == ENOATTR) {
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index e260c47..273c8ff 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -2404,19 +2404,21 @@ static ssize_t smb_time_audit_flistxattr(struct vfs_handle_struct *handle,
 }
 
 static int smb_time_audit_removexattr(struct vfs_handle_struct *handle,
-				      const char *path, const char *name)
+				const struct smb_filename *smb_fname,
+				const char *name)
 {
 	int result;
 	struct timespec ts1,ts2;
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
+	result = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("removexattr", timediff, path);
+		smb_time_audit_log_fname("removexattr", timediff,
+			smb_fname->base_name);
 	}
 
 	return result;
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index 7b60856..95ecb45 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1781,28 +1781,30 @@ err:
 }
 
 static int um_removexattr(struct vfs_handle_struct *handle,
-			  const char *path,
+			  const struct smb_filename *smb_fname,
 			  const char *name)
 {
 	int status;
-	char *client_path = NULL;
+	struct smb_filename *client_fname = NULL;
 
 	DEBUG(10, ("Entering um_removexattr\n"));
 
-	if (!is_in_media_files(path)) {
-		return SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		return SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
 	}
 
-	status = alloc_get_client_path(handle, talloc_tos(),
-				       path, &client_path);
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&client_fname);
 	if (status != 0) {
 		goto err;
 	}
 
-	status = SMB_VFS_NEXT_REMOVEXATTR(handle, client_path, name);
+	status = SMB_VFS_NEXT_REMOVEXATTR(handle, client_fname, name);
 
 err:
-	TALLOC_FREE(client_path);
+	TALLOC_FREE(client_fname);
 	return status;
 }
 
diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c
index c678636..630004e 100644
--- a/source3/modules/vfs_vxfs.c
+++ b/source3/modules/vfs_vxfs.c
@@ -534,7 +534,6 @@ static int vxfs_set_xattr(struct vfs_handle_struct *handle,  const char *path,
 	}
 
 	is_dir = S_ISDIR(smb_fname->st.st_ex_mode);
-	TALLOC_FREE(smb_fname);
 
 	ret = vxfs_setxattr_path(path, name, value, size, flags,
 				  is_dir);
@@ -543,7 +542,8 @@ static int vxfs_set_xattr(struct vfs_handle_struct *handle,  const char *path,
 		/*
 		 * Now remve old style xattr if it exists
 		 */
-		SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
+		SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
+		TALLOC_FREE(smb_fname);
 		/*
 		 * Do not bother about return value
 		 */
@@ -551,6 +551,8 @@ static int vxfs_set_xattr(struct vfs_handle_struct *handle,  const char *path,
 		return ret;
 	}
 
+	TALLOC_FREE(smb_fname);
+
 	DEBUG(10, ("Fallback to xattr\n"));
 	if (strcmp(name, XATTR_NTACL_NAME) == 0) {
 		return SMB_VFS_NEXT_SETXATTR(handle, path, XATTR_USER_NTACL,
@@ -651,31 +653,36 @@ static ssize_t vxfs_fget_xattr(struct vfs_handle_struct *handle,
 }
 
 static int vxfs_remove_xattr(struct vfs_handle_struct *handle,
-			     const char *path, const char *name){
-	struct smb_filename *smb_fname;
+				const struct smb_filename *smb_fname_in,
+				const char *name)
+{
 	bool is_dir = false;
 	int ret = 0, ret_new = 0, old_errno;
+	struct smb_filename *smb_fname = NULL;
 
 	DEBUG(10, ("In vxfs_remove_xattr\n"));
 
+	smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
+	if (smb_fname == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	/* We need streamname to be NULL */
+	TALLOC_FREE(smb_fname->stream_name);
+
 	/* Remove with old way */
 	if (strcmp(name, XATTR_NTACL_NAME) == 0) {
-		ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path,
+		ret = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname,
 					       XATTR_USER_NTACL);
 	} else {
 		if (strcasecmp(name, XATTR_USER_NTACL) != 0) {
-			ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path,
+			ret = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname,
 						       name);
 		}
 	}
-	old_errno = errno;
-
 	/* Remove with new way */
-	smb_fname = synthetic_smb_fname(talloc_tos(), path, NULL, NULL, 0);
-	if (smb_fname == NULL) {
-		errno = ENOMEM;
-		return -1;
-	}
+	old_errno = errno;
 
 	if (SMB_VFS_NEXT_STAT(handle, smb_fname) != 0) {
 		TALLOC_FREE(smb_fname);
@@ -687,7 +694,7 @@ static int vxfs_remove_xattr(struct vfs_handle_struct *handle,
 	/*
 	 * If both fail, return failuer else return whichever succeeded
 	 */
-	ret_new = vxfs_removexattr_path(path, name, is_dir);
+	ret_new = vxfs_removexattr_path(smb_fname_in->base_name, name, is_dir);
 	if (errno == ENOTSUP || errno == ENOSYS) {
 		errno = old_errno;
 	}
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
index a4f80b2..1ff80a7 100644
--- a/source3/modules/vfs_xattr_tdb.c
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -260,7 +260,8 @@ static ssize_t xattr_tdb_flistxattr(struct vfs_handle_struct *handle,
 }
 
 static int xattr_tdb_removexattr(struct vfs_handle_struct *handle,
-				 const char *path, const char *name)
+				const struct smb_filename *smb_fname,
+				const char *name)
 {
 	struct file_id id;
 	struct db_context *db;
@@ -273,7 +274,7 @@ static int xattr_tdb_removexattr(struct vfs_handle_struct *handle,
 					TALLOC_FREE(frame); return -1;
 				});
 
-	ret = xattr_tdb_get_file_id(handle, path, &id);
+	ret = xattr_tdb_get_file_id(handle, smb_fname->base_name, &id);
 	if (ret == -1) {
 		TALLOC_FREE(frame);
 		return ret;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 8c1190b..561525d 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -800,7 +800,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
 				DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
 					unix_ea_name, smb_fname->base_name));
 				ret = SMB_VFS_REMOVEXATTR(conn,
-						smb_fname->base_name,
+						smb_fname,
 						unix_ea_name);
 			}
 #ifdef ENOATTR
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index d27ab39..25cdf68 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2536,10 +2536,11 @@ ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
 }
 
 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
-			     const char *path, const char *name)
+				const struct smb_filename *smb_fname,
+				const char *name)
 {
 	VFS_FIND(removexattr);
-	return handle->fns->removexattr_fn(handle, path, name);
+	return handle->fns->removexattr_fn(handle, smb_fname, name);
 }
 
 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 7155ac3..8bd5413 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -1423,13 +1423,24 @@ static NTSTATUS cmd_removexattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 				int argc, const char **argv)
 {
 	ssize_t ret;
+	struct smb_filename *smb_fname = NULL;
 
 	if (argc != 3) {
 		printf("Usage: removexattr <path> <xattr>\n");
 		return NT_STATUS_OK;
 	}
 
-	ret = SMB_VFS_REMOVEXATTR(vfs->conn, argv[1], argv[2]);
+	smb_fname = synthetic_smb_fname(talloc_tos(),
+					argv[1],
+					NULL,
+					NULL,
+					ssf_flags());
+
+	if (smb_fname == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	ret = SMB_VFS_REMOVEXATTR(vfs->conn, smb_fname, argv[2]);
 	if (ret == -1) {
 		int err = errno;
 		printf("removexattr returned (%s)\n", strerror(err));
-- 
2.9.3


From fc543cda5e0884d083b12fe658b9b1809a8c0bf1 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 25 May 2017 12:41:31 -0700
Subject: [PATCH 7/8] s3: VFS: Change SMB_VFS_SETXATTR to use const struct
 smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c          |  9 ++++--
 examples/VFS/skel_transparent.c     | 12 +++++---
 source3/include/vfs.h               | 19 +++++++++---
 source3/include/vfs_macros.h        |  8 ++---
 source3/modules/posixacl_xattr.c    |  2 +-
 source3/modules/vfs_acl_xattr.c     |  2 +-
 source3/modules/vfs_cap.c           | 36 ++++++++++++++++++++--
 source3/modules/vfs_catia.c         | 36 ++++++++++++++++++----
 source3/modules/vfs_ceph.c          | 13 ++++++--
 source3/modules/vfs_default.c       |  9 ++++--
 source3/modules/vfs_fake_acls.c     | 10 +++----
 source3/modules/vfs_fruit.c         |  2 +-
 source3/modules/vfs_full_audit.c    |  6 ++--
 source3/modules/vfs_glusterfs.c     |  5 ++--
 source3/modules/vfs_media_harmony.c | 27 +++++++----------
 source3/modules/vfs_nfs4acl_xattr.c |  6 ++--
 source3/modules/vfs_posix_eadb.c    | 10 +++++--
 source3/modules/vfs_shadow_copy2.c  | 27 +++++++++++++----
 source3/modules/vfs_snapper.c       | 44 +++++++++++++++++++--------
 source3/modules/vfs_streams_depot.c |  9 +++---
 source3/modules/vfs_streams_xattr.c |  6 ++--
 source3/modules/vfs_time_audit.c    | 13 ++++----
 source3/modules/vfs_unityed_media.c | 18 ++++++-----
 source3/modules/vfs_vxfs.c          | 60 ++++++++++++++++++++++++++-----------
 source3/modules/vfs_xattr_tdb.c     |  9 ++++--
 source3/smbd/dosmode.c              |  2 +-
 source3/smbd/posix_acls.c           |  2 +-
 source3/smbd/trans2.c               |  2 +-
 source3/smbd/vfs.c                  | 12 +++++---
 source3/torture/cmd_vfs.c           |  9 +++++-
 30 files changed, 296 insertions(+), 129 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index ea66742..7095dbe 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -845,9 +845,12 @@ static int skel_fremovexattr(vfs_handle_struct *handle,
 	return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
 }
 
-static int skel_setxattr(vfs_handle_struct *handle, const char *path,
-			 const char *name, const void *value, size_t size,
-			 int flags)
+static int skel_setxattr(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name,
+			const void *value,
+			size_t size,
+			int flags)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index e72edbc..97e61a4 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -974,11 +974,15 @@ static int skel_fremovexattr(vfs_handle_struct *handle,
 	return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
 }
 
-static int skel_setxattr(vfs_handle_struct *handle, const char *path,
-			 const char *name, const void *value, size_t size,
-			 int flags)
+static int skel_setxattr(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name,
+			const void *value,
+			size_t size,
+			int flags)
 {
-	return SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size, flags);
+	return SMB_VFS_NEXT_SETXATTR(handle, smb_fname,
+			name, value, size, flags);
 }
 
 static int skel_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 56c3f5d..6b1d11f 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -209,6 +209,9 @@
 		to const struct smb_filename * */
 /* Version 37 - Change removexattr from const char *
 		to const struct smb_filename * */
+/* Version 37 - Change setxattr from const char *
+		to const struct smb_filename * */
+
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -902,7 +905,12 @@ struct vfs_fn_pointers {
 					const struct smb_filename *smb_fname,
 					const char *name);
 	int (*fremovexattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name);
-	int (*setxattr_fn)(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags);
+	int (*setxattr_fn)(struct vfs_handle_struct *handle,
+					const struct smb_filename *smb_fname,
+					const char *name,
+					const void *value,
+					size_t size,
+					int flags);
 	int (*fsetxattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags);
 
 	/* aio operations */
@@ -1376,9 +1384,12 @@ int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
 				const char *name);
 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
 			      struct files_struct *fsp, const char *name);
-int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
-			  const char *name, const void *value, size_t size,
-			  int flags);
+int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				const char *name,
+				const void *value,
+				size_t size,
+				int flags);
 int smb_vfs_call_lsetxattr(struct vfs_handle_struct *handle, const char *path,
 			   const char *name, const void *value, size_t size,
 			   int flags);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index e1a9ba0..8e3fb32 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -545,10 +545,10 @@
 #define SMB_VFS_NEXT_FREMOVEXATTR(handle,fsp,name) \
 	smb_vfs_call_fremovexattr((handle)->next,(fsp),(name))
 
-#define SMB_VFS_SETXATTR(conn,path,name,value,size,flags) \
-	smb_vfs_call_setxattr((conn)->vfs_handles,(path),(name),(value),(size),(flags))
-#define SMB_VFS_NEXT_SETXATTR(handle,path,name,value,size,flags) \
-	smb_vfs_call_setxattr((handle)->next,(path),(name),(value),(size),(flags))
+#define SMB_VFS_SETXATTR(conn,smb_fname,name,value,size,flags) \
+	smb_vfs_call_setxattr((conn)->vfs_handles,(smb_fname),(name),(value),(size),(flags))
+#define SMB_VFS_NEXT_SETXATTR(handle,smb_fname,name,value,size,flags) \
+	smb_vfs_call_setxattr((handle)->next,(smb_fname),(name),(value),(size),(flags))
 
 #define SMB_VFS_FSETXATTR(fsp,name,value,size,flags) \
 	smb_vfs_call_fsetxattr((fsp)->conn->vfs_handles, (fsp), (name),(value),(size),(flags))
diff --git a/source3/modules/posixacl_xattr.c b/source3/modules/posixacl_xattr.c
index 780f68a..dcdf2ff 100644
--- a/source3/modules/posixacl_xattr.c
+++ b/source3/modules/posixacl_xattr.c
@@ -474,7 +474,7 @@ int posixacl_xattr_acl_set_file(vfs_handle_struct *handle,
 		return -1;
 	}
 
-	return SMB_VFS_SETXATTR(handle->conn, smb_fname->base_name,
+	return SMB_VFS_SETXATTR(handle->conn, smb_fname,
 			name, buf, size, 0);
 }
 
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index b21207b..6362ac8 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -144,7 +144,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
 		ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME,
 			pblob->data, pblob->length, 0);
 	} else {
-		ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name,
+		ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name,
 				XATTR_NTACL_NAME,
 				pblob->data, pblob->length, 0);
 	}
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index fe70d78..62d40b5 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -760,16 +760,46 @@ static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp,
         return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
 }
 
-static int cap_setxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
+static int cap_setxattr(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name,
+			const void *value,
+			size_t size,
+			int flags)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	struct smb_filename *cap_smb_fname = NULL;
+	char *cappath = capencode(talloc_tos(), smb_fname->base_name);
 	char *capname = capencode(talloc_tos(), name);
+	int ret;
+	int saved_errno = 0;
 
 	if (!cappath || !capname) {
 		errno = ENOMEM;
 		return -1;
 	}
-        return SMB_VFS_NEXT_SETXATTR(handle, cappath, capname, value, size, flags);
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					cappath,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(cappath);
+		TALLOC_FREE(capname);
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_SETXATTR(handle, cap_smb_fname,
+				capname, value, size, flags);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(cappath);
+	TALLOC_FREE(capname);
+	TALLOC_FREE(cap_smb_fname);
+	if (saved_errno) {
+		errno = saved_errno;
+	}
+	return ret;
 }
 
 static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 3266d95..60d6e7f 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -1508,17 +1508,24 @@ catia_removexattr(vfs_handle_struct *handle,
 }
 
 static int
-catia_setxattr(vfs_handle_struct *handle, const char *path,
-	       const char *name, const void *value, size_t size,
-	       int flags)
+catia_setxattr(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name,
+			const void *value,
+			size_t size,
+			int flags)
 {
+	struct smb_filename *mapped_smb_fname = NULL;
 	char *mapped_name = NULL;
 	char *mapped_ea_name = NULL;
 	NTSTATUS status;
 	ssize_t ret;
+	int saved_errno = 0;
 
 	status = catia_string_replace_allocate(handle->conn,
-				path, &mapped_name, vfs_translate_to_unix);
+				smb_fname->base_name,
+				&mapped_name,
+				vfs_translate_to_unix);
 	if (!NT_STATUS_IS_OK(status)) {
 		errno = map_errno_from_nt_status(status);
 		return -1;
@@ -1532,10 +1539,29 @@ catia_setxattr(vfs_handle_struct *handle, const char *path,
 		return -1;
 	}
 
-	ret = SMB_VFS_NEXT_SETXATTR(handle, mapped_name, mapped_ea_name,
+	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
+					mapped_name,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (mapped_smb_fname == NULL) {
+		TALLOC_FREE(mapped_name);
+		TALLOC_FREE(mapped_ea_name);
+		errno = ENOMEM;
+		return -1;
+	}
+
+	ret = SMB_VFS_NEXT_SETXATTR(handle, mapped_smb_fname, mapped_ea_name,
 			value, size, flags);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
 	TALLOC_FREE(mapped_name);
 	TALLOC_FREE(mapped_ea_name);
+	TALLOC_FREE(mapped_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 
 	return ret;
 }
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 825df00..06eada9 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1321,11 +1321,18 @@ static int cephwrap_fremovexattr(struct vfs_handle_struct *handle, struct files_
 	WRAP_RETURN(ret);
 }
 
-static int cephwrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
+static int cephwrap_setxattr(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				const char *name,
+				const void *value,
+				size_t size,
+				int flags)
 {
 	int ret;
-	DBG_DEBUG("[CEPH] setxattr(%p, %s, %s, %p, %llu, %d)\n", handle, path, name, value, llu(size), flags);
-	ret = ceph_setxattr(handle->data, path, name, value, size, flags);
+	DBG_DEBUG("[CEPH] setxattr(%p, %s, %s, %p, %llu, %d)\n", handle,
+			smb_fname->base_name, name, value, llu(size), flags);
+	ret = ceph_setxattr(handle->data, smb_fname->base_name,
+			name, value, size, flags);
 	DBG_DEBUG("[CEPH] setxattr(...) = %d\n", ret);
 	WRAP_RETURN(ret);
 }
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 9b6e70d..e649d4c 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2780,9 +2780,14 @@ static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_s
 	return fremovexattr(fsp->fh->fd, name);
 }
 
-static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
+static int vfswrap_setxattr(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				const char *name,
+				const void *value,
+				size_t size,
+				int flags)
 {
-	return setxattr(path, name, value, size, flags);
+	return setxattr(smb_fname->base_name, name, value, size, flags);
 }
 
 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
index 529064b..61c645b 100644
--- a/source3/modules/vfs_fake_acls.c
+++ b/source3/modules/vfs_fake_acls.c
@@ -339,7 +339,7 @@ static int fake_acls_sys_acl_set_file(vfs_handle_struct *handle,
 		name = FAKE_ACL_DEFAULT_XATTR;
 		break;
 	}
-	ret = SMB_VFS_NEXT_SETXATTR(handle, smb_fname->base_name,
+	ret = SMB_VFS_NEXT_SETXATTR(handle, smb_fname,
 			name, blob.data, blob.length, 0);
 	TALLOC_FREE(frame);
 	return ret;
@@ -409,7 +409,7 @@ static int fake_acls_chown(vfs_handle_struct *handle,
 	if (uid != -1) {
 		SIVAL(id_buf, 0, uid);
 		ret = SMB_VFS_NEXT_SETXATTR(handle,
-				smb_fname->base_name,
+				smb_fname,
 				FAKE_UID,
 				id_buf,
 				sizeof(id_buf),
@@ -421,7 +421,7 @@ static int fake_acls_chown(vfs_handle_struct *handle,
 	if (gid != -1) {
 		SIVAL(id_buf, 0, gid);
 		ret = SMB_VFS_NEXT_SETXATTR(handle,
-				smb_fname->base_name,
+				smb_fname,
 				FAKE_GID,
 				id_buf,
 				sizeof(id_buf),
@@ -451,7 +451,7 @@ static int fake_acls_lchown(vfs_handle_struct *handle,
 		 */
 		SIVAL(id_buf, 0, uid);
 		ret = SMB_VFS_NEXT_SETXATTR(handle,
-				smb_fname->base_name,
+				smb_fname,
 				FAKE_UID,
 				id_buf,
 				sizeof(id_buf),
@@ -463,7 +463,7 @@ static int fake_acls_lchown(vfs_handle_struct *handle,
 	if (gid != -1) {
 		SIVAL(id_buf, 0, gid);
 		ret = SMB_VFS_NEXT_SETXATTR(handle,
-				smb_fname->base_name,
+				smb_fname,
 				FAKE_GID,
 				id_buf,
 				sizeof(id_buf),
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index b6d4f9b..11103cc 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -1419,7 +1419,7 @@ static int ad_set(struct adouble *ad, const struct smb_filename *smb_fname)
 	}
 
 	ret = SMB_VFS_SETXATTR(ad->ad_handle->conn,
-			       smb_fname->base_name,
+			       smb_fname,
 			       AFPINFO_EA_NETATALK,
 			       ad->ad_data,
 			       AD_DATASZ_XATTR, 0);
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 905d573..3054c33 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2341,17 +2341,17 @@ static int smb_full_audit_fremovexattr(struct vfs_handle_struct *handle,
 }
 
 static int smb_full_audit_setxattr(struct vfs_handle_struct *handle,
-			  const char *path,
+			  const struct smb_filename *smb_fname,
 			  const char *name, const void *value, size_t size,
 			  int flags)
 {
 	int result;
 
-	result = SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size,
+	result = SMB_VFS_NEXT_SETXATTR(handle, smb_fname, name, value, size,
 				       flags);
 
 	do_log(SMB_VFS_OP_SETXATTR, (result >= 0), handle,
-	       "%s|%s", path, name);
+	       "%s|%s", smb_fname->base_name, name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index 8784232..e51556f 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -1344,10 +1344,11 @@ static int vfs_gluster_fremovexattr(struct vfs_handle_struct *handle,
 }
 
 static int vfs_gluster_setxattr(struct vfs_handle_struct *handle,
-				const char *path, const char *name,
+				const struct smb_filename *smb_fname,
+				const char *name,
 				const void *value, size_t size, int flags)
 {
-	return glfs_setxattr(handle->data, path, name, value, size, flags);
+	return glfs_setxattr(handle->data, smb_fname->base_name, name, value, size, flags);
 }
 
 static int vfs_gluster_fsetxattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index 3c33020..dd715d1 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -2313,38 +2313,33 @@ out:
  * In this case, "name" is an attr name.
  */
 static int mh_setxattr(struct vfs_handle_struct *handle,
-		const char *path,
+		const struct smb_filename *smb_fname,
 		const char *name,
 		const void *value,
 		size_t size,
 		int flags)
 {
 	int status;
-	char *clientPath;
-	TALLOC_CTX *ctx;
+	struct smb_filename *clientFname = NULL;
 
 	DEBUG(MH_INFO_DEBUG, ("Entering mh_setxattr\n"));
-	if (!is_in_media_files(path))
-	{
-		status = SMB_VFS_NEXT_SETXATTR(handle, path, name, value,
+	if (!is_in_media_files(smb_fname->base_name)) {
+		status = SMB_VFS_NEXT_SETXATTR(handle, smb_fname, name, value,
 				size, flags);
 		goto out;
 	}
 
-	clientPath = NULL;
-	ctx = talloc_tos();
-
-	if ((status = alloc_get_client_path(handle, ctx,
-				path,
-				&clientPath)))
-	{
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&clientFname);
+	if (status != 0) {
 		goto err;
 	}
-
-	status = SMB_VFS_NEXT_SETXATTR(handle, clientPath, name, value,
+	status = SMB_VFS_NEXT_SETXATTR(handle, clientFname, name, value,
 			size, flags);
 err:
-	TALLOC_FREE(clientPath);
+	TALLOC_FREE(clientFname);
 out:
 	return status;
 }
diff --git a/source3/modules/vfs_nfs4acl_xattr.c b/source3/modules/vfs_nfs4acl_xattr.c
index faf9f9b..de3e368 100644
--- a/source3/modules/vfs_nfs4acl_xattr.c
+++ b/source3/modules/vfs_nfs4acl_xattr.c
@@ -251,7 +251,7 @@ static bool nfs4acl_smb4acl2nfs4acl(TALLOC_CTX *mem_ctx,
 }
 
 static bool nfs4acl_xattr_set_smb4acl(vfs_handle_struct *handle,
-				      const char *path,
+				      const struct smb_filename *smb_fname,
 				      struct SMB4ACL_T *smbacl)
 {
 	TALLOC_CTX *frame = talloc_stackframe();
@@ -278,7 +278,7 @@ static bool nfs4acl_xattr_set_smb4acl(vfs_handle_struct *handle,
 		errno = EINVAL;
 		return false;
 	}
-	ret = SMB_VFS_NEXT_SETXATTR(handle, path, NFS4ACL_XATTR_NAME,
+	ret = SMB_VFS_NEXT_SETXATTR(handle, smb_fname, NFS4ACL_XATTR_NAME,
 				    blob.data, blob.length, 0);
 	if (ret != 0) {
 		DEBUG(0, ("can't store acl in xattr: %s\n", strerror(errno)));
@@ -509,7 +509,7 @@ static struct SMB4ACL_T *nfs4acls_inheritacl(vfs_handle_struct *handle,
 
 	/* store the returned ACL to get it directly in the
 	   future and avoid dynamic inheritance behavior. */
-	nfs4acl_xattr_set_smb4acl(handle, path, pchildacl);
+	nfs4acl_xattr_set_smb4acl(handle, smb_fname, pchildacl);
 
 	TALLOC_FREE(frame);
 	return pchildacl;
diff --git a/source3/modules/vfs_posix_eadb.c b/source3/modules/vfs_posix_eadb.c
index add0446..1ba94dc 100644
--- a/source3/modules/vfs_posix_eadb.c
+++ b/source3/modules/vfs_posix_eadb.c
@@ -124,14 +124,18 @@ static int posix_eadb_setattr(struct tdb_wrap *db_ctx,
 }
 
 static int posix_eadb_setxattr(struct vfs_handle_struct *handle,
-			      const char *path, const char *name,
-			      const void *value, size_t size, int flags)
+				const struct smb_filename *smb_fname,
+				const char *name,
+				const void *value,
+				size_t size,
+				int flags)
 {
 	struct tdb_wrap *db;
 
 	SMB_VFS_HANDLE_GET_DATA(handle, db, struct tdb_wrap, return -1);
 
-	return posix_eadb_setattr(db, path, -1, name, value, size, flags);
+	return posix_eadb_setattr(db, smb_fname->base_name,
+			-1, name, value, size, flags);
 }
 
 static int posix_eadb_fsetxattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 4500801..5471ed3 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -2461,7 +2461,7 @@ static int shadow_copy2_removexattr(vfs_handle_struct *handle,
 }
 
 static int shadow_copy2_setxattr(struct vfs_handle_struct *handle,
-				 const char *fname,
+				 const struct smb_filename *smb_fname,
 				 const char *aname, const void *value,
 				 size_t size, int flags)
 {
@@ -2470,24 +2470,39 @@ static int shadow_copy2_setxattr(struct vfs_handle_struct *handle,
 	ssize_t ret;
 	int saved_errno = 0;
 	char *conv;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-					 &timestamp, &stripped)) {
+	if (!shadow_copy2_strip_snapshot(talloc_tos(),
+				handle,
+				smb_fname->base_name,
+				&timestamp,
+				&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_SETXATTR(handle, fname, aname, value, size,
-					     flags);
+		return SMB_VFS_NEXT_SETXATTR(handle, smb_fname,
+					aname, value, size, flags);
 	}
 	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_SETXATTR(handle, conv, aname, value, size, flags);
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (conv_smb_fname == NULL) {
+		TALLOC_FREE(conv);
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_SETXATTR(handle, conv_smb_fname,
+				aname, value, size, flags);
 	if (ret == -1) {
 		saved_errno = errno;
 	}
+	TALLOC_FREE(conv_smb_fname);
 	TALLOC_FREE(conv);
 	if (saved_errno != 0) {
 		errno = saved_errno;
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index e618951..3234369 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -2795,33 +2795,53 @@ static int snapper_gmt_removexattr(vfs_handle_struct *handle,
 }
 
 static int snapper_gmt_setxattr(struct vfs_handle_struct *handle,
-				const char *fname,
+				const struct smb_filename *smb_fname,
 				const char *aname, const void *value,
 				size_t size, int flags)
 {
-	time_t timestamp;
-	char *stripped;
+	time_t timestamp = 0;
+	char *stripped = NULL;
 	ssize_t ret;
-	int saved_errno;
-	char *conv;
+	int saved_errno = 0;
+	char *conv = NULL;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname,
-					&timestamp, &stripped)) {
+	if (!snapper_gmt_strip_snapshot(talloc_tos(),
+					handle,
+					smb_fname->base_name,
+					&timestamp,
+					&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_SETXATTR(handle, fname, aname, value, size,
-					     flags);
+		return SMB_VFS_NEXT_SETXATTR(handle, smb_fname,
+					aname, value, size, flags);
 	}
 	conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_SETXATTR(handle, conv, aname, value, size, flags);
-	saved_errno = errno;
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					fname->flags);
 	TALLOC_FREE(conv);
-	errno = saved_errno;
+	if (conv_smb_fname == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_SETXATTR(handle, conv_smb_fname,
+				aname, value, size, flags);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(conv_smb_fname);
+	TALLOC_FREE(conv);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 58d3a06..b6e95a2 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -87,14 +87,15 @@ static bool file_is_valid(vfs_handle_struct *handle, const char *path)
 	return true;
 }
 
-static bool mark_file_valid(vfs_handle_struct *handle, const char *path)
+static bool mark_file_valid(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname)
 {
 	char buf = '1';
 	int ret;
 
-	DEBUG(10, ("marking file %s as valid\n", path));
+	DEBUG(10, ("marking file %s as valid\n", smb_fname->base_name));
 
-	ret = SMB_VFS_SETXATTR(handle->conn, path, SAMBA_XATTR_MARKER,
+	ret = SMB_VFS_SETXATTR(handle->conn, smb_fname, SAMBA_XATTR_MARKER,
 				    &buf, sizeof(buf), 0);
 
 	if (ret == -1) {
@@ -350,7 +351,7 @@ static char *stream_dir(vfs_handle_struct *handle,
 		goto fail;
 	}
 
-	if (check_valid && !mark_file_valid(handle, smb_fname->base_name)) {
+	if (check_valid && !mark_file_valid(handle, smb_fname)) {
 		goto fail;
 	}
 
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 0f4050e..d69c3f9 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -661,7 +661,7 @@ static int streams_xattr_rename(vfs_handle_struct *handle,
 	}
 
 	/* (over)write the new stream */
-	nret = SMB_VFS_SETXATTR(handle->conn, smb_fname_src->base_name,
+	nret = SMB_VFS_SETXATTR(handle->conn, smb_fname_src,
 				dst_xattr_name, ea.value.data, ea.value.length,
 				0);
 	if (nret < 0) {
@@ -992,7 +992,7 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
 				ea.value.data, ea.value.length, 0);
 	} else {
 		ret = SMB_VFS_SETXATTR(fsp->conn,
-				       fsp->fsp_name->base_name,
+				       fsp->fsp_name,
 				sio->xattr_name,
 				ea.value.data, ea.value.length, 0);
 	}
@@ -1262,7 +1262,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
 				ea.value.data, ea.value.length, 0);
 	} else {
 		ret = SMB_VFS_SETXATTR(fsp->conn,
-				fsp->fsp_name->base_name,
+				fsp->fsp_name,
 				sio->xattr_name,
 				ea.value.data, ea.value.length, 0);
 	}
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 273c8ff..dd915e5 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -2445,22 +2445,25 @@ static int smb_time_audit_fremovexattr(struct vfs_handle_struct *handle,
 }
 
 static int smb_time_audit_setxattr(struct vfs_handle_struct *handle,
-				   const char *path, const char *name,
-				   const void *value, size_t size,
-				   int flags)
+				const struct smb_filename *smb_fname,
+				const char *name,
+				const void *value,
+				size_t size,
+				int flags)
 {
 	int result;
 	struct timespec ts1,ts2;
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size,
+	result = SMB_VFS_NEXT_SETXATTR(handle, smb_fname, name, value, size,
 				       flags);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("setxattr", timediff, path);
+		smb_time_audit_log_fname("setxattr", timediff,
+				smb_fname->base_name);
 	}
 
 	return result;
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index 95ecb45..3dd8b99 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1809,33 +1809,35 @@ err:
 }
 
 static int um_setxattr(struct vfs_handle_struct *handle,
-		       const char *path,
+		       const struct smb_filename *smb_fname,
 		       const char *name,
 		       const void *value,
 		       size_t size,
 		       int flags)
 {
 	int status;
-	char *client_path = NULL;
+	struct smb_filename *client_fname = NULL;
 
 	DEBUG(10, ("Entering um_setxattr\n"));
 
-	if (!is_in_media_files(path)) {
-		return SMB_VFS_NEXT_SETXATTR(handle, path, name, value,
+	if (!is_in_media_files(smb_fname->base_name)) {
+		return SMB_VFS_NEXT_SETXATTR(handle, smb_fname, name, value,
 					     size, flags);
 	}
 
-	status = alloc_get_client_path(handle, talloc_tos(),
-				       path, &client_path);
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&client_fname);
 	if (status != 0) {
 		goto err;
 	}
 
-	status = SMB_VFS_NEXT_SETXATTR(handle, client_path, name, value,
+	status = SMB_VFS_NEXT_SETXATTR(handle, client_fname, name, value,
 				       size, flags);
 
 err:
-	TALLOC_FREE(client_path);
+	TALLOC_FREE(client_fname);
 	return status;
 }
 
diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c
index 630004e..46c0756 100644
--- a/source3/modules/vfs_vxfs.c
+++ b/source3/modules/vfs_vxfs.c
@@ -513,21 +513,29 @@ static int vxfs_sys_acl_set_file(vfs_handle_struct *handle,
 			acltype, theacl);
 }
 
-static int vxfs_set_xattr(struct vfs_handle_struct *handle,  const char *path,
-			  const char *name, const void *value, size_t size,
-			  int flags){
-	struct smb_filename *smb_fname;
+static int vxfs_set_xattr(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname_in,
+			const char *name,
+			const void *value,
+			size_t size,
+			int flags)
+{
+	struct smb_filename *smb_fname = NULL;
 	bool is_dir = false;
 	int ret = 0;
+	int saved_errno = 0;
 
 	DEBUG(10, ("In vxfs_set_xattr\n"));
 
-	smb_fname = synthetic_smb_fname(talloc_tos(), path, NULL, NULL, 0);
+	smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
 	if (smb_fname == NULL) {
 		errno = ENOMEM;
 		return -1;
 	}
 
+	/* We need streamname to be NULL */
+	TALLOC_FREE(smb_fname->stream_name);
+
 	if (SMB_VFS_NEXT_STAT(handle, smb_fname) != 0) {
 		TALLOC_FREE(smb_fname);
 		return -1;
@@ -535,37 +543,55 @@ static int vxfs_set_xattr(struct vfs_handle_struct *handle,  const char *path,
 
 	is_dir = S_ISDIR(smb_fname->st.st_ex_mode);
 
-	ret = vxfs_setxattr_path(path, name, value, size, flags,
-				  is_dir);
+	ret = vxfs_setxattr_path(smb_fname_in->base_name, name, value, size,
+				 flags, is_dir);
 	if ((ret == 0) ||
 	    ((ret == -1) && (errno != ENOTSUP) && (errno != ENOSYS))) {
 		/*
 		 * Now remve old style xattr if it exists
 		 */
 		SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
-		TALLOC_FREE(smb_fname);
 		/*
 		 * Do not bother about return value
 		 */
-
-		return ret;
+		if (ret != 0) {
+			saved_errno = errno;
+		}
+		goto fail;
 	}
 
-	TALLOC_FREE(smb_fname);
-
 	DEBUG(10, ("Fallback to xattr\n"));
 	if (strcmp(name, XATTR_NTACL_NAME) == 0) {
-		return SMB_VFS_NEXT_SETXATTR(handle, path, XATTR_USER_NTACL,
-					     value, size, flags);
+		ret = SMB_VFS_NEXT_SETXATTR(handle, smb_fname,
+					    XATTR_USER_NTACL,
+					    value, size, flags);
+		if (ret != 0) {
+			saved_errno = errno;
+			goto fail;
+		}
+		return 0;
 	}
 
 	/* Clients can't set XATTR_USER_NTACL directly. */
 	if (strcasecmp(name, XATTR_USER_NTACL) == 0) {
-		errno = EACCES;
-		return -1;
+		saved_errno = EACCES;
+		ret = -1;
+		goto fail;
 	}
 
-	return SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size, flags);
+	ret = SMB_VFS_NEXT_SETXATTR(handle, smb_fname,
+				    name, value, size, flags);
+	if (ret != 0) {
+		saved_errno = errno;
+		goto fail;
+	}
+
+fail:
+	TALLOC_FREE(smb_fname);
+	if (saved_errno != 0) {
+		saved_errno = errno;
+	}
+	return ret;
 }
 
 static int vxfs_fset_xattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
index 1ff80a7..d6d4808 100644
--- a/source3/modules/vfs_xattr_tdb.c
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -148,8 +148,11 @@ static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle,
 }
 
 static int xattr_tdb_setxattr(struct vfs_handle_struct *handle,
-			      const char *path, const char *name,
-			      const void *value, size_t size, int flags)
+				const struct smb_filename *smb_fname,
+				const char *name,
+				const void *value,
+				size_t size,
+				int flags)
 {
 	struct file_id id;
 	struct db_context *db;
@@ -162,7 +165,7 @@ static int xattr_tdb_setxattr(struct vfs_handle_struct *handle,
 					TALLOC_FREE(frame); return -1;
 				});
 
-	ret = xattr_tdb_get_file_id(handle, path, &id);
+	ret = xattr_tdb_get_file_id(handle, smb_fname->base_name, &id);
 	if (ret == -1) {
 		TALLOC_FREE(frame);
 		return -1;
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 3c6d47b..de10983 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -420,7 +420,7 @@ NTSTATUS set_ea_dos_attribute(connection_struct *conn,
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	if (SMB_VFS_SETXATTR(conn, smb_fname->base_name,
+	if (SMB_VFS_SETXATTR(conn, smb_fname,
 			     SAMBA_XATTR_DOS_ATTRIB, blob.data, blob.length,
 			     0) == -1) {
 		NTSTATUS status = NT_STATUS_OK;
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 53aebfa..0cd28ad 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -275,7 +275,7 @@ static void store_inheritance_attributes(files_struct *fsp,
 		ret = SMB_VFS_FSETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME,
 				pai_buf, store_size, 0);
 	} else {
-		ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name,
+		ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name,
 				       SAMBA_POSIX_INHERITANCE_EA_NAME,
 				       pai_buf, store_size, 0);
 	}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 561525d..4df4d4e 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -822,7 +822,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
 				DEBUG(10,("set_ea: setting ea name %s on file %s.\n",
 					unix_ea_name, smb_fname->base_name));
 				ret = SMB_VFS_SETXATTR(conn,
-						smb_fname->base_name,
+						smb_fname,
 						unix_ea_name,
 						ea_list->ea.value.data,
 						ea_list->ea.value.length,
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 25cdf68..d640126 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2550,12 +2550,16 @@ int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
 	return handle->fns->fremovexattr_fn(handle, fsp, name);
 }
 
-int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
-			  const char *name, const void *value, size_t size,
-			  int flags)
+int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name,
+			const void *value,
+			size_t size,
+			int flags)
 {
 	VFS_FIND(setxattr);
-	return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
+	return handle->fns->setxattr_fn(handle, smb_fname,
+			name, value, size, flags);
 }
 
 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 8bd5413..038317e 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -1399,6 +1399,7 @@ static NTSTATUS cmd_setxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 {
 	ssize_t ret;
 	int flags = 0;
+	struct smb_filename *smb_fname = NULL;
 
 	if ((argc < 4) || (argc > 5)) {
 		printf("Usage: setxattr <path> <xattr> <value> [flags]\n");
@@ -1409,7 +1410,13 @@ static NTSTATUS cmd_setxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 		flags = atoi(argv[4]);
 	}
 
-	ret = SMB_VFS_SETXATTR(vfs->conn, argv[1], argv[2],
+	smb_fname = synthetic_smb_fname_split(mem_ctx,
+					argv[1],
+					lp_posix_pathnames());
+	if (smb_fname == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	ret = SMB_VFS_SETXATTR(vfs->conn, smb_fname, argv[2],
 			       argv[3], strlen(argv[3]), flags);
 	if (ret == -1) {
 		int err = errno;
-- 
2.9.3


From f5a5c238b8bf19aa44d422b35ee81af79a2db7aa Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 25 May 2017 16:42:04 -0700
Subject: [PATCH 8/8] s3: VFS: Change SMB_VFS_GETXATTR to use const struct
 smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 examples/VFS/skel_opaque.c          |  7 ++--
 examples/VFS/skel_transparent.c     |  9 +++--
 source3/include/vfs.h               | 15 ++++++---
 source3/include/vfs_macros.h        |  8 ++---
 source3/modules/posixacl_xattr.c    |  6 ++--
 source3/modules/vfs_acl_xattr.c     |  2 +-
 source3/modules/vfs_cap.c           | 35 ++++++++++++++++++--
 source3/modules/vfs_catia.c         | 34 ++++++++++++++++---
 source3/modules/vfs_ceph.c          | 12 +++++--
 source3/modules/vfs_default.c       |  8 +++--
 source3/modules/vfs_fake_acls.c     | 26 +++++++++------
 source3/modules/vfs_fruit.c         |  2 +-
 source3/modules/vfs_full_audit.c    |  6 ++--
 source3/modules/vfs_glusterfs.c     |  9 +++--
 source3/modules/vfs_media_harmony.c | 30 ++++++++---------
 source3/modules/vfs_nfs4acl_xattr.c | 45 +++++++++++++++++--------
 source3/modules/vfs_posix_eadb.c    |  9 +++--
 source3/modules/vfs_shadow_copy2.c  | 30 +++++++++++++----
 source3/modules/vfs_snapper.c       | 45 ++++++++++++++++++-------
 source3/modules/vfs_streams_depot.c |  9 ++---
 source3/modules/vfs_streams_xattr.c | 66 +++++++++++++++++++++++++++++--------
 source3/modules/vfs_time_audit.c    | 11 ++++---
 source3/modules/vfs_unityed_media.c | 19 ++++++-----
 source3/modules/vfs_vxfs.c          | 14 ++++----
 source3/modules/vfs_xattr_tdb.c     |  8 +++--
 source3/smbd/dosmode.c              |  2 +-
 source3/smbd/posix_acls.c           | 13 ++++----
 source3/smbd/proto.h                |  6 ++--
 source3/smbd/trans2.c               | 14 +++++---
 source3/smbd/vfs.c                  |  8 +++--
 source3/torture/cmd_vfs.c           | 11 +++++--
 31 files changed, 363 insertions(+), 156 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 7095dbe..c5d4359 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -797,8 +797,11 @@ static int skel_sys_acl_delete_def_file(vfs_handle_struct *handle,
 	return -1;
 }
 
-static ssize_t skel_getxattr(vfs_handle_struct *handle, const char *path,
-			     const char *name, void *value, size_t size)
+static ssize_t skel_getxattr(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				const char *name,
+				void *value,
+				size_t size)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 97e61a4..91ea5c6 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -933,10 +933,13 @@ static int skel_sys_acl_delete_def_file(vfs_handle_struct *handle,
 	return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, smb_fname);
 }
 
-static ssize_t skel_getxattr(vfs_handle_struct *handle, const char *path,
-			     const char *name, void *value, size_t size)
+static ssize_t skel_getxattr(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				const char *name,
+				void *value,
+				size_t size)
 {
-	return SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size);
+	return SMB_VFS_NEXT_GETXATTR(handle, smb_fname, name, value, size);
 }
 
 static ssize_t skel_fgetxattr(vfs_handle_struct *handle,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 6b1d11f..30002bd 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -211,7 +211,8 @@
 		to const struct smb_filename * */
 /* Version 37 - Change setxattr from const char *
 		to const struct smb_filename * */
-
+/* Version 37 - Change getxattr from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -894,7 +895,11 @@ struct vfs_fn_pointers {
 					const struct smb_filename *smb_fname);
 
 	/* EA operations. */
-	ssize_t (*getxattr_fn)(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size);
+	ssize_t (*getxattr_fn)(struct vfs_handle_struct *handle,
+					const struct smb_filename *smb_fname,
+					const char *name,
+					void *value,
+					size_t size);
 	ssize_t (*fgetxattr_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size);
 	ssize_t (*listxattr_fn)(struct vfs_handle_struct *handle,
 					const struct smb_filename *smb_fname,
@@ -1365,8 +1370,10 @@ int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
 				const struct smb_filename *smb_fname);
 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
-			      const char *path, const char *name, void *value,
-			      size_t size);
+				const struct smb_filename *smb_fname,
+				const char *name,
+				void *value,
+				size_t size);
 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
 			       struct files_struct *fsp, const char *name,
 			       void *value, size_t size);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 8e3fb32..0ebd469 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -515,10 +515,10 @@
 #define SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, smb_fname) \
 	smb_vfs_call_sys_acl_delete_def_file((handle)->next, (smb_fname))
 
-#define SMB_VFS_GETXATTR(conn,path,name,value,size) \
-	smb_vfs_call_getxattr((conn)->vfs_handles,(path),(name),(value),(size))
-#define SMB_VFS_NEXT_GETXATTR(handle,path,name,value,size) \
-	smb_vfs_call_getxattr((handle)->next,(path),(name),(value),(size))
+#define SMB_VFS_GETXATTR(conn,smb_fname,name,value,size) \
+	smb_vfs_call_getxattr((conn)->vfs_handles,(smb_fname),(name),(value),(size))
+#define SMB_VFS_NEXT_GETXATTR(handle,smb_fname,name,value,size) \
+	smb_vfs_call_getxattr((handle)->next,(smb_fname),(name),(value),(size))
 
 #define SMB_VFS_FGETXATTR(fsp,name,value,size) \
 	smb_vfs_call_fgetxattr((fsp)->conn->vfs_handles, (fsp), (name),(value),(size))
diff --git a/source3/modules/posixacl_xattr.c b/source3/modules/posixacl_xattr.c
index dcdf2ff..c4953db 100644
--- a/source3/modules/posixacl_xattr.c
+++ b/source3/modules/posixacl_xattr.c
@@ -360,10 +360,10 @@ SMB_ACL_T posixacl_xattr_acl_get_file(vfs_handle_struct *handle,
 		return NULL;
 	}
 
-	ret = SMB_VFS_GETXATTR(handle->conn, smb_fname->base_name,
+	ret = SMB_VFS_GETXATTR(handle->conn, smb_fname,
 				name, buf, size);
 	if (ret < 0 && errno == ERANGE) {
-		size = SMB_VFS_GETXATTR(handle->conn, smb_fname->base_name,
+		size = SMB_VFS_GETXATTR(handle->conn, smb_fname,
 					name, NULL, 0);
 		if (size > 0) {
 			buf = alloca(size);
@@ -371,7 +371,7 @@ SMB_ACL_T posixacl_xattr_acl_get_file(vfs_handle_struct *handle,
 				return NULL;
 			}
 			ret = SMB_VFS_GETXATTR(handle->conn,
-						smb_fname->base_name, name,
+						smb_fname, name,
 						buf, size);
 		}
 	}
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 6362ac8..367be65 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -51,7 +51,7 @@ static ssize_t getxattr_do(vfs_handle_struct *handle,
 	if (fsp && fsp->fh->fd != -1) {
 		sizeret = SMB_VFS_FGETXATTR(fsp, xattr_name, val, size);
 	} else {
-		sizeret = SMB_VFS_GETXATTR(handle->conn, smb_fname->base_name,
+		sizeret = SMB_VFS_GETXATTR(handle->conn, smb_fname,
 					   XATTR_NTACL_NAME, val, size);
 	}
 	if (sizeret == -1) {
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 62d40b5..c124592 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -652,16 +652,45 @@ static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle,
 	return ret;
 }
 
-static ssize_t cap_getxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size)
+static ssize_t cap_getxattr(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name,
+			void *value,
+			size_t size)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	struct smb_filename *cap_smb_fname = NULL;
+	char *cappath = capencode(talloc_tos(), smb_fname->base_name);
 	char *capname = capencode(talloc_tos(), name);
+	ssize_t ret;
+	int saved_errno = 0;
 
 	if (!cappath || !capname) {
 		errno = ENOMEM;
 		return -1;
 	}
-        return SMB_VFS_NEXT_GETXATTR(handle, cappath, capname, value, size);
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					cappath,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(cappath);
+		TALLOC_FREE(capname);
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_GETXATTR(handle, cap_smb_fname,
+			capname, value, size);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(cappath);
+	TALLOC_FREE(capname);
+	TALLOC_FREE(cap_smb_fname);
+	if (saved_errno) {
+		errno = saved_errno;
+	}
+	return ret;
 }
 
 static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 60d6e7f..2efdd9b 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -1376,16 +1376,23 @@ catia_sys_acl_delete_def_file(vfs_handle_struct *handle,
 }
 
 static ssize_t
-catia_getxattr(vfs_handle_struct *handle, const char *path,
-	       const char *name, void *value, size_t size)
+catia_getxattr(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name,
+			void *value,
+			size_t size)
 {
+	struct smb_filename *mapped_smb_fname = NULL;
 	char *mapped_name = NULL;
 	char *mapped_ea_name = NULL;
 	NTSTATUS status;
 	ssize_t ret;
+	int saved_errno = 0;
 
 	status = catia_string_replace_allocate(handle->conn,
-				path, &mapped_name, vfs_translate_to_unix);
+				smb_fname->base_name,
+				&mapped_name,
+				vfs_translate_to_unix);
 	if (!NT_STATUS_IS_OK(status)) {
 		errno = map_errno_from_nt_status(status);
 		return -1;
@@ -1399,10 +1406,29 @@ catia_getxattr(vfs_handle_struct *handle, const char *path,
 		return -1;
 	}
 
-	ret = SMB_VFS_NEXT_GETXATTR(handle, mapped_name,
+	mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
+					mapped_name,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (mapped_smb_fname == NULL) {
+		TALLOC_FREE(mapped_name);
+		TALLOC_FREE(mapped_ea_name);
+		errno = ENOMEM;
+		return -1;
+	}
+
+	ret = SMB_VFS_NEXT_GETXATTR(handle, mapped_smb_fname,
 				mapped_ea_name, value, size);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
 	TALLOC_FREE(mapped_name);
 	TALLOC_FREE(mapped_ea_name);
+	TALLOC_FREE(mapped_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 
 	return ret;
 }
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 06eada9..571d144 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1217,11 +1217,17 @@ static const char *cephwrap_connectpath(struct vfs_handle_struct *handle,
  Extended attribute operations.
 *****************************************************************/
 
-static ssize_t cephwrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
+static ssize_t cephwrap_getxattr(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name,
+			void *value,
+			size_t size)
 {
 	int ret;
-	DBG_DEBUG("[CEPH] getxattr(%p, %s, %s, %p, %llu)\n", handle, path, name, value, llu(size));
-	ret = ceph_getxattr(handle->data, path, name, value, size);
+	DBG_DEBUG("[CEPH] getxattr(%p, %s, %s, %p, %llu)\n", handle,
+			smb_fname->base_name, name, value, llu(size));
+	ret = ceph_getxattr(handle->data,
+			smb_fname->base_name, name, value, size);
 	DBG_DEBUG("[CEPH] getxattr(...) = %d\n", ret);
 	if (ret < 0) {
 		WRAP_RETURN(ret);
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index e649d4c..0f5e2de 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2745,9 +2745,13 @@ static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle,
  Extended attribute operations.
 *****************************************************************/
 
-static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
+static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			const char *name,
+			void *value,
+			size_t size)
 {
-	return getxattr(path, name, value, size);
+	return getxattr(smb_fname->base_name, name, value, size);
 }
 
 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c
index 61c645b..751d460 100644
--- a/source3/modules/vfs_fake_acls.c
+++ b/source3/modules/vfs_fake_acls.c
@@ -36,12 +36,13 @@
 #define FAKE_ACL_DEFAULT_XATTR "system.fake_default_acl"
 
 static int fake_acls_uid(vfs_handle_struct *handle,
-			 const char *path,
+			 struct smb_filename *smb_fname,
 			 uid_t *uid)
 {
 	ssize_t size;
 	uint8_t uid_buf[4];
-	size = SMB_VFS_NEXT_GETXATTR(handle, path, FAKE_UID, uid_buf, sizeof(uid_buf));
+	size = SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
+			FAKE_UID, uid_buf, sizeof(uid_buf));
 	if (size == -1 && errno == ENOATTR) {
 		return 0;
 	}
@@ -53,13 +54,14 @@ static int fake_acls_uid(vfs_handle_struct *handle,
 }
 
 static int fake_acls_gid(vfs_handle_struct *handle,
-			 const char *path,
+			 struct smb_filename *smb_fname,
 			 uid_t *gid)
 {
 	ssize_t size;
 	uint8_t gid_buf[4];
 
-	size = SMB_VFS_NEXT_GETXATTR(handle, path, FAKE_GID, gid_buf, sizeof(gid_buf));
+	size = SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
+			FAKE_GID, gid_buf, sizeof(gid_buf));
 	if (size == -1 && errno == ENOATTR) {
 		return 0;
 	}
@@ -131,12 +133,14 @@ static int fake_acls_stat(vfs_handle_struct *handle,
 			return -1;
 		}
 		
-		ret = fake_acls_uid(handle, path, &smb_fname->st.st_ex_uid);
+		ret = fake_acls_uid(handle, &smb_fname_base,
+					&smb_fname->st.st_ex_uid);
 		if (ret != 0) {
 			TALLOC_FREE(frame);
 			return ret;
 		}
-		ret = fake_acls_gid(handle, path, &smb_fname->st.st_ex_gid);
+		ret = fake_acls_gid(handle, &smb_fname_base,
+					&smb_fname->st.st_ex_gid);
 		if (ret != 0) {
 			TALLOC_FREE(frame);
 			return ret;
@@ -179,8 +183,10 @@ static int fake_acls_lstat(vfs_handle_struct *handle,
 		 * because linux doesn't support using them, but we
 		 * could fake them in xattr_tdb if we really wanted
 		 * to.  We ignore errors because the link might not point anywhere */
-		fake_acls_uid(handle, path, &smb_fname->st.st_ex_uid);
-		fake_acls_gid(handle, path, &smb_fname->st.st_ex_gid);
+		fake_acls_uid(handle, &smb_fname_base,
+			&smb_fname->st.st_ex_uid);
+		fake_acls_gid(handle, &smb_fname_base,
+			&smb_fname->st.st_ex_gid);
 		TALLOC_FREE(frame);
 	}
 
@@ -250,7 +256,6 @@ static SMB_ACL_T fake_acls_sys_acl_get_file(struct vfs_handle_struct *handle,
 	ssize_t length;
 	const char *name = NULL;
 	struct smb_acl_t *acl = NULL;
-	const char *path = smb_fname->base_name;
 	TALLOC_CTX *frame = talloc_stackframe();
 	switch (type) {
 	case SMB_ACL_TYPE_ACCESS:
@@ -269,7 +274,8 @@ static SMB_ACL_T fake_acls_sys_acl_get_file(struct vfs_handle_struct *handle,
 			TALLOC_FREE(frame);
 			return NULL;
 		}
-		length = SMB_VFS_NEXT_GETXATTR(handle, path, name, blob.data, blob.length);
+		length = SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
+				name, blob.data, blob.length);
 		blob.length = length;
 	} while (length == -1 && errno == ERANGE);
 	if (length == -1 && errno == ENOATTR) {
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 11103cc..c4277b9 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -796,7 +796,7 @@ static ssize_t ad_read_meta(struct adouble *ad,
 
 	DEBUG(10, ("reading meta xattr for %s\n", smb_fname->base_name));
 
-	ealen = SMB_VFS_GETXATTR(ad->ad_handle->conn, smb_fname->base_name,
+	ealen = SMB_VFS_GETXATTR(ad->ad_handle->conn, smb_fname,
 				 AFPINFO_EA_NETATALK, ad->ad_data,
 				 AD_DATASZ_XATTR);
 	if (ealen == -1) {
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 3054c33..fd8c8c1 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -2256,15 +2256,15 @@ static int smb_full_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
 }
 
 static ssize_t smb_full_audit_getxattr(struct vfs_handle_struct *handle,
-			      const char *path,
+			      const struct smb_filename *smb_fname,
 			      const char *name, void *value, size_t size)
 {
 	ssize_t result;
 
-	result = SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size);
+	result = SMB_VFS_NEXT_GETXATTR(handle, smb_fname, name, value, size);
 
 	do_log(SMB_VFS_OP_GETXATTR, (result >= 0), handle,
-	       "%s|%s", path, name);
+	       "%s|%s", smb_fname->base_name, name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index e51556f..c648973 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -1302,10 +1302,13 @@ static const char *vfs_gluster_connectpath(struct vfs_handle_struct *handle,
 /* EA Operations */
 
 static ssize_t vfs_gluster_getxattr(struct vfs_handle_struct *handle,
-				    const char *path, const char *name,
-				    void *value, size_t size)
+				const struct smb_filename *smb_fname,
+				const char *name,
+				void *value,
+				size_t size)
 {
-	return glfs_getxattr(handle->data, path, name, value, size);
+	return glfs_getxattr(handle->data, smb_fname->base_name,
+			name, value, size);
 }
 
 static ssize_t vfs_gluster_fgetxattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index dd715d1..422ca3d 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -2205,37 +2205,33 @@ out:
  * In this case, "name" is an attr name.
  */
 static ssize_t mh_getxattr(struct vfs_handle_struct *handle,
-		const char *path,
+		const struct smb_filename *smb_fname,
 		const char *name,
 		void *value,
 		size_t size)
 {
+	int status;
+	struct smb_filename *clientFname = NULL;
 	ssize_t ret;
-	char *clientPath;
-	TALLOC_CTX *ctx;
 
 	DEBUG(MH_INFO_DEBUG, ("Entering mh_getxattr\n"));
-	if (!is_in_media_files(path))
-	{
-		ret = SMB_VFS_NEXT_GETXATTR(handle, path, name, value,
-				size);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		ret = SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
+					name, value, size);
 		goto out;
 	}
 
-	clientPath = NULL;
-	ctx = talloc_tos();
-
-	if (alloc_get_client_path(handle, ctx,
-				path,
-				&clientPath))
-	{
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&clientFname);
+	if (status != 0) {
 		ret = -1;
 		goto err;
 	}
-
-	ret = SMB_VFS_NEXT_GETXATTR(handle, clientPath, name, value, size);
+	ret = SMB_VFS_NEXT_GETXATTR(handle, clientFname, name, value, size);
 err:
-	TALLOC_FREE(clientPath);
+	TALLOC_FREE(clientFname);
 out:
 	return ret;
 }
diff --git a/source3/modules/vfs_nfs4acl_xattr.c b/source3/modules/vfs_nfs4acl_xattr.c
index de3e368..a9d479b 100644
--- a/source3/modules/vfs_nfs4acl_xattr.c
+++ b/source3/modules/vfs_nfs4acl_xattr.c
@@ -148,8 +148,10 @@ static NTSTATUS nfs4_fget_nfs4_acl(vfs_handle_struct *handle, TALLOC_CTX *mem_ct
 }
 
 /* Fetch the NFSv4 ACL from the xattr, and convert into Samba's internal NFSv4 format */
-static NTSTATUS nfs4_get_nfs4_acl(vfs_handle_struct *handle, TALLOC_CTX *mem_ctx,
-				  const char *path, struct SMB4ACL_T **ppacl)
+static NTSTATUS nfs4_get_nfs4_acl(vfs_handle_struct *handle,
+				TALLOC_CTX *mem_ctx,
+				const struct smb_filename *smb_fname,
+				struct SMB4ACL_T **ppacl)
 {
 	NTSTATUS status;
 	DATA_BLOB blob = data_blob_null;
@@ -164,7 +166,8 @@ static NTSTATUS nfs4_get_nfs4_acl(vfs_handle_struct *handle, TALLOC_CTX *mem_ctx
 			errno = ENOMEM;
 			return NT_STATUS_NO_MEMORY;
 		}
-		length = SMB_VFS_NEXT_GETXATTR(handle, path, NFS4ACL_XATTR_NAME, blob.data, blob.length);
+		length = SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
+				NFS4ACL_XATTR_NAME, blob.data, blob.length);
 		blob.length = length;
 	} while (length == -1 && errno == ERANGE);
 	if (length == -1) {
@@ -402,7 +405,7 @@ static struct SMB4ACL_T *nfs4acls_defaultacl(TALLOC_CTX *mem_ctx)
  * Todo: Really use mem_ctx after fixing interface of nfs4_acls
  */
 static struct SMB4ACL_T *nfs4acls_inheritacl(vfs_handle_struct *handle,
-	const char *path,
+	const struct smb_filename *smb_fname_in,
 	TALLOC_CTX *mem_ctx)
 {
 	char *parent_dir = NULL;
@@ -412,12 +415,14 @@ static struct SMB4ACL_T *nfs4acls_inheritacl(vfs_handle_struct *handle,
 	SMB_ACE4PROP_T ace;
 	bool isdir;
 	struct smb_filename *smb_fname = NULL;
+	struct smb_filename *smb_fname_parent = NULL;
 	NTSTATUS status;
 	int ret;
 	TALLOC_CTX *frame = talloc_stackframe();
 
-	DEBUG(10, ("nfs4acls_inheritacl invoked for %s\n", path));
-	smb_fname = synthetic_smb_fname(frame, path, NULL, NULL, 0);
+	DEBUG(10, ("nfs4acls_inheritacl invoked for %s\n",
+			smb_fname_in->base_name));
+	smb_fname = cp_smb_filename(frame, smb_fname_in);
 	if (smb_fname == NULL) {
 		TALLOC_FREE(frame);
 		errno = ENOMEM;
@@ -436,7 +441,7 @@ static struct SMB4ACL_T *nfs4acls_inheritacl(vfs_handle_struct *handle,
 	isdir = S_ISDIR(smb_fname->st.st_ex_mode);
 
 	if (!parent_dirname(talloc_tos(),
-			    path,
+			    smb_fname->base_name,
 			    &parent_dir,
 			    NULL)) {
 		TALLOC_FREE(frame);
@@ -444,11 +449,24 @@ static struct SMB4ACL_T *nfs4acls_inheritacl(vfs_handle_struct *handle,
 		return NULL;
 	}
 
-	status = nfs4_get_nfs4_acl(handle, frame, parent_dir, &pparentacl);
+	smb_fname_parent = synthetic_smb_fname(talloc_tos(),
+				parent_dir,
+				NULL,
+				NULL,
+				0);
+	if (smb_fname_parent == NULL) {
+		TALLOC_FREE(frame);
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	status = nfs4_get_nfs4_acl(handle, frame, smb_fname_parent,
+					&pparentacl);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)
 	    && strncmp(parent_dir, ".", 2) != 0) {
-		pparentacl = nfs4acls_inheritacl(handle, parent_dir,
-						 frame);
+		pparentacl = nfs4acls_inheritacl(handle,
+						smb_fname_parent,
+						frame);
 	}
 	else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
 		pparentacl = nfs4acls_defaultacl(frame);
@@ -527,7 +545,7 @@ static NTSTATUS nfs4acl_xattr_fget_nt_acl(struct vfs_handle_struct *handle,
 
 	status = nfs4_fget_nfs4_acl(handle, frame, fsp, &pacl);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
-		pacl = nfs4acls_inheritacl(handle, fsp->fsp_name->base_name,
+		pacl = nfs4acls_inheritacl(handle, fsp->fsp_name,
 					   frame);
 	}
 	else if (!NT_STATUS_IS_OK(status)) {
@@ -549,12 +567,11 @@ static NTSTATUS nfs4acl_xattr_get_nt_acl(struct vfs_handle_struct *handle,
 {
 	struct SMB4ACL_T *pacl;
 	NTSTATUS status;
-	const char *name = smb_fname->base_name;
 	TALLOC_CTX *frame = talloc_stackframe();
 
-	status = nfs4_get_nfs4_acl(handle, frame, name, &pacl);
+	status = nfs4_get_nfs4_acl(handle, frame, smb_fname, &pacl);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
-		pacl = nfs4acls_inheritacl(handle, name, frame);
+		pacl = nfs4acls_inheritacl(handle, smb_fname, frame);
 	}
 	else if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(frame);
diff --git a/source3/modules/vfs_posix_eadb.c b/source3/modules/vfs_posix_eadb.c
index 1ba94dc..889655e 100644
--- a/source3/modules/vfs_posix_eadb.c
+++ b/source3/modules/vfs_posix_eadb.c
@@ -77,14 +77,17 @@ static ssize_t posix_eadb_getattr(struct tdb_wrap *db_ctx,
 }
 
 static ssize_t posix_eadb_getxattr(struct vfs_handle_struct *handle,
-				  const char *path, const char *name,
-				  void *value, size_t size)
+				const struct smb_filename *smb_fname,
+				const char *name,
+				void *value,
+				size_t size)
 {
 	struct tdb_wrap *db;
 
 	SMB_VFS_HANDLE_GET_DATA(handle, db, struct tdb_wrap, return -1);
 
-	return posix_eadb_getattr(db, path, -1, name, value, size);
+	return posix_eadb_getattr(db, smb_fname->base_name,
+			-1, name, value, size);
 }
 
 static ssize_t posix_eadb_fgetxattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 5471ed3..dba164e 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -2333,21 +2333,27 @@ static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname,
 }
 
 static ssize_t shadow_copy2_getxattr(vfs_handle_struct *handle,
-				     const char *fname, const char *aname,
-				     void *value, size_t size)
+				const struct smb_filename *smb_fname,
+				const char *aname,
+				void *value,
+				size_t size)
 {
 	time_t timestamp = 0;
 	char *stripped = NULL;
 	ssize_t ret;
 	int saved_errno = 0;
 	char *conv;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-					 &timestamp, &stripped)) {
+	if (!shadow_copy2_strip_snapshot(talloc_tos(),
+				handle,
+				smb_fname->base_name,
+				&timestamp,
+				&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_GETXATTR(handle, fname, aname, value,
+		return SMB_VFS_NEXT_GETXATTR(handle, smb_fname, aname, value,
 					     size);
 	}
 	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
@@ -2355,10 +2361,22 @@ static ssize_t shadow_copy2_getxattr(vfs_handle_struct *handle,
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_GETXATTR(handle, conv, aname, value, size);
+
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (conv_smb_fname == NULL) {
+		TALLOC_FREE(conv);
+		return -1;
+	}
+
+	ret = SMB_VFS_NEXT_GETXATTR(handle, conv_smb_fname, aname, value, size);
 	if (ret == -1) {
 		saved_errno = errno;
 	}
+	TALLOC_FREE(conv_smb_fname);
 	TALLOC_FREE(conv);
 	if (saved_errno != 0) {
 		errno = saved_errno;
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index 3234369..f391a1a 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -2669,21 +2669,27 @@ static int snapper_gmt_chflags(vfs_handle_struct *handle, const char *fname,
 }
 
 static ssize_t snapper_gmt_getxattr(vfs_handle_struct *handle,
-				    const char *fname, const char *aname,
-				    void *value, size_t size)
+				const struct smb_filename *smb_fname,
+				const char *aname,
+				void *value,
+				size_t size)
 {
-	time_t timestamp;
-	char *stripped;
+	time_t timestamp = 0;
+	char *stripped = NULL;
 	ssize_t ret;
-	int saved_errno;
-	char *conv;
+	int saved_errno = 0;
+	char *conv = NULL;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname,
-					&timestamp, &stripped)) {
+	if (!snapper_gmt_strip_snapshot(talloc_tos(),
+					handle,
+					smb_fname->base_name,
+					&timestamp,
+					&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_GETXATTR(handle, fname, aname, value,
+		return SMB_VFS_NEXT_GETXATTR(handle, smb_fname, aname, value,
 					     size);
 	}
 	conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
@@ -2691,10 +2697,25 @@ static ssize_t snapper_gmt_getxattr(vfs_handle_struct *handle,
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_GETXATTR(handle, conv, aname, value, size);
-	saved_errno = errno;
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					fname->flags);
 	TALLOC_FREE(conv);
-	errno = saved_errno;
+	if (conv_smb_fname == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_GETXATTR(handle, conv_smb_fname, aname, value, size);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(conv_smb_fname);
+	TALLOC_FREE(conv);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index b6e95a2..04c1cdb 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -67,13 +67,14 @@ static uint32_t hash_fn(DATA_BLOB key)
  * an option to put in a special ACL entry for a non-existing group.
  */
 
-static bool file_is_valid(vfs_handle_struct *handle, const char *path)
+static bool file_is_valid(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname)
 {
 	char buf;
 
-	DEBUG(10, ("file_is_valid (%s) called\n", path));
+	DEBUG(10, ("file_is_valid (%s) called\n", smb_fname->base_name));
 
-	if (SMB_VFS_GETXATTR(handle->conn, path, SAMBA_XATTR_MARKER,
+	if (SMB_VFS_GETXATTR(handle->conn, smb_fname, SAMBA_XATTR_MARKER,
 				  &buf, sizeof(buf)) != sizeof(buf)) {
 		DEBUG(10, ("GETXATTR failed: %s\n", strerror(errno)));
 		return false;
@@ -228,7 +229,7 @@ static char *stream_dir(vfs_handle_struct *handle,
 		}
 
 		if (!check_valid ||
-		    file_is_valid(handle, smb_fname->base_name)) {
+		    file_is_valid(handle, smb_fname)) {
 			return result;
 		}
 
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index d69c3f9..5114c09 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -79,14 +79,14 @@ static SMB_INO_T stream_inode(const SMB_STRUCT_STAT *sbuf, const char *sname)
 
 static ssize_t get_xattr_size(connection_struct *conn,
 				files_struct *fsp,
-				const char *fname,
+				const struct smb_filename *smb_fname,
 				const char *xattr_name)
 {
 	NTSTATUS status;
 	struct ea_struct ea;
 	ssize_t result;
 
-	status = get_ea_value(talloc_tos(), conn, fsp, fname,
+	status = get_ea_value(talloc_tos(), conn, fsp, smb_fname,
 			      xattr_name, &ea);
 
 	if (!NT_STATUS_IS_OK(status)) {
@@ -190,8 +190,8 @@ static bool streams_xattr_recheck(struct stream_io *sio)
 	TALLOC_FREE(sio->base);
 	sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
 					xattr_name);
-	sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
-				  sio->fsp->fsp_name->base_name);
+        sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
+                                  sio->fsp->fsp_name->base_name);
 	sio->fsp_name_ptr = sio->fsp->fsp_name;
 
 	TALLOC_FREE(xattr_name);
@@ -259,15 +259,16 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
 		ret = SMB_VFS_STAT(handle->conn, smb_fname_base);
 	}
 	*sbuf = smb_fname_base->st;
-	TALLOC_FREE(smb_fname_base);
 
 	if (ret == -1) {
+		TALLOC_FREE(smb_fname_base);
 		return -1;
 	}
 
 	sbuf->st_ex_size = get_xattr_size(handle->conn, fsp,
-					io->base, io->xattr_name);
+					smb_fname_base, io->xattr_name);
 	if (sbuf->st_ex_size == -1) {
+		TALLOC_FREE(smb_fname_base);
 		return -1;
 	}
 
@@ -278,6 +279,7 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
         sbuf->st_ex_mode |= S_IFREG;
         sbuf->st_ex_blocks = sbuf->st_ex_size / STAT_ST_BLOCKSIZE + 1;
 
+	TALLOC_FREE(smb_fname_base);
 	return 0;
 }
 
@@ -317,7 +319,7 @@ static int streams_xattr_stat(vfs_handle_struct *handle,
 
 	/* Augment the base file's stat information before returning. */
 	smb_fname->st.st_ex_size = get_xattr_size(handle->conn, NULL,
-						  smb_fname->base_name,
+						  smb_fname,
 						  xattr_name);
 	if (smb_fname->st.st_ex_size == -1) {
 		errno = ENOENT;
@@ -368,7 +370,7 @@ static int streams_xattr_lstat(vfs_handle_struct *handle,
 
 	/* Augment the base file's stat information before returning. */
 	smb_fname->st.st_ex_size = get_xattr_size(handle->conn, NULL,
-						  smb_fname->base_name,
+						  smb_fname,
 						  xattr_name);
 	if (smb_fname->st.st_ex_size == -1) {
 		errno = ENOENT;
@@ -470,7 +472,7 @@ static int streams_xattr_open(vfs_handle_struct *handle,
         }
 
 	status = get_ea_value(talloc_tos(), handle->conn, NULL,
-			      smb_fname->base_name, xattr_name, &ea);
+			      smb_fname, xattr_name, &ea);
 
 	DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status)));
 
@@ -654,7 +656,7 @@ static int streams_xattr_rename(vfs_handle_struct *handle,
 
 	/* read the old stream */
 	status = get_ea_value(talloc_tos(), handle->conn, NULL,
-			      smb_fname_src->base_name, src_xattr_name, &ea);
+			      smb_fname_src, src_xattr_name, &ea);
 	if (!NT_STATUS_IS_OK(status)) {
 		errno = ENOENT;
 		goto fail;
@@ -744,7 +746,7 @@ static NTSTATUS walk_xattr_streams(vfs_handle_struct *handle,
 		status = get_ea_value(names,
 					handle->conn,
 					fsp,
-					smb_fname->base_name,
+					smb_fname,
 					names[i],
 					&ea);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -950,6 +952,7 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
 		(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
 	struct ea_struct ea;
 	NTSTATUS status;
+	struct smb_filename *smb_fname_base = NULL;
 	int ret;
 
 	DEBUG(10, ("streams_xattr_pwrite called for %d bytes\n", (int)n));
@@ -962,8 +965,19 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
 		return -1;
 	}
 
+	/* Create an smb_filename with stream_name == NULL. */
+	smb_fname_base = synthetic_smb_fname(talloc_tos(),
+					sio->base,
+					NULL,
+					NULL,
+					fsp->fsp_name->flags);
+	if (smb_fname_base == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+
 	status = get_ea_value(talloc_tos(), handle->conn, fsp,
-			      sio->base, sio->xattr_name, &ea);
+			      smb_fname_base, sio->xattr_name, &ea);
 	if (!NT_STATUS_IS_OK(status)) {
 		return -1;
 	}
@@ -1014,6 +1028,7 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle,
 	struct ea_struct ea;
 	NTSTATUS status;
 	size_t length, overlap;
+	struct smb_filename *smb_fname_base = NULL;
 
 	DEBUG(10, ("streams_xattr_pread: offset=%d, size=%d\n",
 		   (int)offset, (int)n));
@@ -1026,8 +1041,19 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle,
 		return -1;
 	}
 
+	/* Create an smb_filename with stream_name == NULL. */
+	smb_fname_base = synthetic_smb_fname(talloc_tos(),
+					sio->base,
+					NULL,
+					NULL,
+					fsp->fsp_name->flags);
+	if (smb_fname_base == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+
 	status = get_ea_value(talloc_tos(), handle->conn, fsp,
-			      sio->base, sio->xattr_name, &ea);
+			      smb_fname_base, sio->xattr_name, &ea);
 	if (!NT_STATUS_IS_OK(status)) {
 		return -1;
 	}
@@ -1219,6 +1245,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
 	NTSTATUS status;
         struct stream_io *sio =
 		(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+	struct smb_filename *smb_fname_base = NULL;
 
 	DEBUG(10, ("streams_xattr_ftruncate called for file %s offset %.0f\n",
 		   fsp_str_dbg(fsp), (double)offset));
@@ -1231,8 +1258,19 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
 		return -1;
 	}
 
+	/* Create an smb_filename with stream_name == NULL. */
+	smb_fname_base = synthetic_smb_fname(talloc_tos(),
+					sio->base,
+					NULL,
+					NULL,
+					fsp->fsp_name->flags);
+	if (smb_fname_base == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+
 	status = get_ea_value(talloc_tos(), handle->conn, fsp,
-			      sio->base, sio->xattr_name, &ea);
+			      smb_fname_base, sio->xattr_name, &ea);
 	if (!NT_STATUS_IS_OK(status)) {
 		return -1;
 	}
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index dd915e5..761711b7 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -2321,20 +2321,23 @@ static int smb_time_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
 }
 
 static ssize_t smb_time_audit_getxattr(struct vfs_handle_struct *handle,
-				       const char *path, const char *name,
-				       void *value, size_t size)
+				const struct smb_filename *smb_fname,
+				const char *name,
+				void *value,
+				size_t size)
 {
 	ssize_t result;
 	struct timespec ts1,ts2;
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size);
+	result = SMB_VFS_NEXT_GETXATTR(handle, smb_fname, name, value, size);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("getxattr", timediff, path);
+		smb_time_audit_log_fname("getxattr", timediff,
+			smb_fname->base_name);
 	}
 
 	return result;
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index 3dd8b99..7c8bee0 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1722,30 +1722,33 @@ err:
 }
 
 static ssize_t um_getxattr(struct vfs_handle_struct *handle,
-			   const char *path,
+			   const struct smb_filename *smb_fname,
 			   const char *name,
 			   void *value,
 			   size_t size)
 {
 	ssize_t ret;
-	char *client_path = NULL;
+	struct smb_filename *client_fname = NULL;
 	int status;
 
 	DEBUG(10, ("Entering um_getxattr\n"));
-	if (!is_in_media_files(path)) {
-		return SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		return SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
+				name, value, size);
 	}
 
-	status = alloc_get_client_path(handle, talloc_tos(),
-				       path, &client_path);
+	status = alloc_get_client_smb_fname(handle,
+				talloc_tos(),
+				smb_fname,
+				&client_fname);
 	if (status != 0) {
 		ret = -1;
 		goto err;
 	}
 
-	ret = SMB_VFS_NEXT_GETXATTR(handle, client_path, name, value, size);
+	ret = SMB_VFS_NEXT_GETXATTR(handle, client_fname, name, value, size);
 err:
-	TALLOC_FREE(client_path);
+	TALLOC_FREE(client_fname);
 	return ret;
 }
 
diff --git a/source3/modules/vfs_vxfs.c b/source3/modules/vfs_vxfs.c
index 46c0756..c77624c 100644
--- a/source3/modules/vfs_vxfs.c
+++ b/source3/modules/vfs_vxfs.c
@@ -624,12 +624,14 @@ static int vxfs_fset_xattr(struct vfs_handle_struct *handle,
 }
 
 static ssize_t vxfs_get_xattr(struct vfs_handle_struct *handle,
-			      const char *path, const char *name,
-			      void *value, size_t size){
+				const struct smb_filename *smb_fname,
+				const char *name,
+				void *value,
+				size_t size){
 	int ret;
 
 	DEBUG(10, ("In vxfs_get_xattr\n"));
-	ret = vxfs_getxattr_path(path, name, value, size);
+	ret = vxfs_getxattr_path(smb_fname->base_name, name, value, size);
 	if ((ret != -1) || ((errno != ENOTSUP) &&
 			    (errno != ENOSYS) && (errno != ENODATA))) {
 		return ret;
@@ -637,8 +639,8 @@ static ssize_t vxfs_get_xattr(struct vfs_handle_struct *handle,
 
 	DEBUG(10, ("Fallback to xattr\n"));
 	if (strcmp(name, XATTR_NTACL_NAME) == 0) {
-		return SMB_VFS_NEXT_GETXATTR(handle, path, XATTR_USER_NTACL,
-					     value, size);
+		return SMB_VFS_NEXT_GETXATTR(handle, smb_fname,
+				XATTR_USER_NTACL, value, size);
 	}
 
 	/* Clients can't see XATTR_USER_NTACL directly. */
@@ -647,7 +649,7 @@ static ssize_t vxfs_get_xattr(struct vfs_handle_struct *handle,
 		return -1;
 	}
 
-	return SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size);
+	return SMB_VFS_NEXT_GETXATTR(handle, smb_fname, name, value, size);
 }
 
 static ssize_t vxfs_fget_xattr(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
index d6d4808..c9bb472 100644
--- a/source3/modules/vfs_xattr_tdb.c
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -57,8 +57,10 @@ static int xattr_tdb_get_file_id(struct vfs_handle_struct *handle,
 }
 
 static ssize_t xattr_tdb_getxattr(struct vfs_handle_struct *handle,
-				  const char *path, const char *name,
-				  void *value, size_t size)
+				const struct smb_filename *smb_fname,
+				const char *name,
+				void *value,
+				size_t size)
 {
 	struct file_id id;
 	struct db_context *db;
@@ -73,7 +75,7 @@ static ssize_t xattr_tdb_getxattr(struct vfs_handle_struct *handle,
 					TALLOC_FREE(frame); return -1;
 				});
 
-	ret = xattr_tdb_get_file_id(handle, path, &id);
+	ret = xattr_tdb_get_file_id(handle, smb_fname->base_name, &id);
 	if (ret == -1) {
 		TALLOC_FREE(frame);
 		return -1;
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index de10983..0ee6894 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -278,7 +278,7 @@ NTSTATUS get_ea_dos_attribute(connection_struct *conn,
 	/* Don't reset pattr to zero as we may already have filename-based attributes we
 	   need to preserve. */
 
-	sizeret = SMB_VFS_GETXATTR(conn, smb_fname->base_name,
+	sizeret = SMB_VFS_GETXATTR(conn, smb_fname,
 				   SAMBA_XATTR_DOS_ATTRIB, attrstr,
 				   sizeof(attrstr));
 	if (sizeret == -1) {
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 0cd28ad..847c5d3 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -629,7 +629,7 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
 					pai_buf, pai_buf_size);
 		} else {
 			ret = SMB_VFS_GETXATTR(fsp->conn,
-					       fsp->fsp_name->base_name,
+					       fsp->fsp_name,
 					       SAMBA_POSIX_INHERITANCE_EA_NAME,
 					       pai_buf, pai_buf_size);
 		}
@@ -681,7 +681,7 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
 ************************************************************************/
 
 static struct pai_val *load_inherited_info(const struct connection_struct *conn,
-					   const char *fname)
+					   const struct smb_filename *smb_fname)
 {
 	char *pai_buf;
 	size_t pai_buf_size = 1024;
@@ -697,7 +697,7 @@ static struct pai_val *load_inherited_info(const struct connection_struct *conn,
 	}
 
 	do {
-		ret = SMB_VFS_GETXATTR(conn, fname,
+		ret = SMB_VFS_GETXATTR(conn, smb_fname,
 				       SAMBA_POSIX_INHERITANCE_EA_NAME,
 				       pai_buf, pai_buf_size);
 
@@ -716,7 +716,8 @@ static struct pai_val *load_inherited_info(const struct connection_struct *conn,
 		}
 	} while (ret == -1);
 
-	DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fname));
+	DEBUG(10,("load_inherited_info: ret = %lu for file %s\n",
+			(unsigned long)ret, smb_fname->base_name));
 
 	if (ret == -1) {
 		/* No attribute or not supported. */
@@ -736,7 +737,7 @@ static struct pai_val *load_inherited_info(const struct connection_struct *conn,
 	if (paiv) {
 		DEBUG(10,("load_inherited_info: ACL type 0x%x for file %s\n",
 			(unsigned int)paiv->sd_type,
-			fname));
+			smb_fname->base_name));
 	}
 
 	TALLOC_FREE(pai_buf);
@@ -3593,7 +3594,7 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn,
 		def_acl = free_empty_sys_acl(conn, def_acl);
 	}
 
-	pal = load_inherited_info(conn, smb_fname->base_name);
+	pal = load_inherited_info(conn, smb_fname);
 
 	status = posix_get_nt_acl_common(conn,
 					smb_fname->base_name,
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 34feed1..2eed439 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1141,8 +1141,10 @@ uint64_t get_FileIndex(connection_struct *conn, const SMB_STRUCT_STAT *psbuf);
 void aapl_force_zero_file_id(struct smbd_server_connection *sconn);
 bool samba_private_attr_name(const char *unix_ea_name);
 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
-		      files_struct *fsp, const char *fname,
-		      const char *ea_name, struct ea_struct *pea);
+			files_struct *fsp,
+			const struct smb_filename *smb_fname,
+			const char *ea_name,
+			struct ea_struct *pea);
 NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
 			connection_struct *conn,
 			files_struct *fsp,
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 4df4d4e..a35297c 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -203,9 +203,12 @@ bool samba_private_attr_name(const char *unix_ea_name)
  Get one EA value. Fill in a struct ea_struct.
 ****************************************************************************/
 
-NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
-		      files_struct *fsp, const char *fname,
-		      const char *ea_name, struct ea_struct *pea)
+NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx,
+			connection_struct *conn,
+			files_struct *fsp,
+			const struct smb_filename *smb_fname,
+			const char *ea_name,
+			struct ea_struct *pea)
 {
 	/* Get the value of this xattr. Max size is 64k. */
 	size_t attr_size = 256;
@@ -222,7 +225,8 @@ NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
 	if (fsp && fsp->fh->fd != -1) {
 		sizeret = SMB_VFS_FGETXATTR(fsp, ea_name, val, attr_size);
 	} else {
-		sizeret = SMB_VFS_GETXATTR(conn, fname, ea_name, val, attr_size);
+		sizeret = SMB_VFS_GETXATTR(conn, smb_fname,
+				ea_name, val, attr_size);
 	}
 
 	if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
@@ -458,7 +462,7 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
 		status = get_ea_value(listp,
 					conn,
 					fsp,
-					smb_fname->base_name,
+					smb_fname,
 					names[i],
 					&listp->ea);
 
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index d640126..9873f7f 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2503,11 +2503,13 @@ int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
 }
 
 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
-			      const char *path, const char *name, void *value,
-			      size_t size)
+				const struct smb_filename *smb_fname,
+				const char *name,
+				void *value,
+				size_t size)
 {
 	VFS_FIND(getxattr);
-	return handle->fns->getxattr_fn(handle, path, name, value, size);
+	return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
 }
 
 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 038317e..0e04a88 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -1309,6 +1309,7 @@ static NTSTATUS cmd_getxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 {
 	uint8_t *buf;
 	ssize_t ret;
+	struct smb_filename *smb_fname = NULL;
 
 	if (argc != 3) {
 		printf("Usage: getxattr <path> <xattr>\n");
@@ -1317,7 +1318,13 @@ static NTSTATUS cmd_getxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 
 	buf = NULL;
 
-	ret = SMB_VFS_GETXATTR(vfs->conn, argv[1], argv[2], buf,
+	smb_fname = synthetic_smb_fname_split(mem_ctx,
+					argv[1],
+					lp_posix_pathnames());
+	if (smb_fname == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	ret = SMB_VFS_GETXATTR(vfs->conn, smb_fname, argv[2], buf,
 			       talloc_get_size(buf));
 	if (ret == -1) {
 		int err = errno;
@@ -1328,7 +1335,7 @@ static NTSTATUS cmd_getxattr(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
 	if (buf == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
-	ret = SMB_VFS_GETXATTR(vfs->conn, argv[1], argv[2], buf,
+	ret = SMB_VFS_GETXATTR(vfs->conn, smb_fname, argv[2], buf,
 			       talloc_get_size(buf));
 	if (ret == -1) {
 		int err = errno;
-- 
2.9.3



More information about the samba-technical mailing list