From 7bb59372e9e0205a683d4266a40981ec4daac91d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Baumbach?= Date: Mon, 1 Oct 2012 09:55:28 +0200 Subject: [PATCH 1/2] s3: make recursive_rmdir function non-static Part of fix for bug #9300. (cherry picked from commit 7a76762c688f4fc7519dbd204b036963c460e093) --- source3/smbd/close.c | 8 ++++---- source3/smbd/proto.h | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 8bf481d..9b988e0 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -853,13 +853,13 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, return status; } /**************************************************************************** - Static function used by reply_rmdir to delete an entire directory + Function used by reply_rmdir to delete an entire directory tree recursively. Return True on ok, False on fail. ****************************************************************************/ -static bool recursive_rmdir(TALLOC_CTX *ctx, - connection_struct *conn, - struct smb_filename *smb_dname) +bool recursive_rmdir(TALLOC_CTX *ctx, + connection_struct *conn, + struct smb_filename *smb_dname) { const char *dname = NULL; char *talloced = NULL; diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 5d6a299..4ef5ba7 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -139,6 +139,9 @@ void msg_close_file(struct messaging_context *msg_ctx, struct server_id server_id, DATA_BLOB *data); NTSTATUS delete_all_streams(connection_struct *conn, const char *fname); +bool recursive_rmdir(TALLOC_CTX *ctx, + connection_struct *conn, + struct smb_filename *smb_dname); /* The following definitions come from smbd/conn.c */ -- 1.7.8.6 From c882eb9bd19aca33a55510e9e90d54b01cc24f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Baumbach?= Date: Thu, 27 Sep 2012 12:40:47 +0200 Subject: [PATCH 2/2] s3: vfs_streams_depot: add delete_lost option (bug #9300) With this option lost stream directories will be removed instead of renamed. Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Mon Oct 1 18:47:30 CEST 2012 on sn-devel-104 (cherry picked from commit 8da8a2289ea51d4fcdf6b5352a46c14d36d8f072) --- source3/modules/vfs_streams_depot.c | 65 ++++++++++++++++++++++------------ 1 files changed, 42 insertions(+), 23 deletions(-) diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index c0d5945..620a580 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -198,6 +198,7 @@ static char *stream_dir(vfs_handle_struct *handle, if (SMB_VFS_NEXT_STAT(handle, smb_fname_hash) == 0) { struct smb_filename *smb_fname_new = NULL; char *newname; + bool delete_lost; if (!S_ISDIR(smb_fname_hash->st.st_ex_mode)) { errno = EINVAL; @@ -211,36 +212,54 @@ static char *stream_dir(vfs_handle_struct *handle, /* * Someone has recreated a file under an existing inode - * without deleting the streams directory. For now, just move - * it away. + * without deleting the streams directory. + * Move it away or remove if streams_depot:delete_lost is set. */ again: - newname = talloc_asprintf(talloc_tos(), "lost-%lu", random()); - if (newname == NULL) { - errno = ENOMEM; - goto fail; - } + delete_lost = lp_parm_bool(SNUM(handle->conn), "streams_depot", + "delete_lost", false); + + if (delete_lost) { + DEBUG(3, ("Someone has recreated a file under an " + "existing inode. Removing: %s\n", + smb_fname_hash->base_name)); + recursive_rmdir(talloc_tos(), handle->conn, + smb_fname_hash); + SMB_VFS_NEXT_RMDIR(handle, smb_fname_hash->base_name); + } else { + newname = talloc_asprintf(talloc_tos(), "lost-%lu", + random()); + DEBUG(3, ("Someone has recreated a file under an " + "existing inode. Renaming: %s to: %s\n", + smb_fname_hash->base_name, + newname)); + if (newname == NULL) { + errno = ENOMEM; + goto fail; + } - status = create_synthetic_smb_fname(talloc_tos(), newname, - NULL, NULL, - &smb_fname_new); - TALLOC_FREE(newname); - if (!NT_STATUS_IS_OK(status)) { - errno = map_errno_from_nt_status(status); - goto fail; - } + status = create_synthetic_smb_fname(talloc_tos(), + newname, + NULL, NULL, + &smb_fname_new); + TALLOC_FREE(newname); + if (!NT_STATUS_IS_OK(status)) { + errno = map_errno_from_nt_status(status); + goto fail; + } - if (SMB_VFS_NEXT_RENAME(handle, smb_fname_hash, - smb_fname_new) == -1) { - TALLOC_FREE(smb_fname_new); - if ((errno == EEXIST) || (errno == ENOTEMPTY)) { - goto again; + if (SMB_VFS_NEXT_RENAME(handle, smb_fname_hash, + smb_fname_new) == -1) { + TALLOC_FREE(smb_fname_new); + if ((errno == EEXIST) || (errno == ENOTEMPTY)) { + goto again; + } + goto fail; } - goto fail; - } - TALLOC_FREE(smb_fname_new); + TALLOC_FREE(smb_fname_new); + } } if (!create_it) { -- 1.7.8.6