s3:tldap: store plain and gensec tstream
authorStefan Metzmacher <metze@samba.org>
Tue, 23 Jan 2024 15:00:11 +0000 (16:00 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 23 Apr 2024 23:50:34 +0000 (23:50 +0000)
Also allow resetting to plain.

We now have ld->active as the currently active
tstream, which will allow us to add tls support
soon.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/include/tldap.h
source3/lib/tldap.c
source3/lib/tldap_gensec_bind.c

index 23e3f1b655b2f707c20b35c4beecc2832b1b54a6..431aca977b13a21aae57c7bd9510dfd0a86205bd 100644 (file)
@@ -123,9 +123,10 @@ bool tevent_req_ldap_error(struct tevent_req *req, TLDAPRC rc);
 bool tevent_req_is_ldap_error(struct tevent_req *req, TLDAPRC *perr);
 
 struct tldap_context *tldap_context_create(TALLOC_CTX *mem_ctx, int fd);
-struct tstream_context *tldap_get_tstream(struct tldap_context *ld);
-void tldap_set_tstream(struct tldap_context *ld,
-                      struct tstream_context *stream);
+struct tstream_context *tldap_get_plain_tstream(struct tldap_context *ld);
+bool tldap_has_gensec_tstream(struct tldap_context *ld);
+void tldap_set_gensec_tstream(struct tldap_context *ld,
+                             struct tstream_context **stream);
 
 bool tldap_connection_ok(struct tldap_context *ld);
 bool tldap_context_setattr(struct tldap_context *ld,
index 6e82516c273028da0ca717b4e29487325e57aa36..bfc4579ab5c287cae09ee296271621cb82a63c9d 100644 (file)
@@ -83,7 +83,9 @@ struct tldap_ctx_attribute {
 
 struct tldap_context {
        int ld_version;
-       struct tstream_context *conn;
+       struct tstream_context *plain;
+       struct tstream_context *gensec;
+       struct tstream_context *active;
        int msgid;
        struct tevent_queue *outgoing;
        struct tevent_req **pending;
@@ -174,11 +176,12 @@ struct tldap_context *tldap_context_create(TALLOC_CTX *mem_ctx, int fd)
        if (ctx == NULL) {
                return NULL;
        }
-       ret = tstream_bsd_existing_socket(ctx, fd, &ctx->conn);
+       ret = tstream_bsd_existing_socket(ctx, fd, &ctx->plain);
        if (ret == -1) {
                TALLOC_FREE(ctx);
                return NULL;
        }
+       ctx->active = ctx->plain;
        ctx->msgid = 1;
        ctx->ld_version = 3;
        ctx->outgoing = tevent_queue_create(ctx, "tldap_outgoing");
@@ -197,11 +200,11 @@ bool tldap_connection_ok(struct tldap_context *ld)
                return false;
        }
 
-       if (ld->conn == NULL) {
+       if (ld->active == NULL) {
                return false;
        }
 
-       ret = tstream_pending_bytes(ld->conn);
+       ret = tstream_pending_bytes(ld->active);
        if (ret == -1) {
                return false;
        }
@@ -214,15 +217,28 @@ static size_t tldap_pending_reqs(struct tldap_context *ld)
        return talloc_array_length(ld->pending);
 }
 
-struct tstream_context *tldap_get_tstream(struct tldap_context *ld)
+struct tstream_context *tldap_get_plain_tstream(struct tldap_context *ld)
 {
-       return ld->conn;
+       return ld->plain;
 }
 
-void tldap_set_tstream(struct tldap_context *ld,
-                      struct tstream_context *stream)
+bool tldap_has_gensec_tstream(struct tldap_context *ld)
 {
-       ld->conn = stream;
+       return ld->gensec != NULL && ld->active == ld->gensec;
+}
+
+void tldap_set_gensec_tstream(struct tldap_context *ld,
+                             struct tstream_context **stream)
+{
+       TALLOC_FREE(ld->gensec);
+       if (stream != NULL) {
+               ld->gensec = talloc_move(ld, stream);
+       }
+       if (ld->gensec != NULL) {
+               ld->active = ld->gensec;
+       } else {
+               ld->active = ld->plain;
+       }
 }
 
 static struct tldap_ctx_attribute *tldap_context_findattr(
@@ -429,7 +445,7 @@ static void _tldap_context_disconnect(struct tldap_context *ld,
                                      TLDAPRC status,
                                      const char *location)
 {
-       if (ld->conn == NULL) {
+       if (ld->active == NULL) {
                /*
                 * We don't need to tldap_debug() on
                 * a potential 2nd run.
@@ -446,7 +462,9 @@ static void _tldap_context_disconnect(struct tldap_context *ld,
                    location);
        tevent_queue_stop(ld->outgoing);
        TALLOC_FREE(ld->read_req);
-       TALLOC_FREE(ld->conn);
+       ld->active = NULL;
+       TALLOC_FREE(ld->gensec);
+       TALLOC_FREE(ld->plain);
 
        while (talloc_array_length(ld->pending) > 0) {
                struct tevent_req *req = NULL;
@@ -515,7 +533,7 @@ static struct tevent_req *tldap_msg_send(TALLOC_CTX *mem_ctx,
        state->iov.iov_base = (void *)blob.data;
        state->iov.iov_len = blob.length;
 
-       subreq = tstream_writev_queue_send(state, ev, ld->conn, ld->outgoing,
+       subreq = tstream_writev_queue_send(state, ev, ld->active, ld->outgoing,
                                           &state->iov, 1);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
@@ -602,7 +620,7 @@ static bool tldap_msg_set_pending(struct tevent_req *req)
         * We're the first one, add the read_ldap request that waits for the
         * answer from the server
         */
-       ld->read_req = read_ldap_send(ld->pending, state->ev, ld->conn);
+       ld->read_req = read_ldap_send(ld->pending, state->ev, ld->active);
        if (ld->read_req == NULL) {
                tldap_msg_unset_pending(req);
                return false;
@@ -730,7 +748,7 @@ static void tldap_msg_received(struct tevent_req *subreq)
        }
 
        state = tevent_req_data(ld->pending[0], struct tldap_msg_state);
-       ld->read_req = read_ldap_send(ld->pending, state->ev, ld->conn);
+       ld->read_req = read_ldap_send(ld->pending, state->ev, ld->active);
        if (ld->read_req == NULL) {
                status = TLDAP_NO_MEMORY;
                goto fail;
index 0e8bb62233c4bf686c7a2872d423dfb5da4d2447..2be6294cfb76276205c6ed3aca034931e5b5c977 100644 (file)
@@ -270,7 +270,7 @@ static TLDAPRC tldap_gensec_bind_recv(struct tevent_req *req)
         */
        talloc_steal(state->ctx, state->gensec);
 
-       plain = tldap_get_tstream(state->ctx);
+       plain = tldap_get_plain_tstream(state->ctx);
 
        status = gensec_create_tstream(state->ctx, state->gensec,
                                       plain, &sec);
@@ -280,7 +280,7 @@ static TLDAPRC tldap_gensec_bind_recv(struct tevent_req *req)
                return TLDAP_OPERATIONS_ERROR;
        }
 
-       tldap_set_tstream(state->ctx, sec);
+       tldap_set_gensec_tstream(state->ctx, &sec);
 
        return TLDAP_SUCCESS;
 }