From b78b7b9e6b5c4f1cdb128347d14df67dea2bf4f1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 23 Feb 2016 13:14:03 -0800 Subject: [PATCH] s3: VFS: Modify mkdir to take a const struct smb_filename * instead of const char * Preparing to reduce use of lp_posix_pathnames(). Uses the same techniques as commit 616d068f0cebb8e50a855b6e30f36fccb7f5a3c8 (synthetic_smb_fname()) to cope with modules that modify the incoming pathname. Signed-off-by: Jeremy Allison --- examples/VFS/skel_opaque.c | 4 +++- examples/VFS/skel_transparent.c | 6 ++++-- source3/include/vfs.h | 11 ++++++++--- source3/include/vfs_macros.h | 8 ++++---- source3/modules/vfs_audit.c | 8 +++++--- source3/modules/vfs_cap.c | 20 ++++++++++++++++--- source3/modules/vfs_catia.c | 21 ++++++++++++++++---- source3/modules/vfs_default.c | 5 ++++- source3/modules/vfs_extd_audit.c | 10 ++++++---- source3/modules/vfs_full_audit.c | 7 ++++--- source3/modules/vfs_linux_xfs_sgid.c | 26 +++++++++++++++--------- source3/modules/vfs_media_harmony.c | 25 +++++++++++------------- source3/modules/vfs_recycle.c | 15 +++++++++++++- source3/modules/vfs_shadow_copy2.c | 24 ++++++++++++++++++----- source3/modules/vfs_snapper.c | 20 +++++++++++++++---- source3/modules/vfs_streams_depot.c | 38 ++++++++++++++++++++++++++++++++---- source3/modules/vfs_syncops.c | 6 ++++-- source3/modules/vfs_time_audit.c | 9 ++++++--- source3/modules/vfs_unityed_media.c | 24 +++++++++++------------ source3/smbd/open.c | 2 +- source3/smbd/vfs.c | 7 ++++--- source3/torture/cmd_vfs.c | 13 +++++++++++- 22 files changed, 221 insertions(+), 88 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 0d5571c..9a855bc 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -157,7 +157,9 @@ static void skel_rewind_dir(vfs_handle_struct *handle, DIR *dirp) ; } -static int skel_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +static int skel_mkdir(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode) { errno = ENOSYS; return -1; diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index fc3c818..ac8cbc8 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -157,9 +157,11 @@ static void skel_rewind_dir(vfs_handle_struct *handle, DIR *dirp) SMB_VFS_NEXT_REWINDDIR(handle, dirp); } -static int skel_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +static int skel_mkdir(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode) { - return SMB_VFS_NEXT_MKDIR(handle, path, mode); + return SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); } static int skel_rmdir(vfs_handle_struct *handle, const char *path) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index d416a5b..48bacb0 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -173,6 +173,8 @@ /* Bump to version 35 - Samba 4.5 will ship with that */ /* Version 35 - Change get_nt_acl_fn from const char *, to const struct smb_filename * */ +/* Version 35 - Change mkdir from const char *, to + const struct smb_filename * */ #define SMB_VFS_INTERFACE_VERSION 35 @@ -554,7 +556,9 @@ struct vfs_fn_pointers { void (*seekdir_fn)(struct vfs_handle_struct *handle, DIR *dirp, long offset); long (*telldir_fn)(struct vfs_handle_struct *handle, DIR *dirp); void (*rewind_dir_fn)(struct vfs_handle_struct *handle, DIR *dirp); - int (*mkdir_fn)(struct vfs_handle_struct *handle, const char *path, mode_t mode); + int (*mkdir_fn)(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode); int (*rmdir_fn)(struct vfs_handle_struct *handle, const char *path); int (*closedir_fn)(struct vfs_handle_struct *handle, DIR *dir); void (*init_search_op_fn)(struct vfs_handle_struct *handle, DIR *dirp); @@ -971,8 +975,9 @@ long smb_vfs_call_telldir(struct vfs_handle_struct *handle, DIR *dirp); void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle, DIR *dirp); -int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path, - mode_t mode); +int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode); int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path); int smb_vfs_call_closedir(struct vfs_handle_struct *handle, DIR *dir); diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index cef3849..758938a 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -109,10 +109,10 @@ #define SMB_VFS_NEXT_REWINDDIR(handle, dirp) \ smb_vfs_call_rewind_dir((handle)->next, (dirp)) -#define SMB_VFS_MKDIR(conn, path, mode) \ - smb_vfs_call_mkdir((conn)->vfs_handles,(path), (mode)) -#define SMB_VFS_NEXT_MKDIR(handle, path, mode) \ - smb_vfs_call_mkdir((handle)->next,(path), (mode)) +#define SMB_VFS_MKDIR(conn, smb_fname, mode) \ + smb_vfs_call_mkdir((conn)->vfs_handles,(smb_fname), (mode)) +#define SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode) \ + smb_vfs_call_mkdir((handle)->next,(smb_fname), (mode)) #define SMB_VFS_RMDIR(conn, path) \ smb_vfs_call_rmdir((conn)->vfs_handles, (path)) diff --git a/source3/modules/vfs_audit.c b/source3/modules/vfs_audit.c index 02e8f35..8905d1f 100644 --- a/source3/modules/vfs_audit.c +++ b/source3/modules/vfs_audit.c @@ -120,14 +120,16 @@ static DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const ch return result; } -static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +static int audit_mkdir(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode) { int result; - result = SMB_VFS_NEXT_MKDIR(handle, path, mode); + result = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n", - path, + smb_fname->base_name, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 65b0b25..b09a443 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -97,15 +97,29 @@ static struct dirent *cap_readdir(vfs_handle_struct *handle, return newdirent; } -static int cap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +static int cap_mkdir(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode) { - char *cappath = capencode(talloc_tos(), path); + char *cappath = capencode(talloc_tos(), smb_fname->base_name); + struct smb_filename *cap_smb_fname = NULL; if (!cappath) { errno = ENOMEM; return -1; } - return SMB_VFS_NEXT_MKDIR(handle, cappath, mode); + + cap_smb_fname = synthetic_smb_fname(talloc_tos(), + cappath, + NULL, + NULL); + if (cap_smb_fname == NULL) { + TALLOC_FREE(cappath); + errno = ENOMEM; + return -1; + } + + return SMB_VFS_NEXT_MKDIR(handle, cap_smb_fname, mode); } static int cap_rmdir(vfs_handle_struct *handle, const char *path) diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index 48e2e3f..524d987 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -590,22 +590,35 @@ static int catia_rmdir(vfs_handle_struct *handle, } static int catia_mkdir(vfs_handle_struct *handle, - const char *path, + const struct smb_filename *smb_fname, mode_t mode) { char *name = NULL; NTSTATUS status; int ret; + struct smb_filename *catia_smb_fname = NULL; - status = catia_string_replace_allocate(handle->conn, path, - &name, vfs_translate_to_unix); + status = catia_string_replace_allocate(handle->conn, + smb_fname->base_name, + &name, + vfs_translate_to_unix); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); return -1; } + catia_smb_fname = synthetic_smb_fname(talloc_tos(), + name, + NULL, + NULL); + if (catia_smb_fname == NULL) { + TALLOC_FREE(name); + errno = ENOMEM; + return -1; + } - ret = SMB_VFS_NEXT_MKDIR(handle, name, mode); + ret = SMB_VFS_NEXT_MKDIR(handle, catia_smb_fname, mode); TALLOC_FREE(name); + TALLOC_FREE(catia_smb_fname); return ret; } diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 43e65ac..28f0257 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -465,10 +465,13 @@ static void vfswrap_rewinddir(vfs_handle_struct *handle, DIR *dirp) END_PROFILE(syscall_rewinddir); } -static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +static int vfswrap_mkdir(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode) { int result; bool has_dacl = False; + const char *path = smb_fname->base_name; char *parent = NULL; START_PROFILE(syscall_mkdir); diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c index 7d6b4d3..7b7c2af 100644 --- a/source3/modules/vfs_extd_audit.c +++ b/source3/modules/vfs_extd_audit.c @@ -136,20 +136,22 @@ static DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const ch return result; } -static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +static int audit_mkdir(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode) { int result; - result = SMB_VFS_NEXT_MKDIR(handle, path, mode); + result = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); if (lp_syslog() > 0) { syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n", - path, + smb_fname->base_name, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); } DEBUG(0, ("vfs_extd_audit: mkdir %s %s %s\n", - path, + smb_fname->base_name, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 9c77185..6dd6140 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -844,13 +844,14 @@ static void smb_full_audit_rewinddir(vfs_handle_struct *handle, } static int smb_full_audit_mkdir(vfs_handle_struct *handle, - const char *path, mode_t mode) + const struct smb_filename *smb_fname, mode_t mode) { int result; - result = SMB_VFS_NEXT_MKDIR(handle, path, mode); + result = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); - do_log(SMB_VFS_OP_MKDIR, (result >= 0), handle, "%s", path); + do_log(SMB_VFS_OP_MKDIR, (result >= 0), handle, "%s", + smb_fname->base_name); return result; } diff --git a/source3/modules/vfs_linux_xfs_sgid.c b/source3/modules/vfs_linux_xfs_sgid.c index 5a33f63..5c8fab8 100644 --- a/source3/modules/vfs_linux_xfs_sgid.c +++ b/source3/modules/vfs_linux_xfs_sgid.c @@ -22,22 +22,27 @@ #include "system/filesys.h" #include "smbd/smbd.h" -static int linux_xfs_sgid_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode) +static int linux_xfs_sgid_mkdir(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode) { struct smb_filename fname = { 0, }; int mkdir_res; int res; - DEBUG(10, ("Calling linux_xfs_sgid_mkdir(%s)\n", path)); + DEBUG(10, ("Calling linux_xfs_sgid_mkdir(%s)\n", smb_fname->base_name)); - mkdir_res = SMB_VFS_NEXT_MKDIR(handle, path, mode); + mkdir_res = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); if (mkdir_res == -1) { DEBUG(10, ("SMB_VFS_NEXT_MKDIR returned error: %s\n", strerror(errno))); return mkdir_res; } - if (!parent_dirname(talloc_tos(), path, &fname.base_name, NULL)) { + if (!parent_dirname(talloc_tos(), + smb_fname->base_name, + &fname.base_name, + NULL)) { DEBUG(1, ("parent_dirname failed\n")); /* return success, we did the mkdir */ return mkdir_res; @@ -57,12 +62,13 @@ static int linux_xfs_sgid_mkdir(vfs_handle_struct *handle, const char *path, mo return mkdir_res; } - fname.base_name = discard_const_p(char, path); + fname.base_name = discard_const_p(char, smb_fname->base_name); res = SMB_VFS_NEXT_STAT(handle, &fname); if (res == -1) { - DEBUG(2, ("Could not stat just created dir %s: %s\n", path, - strerror(errno))); + DEBUG(2, ("Could not stat just created dir %s: %s\n", + smb_fname->base_name, + strerror(errno))); /* return success, we did the mkdir */ return mkdir_res; } @@ -75,11 +81,13 @@ static int linux_xfs_sgid_mkdir(vfs_handle_struct *handle, const char *path, mo * return success. What can you do... */ become_root(); - res = SMB_VFS_NEXT_CHMOD(handle, path, fname.st.st_ex_mode); + res = SMB_VFS_NEXT_CHMOD(handle, + smb_fname->base_name, + fname.st.st_ex_mode); unbecome_root(); if (res == -1) { - DEBUG(2, ("CHMOD(%s, %o) failed: %s\n", path, + DEBUG(2, ("CHMOD(%s, %o) failed: %s\n", smb_fname->base_name, (int)fname.st.st_ex_mode, strerror(errno))); /* return success, we did the mkdir */ return mkdir_res; diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c index 65673e1..594db83 100644 --- a/source3/modules/vfs_media_harmony.c +++ b/source3/modules/vfs_media_harmony.c @@ -1033,35 +1033,32 @@ static void mh_rewinddir(vfs_handle_struct *handle, * Failure: set errno, return -1 */ static int mh_mkdir(vfs_handle_struct *handle, - const char *path, + const struct smb_filename *smb_fname, mode_t mode) { int status; - char *clientPath; - TALLOC_CTX *ctx; - + struct smb_filename *clientFname = NULL; + const char *path = smb_fname->base_name; DEBUG(MH_INFO_DEBUG, ("Entering with path '%s'\n", path)); if (!is_in_media_files(path)) { - status = SMB_VFS_NEXT_MKDIR(handle, path, mode); + status = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); 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_MKDIR(handle, clientPath, mode); + status = SMB_VFS_NEXT_MKDIR(handle, clientFname, mode); err: - TALLOC_FREE(clientPath); + TALLOC_FREE(clientFname); out: DEBUG(MH_INFO_DEBUG, ("Leaving with path '%s'\n", path)); return status; diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index 9af78fd..4981f55 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -292,12 +292,25 @@ static bool recycle_create_dir(vfs_handle_struct *handle, const char *dname) if (recycle_directory_exist(handle, new_dir)) DEBUG(10, ("recycle: dir %s already exists\n", new_dir)); else { + struct smb_filename *smb_fname = NULL; + DEBUG(5, ("recycle: creating new dir %s\n", new_dir)); - if (SMB_VFS_NEXT_MKDIR(handle, new_dir, mode) != 0) { + + smb_fname = synthetic_smb_fname(talloc_tos(), + new_dir, + NULL, + NULL); + if (smb_fname == NULL) { + goto done; + } + + if (SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode) != 0) { DEBUG(1,("recycle: mkdir failed for %s with error: %s\n", new_dir, strerror(errno))); + TALLOC_FREE(smb_fname); ret = False; goto done; } + TALLOC_FREE(smb_fname); } if (strlcat(new_dir, "/", len+1) >= len+1) { goto done; diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 87b4cd2..6d59339 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -1543,28 +1543,42 @@ static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle, } static int shadow_copy2_mkdir(vfs_handle_struct *handle, - const char *fname, mode_t mode) + const struct smb_filename *smb_fname, + mode_t mode) { time_t timestamp; char *stripped; int ret, saved_errno; 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_MKDIR(handle, fname, mode); + return SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); } conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp); TALLOC_FREE(stripped); if (conv == NULL) { return -1; } - ret = SMB_VFS_NEXT_MKDIR(handle, conv, mode); + conv_smb_fname = synthetic_smb_fname(talloc_tos(), + conv, + NULL, + NULL); + if (conv_smb_fname == NULL) { + TALLOC_FREE(conv); + return -1; + } + ret = SMB_VFS_NEXT_MKDIR(handle, conv_smb_fname, mode); saved_errno = errno; TALLOC_FREE(conv); + TALLOC_FREE(conv_smb_fname); errno = saved_errno; return ret; } diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c index 970373c..7161b80 100644 --- a/source3/modules/vfs_snapper.c +++ b/source3/modules/vfs_snapper.c @@ -2489,14 +2489,16 @@ static NTSTATUS snapper_gmt_get_nt_acl(vfs_handle_struct *handle, } static int snapper_gmt_mkdir(vfs_handle_struct *handle, - const char *fname, mode_t mode) + const struct smb_filename *fname, + mode_t mode) { time_t timestamp; char *stripped; int ret, saved_errno; char *conv; + struct smb_filename *smb_fname = NULL; - if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname, + if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname->base_name, ×tamp, &stripped)) { return -1; } @@ -2508,9 +2510,19 @@ static int snapper_gmt_mkdir(vfs_handle_struct *handle, if (conv == NULL) { return -1; } - ret = SMB_VFS_NEXT_MKDIR(handle, conv, mode); - saved_errno = errno; + smb_fname = synthetic_smb_fname(talloc_tos(), + conv, + NULL, + NULL); TALLOC_FREE(conv); + if (smb_fname == NULL) { + errno = ENOMEM; + return -1; + } + + ret = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); + saved_errno = errno; + TALLOC_FREE(smb_fname); errno = saved_errno; return ret; } diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index 5964852..38c76c1 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -124,6 +124,8 @@ static char *stream_dir(vfs_handle_struct *handle, uint8_t id_buf[16]; bool check_valid; const char *rootdir; + struct smb_filename *rootdir_fname = NULL; + struct smb_filename *tmp_fname = NULL; check_valid = lp_parm_bool(SNUM(handle->conn), "streams_depot", "check_valid", true); @@ -139,6 +141,15 @@ static char *stream_dir(vfs_handle_struct *handle, SNUM(handle->conn), "streams_depot", "directory", tmp); + rootdir_fname = synthetic_smb_fname(talloc_tos(), + rootdir, + NULL, + NULL); + if (rootdir_fname == NULL) { + errno = ENOMEM; + goto fail; + } + /* Stat the base file if it hasn't already been done. */ if (base_sbuf == NULL) { struct smb_filename *smb_fname_base; @@ -261,7 +272,7 @@ static char *stream_dir(vfs_handle_struct *handle, goto fail; } - if ((SMB_VFS_NEXT_MKDIR(handle, rootdir, 0755) != 0) + if ((SMB_VFS_NEXT_MKDIR(handle, rootdir_fname, 0755) != 0) && (errno != EEXIST)) { goto fail; } @@ -272,12 +283,19 @@ static char *stream_dir(vfs_handle_struct *handle, goto fail; } - if ((SMB_VFS_NEXT_MKDIR(handle, tmp, 0755) != 0) + tmp_fname = synthetic_smb_fname(talloc_tos(), tmp, NULL, NULL); + if (tmp_fname == NULL) { + errno = ENOMEM; + goto fail; + } + + if ((SMB_VFS_NEXT_MKDIR(handle, tmp_fname, 0755) != 0) && (errno != EEXIST)) { goto fail; } TALLOC_FREE(tmp); + TALLOC_FREE(tmp_fname); tmp = talloc_asprintf(result, "%s/%2.2X/%2.2X", rootdir, first, second); @@ -286,14 +304,22 @@ static char *stream_dir(vfs_handle_struct *handle, goto fail; } - if ((SMB_VFS_NEXT_MKDIR(handle, tmp, 0755) != 0) + tmp_fname = synthetic_smb_fname(talloc_tos(), tmp, NULL, NULL); + if (tmp_fname == NULL) { + errno = ENOMEM; + goto fail; + } + + if ((SMB_VFS_NEXT_MKDIR(handle, tmp_fname, 0755) != 0) && (errno != EEXIST)) { goto fail; } TALLOC_FREE(tmp); + TALLOC_FREE(tmp_fname); - if ((SMB_VFS_NEXT_MKDIR(handle, result, 0755) != 0) + /* smb_fname_hash is the struct smb_filename version of 'result' */ + if ((SMB_VFS_NEXT_MKDIR(handle, smb_fname_hash, 0755) != 0) && (errno != EEXIST)) { goto fail; } @@ -302,10 +328,14 @@ static char *stream_dir(vfs_handle_struct *handle, goto fail; } + TALLOC_FREE(rootdir_fname); + TALLOC_FREE(tmp_fname); TALLOC_FREE(smb_fname_hash); return result; fail: + TALLOC_FREE(rootdir_fname); + TALLOC_FREE(tmp_fname); TALLOC_FREE(smb_fname_hash); TALLOC_FREE(result); return NULL; diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c index 99f6178..e533a55 100644 --- a/source3/modules/vfs_syncops.c +++ b/source3/modules/vfs_syncops.c @@ -217,9 +217,11 @@ static int syncops_mknod(vfs_handle_struct *handle, SYNCOPS_NEXT(MKNOD, fname, (handle, fname, mode, dev)); } -static int syncops_mkdir(vfs_handle_struct *handle, const char *fname, mode_t mode) +static int syncops_mkdir(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode) { - SYNCOPS_NEXT(MKDIR, fname, (handle, fname, mode)); + SYNCOPS_NEXT_SMB_FNAME(MKDIR, smb_fname, (handle, smb_fname, mode)); } static int syncops_rmdir(vfs_handle_struct *handle, const char *fname) diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 6e0c8a4..8516c98 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -460,19 +460,22 @@ static void smb_time_audit_rewinddir(vfs_handle_struct *handle, } static int smb_time_audit_mkdir(vfs_handle_struct *handle, - const char *path, mode_t mode) + const struct smb_filename *smb_fname, + mode_t mode) { int result; struct timespec ts1,ts2; double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_MKDIR(handle, path, mode); + result = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; if (timediff > audit_timeout) { - smb_time_audit_log_fname("mkdir", timediff, path); + smb_time_audit_log_smb_fname("mkdir", + timediff, + smb_fname); } return result; diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c index f53a13b..8437e3a 100644 --- a/source3/modules/vfs_unityed_media.c +++ b/source3/modules/vfs_unityed_media.c @@ -766,32 +766,30 @@ static void um_rewinddir(vfs_handle_struct *handle, } static int um_mkdir(vfs_handle_struct *handle, - const char *path, + const struct smb_filename *smb_fname, mode_t mode) { int status; - char *clientPath; - TALLOC_CTX *ctx; - + const char *path = smb_fname->base_name; + struct smb_filename *client_fname = NULL; DEBUG(10, ("Entering with path '%s'\n", path)); if (!is_in_media_files(path) || !is_in_media_dir(path)) { - return SMB_VFS_NEXT_MKDIR(handle, path, mode); + return SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode); } - 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, + &client_fname); + if (status != 0) { goto err; } - status = SMB_VFS_NEXT_MKDIR(handle, clientPath, mode); + status = SMB_VFS_NEXT_MKDIR(handle, client_fname, mode); err: - TALLOC_FREE(clientPath); + TALLOC_FREE(client_fname); DEBUG(10, ("Leaving with path '%s'\n", path)); return status; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 449a76f..3d0349e 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3302,7 +3302,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn, return status; } - if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) { + if (SMB_VFS_MKDIR(conn, smb_dname, mode) != 0) { return map_nt_error_from_unix(errno); } diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 57b833b..268c653 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -1497,11 +1497,12 @@ void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle, handle->fns->rewind_dir_fn(handle, dirp); } -int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path, - mode_t mode) +int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + mode_t mode) { VFS_FIND(mkdir); - return handle->fns->mkdir_fn(handle, path, mode); + return handle->fns->mkdir_fn(handle, smb_fname, mode); } int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path) diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 3a8b7f7..f9819da 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -200,12 +200,23 @@ static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc static NTSTATUS cmd_mkdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { + struct smb_filename *smb_fname = NULL; + if (argc != 2) { printf("Usage: mkdir \n"); return NT_STATUS_OK; } - if (SMB_VFS_MKDIR(vfs->conn, argv[1], 00755) == -1) { + smb_fname = synthetic_smb_fname(talloc_tos(), + argv[1], + NULL, + NULL); + + if (smb_fname == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (SMB_VFS_MKDIR(vfs->conn, smb_fname, 00755) == -1) { printf("mkdir error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } -- 2.7.0.rc3.207.g0ac5344