diff options
author | Stefan Metzmacher <metze@samba.org> | 2010-09-22 14:24:03 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2010-10-08 11:55:26 +0000 |
commit | 61c7b67df9ba484c0e810c07c8da852edf1ef2fc (patch) | |
tree | 3ee039f28f60d23abb5ced22b90c76c77db3a6bf /source4/ldap_server/ldap_bind.c | |
parent | 9300f922ae570756651c6f9979dd3e490ce2fd4e (diff) | |
download | samba-61c7b67df9ba484c0e810c07c8da852edf1ef2fc.tar.gz samba-61c7b67df9ba484c0e810c07c8da852edf1ef2fc.tar.bz2 samba-61c7b67df9ba484c0e810c07c8da852edf1ef2fc.zip |
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
Diffstat (limited to 'source4/ldap_server/ldap_bind.c')
-rw-r--r-- | source4/ldap_server/ldap_bind.c | 93 |
1 files changed, 67 insertions, 26 deletions
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 529a12d1ca..5036353a4b 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -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_postprocess_state { + uint8_t dummy; +}; + +static struct tevent_req *ldapsrv_sasl_postprocess_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + 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_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; + } - ctx->conn->sockets.sasl = ctx->sasl_socket; - ctx->conn->connection->socket = ctx->sasl_socket; - packet_set_socket(ctx->conn->packet, ctx->conn->connection->socket); + 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 (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 (!ctx || !NT_STATUS_IS_OK(status)) { + 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) { |