summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-06-20 08:47:52 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:18:36 -0500
commit3dd67b97468e86a88bc151a8b4f206c1722a8d8b (patch)
treeea6083ae7311969417b3cb55641b4f9036d2f3d5
parenta124028b660ba5de566442302a8ee3b925595850 (diff)
downloadsamba-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.c14
-rw-r--r--source4/smb_server/smb_server.h2
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;
};