diff options
Diffstat (limited to 'source3/modules')
-rw-r--r-- | source3/modules/onefs_streams.c | 35 | ||||
-rw-r--r-- | source3/modules/vfs_acl_tdb.c | 27 | ||||
-rw-r--r-- | source3/modules/vfs_audit.c | 7 | ||||
-rw-r--r-- | source3/modules/vfs_cap.c | 25 | ||||
-rw-r--r-- | source3/modules/vfs_catia.c | 25 | ||||
-rw-r--r-- | source3/modules/vfs_default.c | 17 | ||||
-rw-r--r-- | source3/modules/vfs_extd_audit.c | 9 | ||||
-rw-r--r-- | source3/modules/vfs_full_audit.c | 7 | ||||
-rw-r--r-- | source3/modules/vfs_netatalk.c | 33 | ||||
-rw-r--r-- | source3/modules/vfs_onefs_shadow_copy.c | 41 | ||||
-rw-r--r-- | source3/modules/vfs_recycle.c | 197 | ||||
-rw-r--r-- | source3/modules/vfs_shadow_copy2.c | 14 | ||||
-rw-r--r-- | source3/modules/vfs_streams_depot.c | 70 | ||||
-rw-r--r-- | source3/modules/vfs_streams_xattr.c | 43 | ||||
-rw-r--r-- | source3/modules/vfs_syncops.c | 7 | ||||
-rw-r--r-- | source3/modules/vfs_xattr_tdb.c | 26 |
16 files changed, 370 insertions, 213 deletions
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 8963037c22..c22fc711a0 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -462,38 +462,49 @@ int onefs_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) return ret; } -int onefs_unlink(vfs_handle_struct *handle, const char *path) +int onefs_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { + struct smb_filename *smb_fname_onefs = NULL; int ret; bool is_stream; char *base = NULL; char *stream = NULL; int dir_fd, saved_errno; - ret = onefs_is_stream(path, &base, &stream, &is_stream); - if (ret) { - return ret; + /* Not a stream. */ + if (!is_ntfs_stream_smb_fname(smb_fname)) { + return SMB_VFS_NEXT_UNLINK(handle, smb_fname); } - if (!is_stream) { - return SMB_VFS_NEXT_UNLINK(handle, path); + status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname, + &smb_fname_onefs); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; } - /* If it's the ::$DATA stream just unlink the base file name. */ - if (!stream) { - return SMB_VFS_NEXT_UNLINK(handle, base); + /* Default stream (the ::$DATA was just stripped off). */ + if (!is_ntfs_stream_smb_fname(smb_fname_onefs)) { + ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_onefs); + goto out; } - dir_fd = get_stream_dir_fd(handle->conn, base, NULL); + dir_fd = get_stream_dir_fd(handle->conn, smb_fname_onefs->base_name, + NULL); if (dir_fd < 0) { - return -1; + ret = -1; + goto out; } - ret = enc_unlinkat(dir_fd, stream, ENC_DEFAULT, 0); + ret = enc_unlinkat(dir_fd, smb_fname_onefs->stream_name, ENC_DEFAULT, + 0); saved_errno = errno; close(dir_fd); errno = saved_errno; + out: + TALLOC_FREE(smb_fname_onefs); return ret; } diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 9f0b0b317a..64ad3e1a78 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -616,32 +616,41 @@ static int open_acl_tdb(vfs_handle_struct *handle, On unlink we need to delete the tdb record (if using tdb). *********************************************************************/ -static int unlink_acl_tdb(vfs_handle_struct *handle, const char *path) +static int unlink_acl_tdb(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { - SMB_STRUCT_STAT sbuf; + struct smb_filename *smb_fname_tmp = NULL; struct db_context *db; + NTSTATUS status; int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + goto out; + } + if (lp_posix_pathnames()) { - ret = vfs_lstat_smb_fname(handle->conn, path, &sbuf); + ret = SMB_VFS_LSTAT(handle->conn, smb_fname_tmp); } else { - ret = vfs_stat_smb_fname(handle->conn, path, &sbuf); + ret = SMB_VFS_STAT(handle->conn, smb_fname_tmp); } if (ret == -1) { - return -1; + goto out; } - ret = SMB_VFS_NEXT_UNLINK(handle, path); + ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp); if (ret == -1) { - return -1; + goto out; } - acl_tdb_delete(handle, db, &sbuf); - return 0; + acl_tdb_delete(handle, db, &smb_fname_tmp->st); + out: + return ret; } /********************************************************************* diff --git a/source3/modules/vfs_audit.c b/source3/modules/vfs_audit.c index 809ecc9e44..8c0141906b 100644 --- a/source3/modules/vfs_audit.c +++ b/source3/modules/vfs_audit.c @@ -187,14 +187,15 @@ static int audit_rename(vfs_handle_struct *handle, return result; } -static int audit_unlink(vfs_handle_struct *handle, const char *path) +static int audit_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { int result; - result = SMB_VFS_NEXT_UNLINK(handle, path); + result = SMB_VFS_NEXT_UNLINK(handle, smb_fname); syslog(audit_syslog_priority(handle), "unlink %s %s%s\n", - path, + smb_fname_str_dbg(smb_fname), (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 4d16aa44ae..9348ab9554 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -226,15 +226,34 @@ static int cap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname) return ret; } -static int cap_unlink(vfs_handle_struct *handle, const char *path) +static int cap_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { - char *cappath = capencode(talloc_tos(), path); + struct smb_filename *smb_fname_tmp = NULL; + char *cappath = NULL; + NTSTATUS status; + int ret; + cappath = capencode(talloc_tos(), smb_fname->base_name); if (!cappath) { errno = ENOMEM; return -1; } - return SMB_VFS_NEXT_UNLINK(handle, cappath); + + /* Setup temporary smb_filename structs. */ + status = copy_smb_filename(talloc_tos(), smb_fname, + &smb_fname_tmp); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + smb_fname_tmp->base_name = cappath; + + ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp); + + TALLOC_FREE(smb_fname_tmp); + return ret; } static int cap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index b5283d25c2..18db92dbb7 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -258,15 +258,34 @@ static int catia_lstat(vfs_handle_struct *handle, return ret; } -static int catia_unlink(vfs_handle_struct *handle, const char *path) +static int catia_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { - char *name = to_unix(talloc_tos(), path); + struct smb_filename *smb_fname_tmp = NULL; + char *name = NULL; + NTSTATUS status; + int ret; + name = to_unix(talloc_tos(), smb_fname->base_name); if (!name) { errno = ENOMEM; return -1; } - return SMB_VFS_NEXT_UNLINK(handle, name); + + /* Setup temporary smb_filename structs. */ + status = copy_smb_filename(talloc_tos(), smb_fname, + &smb_fname_tmp); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + smb_fname_tmp->base_name = name; + + ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp); + + TALLOC_FREE(smb_fname_tmp); + return ret; } static int catia_chmod(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 9a55456b0c..c95c68fe0f 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -524,13 +524,12 @@ static int vfswrap_rename(vfs_handle_struct *handle, const struct smb_filename *smb_fname_src, const struct smb_filename *smb_fname_dst) { - int result; + int result = -1; START_PROFILE(syscall_rename); if (smb_fname_src->stream_name || smb_fname_dst->stream_name) { errno = ENOENT; - result = -1; goto out; } @@ -651,12 +650,20 @@ static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle, return result; } -static int vfswrap_unlink(vfs_handle_struct *handle, const char *path) +static int vfswrap_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { - int result; + int result = -1; START_PROFILE(syscall_unlink); - result = unlink(path); + + if (smb_fname->stream_name) { + errno = ENOENT; + goto out; + } + result = unlink(smb_fname->base_name); + + out: END_PROFILE(syscall_unlink); return result; } diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c index f442c05c29..68b85516ea 100644 --- a/source3/modules/vfs_extd_audit.c +++ b/source3/modules/vfs_extd_audit.c @@ -235,20 +235,21 @@ static int audit_rename(vfs_handle_struct *handle, return result; } -static int audit_unlink(vfs_handle_struct *handle, const char *path) +static int audit_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { int result; - result = SMB_VFS_NEXT_UNLINK(handle, path); + result = SMB_VFS_NEXT_UNLINK(handle, smb_fname); if (lp_syslog() > 0) { syslog(audit_syslog_priority(handle), "unlink %s %s%s\n", - path, + smb_fname->base_name, (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : ""); } DEBUG(0, ("vfs_extd_audit: unlink %s %s %s\n", - path, + smb_fname_str_dbg(smb_fname), (result < 0) ? "failed: " : "", (result < 0) ? strerror(errno) : "")); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index e20a65092d..1f5e8333b9 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -910,13 +910,14 @@ static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle, } static int smb_full_audit_unlink(vfs_handle_struct *handle, - const char *path) + const struct smb_filename *smb_fname) { int result; - result = SMB_VFS_NEXT_UNLINK(handle, path); + result = SMB_VFS_NEXT_UNLINK(handle, smb_fname); - do_log(SMB_VFS_OP_UNLINK, (result >= 0), handle, "%s", path); + do_log(SMB_VFS_OP_UNLINK, (result >= 0), handle, "%s", + smb_fname_str_do_log(smb_fname)); return result; } diff --git a/source3/modules/vfs_netatalk.c b/source3/modules/vfs_netatalk.c index 0e20beca41..7710772174 100644 --- a/source3/modules/vfs_netatalk.c +++ b/source3/modules/vfs_netatalk.c @@ -254,24 +254,29 @@ static int atalk_rename(struct vfs_handle_struct *handle, atalk_unlink_file(adbl_path); exit_rename: + TALLOC_FREE(oldname); TALLOC_FREE(adbl_path); TALLOC_FREE(orig_path); - TALLOC_FREE(orig_path); return ret; } -static int atalk_unlink(struct vfs_handle_struct *handle, const char *path) +static int atalk_unlink(struct vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { int ret = 0, i; - char *adbl_path = 0; - char *orig_path = 0; + char *path = NULL; + char *adbl_path = NULL; + char *orig_path = NULL; SMB_STRUCT_STAT adbl_info; SMB_STRUCT_STAT orig_info; - TALLOC_CTX *ctx; + NTSTATUS status; - ret = SMB_VFS_NEXT_UNLINK(handle, path); + ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname); - if (!path) return ret; + status = get_full_smb_filename(talloc_tos(), smb_fname, &path); + if (!NT_STATUS_IS_OK(status)) { + return ret; + } /* no .AppleDouble sync if veto or hide list is empty, * otherwise "Cannot find the specified file" error will be caused @@ -292,15 +297,13 @@ static int atalk_unlink(struct vfs_handle_struct *handle, const char *path) else { DEBUG(3, ("ATALK: %s is not hidden, skipped..\n", APPLEDOUBLE)); - return ret; + goto exit_unlink; } } } - if (!(ctx = talloc_init("unlink_file"))) - return ret; - - if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path, + if (atalk_build_paths(talloc_tos(), handle->conn->origpath, path, + &adbl_path, &orig_path, &adbl_info, &orig_info) != 0) goto exit_unlink; @@ -311,8 +314,10 @@ static int atalk_unlink(struct vfs_handle_struct *handle, const char *path) atalk_unlink_file(adbl_path); -exit_unlink: - talloc_destroy(ctx); +exit_unlink: + TALLOC_FREE(path); + TALLOC_FREE(adbl_path); + TALLOC_FREE(orig_path); return ret; } diff --git a/source3/modules/vfs_onefs_shadow_copy.c b/source3/modules/vfs_onefs_shadow_copy.c index 04460d6056..1a43e0671a 100644 --- a/source3/modules/vfs_onefs_shadow_copy.c +++ b/source3/modules/vfs_onefs_shadow_copy.c @@ -143,9 +143,6 @@ onefs_shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, return ret; \ } while (0) \ -/* - * XXX: Convert osc_canonicalize_path to use talloc instead of malloc. - */ #define SHADOW_NEXT_SMB_FNAME(op, args, rtype) do { \ char *smb_base_name_tmp = NULL; \ char *cpath = NULL; \ @@ -165,6 +162,35 @@ onefs_shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, } while (0) \ +/* + * XXX: Convert osc_canonicalize_path to use talloc instead of malloc. + */ +#define SHADOW_NEXT_SMB_FNAME_CONST(op, args, rtype) do { \ + struct smb_filename *smb_fname_tmp = NULL; \ + char *cpath = NULL; \ + char *snap_component = NULL; \ + rtype ret; \ + if (shadow_copy_match_name(smb_fname->base_name, \ + &snap_component)) { \ + cpath = osc_canonicalize_path(smb_fname->base_name, \ + snap_component); \ + smb_fname->base_name = cpath; \ + } \ + status = create_synthetic_smb_fname(talloc_tos(), \ + cpath ?: smb_fname->base_name, \ + smb_fname->stream_name, &smb_fname->st, \ + &smb_fname_tmp); \ + if (!NT_STATUS_IS_OK(status)) { \ + errno = map_errno_from_nt_status(status); \ + return ret; \ + } \ + ret = SMB_VFS_NEXT_ ## op args; \ + TALLOC_FREE(smb_fname_tmp) \ + SAFE_FREE(cpath); \ + return ret; \ + } while (0) \ + + static uint64_t onefs_shadow_copy_disk_free(vfs_handle_struct *handle, const char *path, @@ -324,11 +350,12 @@ onefs_shadow_copy_lstat(vfs_handle_struct *handle, } static int -onefs_shadow_copy_unlink(vfs_handle_struct *handle, const char *path) +onefs_shadow_copy_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { - SHADOW_NEXT(UNLINK, - (handle, cpath ?: path), - int); + SHADOW_NEXT_SMB_FNAME_CONST(UNLINK, + (handle, smb_fname_tmp), + int); } static int diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c index 3fbe8d7e55..24166d1266 100644 --- a/source3/modules/vfs_recycle.c +++ b/source3/modules/vfs_recycle.c @@ -33,7 +33,8 @@ static int vfs_recycle_debug_level = DBGC_VFS; static int recycle_connect(vfs_handle_struct *handle, const char *service, const char *user); static void recycle_disconnect(vfs_handle_struct *handle); -static int recycle_unlink(vfs_handle_struct *handle, const char *name); +static int recycle_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname); static vfs_op_tuple recycle_ops[] = { @@ -223,17 +224,26 @@ static bool recycle_directory_exist(vfs_handle_struct *handle, const char *dname return False; } -static bool recycle_file_exist(vfs_handle_struct *handle, const char *fname) +static bool recycle_file_exist(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { - SMB_STRUCT_STAT st; + struct smb_filename *smb_fname_tmp = NULL; + NTSTATUS status; + bool ret = false; - if (vfs_stat_smb_fname(handle->conn, fname, &st) == 0) { - if (S_ISREG(st.st_ex_mode)) { - return True; + status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp); + if (!NT_STATUS_IS_OK(status)) { + return false; + } + + if (SMB_VFS_STAT(handle->conn, smb_fname_tmp) == 0) { + if (S_ISREG(smb_fname_tmp->st.st_ex_mode)) { + ret = true; } } - return False; + TALLOC_FREE(smb_fname_tmp); + return ret; } /** @@ -242,16 +252,30 @@ static bool recycle_file_exist(vfs_handle_struct *handle, const char *fname) * @param fname file name * @return size in bytes **/ -static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, const char *fname) +static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { - SMB_STRUCT_STAT st; + struct smb_filename *smb_fname_tmp = NULL; + NTSTATUS status; + SMB_OFF_T size; + + status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp); + if (!NT_STATUS_IS_OK(status)) { + size = (SMB_OFF_T)0; + goto out; + } - if (vfs_stat_smb_fname(handle->conn, fname, &st) != 0) { - DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno))); - return (SMB_OFF_T)0; + if (SMB_VFS_STAT(handle->conn, smb_fname_tmp) != 0) { + DEBUG(0,("recycle: stat for %s returned %s\n", + smb_fname_str_dbg(smb_fname_tmp), strerror(errno))); + size = (SMB_OFF_T)0; + goto out; } - return(st.st_ex_size); + size = smb_fname_tmp->st.st_ex_size; + out: + TALLOC_FREE(smb_fname_tmp); + return size; } /** @@ -387,22 +411,37 @@ static bool matchparam(const char **haystack_list, const char *needle) /** * Touch access or modify date **/ -static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, +static void recycle_do_touch(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, bool touch_mtime) { - SMB_STRUCT_STAT st; + struct smb_filename *smb_fname_tmp = NULL; struct smb_file_time ft; + char *fname = NULL; + NTSTATUS status; int ret, err; ZERO_STRUCT(ft); - if (vfs_stat_smb_fname(handle->conn, fname, &st) != 0) { - DEBUG(0,("recycle: stat for %s returned %s\n", - fname, strerror(errno))); + status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp); + if (!NT_STATUS_IS_OK(status)) { return; } - ft.atime = timespec_current(); /* atime */ - ft.mtime = touch_mtime ? ft.atime : st.st_ex_mtime; /* mtime */ + + if (SMB_VFS_STAT(handle->conn, smb_fname_tmp) != 0) { + DEBUG(0,("recycle: stat for %s returned %s\n", + smb_fname_str_dbg(smb_fname_tmp), strerror(errno))); + goto out; + } + /* atime */ + ft.atime = timespec_current(); + /* mtime */ + ft.mtime = touch_mtime ? ft.atime : smb_fname_tmp->st.st_ex_mtime; + + status = get_full_smb_filename(talloc_tos(), smb_fname_tmp, &fname); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } become_root(); ret = SMB_VFS_NEXT_NTIMES(handle, fname, &ft); @@ -410,20 +449,23 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, unbecome_root(); if (ret == -1 ) { DEBUG(0, ("recycle: touching %s failed, reason = %s\n", - fname, strerror(err))); + smb_fname_str_dbg(smb_fname_tmp), strerror(err))); } + + out: + TALLOC_FREE(fname); } /** * Check if file should be recycled **/ -static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) +static int recycle_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { connection_struct *conn = handle->conn; char *path_name = NULL; char *temp_name = NULL; char *final_name = NULL; - struct smb_filename *smb_fname_file = NULL; struct smb_filename *smb_fname_final = NULL; const char *base; char *repository = NULL; @@ -447,19 +489,21 @@ static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) trim_char(repository, '\0', '/'); if(!repository || *(repository) == '\0') { - DEBUG(3, ("recycle: repository path not set, purging %s...\n", file_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); + DEBUG(3, ("recycle: repository path not set, purging %s...\n", + smb_fname_str_dbg(smb_fname))); + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } /* we don't recycle the recycle bin... */ - if (strncmp(file_name, repository, strlen(repository)) == 0) { + if (strncmp(smb_fname->base_name, repository, + strlen(repository)) == 0) { DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n")); - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } - file_size = recycle_get_file_size(handle, file_name); + file_size = recycle_get_file_size(handle, smb_fname); /* it is wrong to purge filenames only because they are empty imho * --- simo * @@ -476,14 +520,16 @@ static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) */ maxsize = recycle_maxsize(handle); if(maxsize > 0 && file_size > maxsize) { - DEBUG(3, ("recycle: File %s exceeds maximum recycle size, purging... \n", file_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); + DEBUG(3, ("recycle: File %s exceeds maximum recycle size, " + "purging... \n", smb_fname_str_dbg(smb_fname))); + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } minsize = recycle_minsize(handle); if(minsize > 0 && file_size < minsize) { - DEBUG(3, ("recycle: File %s lowers minimum recycle size, purging... \n", file_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); + DEBUG(3, ("recycle: File %s lowers minimum recycle size, " + "purging... \n", smb_fname_str_dbg(smb_fname))); + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } @@ -500,32 +546,35 @@ static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) */ /* extract filename and path */ - base = strrchr(file_name, '/'); + base = strrchr(smb_fname->base_name, '/'); if (base == NULL) { - base = file_name; + base = smb_fname->base_name; path_name = SMB_STRDUP("/"); ALLOC_CHECK(path_name, done); } else { - path_name = SMB_STRDUP(file_name); + path_name = SMB_STRDUP(smb_fname->base_name); ALLOC_CHECK(path_name, done); - path_name[base - file_name] = '\0'; + path_name[base - smb_fname->base_name] = '\0'; base++; } - DEBUG(10, ("recycle: fname = %s\n", file_name)); /* original filename with path */ - DEBUG(10, ("recycle: fpath = %s\n", path_name)); /* original path */ - DEBUG(10, ("recycle: base = %s\n", base)); /* filename without path */ + /* original filename with path */ + DEBUG(10, ("recycle: fname = %s\n", smb_fname_str_dbg(smb_fname))); + /* original path */ + DEBUG(10, ("recycle: fpath = %s\n", path_name)); + /* filename without path */ + DEBUG(10, ("recycle: base = %s\n", base)); if (matchparam(recycle_exclude(handle), base)) { DEBUG(3, ("recycle: file %s is excluded \n", base)); - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } if (matchdirparam(recycle_exclude_dir(handle), path_name)) { DEBUG(3, ("recycle: directory %s is excluded \n", path_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } @@ -544,8 +593,10 @@ static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) } else { DEBUG(10, ("recycle: Creating directory %s\n", temp_name)); if (recycle_create_dir(handle, temp_name) == False) { - DEBUG(3, ("recycle: Could not create directory, purging %s...\n", file_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); + DEBUG(3, ("recycle: Could not create directory, " + "purging %s...\n", + smb_fname_str_dbg(smb_fname))); + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } } @@ -553,13 +604,27 @@ static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) if (asprintf(&final_name, "%s/%s", temp_name, base) == -1) { ALLOC_CHECK(final_name, done); } - DEBUG(10, ("recycle: recycled file name: %s\n", final_name)); /* new filename with path */ + + /* Create smb_fname with final base name and orig stream name. */ + status = create_synthetic_smb_fname(talloc_tos(), final_name, + smb_fname->stream_name, NULL, + &smb_fname_final); + if (!NT_STATUS_IS_OK(status)) { + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); + goto done; + } + + /* new filename with path */ + DEBUG(10, ("recycle: recycled file name: %s\n", + smb_fname_str_dbg(smb_fname_final))); /* check if we should delete file from recycle bin */ - if (recycle_file_exist(handle, final_name)) { + if (recycle_file_exist(handle, smb_fname_final)) { if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) { - DEBUG(3, ("recycle: Removing old file %s from recycle bin\n", final_name)); - if (SMB_VFS_NEXT_UNLINK(handle, final_name) != 0) { + DEBUG(3, ("recycle: Removing old file %s from recycle " + "bin\n", smb_fname_str_dbg(smb_fname_final))); + if (SMB_VFS_NEXT_UNLINK(handle, + smb_fname_final) != 0) { DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno))); } } @@ -567,43 +632,41 @@ static int recycle_unlink(vfs_handle_struct *handle, const char *file_name) /* rename file we move to recycle bin */ i = 1; - while (recycle_file_exist(handle, final_name)) { + while (recycle_file_exist(handle, smb_fname_final)) { SAFE_FREE(final_name); if (asprintf(&final_name, "%s/Copy #%d of %s", temp_name, i++, base) == -1) { ALLOC_CHECK(final_name, done); } + TALLOC_FREE(smb_fname_final->base_name); + smb_fname_final->base_name = talloc_strdup(smb_fname_final, + final_name); + if (smb_fname_final->base_name == NULL) { + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); + goto done; + } } - status = create_synthetic_smb_fname_split(talloc_tos(), file_name, - NULL, &smb_fname_file); - if (!NT_STATUS_IS_OK(status)) { - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); - goto done; - } - status = create_synthetic_smb_fname_split(talloc_tos(), final_name, - NULL, &smb_fname_final); - if (!NT_STATUS_IS_OK(status)) { - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); - goto done; - } - - DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name)); - rc = SMB_VFS_NEXT_RENAME(handle, smb_fname_file, smb_fname_final); + DEBUG(10, ("recycle: Moving %s to %s\n", smb_fname_str_dbg(smb_fname), + smb_fname_str_dbg(smb_fname_final))); + rc = SMB_VFS_NEXT_RENAME(handle, smb_fname, smb_fname_final); if (rc != 0) { - DEBUG(3, ("recycle: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name)); - rc = SMB_VFS_NEXT_UNLINK(handle, file_name); + DEBUG(3, ("recycle: Move error %d (%s), purging file %s " + "(%s)\n", errno, strerror(errno), + smb_fname_str_dbg(smb_fname), + smb_fname_str_dbg(smb_fname_final))); + rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname); goto done; } /* touch access date of moved file */ if (recycle_touch(handle) == True || recycle_touch_mtime(handle)) - recycle_do_touch(handle, final_name, recycle_touch_mtime(handle)); + recycle_do_touch(handle, smb_fname_final, + recycle_touch_mtime(handle)); done: SAFE_FREE(path_name); SAFE_FREE(temp_name); SAFE_FREE(final_name); - TALLOC_FREE(smb_fname_file); TALLOC_FREE(smb_fname_final); TALLOC_FREE(repository); return rc; diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 25c5096da7..05a8b67f71 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -412,9 +412,19 @@ static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_ return ret; } -static int shadow_copy2_unlink(vfs_handle_struct *handle, const char *fname) +static int shadow_copy2_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname_in) { - SHADOW2_NEXT(UNLINK, (handle, name), int, -1); + struct smb_filename *smb_fname = NULL; + NTSTATUS status; + + status = copy_smb_filename(talloc_tos(), smb_fname_in, &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + SHADOW2_NEXT_SMB_FNAME(UNLINK, (handle, smb_fname), int, -1); } static int shadow_copy2_chmod(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index f1b9a504b9..dca18e0953 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -368,45 +368,6 @@ static NTSTATUS stream_smb_fname(vfs_handle_struct *handle, return status; } -/* - * XXX: This function should be removed after the other vfs ops take - * smb_filename structs - */ -static char *stream_name(vfs_handle_struct *handle, const char *fname, - bool create_dir) -{ - struct smb_filename *smb_fname = NULL; - struct smb_filename *smb_fname_stream = NULL; - char *sname = NULL; - NTSTATUS status; - - status = create_synthetic_smb_fname_split(talloc_tos(), fname, - NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - goto out; - } - - status = stream_smb_fname(handle, smb_fname, &smb_fname_stream, - create_dir); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - goto out; - } - - status = get_full_smb_filename(talloc_tos(), smb_fname_stream, - &sname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - goto out; - } - out: - TALLOC_FREE(smb_fname); - TALLOC_FREE(smb_fname_stream); - - return sname; -} - static NTSTATUS walk_streams(vfs_handle_struct *handle, struct smb_filename *smb_fname_base, char **pdirname, @@ -619,25 +580,31 @@ static int streams_depot_open(vfs_handle_struct *handle, return ret; } -static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname) +static int streams_depot_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { struct smb_filename *smb_fname_base = NULL; NTSTATUS status; int ret = -1; - DEBUG(10, ("streams_depot_unlink called for %s\n", fname)); + DEBUG(10, ("streams_depot_unlink called for %s\n", + smb_fname_str_dbg(smb_fname))); - if (is_ntfs_stream_name(fname)) { - char *stream_fname; + /* If there is a valid stream, just unlink the stream and return. */ + if (is_ntfs_stream_smb_fname(smb_fname) && + !is_ntfs_default_stream_smb_fname(smb_fname)) { + struct smb_filename *smb_fname_stream = NULL; - stream_fname = stream_name(handle, fname, false); - if (stream_fname == NULL) { + status = stream_smb_fname(handle, smb_fname, &smb_fname_stream, + false); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); return -1; } - ret = SMB_VFS_NEXT_UNLINK(handle, stream_fname); + ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_stream); - TALLOC_FREE(stream_fname); + TALLOC_FREE(smb_fname_stream); return ret; } @@ -645,8 +612,8 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname) * We potentially need to delete the per-inode streams directory */ - status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL, - &smb_fname_base); + status = create_synthetic_smb_fname(talloc_tos(), smb_fname->base_name, + NULL, NULL, &smb_fname_base); if (!NT_STATUS_IS_OK(status)) { errno = map_errno_from_nt_status(status); return -1; @@ -673,9 +640,10 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname) TALLOC_FREE(dirname); } - TALLOC_FREE(smb_fname_base); + ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname); - return SMB_VFS_NEXT_UNLINK(handle, fname); + TALLOC_FREE(smb_fname_base); + return ret; } static int streams_depot_rename(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 49f11a22ac..6137d01159 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -533,36 +533,42 @@ static int streams_xattr_open(vfs_handle_struct *handle, return -1; } -static int streams_xattr_unlink(vfs_handle_struct *handle, const char *fname) +static int streams_xattr_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { NTSTATUS status; - char *base = NULL; - char *sname = NULL; int ret = -1; char *xattr_name; - if (!is_ntfs_stream_name(fname)) { - return SMB_VFS_NEXT_UNLINK(handle, fname); + if (!is_ntfs_stream_smb_fname(smb_fname)) { + return SMB_VFS_NEXT_UNLINK(handle, smb_fname); } - status = split_ntfs_stream_name(talloc_tos(), fname, &base, &sname); - if (!NT_STATUS_IS_OK(status)) { - errno = EINVAL; - goto fail; - } + /* If the default stream is requested, just open the base file. */ + if (is_ntfs_default_stream_smb_fname(smb_fname)) { + struct smb_filename *smb_fname_base = NULL; + + status = copy_smb_filename(talloc_tos(), smb_fname, + &smb_fname_base); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + return -1; + } + + ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_base); - if (sname == NULL){ - return SMB_VFS_NEXT_UNLINK(handle, base); + TALLOC_FREE(smb_fname_base); + return ret; } - xattr_name = talloc_asprintf(talloc_tos(), "%s%s", - SAMBA_XATTR_DOSSTREAM_PREFIX, sname); - if (xattr_name == NULL) { - errno = ENOMEM; + status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name, + &xattr_name); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); goto fail; } - ret = SMB_VFS_REMOVEXATTR(handle->conn, base, xattr_name); + ret = SMB_VFS_REMOVEXATTR(handle->conn, smb_fname->base_name, xattr_name); if ((ret == -1) && (errno == ENOATTR)) { errno = ENOENT; @@ -572,8 +578,7 @@ static int streams_xattr_unlink(vfs_handle_struct *handle, const char *fname) ret = 0; fail: - TALLOC_FREE(base); - TALLOC_FREE(sname); + TALLOC_FREE(xattr_name); return ret; } diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c index ff210e695b..91345e1cad 100644 --- a/source3/modules/vfs_syncops.c +++ b/source3/modules/vfs_syncops.c @@ -107,7 +107,7 @@ static void syncops_name(const char *name) /* sync two meta data changes for 1 names */ -static void syncops_smb_fname(struct smb_filename *smb_fname) +static void syncops_smb_fname(const struct smb_filename *smb_fname) { char *parent; parent = parent_dir(NULL, smb_fname->base_name); @@ -166,9 +166,10 @@ static int syncops_open(vfs_handle_struct *handle, (handle, smb_fname, fsp, flags, mode)); } -static int syncops_unlink(vfs_handle_struct *handle, const char *fname) +static int syncops_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { - SYNCOPS_NEXT(UNLINK, fname, (handle, fname)); + SYNCOPS_NEXT_SMB_FNAME(UNLINK, smb_fname, (handle, smb_fname)); } static int syncops_mknod(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 39adfdfe15..e805fbcb2c 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -611,27 +611,35 @@ static bool xattr_tdb_init(int snum, struct db_context **p_db) /* * On unlink we need to delete the tdb record */ -static int xattr_tdb_unlink(vfs_handle_struct *handle, const char *path) +static int xattr_tdb_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) { - SMB_STRUCT_STAT sbuf; + struct smb_filename *smb_fname_tmp = NULL; struct file_id id; struct db_context *db; struct db_record *rec; - int ret; + NTSTATUS status; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (vfs_stat_smb_fname(handle->conn, path, &sbuf) == -1) { + status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); return -1; } - ret = SMB_VFS_NEXT_UNLINK(handle, path); + if (SMB_VFS_STAT(handle->conn, smb_fname_tmp) == -1) { + goto out; + } + + ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp); if (ret == -1) { - return -1; + goto out; } - id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf); + id = SMB_VFS_FILE_ID_CREATE(handle->conn, &smb_fname_tmp->st); rec = xattr_tdb_lock_attrs(talloc_tos(), db, &id); @@ -644,7 +652,9 @@ static int xattr_tdb_unlink(vfs_handle_struct *handle, const char *path) TALLOC_FREE(rec); } - return 0; + out: + TALLOC_FREE(smb_fname_tmp); + return ret; } /* |