diff options
Diffstat (limited to 'source4/ldap_server')
-rw-r--r-- | source4/ldap_server/config.mk | 2 | ||||
-rw-r--r-- | source4/ldap_server/ldap_bind.c | 28 | ||||
-rw-r--r-- | source4/ldap_server/ldap_server.c | 127 | ||||
-rw-r--r-- | source4/ldap_server/ldap_server.h | 7 |
4 files changed, 49 insertions, 115 deletions
diff --git a/source4/ldap_server/config.mk b/source4/ldap_server/config.mk index 0ef8ced928..fc9d04c46a 100644 --- a/source4/ldap_server/config.mk +++ b/source4/ldap_server/config.mk @@ -11,6 +11,6 @@ OBJ_FILES = \ ldap_backend.o \ ldap_bind.o PUBLIC_DEPENDENCIES = \ - LIBCLI_LDAP SAMDB process_model auth + LIBCLI_LDAP SAMDB process_model auth GENSEC_SOCKET # End SUBSYSTEM SMB ####################### diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 35b6ad5fbf..7fce390450 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -22,10 +22,11 @@ #include "ldap_server/ldap_server.h" #include "auth/auth.h" #include "libcli/ldap/ldap.h" -#include "smbd/service_stream.h" +#include "smbd/service.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" #include "dsdb/samdb/samdb.h" +#include "auth/gensec/socket.h" static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) { @@ -89,6 +90,23 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) return NT_STATUS_OK; } +static void ldapsrv_set_sasl(void *private) +{ + struct ldapsrv_connection *conn = talloc_get_type(private, struct ldapsrv_connection); + struct socket_context *socket = gensec_socket_init(conn->gensec, + conn->connection->socket, + conn->connection->event.ctx, + stream_io_handler_callback, + conn->connection); + if (socket) { + conn->connection->socket = socket; + talloc_steal(conn->connection->socket, socket); + packet_set_socket(conn->packet, socket); + } else { + ldapsrv_terminate_connection(conn, "Failed to setup SASL wrapping on socket"); + } +} + static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) { struct ldap_BindRequest *req = &call->request->r.BindRequest; @@ -175,10 +193,10 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) result = LDAP_SUCCESS; errstr = NULL; - if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL) || - gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) { - conn->enable_wrap = True; - } + + call->send_callback = ldapsrv_set_sasl; + call->send_private = conn; + old_session_info = conn->session_info; conn->session_info = NULL; status = gensec_session_info(conn->gensec, &conn->session_info); diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index 07b1bc6a27..cfbe6eb5b2 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -31,10 +31,8 @@ #include "smbd/service_task.h" #include "smbd/service_stream.h" #include "smbd/service.h" -#include "lib/socket/socket.h" #include "lib/tls/tls.h" #include "lib/messaging/irpc.h" -#include "lib/stream/packet.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" #include "system/network.h" @@ -43,7 +41,7 @@ /* close the socket and shutdown a server_context */ -static void ldapsrv_terminate_connection(struct ldapsrv_connection *conn, +void ldapsrv_terminate_connection(struct ldapsrv_connection *conn, const char *reason) { stream_terminate_connection(conn->connection, reason); @@ -68,7 +66,6 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn, struct ldapsrv_call *call; NTSTATUS status; DATA_BLOB blob; - BOOL enable_wrap = conn->enable_wrap; call = talloc(conn, struct ldapsrv_call); if (!call) { @@ -79,11 +76,14 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn, call->request = talloc_steal(call, msg); call->conn = conn; call->replies = NULL; - + call->send_callback = NULL; + call->send_private = NULL; + /* make the call */ status = ldapsrv_do_call(call); if (!NT_STATUS_IS_OK(status)) { - goto failed; + talloc_free(call); + return; } blob = data_blob(NULL, 0); @@ -100,49 +100,36 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn, msg = call->replies->msg; if (!ldap_encode(msg, &b, call)) { DEBUG(0,("Failed to encode ldap reply of type %d\n", msg->type)); - goto failed; + talloc_free(call); + return; } status = data_blob_append(call, &blob, b.data, b.length); data_blob_free(&b); - if (!NT_STATUS_IS_OK(status)) goto failed; - - DLIST_REMOVE(call->replies, call->replies); - } + talloc_set_name_const(blob.data, "Outgoing, encoded LDAP packet"); - /* possibly encrypt/sign the reply */ - if (enable_wrap) { - DATA_BLOB wrapped; - - status = gensec_wrap(conn->gensec, call, &blob, &wrapped); if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - data_blob_free(&blob); - blob = data_blob_talloc(call, NULL, wrapped.length + 4); - if (blob.data == NULL) { - goto failed; + talloc_free(call); + return; } - RSIVAL(blob.data, 0, wrapped.length); - memcpy(blob.data+4, wrapped.data, wrapped.length); - data_blob_free(&wrapped); + + DLIST_REMOVE(call->replies, call->replies); } - packet_send(conn->packet, blob); + packet_send_callback(conn->packet, blob, + call->send_callback, call->send_private); talloc_free(call); return; - -failed: - talloc_free(call); } - /* - decode the input buffer + decode/process data */ -static NTSTATUS ldapsrv_decode_plain(struct ldapsrv_connection *conn, DATA_BLOB blob) +static NTSTATUS ldapsrv_decode(void *private, DATA_BLOB blob) { + struct ldapsrv_connection *conn = talloc_get_type(private, + struct ldapsrv_connection); struct asn1_data asn1; struct ldap_message *msg = talloc(conn, struct ldap_message); @@ -165,63 +152,6 @@ static NTSTATUS ldapsrv_decode_plain(struct ldapsrv_connection *conn, DATA_BLOB return NT_STATUS_OK; } - -/* - decode/process wrapped data -*/ -static NTSTATUS ldapsrv_decode_wrapped(struct ldapsrv_connection *conn, - DATA_BLOB blob) -{ - DATA_BLOB wrapped, unwrapped; - struct asn1_data asn1; - struct ldap_message *msg = talloc(conn, struct ldap_message); - NTSTATUS status; - - if (msg == NULL) { - return NT_STATUS_NO_MEMORY; - } - - wrapped = data_blob_const(blob.data+4, blob.length-4); - - status = gensec_unwrap(conn->gensec, msg, &wrapped, &unwrapped); - if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - data_blob_free(&blob); - - if (!asn1_load(&asn1, unwrapped)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - while (ldap_decode(&asn1, msg)) { - ldapsrv_process_message(conn, msg); - msg = talloc(conn, struct ldap_message); - } - - if (asn1.ofs < asn1.length) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - talloc_free(msg); - asn1_free(&asn1); - - return NT_STATUS_OK; -} - -/* - decode/process data -*/ -static NTSTATUS ldapsrv_decode(void *private, DATA_BLOB blob) -{ - struct ldapsrv_connection *conn = talloc_get_type(private, - struct ldapsrv_connection); - if (conn->enable_wrap) { - return ldapsrv_decode_wrapped(conn, blob); - } - return ldapsrv_decode_plain(conn, blob); -} - /* Idle timeout handler */ @@ -238,7 +168,7 @@ static void ldapsrv_conn_idle_timeout(struct event_context *ev, /* called when a LDAP socket becomes readable */ -static void ldapsrv_recv(struct stream_connection *c, uint16_t flags) +void ldapsrv_recv(struct stream_connection *c, uint16_t flags) { struct ldapsrv_connection *conn = talloc_get_type(c->private, struct ldapsrv_connection); @@ -262,20 +192,6 @@ static void ldapsrv_recv(struct stream_connection *c, uint16_t flags) } /* - check if a blob is a complete ldap packet - handle wrapper or unwrapped connections -*/ -NTSTATUS ldapsrv_complete_packet(void *private, DATA_BLOB blob, size_t *size) -{ - struct ldapsrv_connection *conn = talloc_get_type(private, - struct ldapsrv_connection); - if (conn->enable_wrap) { - return packet_full_request_u32(private, blob, size); - } - return ldap_full_packet(private, blob, size); -} - -/* called when a LDAP socket becomes writable */ static void ldapsrv_send(struct stream_connection *c, uint16_t flags) @@ -411,7 +327,6 @@ static void ldapsrv_accept(struct stream_connection *c) return; } - conn->enable_wrap = False; conn->packet = NULL; conn->connection = c; conn->service = ldapsrv_service; @@ -445,7 +360,7 @@ static void ldapsrv_accept(struct stream_connection *c) packet_set_private(conn->packet, conn); packet_set_socket(conn->packet, c->socket); packet_set_callback(conn->packet, ldapsrv_decode); - packet_set_full_request(conn->packet, ldapsrv_complete_packet); + packet_set_full_request(conn->packet, ldap_full_packet); packet_set_error_handler(conn->packet, ldapsrv_error_handler); packet_set_event_context(conn->packet, c->event.ctx); packet_set_fde(conn->packet, c->event.fde); diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h index 0b0b78ea7f..c35f62f134 100644 --- a/source4/ldap_server/ldap_server.h +++ b/source4/ldap_server/ldap_server.h @@ -20,6 +20,8 @@ */ #include "libcli/ldap/ldap.h" +#include "lib/socket/socket.h" +#include "lib/stream/packet.h" struct ldapsrv_connection { struct stream_connection *connection; @@ -29,9 +31,6 @@ struct ldapsrv_connection { struct cli_credentials *server_credentials; struct ldb_context *ldb; - /* are we using gensec wrapping? */ - BOOL enable_wrap; - BOOL global_catalog; struct packet_context *packet; @@ -54,6 +53,8 @@ struct ldapsrv_call { struct ldapsrv_reply *prev, *next; struct ldap_message *msg; } *replies; + packet_send_callback_fn_t send_callback; + void *send_private; }; struct ldapsrv_service; |