r7782: fixed an ordering problem with smb requests. I found this when I had "sam...
authorAndrew Tridgell <tridge@samba.org>
Mon, 20 Jun 2005 08:47:52 +0000 (08:47 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:18:36 +0000 (13:18 -0500)
set to the internal ldap server over loopback. The following happened:

  - DCERPC_AUTH3 request
     - auth requests calls ldb
     - ldb calls ldap
     - ldap calls our internal ldap server, triggering events
  - samrConnect from client
     - connect refused
  - SMBclose from client
     - causes dcerpc_pipe to be destroyed
  - AUTH3 continues
     - dies on freed pipe

I chose this solution as it provides a guarantee that backends only have to think about
async issues when they mark a request async. When they don't, this code guarantees that
a second request won't happen on the same connection while processing the first one
(This used to be commit 45487e8a1402c64d1c314befe8bd9f65587fd0d6)

source4/smb_server/smb_server.c
source4/smb_server/smb_server.h

index 3b4d06f3b27086d44470de1cc5747c83ac4498ad..7e0aa2c0cbdae07257b0d0ca321a274032141b86 100644 (file)
@@ -665,7 +665,18 @@ static void smbsrv_recv(struct stream_connection *conn, uint16_t flags)
 
        DEBUG(10,("smbsrv_recv\n"));
 
+       /* our backends are designed to process one request at a time,
+          unless they deliberately mark the request as async and
+          process it later on a timer or other event. This enforces
+          that ordering. */
+       if (smb_conn->processing) {
+               EVENT_FD_NOT_READABLE(conn->event.fde);
+               return;
+       }
+
+       smb_conn->processing = True;
        status = receive_smb_request(smb_conn);
+       smb_conn->processing = False;
        if (NT_STATUS_IS_ERR(status)) {
                talloc_free(conn->event.fde);
                conn->event.fde = NULL;
@@ -673,6 +684,8 @@ static void smbsrv_recv(struct stream_connection *conn, uint16_t flags)
                return;
        }
 
+       EVENT_FD_READABLE(conn->event.fde);
+
        /* free up temporary memory */
        lp_talloc_free();
 }
@@ -749,6 +762,7 @@ static void smbsrv_accept(struct stream_connection *conn)
        smbsrv_tcon_init(smb_conn);
 
        smb_conn->connection = conn;
+       smb_conn->processing = False;
 
        conn->private = smb_conn;
 }
index 01222adc0c4e0fa49375fca501fcf35b3e2b0af5..a8e9d7ed3417cac6c32afa4bb4c2e969e858670c 100644 (file)
@@ -254,4 +254,6 @@ struct smbsrv_connection {
                struct smb_trans2 *trans;
                uint8_t command;
        } *trans_partial;
+
+       BOOL processing;
 };