From 602db7dcb99f6bed95cbe5ac7761bfe2451c5ca9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 May 2017 15:01:52 -0700 Subject: [PATCH] s3: VFS: Change SMB_VFS_MKNOD 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 --- examples/VFS/skel_opaque.c | 6 ++++-- examples/VFS/skel_transparent.c | 8 +++++--- source3/include/vfs.h | 12 +++++++++--- source3/include/vfs_macros.h | 8 ++++---- source3/modules/vfs_cap.c | 31 ++++++++++++++++++++++++++++--- source3/modules/vfs_ceph.c | 7 +++++-- source3/modules/vfs_default.c | 7 +++++-- source3/modules/vfs_full_audit.c | 9 ++++++--- source3/modules/vfs_glusterfs.c | 8 +++++--- source3/modules/vfs_media_harmony.c | 21 +++++++++------------ source3/modules/vfs_shadow_copy2.c | 21 +++++++++++++++------ source3/modules/vfs_snapper.c | 35 ++++++++++++++++++++++++----------- source3/modules/vfs_syncops.c | 7 +++++-- source3/modules/vfs_time_audit.c | 7 ++++--- source3/modules/vfs_unityed_media.c | 16 ++++++++-------- source3/smbd/trans2.c | 2 +- source3/smbd/vfs.c | 8 +++++--- source3/torture/cmd_vfs.c | 9 ++++++++- 18 files changed, 150 insertions(+), 72 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index af119f32db1..bfd1da38b4b 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -492,8 +492,10 @@ static int skel_link(vfs_handle_struct *handle, const char *oldpath, return -1; } -static int skel_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, - SMB_DEV_T dev) +static int skel_mknod(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { errno = ENOSYS; return -1; diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index e9745292730..07eab08e027 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -583,10 +583,12 @@ static int skel_link(vfs_handle_struct *handle, const char *oldpath, return SMB_VFS_NEXT_LINK(handle, oldpath, newpath); } -static int skel_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, - SMB_DEV_T dev) +static int skel_mknod(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { - return SMB_VFS_NEXT_MKNOD(handle, path, mode, dev); + return SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev); } static char *skel_realpath(vfs_handle_struct *handle, const char *path) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 79089806e24..85928ce3703 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -197,6 +197,7 @@ /* 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 mknod from const char * to const struct smb_filename * */ #define SMB_VFS_INTERFACE_VERSION 37 @@ -712,7 +713,10 @@ struct vfs_fn_pointers { 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 (*mknod_fn)(struct vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev); + int (*mknod_fn)(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev); char *(*realpath_fn)(struct vfs_handle_struct *handle, const char *path); int (*chflags_fn)(struct vfs_handle_struct *handle, const char *path, unsigned int flags); struct file_id (*file_id_create_fn)(struct vfs_handle_struct *handle, @@ -1188,8 +1192,10 @@ 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_mknod(struct vfs_handle_struct *handle, const char *path, - mode_t mode, SMB_DEV_T dev); +int smb_vfs_call_mknod(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev); char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path); int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path, unsigned int flags); diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 0cbcf89cce5..cf03fb42485 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -326,10 +326,10 @@ #define SMB_VFS_NEXT_LINK(handle, oldpath, newpath) \ smb_vfs_call_link((handle)->next, (oldpath), (newpath)) -#define SMB_VFS_MKNOD(conn, path, mode, dev) \ - smb_vfs_call_mknod((conn)->vfs_handles, (path), (mode), (dev)) -#define SMB_VFS_NEXT_MKNOD(handle, path, mode, dev) \ - smb_vfs_call_mknod((handle)->next, (path), (mode), (dev)) +#define SMB_VFS_MKNOD(conn, smb_fname, mode, dev) \ + smb_vfs_call_mknod((conn)->vfs_handles, (smb_fname), (mode), (dev)) +#define SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev) \ + smb_vfs_call_mknod((handle)->next, (smb_fname), (mode), (dev)) #define SMB_VFS_REALPATH(conn, path) \ smb_vfs_call_realpath((conn)->vfs_handles, (path)) diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 03608301bf5..e6369120bb2 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -488,15 +488,40 @@ static int cap_link(vfs_handle_struct *handle, const char *oldpath, const char * return SMB_VFS_NEXT_LINK(handle, capold, capnew); } -static int cap_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev) +static int cap_mknod(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { - 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_MKNOD(handle, cappath, mode, dev); + 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_MKNOD(handle, cap_smb_fname, mode, dev); + if (ret == -1) { + saved_errno = errno; + } + TALLOC_FREE(cappath); + TALLOC_FREE(cap_smb_fname); + if (saved_errno != 0) { + errno = saved_errno; + } + return ret; } static char *cap_realpath(vfs_handle_struct *handle, const char *path) diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c index d819fe18dc3..55266b84971 100644 --- a/source3/modules/vfs_ceph.c +++ b/source3/modules/vfs_ceph.c @@ -1145,11 +1145,14 @@ static int cephwrap_link(struct vfs_handle_struct *handle, const char *oldpath, WRAP_RETURN(result); } -static int cephwrap_mknod(struct vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev) +static int cephwrap_mknod(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { int result = -1; DBG_DEBUG("[CEPH] mknod(%p, %s)\n", handle, pathname); - result = ceph_mknod(handle->data, pathname, mode, dev); + result = ceph_mknod(handle->data, smb_fname->base_name, mode, dev); DBG_DEBUG("[CEPH] mknod(...) = %d\n", result); WRAP_RETURN(result); } diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index fa89f7f2551..6df7c764ad0 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -2440,12 +2440,15 @@ static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const ch return result; } -static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev) +static int vfswrap_mknod(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { int result; START_PROFILE(syscall_mknod); - result = sys_mknod(pathname, mode, dev); + result = sys_mknod(smb_fname->base_name, mode, dev); END_PROFILE(syscall_mknod); return result; } diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 4c2eb87ddb1..af79a67d682 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -1659,13 +1659,16 @@ static int smb_full_audit_link(vfs_handle_struct *handle, } static int smb_full_audit_mknod(vfs_handle_struct *handle, - const char *pathname, mode_t mode, SMB_DEV_T dev) + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { int result; - result = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev); + result = SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev); - do_log(SMB_VFS_OP_MKNOD, (result >= 0), handle, "%s", pathname); + do_log(SMB_VFS_OP_MKNOD, (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 628dea79336..f92e7f21301 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -1248,10 +1248,12 @@ static int vfs_gluster_link(struct vfs_handle_struct *handle, return glfs_link(handle->data, oldpath, newpath); } -static int vfs_gluster_mknod(struct vfs_handle_struct *handle, const char *path, - mode_t mode, SMB_DEV_T dev) +static int vfs_gluster_mknod(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { - return glfs_mknod(handle->data, path, mode, dev); + return glfs_mknod(handle->data, smb_fname->base_name, mode, dev); } static int vfs_gluster_chflags(struct vfs_handle_struct *handle, diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c index 794644ed493..2e9698525a6 100644 --- a/source3/modules/vfs_media_harmony.c +++ b/source3/modules/vfs_media_harmony.c @@ -1853,34 +1853,31 @@ out: * Failure: set errno, return -1 */ static int mh_mknod(vfs_handle_struct *handle, - const char *pathname, + const struct smb_filename *smb_fname, mode_t mode, SMB_DEV_T dev) { int status; - char *clientPath; + struct smb_filename *clientFname = NULL; TALLOC_CTX *ctx; DEBUG(MH_INFO_DEBUG, ("Entering mh_mknod\n")); - if (!is_in_media_files(pathname)) - { - status = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev); + if (!is_in_media_files(smb_fname->base_name)) { + status = SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev); goto out; } - clientPath = NULL; ctx = talloc_tos(); - if ((status = alloc_get_client_path(handle, ctx, - pathname, - &clientPath))) - { + if ((status = alloc_get_client_smb_fname(handle, ctx, + smb_fname, + &clientFname))) { goto err; } - status = SMB_VFS_NEXT_MKNOD(handle, clientPath, mode, dev); + status = SMB_VFS_NEXT_MKNOD(handle, clientFname, mode, dev); err: - TALLOC_FREE(clientPath); + TALLOC_FREE(clientFname); out: return status; } diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 6777d7a8208..7d810e5351f 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -1656,24 +1656,33 @@ static int shadow_copy2_readlink(vfs_handle_struct *handle, } static int shadow_copy2_mknod(vfs_handle_struct *handle, - const char *fname, mode_t mode, SMB_DEV_T dev) + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { time_t timestamp = 0; char *stripped = NULL; int saved_errno = 0; int ret; - char *conv; + struct smb_filename *conv = NULL; - if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, + smb_fname->base_name, ×tamp, &stripped)) { return -1; } if (timestamp == 0) { - return SMB_VFS_NEXT_MKNOD(handle, fname, mode, dev); + return SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev); } - conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp); - TALLOC_FREE(stripped); + conv = cp_smb_filename(talloc_tos(), smb_fname); if (conv == NULL) { + errno = ENOMEM; + return -1; + } + conv->base_name = shadow_copy2_convert( + conv, handle, stripped, timestamp); + TALLOC_FREE(stripped); + if (conv->base_name == NULL) { return -1; } ret = SMB_VFS_NEXT_MKNOD(handle, conv, mode, dev); diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c index 69e2ab90a62..3ddc77bd78c 100644 --- a/source3/modules/vfs_snapper.c +++ b/source3/modules/vfs_snapper.c @@ -2417,29 +2417,42 @@ static int snapper_gmt_readlink(vfs_handle_struct *handle, } static int snapper_gmt_mknod(vfs_handle_struct *handle, - const char *fname, mode_t mode, SMB_DEV_T dev) + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { - time_t timestamp; - char *stripped; - int ret, saved_errno; - char *conv; + time_t timestamp = (time_t)0; + char *stripped = NULL; + int ret, saved_errno = 0; + struct smb_filename *conv = NULL; - if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname, + if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, + smb_fname->base_name, ×tamp, &stripped)) { return -1; } if (timestamp == 0) { - return SMB_VFS_NEXT_MKNOD(handle, fname, mode, dev); + return SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev); } - conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp); - TALLOC_FREE(stripped); + conv = cp_smb_filename(talloc_tos(), smb_fname); if (conv == NULL) { + errno = ENOMEM; + return -1; + } + conv->base_name = snapper_gmt_convert(conv, handle, + stripped, timestamp); + TALLOC_FREE(stripped); + if (conv->base_name == NULL) { return -1; } ret = SMB_VFS_NEXT_MKNOD(handle, conv, mode, dev); - saved_errno = errno; + if (ret == -1) { + saved_errno = errno; + } TALLOC_FREE(conv); - errno = saved_errno; + if (saved_errno != 0) { + errno = saved_errno; + } return ret; } diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c index 381b80bf87e..8c20af3bd06 100644 --- a/source3/modules/vfs_syncops.c +++ b/source3/modules/vfs_syncops.c @@ -212,9 +212,12 @@ static int syncops_unlink(vfs_handle_struct *handle, } static int syncops_mknod(vfs_handle_struct *handle, - const char *fname, mode_t mode, SMB_DEV_T dev) + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { - SYNCOPS_NEXT(MKNOD, fname, (handle, fname, mode, dev)); + SYNCOPS_NEXT_SMB_FNAME(MKNOD, + smb_fname, (handle, smb_fname, mode, dev)); } static int syncops_mkdir(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 52bd00edb13..ebbad06e139 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1472,7 +1472,8 @@ static int smb_time_audit_link(vfs_handle_struct *handle, } static int smb_time_audit_mknod(vfs_handle_struct *handle, - const char *pathname, mode_t mode, + const struct smb_filename *smb_fname, + mode_t mode, SMB_DEV_T dev) { int result; @@ -1480,12 +1481,12 @@ static int smb_time_audit_mknod(vfs_handle_struct *handle, double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev); + result = SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; if (timediff > audit_timeout) { - smb_time_audit_log_fname("mknod", timediff, pathname); + smb_time_audit_log_smb_fname("mknod", timediff, smb_fname); } return result; diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c index ccafb882df7..4810fddbd5f 100644 --- a/source3/modules/vfs_unityed_media.c +++ b/source3/modules/vfs_unityed_media.c @@ -1412,28 +1412,28 @@ err: } static int um_mknod(vfs_handle_struct *handle, - const char *pathname, + const struct smb_filename *smb_fname, mode_t mode, SMB_DEV_T dev) { int status; - char *client_path = NULL; + struct smb_filename *client_fname = NULL; DEBUG(10, ("Entering um_mknod\n")); - if (!is_in_media_files(pathname)) { - return SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev); + if (!is_in_media_files(smb_fname->base_name)) { + return SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev); } - status = alloc_get_client_path(handle, talloc_tos(), - pathname, &client_path); + status = alloc_get_client_smb_fname(handle, talloc_tos(), + smb_fname, &client_fname); if (status != 0) { goto err; } - status = SMB_VFS_NEXT_MKNOD(handle, client_path, mode, dev); + status = SMB_VFS_NEXT_MKNOD(handle, client_fname, mode, dev); err: - TALLOC_FREE(client_path); + TALLOC_FREE(client_fname); return status; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 5155abb0095..51e5804c26e 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7576,7 +7576,7 @@ static NTSTATUS smb_unix_mknod(connection_struct *conn, (unsigned int)unixmode, smb_fname_str_dbg(smb_fname))); /* Ok - do the mknod. */ - if (SMB_VFS_MKNOD(conn, smb_fname->base_name, unixmode, dev) != 0) { + if (SMB_VFS_MKNOD(conn, smb_fname, unixmode, dev) != 0) { return map_nt_error_from_unix(errno); } diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 560c4b217a4..db5c2a5f0ae 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2167,11 +2167,13 @@ int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath, return handle->fns->link_fn(handle, oldpath, newpath); } -int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path, - mode_t mode, SMB_DEV_T dev) +int smb_vfs_call_mknod(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode, + SMB_DEV_T dev) { VFS_FIND(mknod); - return handle->fns->mknod_fn(handle, path, mode, dev); + return handle->fns->mknod_fn(handle, smb_fname, mode, dev); } char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path) diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index b57a061ee4c..0fac3528cce 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -1260,6 +1260,7 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, mode_t mode; unsigned int dev_val; SMB_DEV_T dev; + struct smb_filename *smb_fname = NULL; if (argc != 4) { printf("Usage: mknod \n"); @@ -1279,7 +1280,13 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, } dev = (SMB_DEV_T)dev_val; - if (SMB_VFS_MKNOD(vfs->conn, argv[1], mode, dev) == -1) { + smb_fname = synthetic_smb_fname_split(mem_ctx, + argv[1], + lp_posix_pathnames()); + if (smb_fname == NULL) { + return NT_STATUS_NO_MEMORY; + } + if (SMB_VFS_MKNOD(vfs->conn, smb_fname, mode, dev) == -1) { printf("mknod: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } -- 2.13.0.303.g4ebf302169-goog