smbd:close: only remove kernel share modes if they had been taken at open
[sfrench/samba-autobuild/.git] / source3 / smbd / close.c
index f3d6620f87d3886b0b6cbb6c3f7b487d9b3d45ee..9d1f1a98afefd17ed02daeb28be297fae702ebf8 100644 (file)
@@ -161,7 +161,8 @@ static NTSTATUS close_filestruct(files_struct *fsp)
  Delete all streams
 ****************************************************************************/
 
-NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
+NTSTATUS delete_all_streams(connection_struct *conn,
+                       const struct smb_filename *smb_fname)
 {
        struct stream_struct *stream_info = NULL;
        int i;
@@ -169,7 +170,7 @@ NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
        TALLOC_CTX *frame = talloc_stackframe();
        NTSTATUS status;
 
-       status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
+       status = vfs_streaminfo(conn, NULL, smb_fname, talloc_tos(),
                                &num_streams, &stream_info);
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
@@ -200,8 +201,11 @@ NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
                        continue;
                }
 
-               smb_fname_stream = synthetic_smb_fname(
-                       talloc_tos(), fname, stream_info[i].name, NULL);
+               smb_fname_stream = synthetic_smb_fname(talloc_tos(),
+                                       smb_fname->base_name,
+                                       stream_info[i].name,
+                                       NULL,
+                                       smb_fname->flags);
 
                if (smb_fname_stream == NULL) {
                        DEBUG(0, ("talloc_aprintf failed\n"));
@@ -246,7 +250,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        const struct security_token *del_nt_token = NULL;
        bool got_tokens = false;
        bool normal_close;
-       int ret_flock;
 
        /* Ensure any pending write time updates are done. */
        if (fsp->update_write_time_event) {
@@ -427,7 +430,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
            && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
 
-               status = delete_all_streams(conn, fsp->fsp_name->base_name);
+               status = delete_all_streams(conn, fsp->fsp_name);
 
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(5, ("delete_all_streams failed: %s\n",
@@ -470,12 +473,16 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
                pop_sec_ctx();
        }
 
-       /* remove filesystem sharemodes */
-       ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, 0, 0);
-       if (ret_flock == -1) {
-               DEBUG(2, ("close_remove_share_mode: removing kernel flock for "
-                                       "%s failed: %s\n", fsp_str_dbg(fsp),
-                                       strerror(errno)));
+       if (fsp->kernel_share_modes_taken) {
+               int ret_flock;
+
+               /* remove filesystem sharemodes */
+               ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, 0, 0);
+               if (ret_flock == -1) {
+                       DEBUG(2, ("close_remove_share_mode: removing kernel "
+                                 "flock for %s failed: %s\n",
+                                 fsp_str_dbg(fsp), strerror(errno)));
+               }
        }
 
        if (!del_share_mode(lck, fsp)) {
@@ -830,8 +837,11 @@ bool recursive_rmdir(TALLOC_CTX *ctx,
                        goto err_break;
                }
 
-               smb_dname_full = synthetic_smb_fname(talloc_tos(), fullname,
-                                                    NULL, NULL);
+               smb_dname_full = synthetic_smb_fname(talloc_tos(),
+                                               fullname,
+                                               NULL,
+                                               NULL,
+                                               smb_dname->flags);
                if (smb_dname_full == NULL) {
                        errno = ENOMEM;
                        goto err_break;
@@ -981,8 +991,11 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
                                goto err_break;
                        }
 
-                       smb_dname_full = synthetic_smb_fname(
-                               talloc_tos(), fullname, NULL, NULL);
+                       smb_dname_full = synthetic_smb_fname(talloc_tos(),
+                                                       fullname,
+                                                       NULL,
+                                                       NULL,
+                                                       smb_dname->flags);
                        if (smb_dname_full == NULL) {
                                errno = ENOMEM;
                                goto err_break;
@@ -1145,7 +1158,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
                    && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
 
-                       status = delete_all_streams(fsp->conn, fsp->fsp_name->base_name);
+                       status = delete_all_streams(fsp->conn, fsp->fsp_name);
                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(5, ("delete_all_streams failed: %s\n",
                                          nt_errstr(status)));