r10709: fixed a crash bug rather similar to the one volker found in the dcerpc
authorAndrew Tridgell <tridge@samba.org>
Tue, 4 Oct 2005 10:18:07 +0000 (10:18 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:39:23 +0000 (13:39 -0500)
code, where a stream_terminate_connection() while processing a request
can cause a later defererence of the connection structure to die.
(This used to be commit efbcb0f74176058a74d7134dae4658b891fc6f16)

source4/ldap_server/ldap_server.c
source4/ldap_server/ldap_server.h

index 71a7172e5cfaf18faaf563b36364041c8f4add08..83ce0597560fd0d2d9ec23a1ed0c1c928291089b 100644 (file)
 static void ldapsrv_terminate_connection(struct ldapsrv_connection *conn, 
                                         const char *reason)
 {
-       if (conn->tls) {
-               talloc_free(conn->tls);
-               conn->tls = NULL;
-       }
-       stream_terminate_connection(conn->connection, reason);
+       /* we don't actually do the stream termination here as the
+          recv/send functions dereference the connection after the
+          packet processing callbacks. Instead we mark it for
+          termination and do the real termination in the send/recv
+          functions */
+       conn->terminate = reason;
 }
 
 /*
@@ -299,6 +300,14 @@ static void ldapsrv_recv(struct stream_connection *c, uint16_t flags)
        conn->processing = False;
 
        EVENT_FD_READABLE(c->event.fde);
+
+       if (conn->terminate) {
+               if (conn->tls) {
+                       talloc_free(conn->tls);
+                       conn->tls = NULL;
+               }
+               stream_terminate_connection(conn->connection, conn->terminate);
+       }
 }
        
 /*
@@ -331,6 +340,14 @@ static void ldapsrv_send(struct stream_connection *c, uint16_t flags)
        if (conn->send_queue == NULL) {
                EVENT_FD_NOT_WRITEABLE(c->event.fde);
        }
+
+       if (conn->terminate) {
+               if (conn->tls) {
+                       talloc_free(conn->tls);
+                       conn->tls = NULL;
+               }
+               stream_terminate_connection(conn->connection, conn->terminate);
+       }
 }
 
 /*
index a1981843a60181f42c2a615ac96be1389c281ba9..2aa6530f9fa7da60310e22bea120adc1def4f1df 100644 (file)
@@ -38,6 +38,9 @@ struct ldapsrv_connection {
        struct data_blob_list_item *send_queue;
 
        BOOL processing;
+
+       /* connection should be terminated if non-null */
+       const char *terminate;
 };
 
 struct ldapsrv_call {