diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 981bfbffe33..ea66742d858 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 ec7a9f1aee0..e72edbc04d8 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 7046513480d..56c3f5d56b7 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 f5c0332cf20..e1a9ba05024 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 416295fc6a8..59934551e14 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 1dc70824bf5..b21207bc205 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 91f624ee96b..fe70d781d07 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 844f2418c60..72dde16b39e 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 874bd40d733..825df00ddd8 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 dfdcfb4f23d..f2ce646e049 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -2770,9 +2770,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 fc655c874eb..e0e17830ba2 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 7bc259bf352..b6d4f9bf451 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 f50f24d02b1..905d5730c71 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 30629b8db6c..8784232ebd3 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 2113e0310a1..3c330201f06 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 b5f92dff9c1..add04465291 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 74176793a14..450080106da 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, - ×tamp, &stripped)) { + if (!shadow_copy2_strip_snapshot(talloc_tos(), + handle, + smb_fname->base_name, + ×tamp, + &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 bc98f78189a..49e2c61f50c 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 struct 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, - ×tamp, &stripped)) { + if (!snapper_gmt_strip_snapshot(talloc_tos(), + handle, + smb_fname->base_name, + ×tamp, + &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, + smb_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 f481f27657f..0f4050efb9e 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 e260c4727e3..273c8ff02ea 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 7b60856ae75..95ecb458af7 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 c678636d14a..e718c241913 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,32 +653,34 @@ 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")); - /* Remove with old way */ - if (strcmp(name, XATTR_NTACL_NAME) == 0) { - ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path, - XATTR_USER_NTACL); - } else { - if (strcasecmp(name, XATTR_USER_NTACL) != 0) { - ret = SMB_VFS_NEXT_REMOVEXATTR(handle, path, - name); - } - } - old_errno = errno; - - /* Remove with new way */ - smb_fname = synthetic_smb_fname(talloc_tos(), path, NULL, NULL, 0); + smb_fname = cp_smb_filename_nostream(talloc_tos(), smb_fname_in); if (smb_fname == NULL) { errno = ENOMEM; return -1; } + /* Remove with old way */ + if (strcmp(name, XATTR_NTACL_NAME) == 0) { + 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, smb_fname, + name); + } + } + /* Remove with new way */ + old_errno = errno; + if (SMB_VFS_NEXT_STAT(handle, smb_fname) != 0) { TALLOC_FREE(smb_fname); return -1; @@ -687,7 +691,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 a4f80b20eda..1ff80a72b1b 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 8c1190b5d30..561525d6699 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 d27ab397419..25cdf68dcde 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 7155ac3a170..8bd541318f2 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 \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));