mirror of
https://github.com/samba-team/samba.git
synced 2025-08-04 08:22:08 +03:00
s4:ldap_server: rewrite to socket layer to use tstream
This should make our sasl and tls handling much more robust against partial sent pdus. metze Autobuild-User: Stefan Metzmacher <metze@samba.org> Autobuild-Date: Fri Oct 8 11:55:26 UTC 2010 on sn-devel-104
This commit is contained in:
@ -25,7 +25,9 @@
|
||||
#include "lib/ldb/include/ldb_errors.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
#include "auth/gensec/gensec.h"
|
||||
#include "auth/gensec/gensec_tstream.h"
|
||||
#include "param/param.h"
|
||||
#include "../lib/util/tevent_ntstatus.h"
|
||||
|
||||
static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
|
||||
{
|
||||
@ -94,20 +96,42 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
struct ldapsrv_sasl_context {
|
||||
struct ldapsrv_sasl_postprocess_context {
|
||||
struct ldapsrv_connection *conn;
|
||||
struct socket_context *sasl_socket;
|
||||
struct tstream_context *sasl;
|
||||
};
|
||||
|
||||
static void ldapsrv_set_sasl(void *private_data)
|
||||
{
|
||||
struct ldapsrv_sasl_context *ctx = talloc_get_type(private_data, struct ldapsrv_sasl_context);
|
||||
talloc_steal(ctx->conn->connection, ctx->sasl_socket);
|
||||
talloc_unlink(ctx->conn->connection, ctx->conn->connection->socket);
|
||||
struct ldapsrv_sasl_postprocess_state {
|
||||
uint8_t dummy;
|
||||
};
|
||||
|
||||
ctx->conn->sockets.sasl = ctx->sasl_socket;
|
||||
ctx->conn->connection->socket = ctx->sasl_socket;
|
||||
packet_set_socket(ctx->conn->packet, ctx->conn->connection->socket);
|
||||
static struct tevent_req *ldapsrv_sasl_postprocess_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
void *private_data)
|
||||
{
|
||||
struct ldapsrv_sasl_postprocess_context *context =
|
||||
talloc_get_type_abort(private_data,
|
||||
struct ldapsrv_sasl_postprocess_context);
|
||||
struct tevent_req *req;
|
||||
struct ldapsrv_sasl_postprocess_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct ldapsrv_sasl_postprocess_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TALLOC_FREE(context->conn->sockets.sasl);
|
||||
context->conn->sockets.sasl = talloc_move(context->conn, &context->sasl);
|
||||
context->conn->sockets.active = context->conn->sockets.sasl;
|
||||
|
||||
tevent_req_done(req);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
static NTSTATUS ldapsrv_sasl_postprocess_recv(struct tevent_req *req)
|
||||
{
|
||||
return tevent_req_simple_recv_ntstatus(req);
|
||||
}
|
||||
|
||||
static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
|
||||
@ -193,27 +217,41 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
|
||||
errstr = NULL;
|
||||
} else if (NT_STATUS_IS_OK(status)) {
|
||||
struct auth_session_info *old_session_info=NULL;
|
||||
struct ldapsrv_sasl_context *ctx;
|
||||
struct ldapsrv_sasl_postprocess_context *context = NULL;
|
||||
|
||||
result = LDAP_SUCCESS;
|
||||
errstr = NULL;
|
||||
|
||||
ctx = talloc(call, struct ldapsrv_sasl_context);
|
||||
if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
|
||||
gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
|
||||
|
||||
if (!ctx) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
} else {
|
||||
ctx->conn = conn;
|
||||
status = gensec_socket_init(conn->gensec,
|
||||
conn->connection,
|
||||
conn->connection->socket,
|
||||
conn->connection->event.ctx,
|
||||
stream_io_handler_callback,
|
||||
conn->connection,
|
||||
&ctx->sasl_socket);
|
||||
context = talloc(call, struct ldapsrv_sasl_postprocess_context);
|
||||
|
||||
if (!context) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx || !NT_STATUS_IS_OK(status)) {
|
||||
if (context && conn->sockets.tls) {
|
||||
TALLOC_FREE(context);
|
||||
status = NT_STATUS_NOT_SUPPORTED;
|
||||
result = LDAP_UNWILLING_TO_PERFORM;
|
||||
errstr = talloc_asprintf(reply,
|
||||
"SASL:[%s]: Sign or Seal are not allowed if TLS is used",
|
||||
req->creds.SASL.mechanism);
|
||||
}
|
||||
|
||||
if (context) {
|
||||
context->conn = conn;
|
||||
status = gensec_create_tstream(context,
|
||||
context->conn->gensec,
|
||||
context->conn->sockets.raw,
|
||||
&context->sasl);
|
||||
}
|
||||
|
||||
if (result != LDAP_SUCCESS) {
|
||||
conn->session_info = old_session_info;
|
||||
} else if (!NT_STATUS_IS_OK(status)) {
|
||||
conn->session_info = old_session_info;
|
||||
result = LDAP_OPERATIONS_ERROR;
|
||||
errstr = talloc_asprintf(reply,
|
||||
@ -221,9 +259,6 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
|
||||
req->creds.SASL.mechanism, nt_errstr(status));
|
||||
} else {
|
||||
|
||||
call->send_callback = ldapsrv_set_sasl;
|
||||
call->send_private = ctx;
|
||||
|
||||
old_session_info = conn->session_info;
|
||||
conn->session_info = NULL;
|
||||
status = gensec_session_info(conn->gensec, &conn->session_info);
|
||||
@ -251,6 +286,12 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_OK(status) && context) {
|
||||
call->postprocess_send = ldapsrv_sasl_postprocess_send;
|
||||
call->postprocess_recv = ldapsrv_sasl_postprocess_recv;
|
||||
call->postprocess_private = context;
|
||||
}
|
||||
} else {
|
||||
status = auth_nt_status_squash(status);
|
||||
if (result == 0) {
|
||||
|
Reference in New Issue
Block a user