From: Ralph Boehme Date: Thu, 30 Apr 2020 17:30:50 +0000 (+0200) Subject: smbd: vfs: convert link_contents arg of SMB_VFS_SYMLINKAT() to struct smb_filename X-Git-Tag: ldb-2.2.0~683 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=26ca22fa146b481262cb5baccf3910199450d72b;p=thirdparty%2Fsamba.git smbd: vfs: convert link_contents arg of SMB_VFS_SYMLINKAT() to struct smb_filename Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index bab1d34469c..cc3aa7eae6b 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -462,7 +462,7 @@ static bool skel_getlock(vfs_handle_struct *handle, files_struct *fsp, } static int skel_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 92f9e8a8123..235d4533df3 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -587,7 +587,7 @@ static bool skel_getlock(vfs_handle_struct *handle, files_struct *fsp, } static int skel_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 5e4190adc30..3e133a58f43 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -316,6 +316,8 @@ * changed to bitfields. * Version 43 - convert SMB_VFS_GET_REAL_FILENAME() arg path * to be a struct smb_filename + * Version 43 - convert link_contents arg of SMB_VFS_SYMLINKAT() + * to struct smb_filename */ #define SMB_VFS_INTERFACE_VERSION 43 @@ -843,7 +845,7 @@ struct vfs_fn_pointers { int (*linux_setlease_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, int leasetype); bool (*getlock_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid); int (*symlinkat_fn)(struct vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname); int (*readlinkat_fn)(struct vfs_handle_struct *handle, @@ -1384,7 +1386,7 @@ bool smb_vfs_call_getlock(struct vfs_handle_struct *handle, struct files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid); int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname); int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle, @@ -1824,7 +1826,7 @@ bool vfs_not_implemented_getlock(vfs_handle_struct *handle, files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid); int vfs_not_implemented_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname); int vfs_not_implemented_vfs_readlinkat(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 03f73f5b658..ab84c3143cc 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -440,12 +440,13 @@ static int cap_ntimes(vfs_handle_struct *handle, } static int cap_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { - char *capold = capencode(talloc_tos(), link_contents); + char *capold = capencode(talloc_tos(), link_contents->base_name); char *capnew = capencode(talloc_tos(), new_smb_fname->base_name); + struct smb_filename *new_link_target = NULL; struct smb_filename *new_cap_smb_fname = NULL; int saved_errno = 0; int ret; @@ -454,6 +455,20 @@ static int cap_symlinkat(vfs_handle_struct *handle, errno = ENOMEM; return -1; } + + new_link_target = synthetic_smb_fname(talloc_tos(), + capold, + NULL, + NULL, + new_smb_fname->twrp, + new_smb_fname->flags); + if (new_link_target == NULL) { + TALLOC_FREE(capold); + TALLOC_FREE(capnew); + errno = ENOMEM; + return -1; + } + new_cap_smb_fname = synthetic_smb_fname(talloc_tos(), capnew, NULL, @@ -463,11 +478,12 @@ static int cap_symlinkat(vfs_handle_struct *handle, if (new_cap_smb_fname == NULL) { TALLOC_FREE(capold); TALLOC_FREE(capnew); + TALLOC_FREE(new_link_target); errno = ENOMEM; return -1; } ret = SMB_VFS_NEXT_SYMLINKAT(handle, - capold, + new_link_target, dirfsp, new_cap_smb_fname); if (ret == -1) { @@ -475,6 +491,7 @@ static int cap_symlinkat(vfs_handle_struct *handle, } TALLOC_FREE(capold); TALLOC_FREE(capnew); + TALLOC_FREE(new_link_target); TALLOC_FREE(new_cap_smb_fname); if (saved_errno != 0) { errno = saved_errno; diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c index 5bc8f37a87d..d28b48e648d 100644 --- a/source3/modules/vfs_ceph.c +++ b/source3/modules/vfs_ceph.c @@ -1014,19 +1014,19 @@ static int cephwrap_linux_setlease(struct vfs_handle_struct *handle, files_struc } static int cephwrap_symlinkat(struct vfs_handle_struct *handle, - const char *link_target, + const struct smb_filename *link_target, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { int result = -1; DBG_DEBUG("[CEPH] symlink(%p, %s, %s)\n", handle, - link_target, + link_target->base_name, new_smb_fname->base_name); SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp); result = ceph_symlink(handle->data, - link_target, + link_target->base_name, new_smb_fname->base_name); DBG_DEBUG("[CEPH] symlink(...) = %d\n", result); WRAP_RETURN(result); diff --git a/source3/modules/vfs_ceph_snapshots.c b/source3/modules/vfs_ceph_snapshots.c index 4472f9717a1..e75c0bd87ce 100644 --- a/source3/modules/vfs_ceph_snapshots.c +++ b/source3/modules/vfs_ceph_snapshots.c @@ -772,7 +772,7 @@ static int ceph_snap_gmt_renameat(vfs_handle_struct *handle, /* block links from writeable shares to snapshots for now, like other modules */ static int ceph_snap_gmt_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { @@ -781,7 +781,7 @@ static int ceph_snap_gmt_symlinkat(vfs_handle_struct *handle, time_t timestamp_new = 0; ret = ceph_snap_gmt_strip_snapshot(handle, - link_contents, + link_contents->base_name, ×tamp_old, NULL, 0); if (ret < 0) { diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 578eb34180a..2ac2a9953b1 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -2835,7 +2835,7 @@ static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp, } static int vfswrap_symlinkat(vfs_handle_struct *handle, - const char *link_target, + const struct smb_filename *link_target, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { @@ -2845,7 +2845,7 @@ static int vfswrap_symlinkat(vfs_handle_struct *handle, SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp); - result = symlinkat(link_target, + result = symlinkat(link_target->base_name, dirfsp->fh->fd, new_smb_fname->base_name); END_PROFILE(syscall_symlinkat); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index fad8a14e245..b7edf3c13a3 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -1787,7 +1787,7 @@ static bool smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp, } static int smb_full_audit_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { @@ -1802,7 +1802,7 @@ static int smb_full_audit_symlinkat(vfs_handle_struct *handle, (result >= 0), handle, "%s|%s", - link_contents, + link_contents->base_name, smb_fname_str_do_log(handle->conn, new_smb_fname)); return result; diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index d8f39bd9a96..c1124ec108d 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -1672,7 +1672,7 @@ static bool vfs_gluster_getlock(struct vfs_handle_struct *handle, } static int vfs_gluster_symlinkat(struct vfs_handle_struct *handle, - const char *link_target, + const struct smb_filename *link_target, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { @@ -1681,7 +1681,7 @@ static int vfs_gluster_symlinkat(struct vfs_handle_struct *handle, START_PROFILE(syscall_symlinkat); SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp); ret = glfs_symlink(handle->data, - link_target, + link_target->base_name, new_smb_fname->base_name); END_PROFILE(syscall_symlinkat); diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c index 4c5d98f9170..f07ebdd6c3d 100644 --- a/source3/modules/vfs_media_harmony.c +++ b/source3/modules/vfs_media_harmony.c @@ -1600,16 +1600,16 @@ out: */ static int mh_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { int status = -1; - char *client_link_contents = NULL; + struct smb_filename *new_link_target = NULL; struct smb_filename *newclientFname = NULL; DEBUG(MH_INFO_DEBUG, ("Entering mh_symlinkat\n")); - if (!is_in_media_files(link_contents) && + if (!is_in_media_files(link_contents->base_name) && !is_in_media_files(new_smb_fname->base_name)) { status = SMB_VFS_NEXT_SYMLINKAT(handle, link_contents, @@ -1618,9 +1618,9 @@ static int mh_symlinkat(vfs_handle_struct *handle, goto out; } - if ((status = alloc_get_client_path(handle, talloc_tos(), + if ((status = alloc_get_client_smb_fname(handle, talloc_tos(), link_contents, - &client_link_contents))) { + &new_link_target))) { goto err; } if ((status = alloc_get_client_smb_fname(handle, talloc_tos(), @@ -1630,11 +1630,11 @@ static int mh_symlinkat(vfs_handle_struct *handle, } status = SMB_VFS_NEXT_SYMLINKAT(handle, - client_link_contents, + new_link_target, dirfsp, newclientFname); err: - TALLOC_FREE(client_link_contents); + TALLOC_FREE(new_link_target); TALLOC_FREE(newclientFname); out: return status; diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c index f5cd002d897..d734502c7f8 100644 --- a/source3/modules/vfs_not_implemented.c +++ b/source3/modules/vfs_not_implemented.c @@ -461,7 +461,7 @@ bool vfs_not_implemented_getlock(vfs_handle_struct *handle, files_struct *fsp, } int vfs_not_implemented_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index f405c8a80e2..207347c217c 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -1137,7 +1137,7 @@ static int shadow_copy2_renameat(vfs_handle_struct *handle, } static int shadow_copy2_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { @@ -1148,7 +1148,7 @@ static int shadow_copy2_symlinkat(vfs_handle_struct *handle, if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, - link_contents, + link_contents->base_name, ×tamp_old, NULL, &snappath_old, diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c index b98289b90eb..0c240e83ce2 100644 --- a/source3/modules/vfs_snapper.c +++ b/source3/modules/vfs_snapper.c @@ -1997,7 +1997,7 @@ static int snapper_gmt_renameat(vfs_handle_struct *handle, } static int snapper_gmt_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { @@ -2006,7 +2006,7 @@ static int snapper_gmt_symlinkat(vfs_handle_struct *handle, if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, - link_contents, + link_contents->base_name, ×tamp_old, NULL)) { return -1; diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c index f375c359d6f..2c4c386e23f 100644 --- a/source3/modules/vfs_syncops.c +++ b/source3/modules/vfs_syncops.c @@ -167,7 +167,7 @@ static int syncops_renameat(vfs_handle_struct *handle, } while (0) static int syncops_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { @@ -184,7 +184,7 @@ static int syncops_symlinkat(vfs_handle_struct *handle, new_smb_fname); if (ret == 0 && config->onmeta && !config->disable) { - syncops_two_names(link_contents, + syncops_two_names(link_contents->base_name, new_smb_fname->base_name); } return ret; diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 8b7be9660c4..ee1d0341c7f 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1403,7 +1403,7 @@ static bool smb_time_audit_getlock(vfs_handle_struct *handle, } static int smb_time_audit_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c index 98c6a9eab95..56d1ff3451f 100644 --- a/source3/modules/vfs_unityed_media.c +++ b/source3/modules/vfs_unityed_media.c @@ -1234,17 +1234,17 @@ err: } static int um_symlinkat(vfs_handle_struct *handle, - const char *link_contents, + const struct smb_filename *link_contents, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { int status; - char *client_link_contents = NULL; + struct smb_filename *new_link_target = NULL; struct smb_filename *new_client_fname = NULL; DEBUG(10, ("Entering um_symlinkat\n")); - if (!is_in_media_files(link_contents) && + if (!is_in_media_files(link_contents->base_name) && !is_in_media_files(new_smb_fname->base_name)) { return SMB_VFS_NEXT_SYMLINKAT(handle, link_contents, @@ -1252,8 +1252,8 @@ static int um_symlinkat(vfs_handle_struct *handle, new_smb_fname); } - status = alloc_get_client_path(handle, talloc_tos(), - link_contents, &client_link_contents); + status = alloc_get_client_smb_fname(handle, talloc_tos(), + link_contents, &new_link_target); if (status != 0) { goto err; } @@ -1264,12 +1264,12 @@ static int um_symlinkat(vfs_handle_struct *handle, } status = SMB_VFS_NEXT_SYMLINKAT(handle, - client_link_contents, + new_link_target, dirfsp, new_client_fname); err: - TALLOC_FREE(client_link_contents); + TALLOC_FREE(new_link_target); TALLOC_FREE(new_client_fname); return status; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index fa77cb4c6e0..0af680e327f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7019,7 +7019,7 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn, new_smb_fname->base_name, link_target )); ret = SMB_VFS_SYMLINKAT(conn, - target_fname.base_name, + &target_fname, conn->cwd_fsp, new_smb_fname); if (ret != 0) { diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 89180e46e1e..5bc3911b4e0 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2135,7 +2135,7 @@ int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle, } int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle, - const char *link_target, + const struct smb_filename *link_target, struct files_struct *dirfsp, const struct smb_filename *new_smb_fname) { diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index e33c8863883..ab0e451e77b 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -1178,7 +1178,7 @@ static NTSTATUS cmd_symlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc } ret = SMB_VFS_SYMLINKAT(vfs->conn, - target_fname.base_name, + &target_fname, vfs->conn->cwd_fsp, new_smb_fname); if (ret == -1) {