loadparm: make the source3/ lp_ functions take an explicit TALLOC_CTX *.
[jlayton/samba.git] / source3 / smbd / close.c
index e2d7c2c7a7b2ac4230c836ec9d629ee3d177ee0c..8633f82c0a6cec6bb0321e04e78bf745d7d19349 100644 (file)
@@ -46,7 +46,7 @@ static NTSTATUS check_magic(struct files_struct *fsp)
        char *fname = NULL;
        NTSTATUS status;
 
-       if (!*lp_magicscript(SNUM(conn))) {
+       if (!*lp_magicscript(talloc_tos(), SNUM(conn))) {
                return NT_STATUS_OK;
        }
 
@@ -62,13 +62,13 @@ static NTSTATUS check_magic(struct files_struct *fsp)
                p++;
        }
 
-       if (!strequal(lp_magicscript(SNUM(conn)),p)) {
+       if (!strequal(lp_magicscript(talloc_tos(), SNUM(conn)),p)) {
                status = NT_STATUS_OK;
                goto out;
        }
 
-       if (*lp_magicoutput(SNUM(conn))) {
-               magic_output = lp_magicoutput(SNUM(conn));
+       if (*lp_magicoutput(talloc_tos(), SNUM(conn))) {
+               magic_output = lp_magicoutput(talloc_tos(), SNUM(conn));
        } else {
                magic_output = talloc_asprintf(ctx,
                                "%s.out",
@@ -232,7 +232,7 @@ static void notify_deferred_opens(struct smbd_server_connection *sconn,
        for (i=0; i<num_deferred; i++) {
                struct share_mode_entry *e = &deferred[i];
 
-               if (procid_equal(&self, &e->pid)) {
+               if (serverid_equal(&self, &e->pid)) {
                        /*
                         * We need to notify ourself to retry the open.  Do
                         * this by finding the queued SMB record, moving it to
@@ -332,6 +332,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
                                        enum file_close_type close_type)
 {
        connection_struct *conn = fsp->conn;
+       struct server_id self = messaging_server_id(conn->sconn->msg_ctx);
        bool delete_file = false;
        bool changed_user = false;
        struct share_mode_lock *lck = NULL;
@@ -341,6 +342,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        const struct security_unix_token *del_token = NULL;
        const struct security_token *del_nt_token = NULL;
        bool got_tokens = false;
+       bool normal_close;
 
        /* Ensure any pending write time updates are done. */
        if (fsp->update_write_time_event) {
@@ -360,8 +362,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
        if (lck == NULL) {
                DEBUG(0, ("close_remove_share_mode: Could not get share mode "
                          "lock for file %s\n", fsp_str_dbg(fsp)));
-               status = NT_STATUS_INVALID_PARAMETER;
-               goto done;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        if (fsp->write_time_forced) {
@@ -386,12 +387,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
                }
        }
 
-       if (!del_share_mode(lck, fsp)) {
-               DEBUG(0, ("close_remove_share_mode: Could not delete share "
-                         "entry for file %s\n",
-                         fsp_str_dbg(fsp)));
-       }
-
        if (fsp->initial_delete_on_close &&
                        !is_delete_on_close_set(lck, fsp->name_hash)) {
                bool became_user = False;
@@ -432,6 +427,10 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
                            && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
                                continue;
                        }
+                       if (serverid_equal(&self, &e->pid) &&
+                           (e->share_file_id == fsp->fh->gen_id)) {
+                               continue;
+                       }
                        if (share_mode_stale_pid(lck->data, i)) {
                                continue;
                        }
@@ -449,8 +448,16 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
         * reference to a file.
         */
 
-       if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
-                       !delete_file) {
+       normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
+
+       if (!normal_close || !delete_file) {
+
+               if (!del_share_mode(lck, fsp)) {
+                       DEBUG(0, ("close_remove_share_mode: Could not delete "
+                                 "share entry for file %s\n",
+                                 fsp_str_dbg(fsp)));
+               }
+
                TALLOC_FREE(lck);
                return NT_STATUS_OK;
        }
@@ -570,6 +577,11 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
                pop_sec_ctx();
        }
 
+       if (!del_share_mode(lck, fsp)) {
+               DEBUG(0, ("close_remove_share_mode: Could not delete share "
+                         "entry for file %s\n", fsp_str_dbg(fsp)));
+       }
+
        TALLOC_FREE(lck);
 
        if (delete_file) {
@@ -894,7 +906,7 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
                return NT_STATUS_OK;
        }
 
-       if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(SNUM(conn))) {
+       if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), SNUM(conn))) {
                /*
                 * Check to see if the only thing in this directory are
                 * vetoed files/directories. If so then delete them and
@@ -1035,6 +1047,7 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                                enum file_close_type close_type)
 {
+       struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
        struct share_mode_lock *lck = NULL;
        bool delete_dir = False;
        NTSTATUS status = NT_STATUS_OK;
@@ -1051,13 +1064,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
        if (lck == NULL) {
                DEBUG(0, ("close_directory: Could not get share mode lock for "
                          "%s\n", fsp_str_dbg(fsp)));
-               status = NT_STATUS_INVALID_PARAMETER;
-               goto out;
-       }
-
-       if (!del_share_mode(lck, fsp)) {
-               DEBUG(0, ("close_directory: Could not delete share entry for "
-                         "%s\n", fsp_str_dbg(fsp)));
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        if (fsp->initial_delete_on_close) {
@@ -1096,6 +1103,10 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                                if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
                                        continue;
                                }
+                               if (serverid_equal(&self, &e->pid) &&
+                                   (e->share_file_id == fsp->fh->gen_id)) {
+                                       continue;
+                               }
                                if (share_mode_stale_pid(lck->data, i)) {
                                        continue;
                                }
@@ -1120,6 +1131,11 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                                del_token->groups,
                                del_nt_token);
 
+               if (!del_share_mode(lck, fsp)) {
+                       DEBUG(0, ("close_directory: Could not delete share entry for "
+                                 "%s\n", fsp_str_dbg(fsp)));
+               }
+
                TALLOC_FREE(lck);
 
                if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
@@ -1129,7 +1145,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(5, ("delete_all_streams failed: %s\n",
                                          nt_errstr(status)));
-                               goto out;
+                               return status;
                        }
                }
 
@@ -1151,6 +1167,11 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                        remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
                }
        } else {
+               if (!del_share_mode(lck, fsp)) {
+                       DEBUG(0, ("close_directory: Could not delete share entry for "
+                                 "%s\n", fsp_str_dbg(fsp)));
+               }
+
                TALLOC_FREE(lck);
                remove_pending_change_notify_requests_by_fid(
                        fsp, NT_STATUS_OK);
@@ -1170,8 +1191,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
        close_filestruct(fsp);
        file_free(req, fsp);
 
- out:
-       TALLOC_FREE(lck);
        if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
                status = status1;
        }