s3: smbd : Ensure file_new doesn't call into smbXsrv_open_create() for INTERNAL_OPEN_...
authorJeremy Allison <jra@samba.org>
Thu, 1 May 2014 18:01:03 +0000 (11:01 -0700)
committerKarolin Seeger <kseeger@samba.org>
Mon, 19 May 2014 10:20:12 +0000 (12:20 +0200)
This causes deadlocks which cause smbd to crash if the locking
database has already been locked for a compound operation we
need to be atomic (as in the file rename case).

Ensure INTERNAL_OPEN_ONLY opens are synonymous with req==NULL.

INTERNAL_OPEN_ONLY opens leave a NO_OPLOCK record in
the share mode database, so they can be detected by other
processes for share mode violation purposes (because
they're doing an operation on the file that may include
reads or writes they need to have real state inside the
locking database) but have an fnum of FNUM_FIELD_INVALID
and a local share_file_id of zero, as they will never be
seen on the wire.

Ensure validate_my_share_entries() ignores
INTERNAL_OPEN_ONLY records (share_file_id == 0).

Bug 10564 - Lock order violation and file lost

https://bugzilla.samba.org/show_bug.cgi?id=10564

Signed-off-by: Jeremy Allison <jra@samba.org>
Signed-off-by: Volker Lendecke <vl@samba.org>
source3/smbd/files.c
source3/smbd/open.c

index ef229a4098a2f25a5c25f76afe0059db756678b9..53d6d4f6852a74fec6928604f064e7c7c342fe67 100644 (file)
@@ -93,7 +93,7 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
 
        GetTimeOfDay(&fsp->open_time);
 
-       if (sconn->conn) {
+       if (req) {
                struct smbXsrv_open *op = NULL;
                NTTIME now = timeval_to_nttime(&fsp->open_time);
 
@@ -108,6 +108,9 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
                op->compat = fsp;
                fsp->fnum = op->local_id;
                fsp->fh->gen_id = smbXsrv_open_hash(op);
+       } else {
+               DEBUG(10, ("%s: req==NULL, INTERNAL_OPEN_ONLY, smbXsrv_open "
+                          "allocated\n", __func__));
        }
 
        /*
index a41d3d534fe86c443f8bedfe398fb065e1f18f90..a596bceb1817c5d9f690a6e1b086cc42528cdcf1 100644 (file)
@@ -1082,6 +1082,11 @@ static void validate_my_share_entries(struct smbd_server_connection *sconn,
                smb_panic(str);
        }
 
+       if (share_entry->share_file_id == 0) {
+               /* INTERNAL_OPEN_ONLY */
+               return;
+       }
+
        if (!is_valid_share_mode_entry(share_entry)) {
                return;
        }
@@ -2029,9 +2034,12 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                   create_options, (unsigned int)unx_mode, oplock_request,
                   (unsigned int)private_flags));
 
-       if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
-               DEBUG(0, ("No smb request but not an internal only open!\n"));
-               return NT_STATUS_INTERNAL_ERROR;
+       if (req == NULL) {
+               /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
+               SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) != 0));
+       } else {
+               /* And req != NULL means no INTERNAL_OPEN_ONLY */
+               SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
        }
 
        /*