From: Jeremy Allison Date: Fri, 2 Jun 2017 21:21:54 +0000 (-0700) Subject: s3: VFS: Change SMB_VFS_LINK to use const struct smb_filename * instead of const... X-Git-Tag: tevent-0.9.32~57 X-Git-Url: http://git.samba.org/?p=samba.git;a=commitdiff_plain;h=fc92d451cf3162807e2493c62fa7617863adf2ba s3: VFS: Change SMB_VFS_LINK 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 Reviewed-by: Richard Sharpe --- diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 7dd258f1528..371caef4818 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -489,8 +489,9 @@ static int skel_vfs_readlink(vfs_handle_struct *handle, const char *path, return -1; } -static int skel_link(vfs_handle_struct *handle, const char *oldpath, - const char *newpath) +static int skel_link(vfs_handle_struct *handle, + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { errno = ENOSYS; return -1; diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 5e66be49d42..bcd4a44e51d 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -581,10 +581,11 @@ static int skel_vfs_readlink(vfs_handle_struct *handle, const char *path, return SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz); } -static int skel_link(vfs_handle_struct *handle, const char *oldpath, - const char *newpath) +static int skel_link(vfs_handle_struct *handle, + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { - return SMB_VFS_NEXT_LINK(handle, oldpath, newpath); + return SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname); } static int skel_mknod(vfs_handle_struct *handle, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index a0eca7730f9..f54d9ea93b2 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -220,6 +220,8 @@ to const struct smb_filename * */ /* Version 37 - Change get_quota from const char * to const struct smb_filename * */ +/* Version 37 - Change link from const char * + to const struct smb_filename * */ #define SMB_VFS_INTERFACE_VERSION 37 @@ -739,7 +741,9 @@ struct vfs_fn_pointers { bool (*getlock_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid); int (*symlink_fn)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath); int (*readlink_fn)(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz); - int (*link_fn)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath); + int (*link_fn)(struct vfs_handle_struct *handle, + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname); int (*mknod_fn)(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode, @@ -1241,8 +1245,9 @@ int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath); int smb_vfs_call_readlink(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz); -int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath, - const char *newpath); +int smb_vfs_call_link(struct vfs_handle_struct *handle, + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname); int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const struct smb_filename *smb_fname, mode_t mode, diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index cfb02cbdf62..7e89c0917f6 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -504,16 +504,56 @@ static int cap_readlink(vfs_handle_struct *handle, const char *path, return SMB_VFS_NEXT_READLINK(handle, cappath, buf, bufsiz); } -static int cap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +static int cap_link(vfs_handle_struct *handle, + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { - char *capold = capencode(talloc_tos(), oldpath); - char *capnew = capencode(talloc_tos(), newpath); + char *capold = capencode(talloc_tos(), old_smb_fname->base_name); + char *capnew = capencode(talloc_tos(), new_smb_fname->base_name); + struct smb_filename *old_cap_smb_fname = NULL; + struct smb_filename *new_cap_smb_fname = NULL; + int saved_errno = 0; + int ret; if (!capold || !capnew) { errno = ENOMEM; return -1; } - return SMB_VFS_NEXT_LINK(handle, capold, capnew); + old_cap_smb_fname = synthetic_smb_fname(talloc_tos(), + capold, + NULL, + NULL, + old_smb_fname->flags); + if (old_cap_smb_fname == NULL) { + TALLOC_FREE(capold); + TALLOC_FREE(capnew); + errno = ENOMEM; + return -1; + } + new_cap_smb_fname = synthetic_smb_fname(talloc_tos(), + capnew, + NULL, + NULL, + new_smb_fname->flags); + if (new_cap_smb_fname == NULL) { + TALLOC_FREE(capold); + TALLOC_FREE(capnew); + TALLOC_FREE(old_cap_smb_fname); + errno = ENOMEM; + return -1; + } + ret = SMB_VFS_NEXT_LINK(handle, old_cap_smb_fname, new_cap_smb_fname); + if (ret == -1) { + saved_errno = errno; + } + TALLOC_FREE(capold); + TALLOC_FREE(capnew); + TALLOC_FREE(old_cap_smb_fname); + TALLOC_FREE(new_cap_smb_fname); + if (saved_errno != 0) { + errno = saved_errno; + } + return ret; } static int cap_mknod(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c index 5f7440473df..1d9bf13a289 100644 --- a/source3/modules/vfs_ceph.c +++ b/source3/modules/vfs_ceph.c @@ -1141,11 +1141,17 @@ static int cephwrap_readlink(struct vfs_handle_struct *handle, const char *path WRAP_RETURN(result); } -static int cephwrap_link(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath) +static int cephwrap_link(struct vfs_handle_struct *handle, + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { int result = -1; - DBG_DEBUG("[CEPH] link(%p, %s, %s)\n", handle, oldpath, newpath); - result = ceph_link(handle->data, oldpath, newpath); + DBG_DEBUG("[CEPH] link(%p, %s, %s)\n", handle, + old_smb_fname->base_name, + new_smb_fname->base_name); + result = ceph_link(handle->data, + old_smb_fname->base_name, + new_smb_fname->base_name); DBG_DEBUG("[CEPH] link(...) = %d\n", result); WRAP_RETURN(result); } diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 664da956c7c..0aba405c374 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -2436,12 +2436,14 @@ static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *b return result; } -static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath) +static int vfswrap_link(vfs_handle_struct *handle, + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { int result; START_PROFILE(syscall_link); - result = link(oldpath, newpath); + result = link(old_smb_fname->base_name, new_smb_fname->base_name); END_PROFILE(syscall_link); return result; } diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 01cea1aaee4..15ab13f859f 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -1651,14 +1651,15 @@ static int smb_full_audit_readlink(vfs_handle_struct *handle, } static int smb_full_audit_link(vfs_handle_struct *handle, - const char *oldpath, const char *newpath) + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { int result; - result = SMB_VFS_NEXT_LINK(handle, oldpath, newpath); + result = SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname); do_log(SMB_VFS_OP_LINK, (result >= 0), handle, - "%s|%s", oldpath, newpath); + "%s|%s", old_smb_fname->base_name, new_smb_fname->base_name); return result; } diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index 3d28381eaf4..870983ea8fc 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -1246,9 +1246,12 @@ static int vfs_gluster_readlink(struct vfs_handle_struct *handle, } static int vfs_gluster_link(struct vfs_handle_struct *handle, - const char *oldpath, const char *newpath) + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { - return glfs_link(handle->data, oldpath, newpath); + return glfs_link(handle->data, + old_smb_fname->base_name, + new_smb_fname->base_name); } static int vfs_gluster_mknod(struct vfs_handle_struct *handle, diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c index 37b396a5bea..2659b29c498 100644 --- a/source3/modules/vfs_media_harmony.c +++ b/source3/modules/vfs_media_harmony.c @@ -1807,43 +1807,37 @@ out: * Failure: set errno, return -1 */ static int mh_link(vfs_handle_struct *handle, - const char *oldpath, - const char *newpath) + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { int status; - char *oldClientPath; - char *newClientPath; - TALLOC_CTX *ctx; + struct smb_filename *oldclientFname = NULL; + struct smb_filename *newclientFname = NULL; DEBUG(MH_INFO_DEBUG, ("Entering mh_link\n")); - if (!is_in_media_files(oldpath) && !is_in_media_files(newpath)) - { - status = SMB_VFS_NEXT_LINK(handle, oldpath, newpath); + if (!is_in_media_files(old_smb_fname->base_name) && + !is_in_media_files(new_smb_fname->base_name)) { + status = SMB_VFS_NEXT_LINK(handle, + old_smb_fname, + new_smb_fname); goto out; } - oldClientPath = NULL; - newClientPath = NULL; - ctx = talloc_tos(); - - if ((status = alloc_get_client_path(handle, ctx, - oldpath, - &oldClientPath))) - { + if ((status = alloc_get_client_smb_fname(handle, talloc_tos(), + old_smb_fname, + &oldclientFname))) { goto err; } - - if ((status = alloc_get_client_path(handle, ctx, - newpath, - &newClientPath))) - { + if ((status = alloc_get_client_smb_fname(handle, talloc_tos(), + new_smb_fname, + &newclientFname))) { goto err; } - status = SMB_VFS_NEXT_LINK(handle, oldClientPath, newClientPath); + status = SMB_VFS_NEXT_LINK(handle, oldclientFname, newclientFname); err: - TALLOC_FREE(newClientPath); - TALLOC_FREE(oldClientPath); + TALLOC_FREE(newclientFname); + TALLOC_FREE(oldclientFname); out: return status; } diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index faacc459146..5481eda0e25 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -1180,19 +1180,28 @@ static int shadow_copy2_symlink(vfs_handle_struct *handle, } static int shadow_copy2_link(vfs_handle_struct *handle, - const char *oldname, const char *newname) + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { time_t timestamp_old = 0; time_t timestamp_new = 0; char *snappath_old = NULL; char *snappath_new = NULL; - if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname, - ×tamp_old, NULL, &snappath_old)) { + if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), + handle, + old_smb_fname->base_name, + ×tamp_old, + NULL, + &snappath_old)) { return -1; } - if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname, - ×tamp_new, NULL, &snappath_new)) { + if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), + handle, + new_smb_fname->base_name, + ×tamp_new, + NULL, + &snappath_new)) { return -1; } if ((timestamp_old != 0) || (timestamp_new != 0)) { @@ -1206,7 +1215,7 @@ static int shadow_copy2_link(vfs_handle_struct *handle, errno = EROFS; return -1; } - return SMB_VFS_NEXT_LINK(handle, oldname, newname); + return SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname); } static int shadow_copy2_stat(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c index 41800bf7a3a..ec0c680124e 100644 --- a/source3/modules/vfs_snapper.c +++ b/source3/modules/vfs_snapper.c @@ -2057,23 +2057,31 @@ static int snapper_gmt_symlink(vfs_handle_struct *handle, } static int snapper_gmt_link(vfs_handle_struct *handle, - const char *oldname, const char *newname) + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { - time_t timestamp_old, timestamp_new; + time_t timestamp_old = 0; + time_t timestamp_new = 0; - if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, oldname, - ×tamp_old, NULL)) { + if (!snapper_gmt_strip_snapshot(talloc_tos(), + handle, + old_smb_fname->base_name, + ×tamp_old, + NULL)) { return -1; } - if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, newname, - ×tamp_new, NULL)) { + if (!snapper_gmt_strip_snapshot(talloc_tos(), + handle, + new_smb_fname->base_name, + ×tamp_new, + NULL)) { return -1; } if ((timestamp_old != 0) || (timestamp_new != 0)) { errno = EROFS; return -1; } - return SMB_VFS_NEXT_LINK(handle, oldname, newname); + return SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname); } static int snapper_gmt_stat(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c index 8c20af3bd06..725bd1072e4 100644 --- a/source3/modules/vfs_syncops.c +++ b/source3/modules/vfs_syncops.c @@ -192,9 +192,22 @@ static int syncops_symlink(vfs_handle_struct *handle, } static int syncops_link(vfs_handle_struct *handle, - const char *oldname, const char *newname) + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { - SYNCOPS_NEXT(LINK, newname, (handle, oldname, newname)); + int ret; + struct syncops_config_data *config; + + SMB_VFS_HANDLE_GET_DATA(handle, config, + struct syncops_config_data, + return -1); + + ret = SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname); + if (ret == 0 && config->onmeta && !config->disable) { + syncops_two_names(old_smb_fname->base_name, + new_smb_fname->base_name); + } + return ret; } static int syncops_open(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index ebfcb8df655..f07bd29f5e3 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1461,19 +1461,21 @@ static int smb_time_audit_readlink(vfs_handle_struct *handle, } static int smb_time_audit_link(vfs_handle_struct *handle, - const char *oldpath, const char *newpath) + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { int result; struct timespec ts1,ts2; double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_LINK(handle, oldpath, newpath); + result = SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; if (timediff > audit_timeout) { - smb_time_audit_log_fname("link", timediff, newpath); + smb_time_audit_log_fname("link", timediff, + new_smb_fname->base_name); } return result; diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c index aa06ea361fa..aefe2b37ab1 100644 --- a/source3/modules/vfs_unityed_media.c +++ b/source3/modules/vfs_unityed_media.c @@ -1379,35 +1379,35 @@ err: } static int um_link(vfs_handle_struct *handle, - const char *oldpath, - const char *newpath) + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { int status; - char *old_client_path = NULL; - char *new_client_path = NULL; + struct smb_filename *old_client_fname = NULL; + struct smb_filename *new_client_fname = NULL; DEBUG(10, ("Entering um_link\n")); - if (!is_in_media_files(oldpath) && !is_in_media_files(newpath)) { - return SMB_VFS_NEXT_LINK(handle, oldpath, newpath); + if (!is_in_media_files(old_smb_fname->base_name) && + !is_in_media_files(new_smb_fname->base_name)) { + return SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname); } - status = alloc_get_client_path(handle, talloc_tos(), - oldpath, &old_client_path); + status = alloc_get_client_smb_fname(handle, talloc_tos(), + old_smb_fname, &old_client_fname); if (status != 0) { goto err; } - - status = alloc_get_client_path(handle, talloc_tos(), - newpath, &new_client_path); + status = alloc_get_client_smb_fname(handle, talloc_tos(), + new_smb_fname, &new_client_fname); if (status != 0) { goto err; } - status = SMB_VFS_NEXT_LINK(handle, old_client_path, new_client_path); + status = SMB_VFS_NEXT_LINK(handle, old_client_fname, new_client_fname); err: - TALLOC_FREE(new_client_path); - TALLOC_FREE(old_client_path); + TALLOC_FREE(old_client_fname); + TALLOC_FREE(new_client_fname); return status; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 3e1cfa8ca96..33908f0e7e2 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6149,8 +6149,7 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx, DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", smb_fname_old->base_name, smb_fname_new->base_name)); - if (SMB_VFS_LINK(conn, smb_fname_old->base_name, - smb_fname_new->base_name) != 0) { + if (SMB_VFS_LINK(conn, smb_fname_old, smb_fname_new) != 0) { status = map_nt_error_from_unix(errno); DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n", nt_errstr(status), smb_fname_old->base_name, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 7177f882a0c..c747bde5569 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2165,11 +2165,12 @@ int smb_vfs_call_readlink(struct vfs_handle_struct *handle, return handle->fns->readlink_fn(handle, path, buf, bufsiz); } -int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath, - const char *newpath) +int smb_vfs_call_link(struct vfs_handle_struct *handle, + const struct smb_filename *old_smb_fname, + const struct smb_filename *new_smb_fname) { VFS_FIND(link); - return handle->fns->link_fn(handle, oldpath, newpath); + return handle->fns->link_fn(handle, old_smb_fname, new_smb_fname); } int smb_vfs_call_mknod(struct vfs_handle_struct *handle, diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 8d7d2a7f175..38d87464c42 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -1251,12 +1251,28 @@ static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { + struct smb_filename *old_smb_fname = NULL; + struct smb_filename *new_smb_fname = NULL; + if (argc != 3) { printf("Usage: link \n"); return NT_STATUS_OK; } - if (SMB_VFS_LINK(vfs->conn, argv[1], argv[2]) == -1) { + old_smb_fname = synthetic_smb_fname_split(mem_ctx, + argv[1], + lp_posix_pathnames()); + if (old_smb_fname == NULL) { + return NT_STATUS_NO_MEMORY; + } + new_smb_fname = synthetic_smb_fname_split(mem_ctx, + argv[2], + lp_posix_pathnames()); + if (new_smb_fname == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (SMB_VFS_LINK(vfs->conn, old_smb_fname, new_smb_fname) == -1) { printf("link: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; }