1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00
samba-mirror/source3/lib/tldap_tls_connect.c
Volker Lendecke e54a4f06b3 tldap_tls: Remove tldap_[gs]et_starttls_needed()
The caller setting up a tldap connection is aware of whether to use
starttls, which is one single ldap extended operation before the tls
crypto starts. There is no complex logic behind this that is
worthwhile to be hidden behind a flag and an API. If there was more to
it than just a simple call to tldap_extended(), I would all be for
passing down that flag, but for this case I would argue the logic
after this patch is simpler.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
2024-11-11 14:03:03 +00:00

149 lines
3.8 KiB
C

/*
* Unix SMB/CIFS implementation.
* tls based tldap connect
* Copyright (C) Stefan Metzmacher 2024
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "replace.h"
#include "tldap.h"
#include "tldap_tls_connect.h"
#include "lib/util/samba_util.h"
#include "lib/util/debug.h"
#include "lib/param/param.h"
#include "../libcli/util/ntstatus.h"
#include "../source4/lib/tls/tls.h"
struct tldap_tls_connect_state {
struct tevent_context *ev;
struct tldap_context *ctx;
struct tstream_tls_params *tls_params;
};
static void tldap_tls_connect_crypto_done(struct tevent_req *subreq);
struct tevent_req *tldap_tls_connect_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct tldap_context *ctx,
struct tstream_tls_params *tls_params)
{
struct tevent_req *req = NULL, *subreq = NULL;
struct tldap_tls_connect_state *state = NULL;
struct tstream_context *plain_stream = NULL;
req = tevent_req_create(mem_ctx, &state,
struct tldap_tls_connect_state);
if (req == NULL) {
return NULL;
}
state->ev = ev;
state->ctx = ctx;
state->tls_params = tls_params;
if (!tldap_connection_ok(ctx)) {
DBG_ERR("tldap_connection_ok() => false\n");
tevent_req_ldap_error(req, TLDAP_CONNECT_ERROR);
return tevent_req_post(req, ev);
}
if (tldap_has_gensec_tstream(ctx)) {
DBG_ERR("tldap_has_gensec_tstream() => true\n");
tevent_req_ldap_error(req, TLDAP_LOCAL_ERROR);
return tevent_req_post(req, ev);
}
plain_stream = tldap_get_plain_tstream(state->ctx);
if (plain_stream == NULL) {
DBG_ERR("tldap_get_plain_tstream() = NULL\n");
tevent_req_ldap_error(req, TLDAP_LOCAL_ERROR);
return req;
}
subreq = tstream_tls_connect_send(state,
state->ev,
plain_stream,
state->tls_params);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq,
tldap_tls_connect_crypto_done,
req);
return req;
}
static void tldap_tls_connect_crypto_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
struct tldap_tls_connect_state *state = tevent_req_data(
req, struct tldap_tls_connect_state);
struct tstream_context *tls_stream = NULL;
int ret;
int error;
ret = tstream_tls_connect_recv(subreq, &error, state, &tls_stream);
TALLOC_FREE(subreq);
if (ret != 0) {
DBG_ERR("tstream_tls_connect_recv(%s): %d %d\n",
tstream_tls_params_peer_name(state->tls_params),
ret,
error);
tevent_req_ldap_error(req, TLDAP_CONNECT_ERROR);
return;
}
tldap_set_tls_tstream(state->ctx, &tls_stream);
tevent_req_done(req);
}
TLDAPRC tldap_tls_connect_recv(struct tevent_req *req)
{
TLDAPRC rc;
if (tevent_req_is_ldap_error(req, &rc)) {
return rc;
}
return TLDAP_SUCCESS;
}
TLDAPRC tldap_tls_connect(struct tldap_context *ctx,
struct tstream_tls_params *tls_params)
{
TALLOC_CTX *frame = talloc_stackframe();
struct tevent_context *ev;
struct tevent_req *req;
TLDAPRC rc = TLDAP_NO_MEMORY;
ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}
req = tldap_tls_connect_send(frame, ev, ctx, tls_params);
if (req == NULL) {
goto fail;
}
if (!tevent_req_poll(req, ev)) {
rc = TLDAP_OPERATIONS_ERROR;
goto fail;
}
rc = tldap_tls_connect_recv(req);
fail:
TALLOC_FREE(frame);
return rc;
}