s3:lib/tls: we need to call tstream_tls_retry_handshake/disconnect() until all buffer...
authorStefan Metzmacher <metze@samba.org>
Fri, 26 Jan 2024 13:42:40 +0000 (14:42 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 23 Apr 2024 23:50:33 +0000 (23:50 +0000)
Before the handshare or disconnect is over we need to wait until
we delivered the lowlevel messages to the transport/kernel socket.

Otherwise we'll have a problem if another tevent_context is used
after the handshake.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/lib/tls/tls_tstream.c

index 085da5e6473adf5f4e6f8ba2a67efdb742115b1d..364bb42107864a67611170535071580851a0d42b 100644 (file)
@@ -70,6 +70,10 @@ struct tstream_tls {
 
        struct tevent_immediate *retry_im;
 
+       struct {
+               struct tevent_req *mgmt_req;
+       } waiting_flush;
+
        struct {
                uint8_t *buf;
                off_t ofs;
@@ -121,6 +125,17 @@ static void tstream_tls_retry(struct tstream_context *stream, bool deferred)
                tstream_context_data(stream,
                struct tstream_tls);
 
+       if (tlss->push.subreq == NULL && tlss->pull.subreq == NULL) {
+               if (tlss->waiting_flush.mgmt_req != NULL) {
+                       struct tevent_req *req = tlss->waiting_flush.mgmt_req;
+
+                       tlss->waiting_flush.mgmt_req = NULL;
+
+                       tevent_req_done(req);
+                       return;
+               }
+       }
+
        if (tlss->disconnect.req) {
                tstream_tls_retry_disconnect(stream);
                return;
@@ -785,6 +800,11 @@ static void tstream_tls_retry_disconnect(struct tstream_context *stream)
                return;
        }
 
+       if (tlss->push.subreq != NULL || tlss->pull.subreq != NULL) {
+               tlss->waiting_flush.mgmt_req = req;
+               return;
+       }
+
        tevent_req_done(req);
 }
 
@@ -1477,6 +1497,11 @@ static void tstream_tls_retry_handshake(struct tstream_context *stream)
                }
        }
 
+       if (tlss->push.subreq != NULL || tlss->pull.subreq != NULL) {
+               tlss->waiting_flush.mgmt_req = req;
+               return;
+       }
+
        tevent_req_done(req);
 }