diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-06-20 08:47:52 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:18:36 -0500 |
commit | 3dd67b97468e86a88bc151a8b4f206c1722a8d8b (patch) | |
tree | ea6083ae7311969417b3cb55641b4f9036d2f3d5 | |
parent | a124028b660ba5de566442302a8ee3b925595850 (diff) | |
download | samba-3dd67b97468e86a88bc151a8b4f206c1722a8d8b.tar.gz samba-3dd67b97468e86a88bc151a8b4f206c1722a8d8b.tar.bz2 samba-3dd67b97468e86a88bc151a8b4f206c1722a8d8b.zip |
r7782: fixed an ordering problem with smb requests. I found this when I had "sam database"
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)
-rw-r--r-- | source4/smb_server/smb_server.c | 14 | ||||
-rw-r--r-- | source4/smb_server/smb_server.h | 2 |
2 files changed, 16 insertions, 0 deletions
diff --git a/source4/smb_server/smb_server.c b/source4/smb_server/smb_server.c index 3b4d06f3b2..7e0aa2c0cb 100644 --- a/source4/smb_server/smb_server.c +++ b/source4/smb_server/smb_server.c @@ -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; } diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index 01222adc0c..a8e9d7ed34 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -254,4 +254,6 @@ struct smbsrv_connection { struct smb_trans2 *trans; uint8_t command; } *trans_partial; + + BOOL processing; }; |