[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Thu Oct 7 04:32:01 MDT 2010


The branch, master has been updated
       via  ab31d9a Revert "s4:ldap_server: rewrite to socket layer to use tstream"
      from  ea36245 s4:dsdb/common/util_samr.c - use an LDB constant for result checking

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit ab31d9aac9a02756cf5af313ed36fc549a8f4b67
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Oct 5 07:47:51 2010 +0200

    Revert "s4:ldap_server: rewrite to socket layer to use tstream"
    
    This reverts commit b53fbc75acc525f2e2450370e704a62791271788.
    
    There are problems with problems with broken gnutls versions.
    
    We can readd this once we have the needed configure checks to
    detect the bug in gnutls. See https://bugzilla.samba.org/show_bug.cgi?id=7218.
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Thu Oct  7 10:31:18 UTC 2010 on sn-devel-104

-----------------------------------------------------------------------

Summary of changes:
 source4/ldap_server/ldap_bind.c     |   93 ++---
 source4/ldap_server/ldap_extended.c |  105 +----
 source4/ldap_server/ldap_server.c   |  766 +++++++++++------------------------
 source4/ldap_server/ldap_server.h   |   35 +-
 4 files changed, 305 insertions(+), 694 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index 5036353..529a12d 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -25,9 +25,7 @@
 #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)
 {
@@ -96,42 +94,20 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
 	return NT_STATUS_OK;
 }
 
-struct ldapsrv_sasl_postprocess_context {
+struct ldapsrv_sasl_context {
 	struct ldapsrv_connection *conn;
-	struct tstream_context *sasl;
+	struct socket_context *sasl_socket;
 };
 
-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)
+static void ldapsrv_set_sasl(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;
-	}
+	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);
 
-	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);
+	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 NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
@@ -217,41 +193,27 @@ 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_postprocess_context *context = NULL;
+		struct ldapsrv_sasl_context *ctx;
 
 		result = LDAP_SUCCESS;
 		errstr = NULL;
 
-		if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
-		    gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
-
-			context = talloc(call, struct ldapsrv_sasl_postprocess_context);
-
-			if (!context) {
-				status = NT_STATUS_NO_MEMORY;
-			}
-		}
+		ctx = talloc(call, struct ldapsrv_sasl_context);
 
-		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) {
+			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);
 		}
 
-		if (result != LDAP_SUCCESS) {
-			conn->session_info = old_session_info;
-		} else if (!NT_STATUS_IS_OK(status)) {
+		if (!ctx || !NT_STATUS_IS_OK(status)) {
 			conn->session_info = old_session_info;
 			result = LDAP_OPERATIONS_ERROR;
 			errstr = talloc_asprintf(reply, 
@@ -259,6 +221,9 @@ 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);
@@ -286,12 +251,6 @@ 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) {
diff --git a/source4/ldap_server/ldap_extended.c b/source4/ldap_server/ldap_extended.c
index f70b808..42fc83b 100644
--- a/source4/ldap_server/ldap_extended.c
+++ b/source4/ldap_server/ldap_extended.c
@@ -22,91 +22,28 @@
 #include "../lib/util/dlinklist.h"
 #include "lib/tls/tls.h"
 #include "smbd/service_stream.h"
-#include "../lib/util/tevent_ntstatus.h"
 
-struct ldapsrv_starttls_postprocess_context {
+struct ldapsrv_starttls_context {
 	struct ldapsrv_connection *conn;
+	struct socket_context *tls_socket;
 };
 
-struct ldapsrv_starttls_postprocess_state {
-	struct ldapsrv_connection *conn;
-};
-
-static void ldapsrv_starttls_postprocess_done(struct tevent_req *subreq);
-
-static struct tevent_req *ldapsrv_starttls_postprocess_send(TALLOC_CTX *mem_ctx,
-						struct tevent_context *ev,
-						void *private_data)
-{
-	struct ldapsrv_starttls_postprocess_context *context =
-		talloc_get_type_abort(private_data,
-		struct ldapsrv_starttls_postprocess_context);
-	struct ldapsrv_connection *conn = context->conn;
-	struct tevent_req *req;
-	struct ldapsrv_starttls_postprocess_state *state;
-	struct tevent_req *subreq;
-
-	req = tevent_req_create(mem_ctx, &state,
-				struct ldapsrv_starttls_postprocess_state);
-	if (req == NULL) {
-		return NULL;
-	}
-
-	state->conn = conn;
-
-	subreq = tstream_tls_accept_send(conn,
-					 conn->connection->event.ctx,
-					 conn->sockets.raw,
-					 conn->service->tls_params);
-	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
-	}
-	tevent_req_set_callback(subreq, ldapsrv_starttls_postprocess_done, req);
-
-	return req;
-}
-
-static void ldapsrv_starttls_postprocess_done(struct tevent_req *subreq)
+static void ldapsrv_start_tls(void *private_data)
 {
-	struct tevent_req *req =
-		tevent_req_callback_data(subreq,
-		struct tevent_req);
-	struct ldapsrv_starttls_postprocess_state *state =
-		tevent_req_data(req,
-		struct ldapsrv_starttls_postprocess_state);
-	struct ldapsrv_connection *conn = state->conn;
-	int ret;
-	int sys_errno;
-
-	ret = tstream_tls_accept_recv(subreq, &sys_errno,
-				      conn, &conn->sockets.tls);
-	TALLOC_FREE(subreq);
-	if (ret == -1) {
-		NTSTATUS status = map_nt_error_from_unix(sys_errno);
-
-		DEBUG(1,("ldapsrv_starttls_postprocess_done: accept_tls_loop: "
-			 "tstream_tls_accept_recv() - %d:%s => %s",
-			 sys_errno, strerror(sys_errno), nt_errstr(status)));
-
-		tevent_req_nterror(req, status);
-		return;
-	}
-
-	conn->sockets.active = conn->sockets.tls;
-
-	tevent_req_done(req);
-}
+	struct ldapsrv_starttls_context *ctx = talloc_get_type(private_data, struct ldapsrv_starttls_context);
+	talloc_steal(ctx->conn->connection, ctx->tls_socket);
 
-static NTSTATUS ldapsrv_starttls_postprocess_recv(struct tevent_req *req)
-{
-	return tevent_req_simple_recv_ntstatus(req);
+	ctx->conn->sockets.tls = ctx->tls_socket;
+	ctx->conn->connection->socket = ctx->tls_socket;
+	packet_set_socket(ctx->conn->packet, ctx->conn->connection->socket);
+	packet_set_unreliable_select(ctx->conn->packet);
 }
 
 static NTSTATUS ldapsrv_StartTLS(struct ldapsrv_call *call,
 				 struct ldapsrv_reply *reply,
 				 const char **errstr)
 {
-	struct ldapsrv_starttls_postprocess_context *context;
+	struct ldapsrv_starttls_context *ctx;
 
 	(*errstr) = NULL;
 
@@ -121,19 +58,21 @@ static NTSTATUS ldapsrv_StartTLS(struct ldapsrv_call *call,
 		return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
 	}
 
-	if (call->conn->sockets.sasl) {
-		(*errstr) = talloc_asprintf(reply, "START-TLS: SASL is already enabled on this LDAP session");
+	ctx = talloc(call, struct ldapsrv_starttls_context);
+	NT_STATUS_HAVE_NO_MEMORY(ctx);
+
+	ctx->conn = call->conn;
+	ctx->tls_socket = tls_init_server(call->conn->service->tls_params,
+					  call->conn->connection->socket,
+					  call->conn->connection->event.fde,
+					  NULL);
+	if (!ctx->tls_socket) {
+		(*errstr) = talloc_asprintf(reply, "START-TLS: Failed to setup TLS socket");
 		return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
 	}
 
-	context = talloc(call, struct ldapsrv_starttls_postprocess_context);
-	NT_STATUS_HAVE_NO_MEMORY(context);
-
-	context->conn = call->conn;
-
-	call->postprocess_send = ldapsrv_starttls_postprocess_send;
-	call->postprocess_recv = ldapsrv_starttls_postprocess_recv;
-	call->postprocess_private = context;
+	call->send_callback = ldapsrv_start_tls;
+	call->send_private  = ctx;
 
 	reply->msg->r.ExtendedResponse.response.resultcode = LDAP_SUCCESS;
 	reply->msg->r.ExtendedResponse.response.errormessage = NULL;
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index 56e1bdc..d75ddcc 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -22,7 +22,6 @@
 */
 
 #include "includes.h"
-#include "system/network.h"
 #include "lib/events/events.h"
 #include "auth/auth.h"
 #include "auth/credentials/credentials.h"
@@ -43,97 +42,173 @@
 #include "lib/socket/netif.h"
 #include "dsdb/samdb/samdb.h"
 #include "param/param.h"
-#include "../lib/tsocket/tsocket.h"
-#include "../lib/util/tevent_ntstatus.h"
-#include "../libcli/util/tstream.h"
-
-static void ldapsrv_terminate_connection_done(struct tevent_req *subreq);
-
 /*
   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)
 {
-	struct tevent_req *subreq;
+	packet_recv_disable(conn->packet);
+	TALLOC_FREE(conn->packet);
+	TALLOC_FREE(conn->sockets.tls);
+	stream_terminate_connection(conn->connection, reason);
+}
+
+/*
+  handle packet errors
+*/
+static void ldapsrv_error_handler(void *private_data, NTSTATUS status)
+{
+	struct ldapsrv_connection *conn = talloc_get_type(private_data,
+							  struct ldapsrv_connection);
+	ldapsrv_terminate_connection(conn, nt_errstr(status));
+}
 
-	if (conn->limits.reason) {
+/*
+  process a decoded ldap message
+*/
+static void ldapsrv_process_message(struct ldapsrv_connection *conn,
+				    struct ldap_message *msg)
+{
+	struct ldapsrv_call *call;
+	NTSTATUS status;
+	DATA_BLOB blob;
+
+	call = talloc(conn, struct ldapsrv_call);
+	if (!call) {
+		ldapsrv_terminate_connection(conn, "no memory");
 		return;
 	}
 
-	conn->limits.endtime = timeval_current_ofs(0, 500);
-
-	DEBUG(2,("ldapsrv_terminate_connection: %s - disconnecting\n",
-		 reason));
+	call->request = talloc_steal(call, msg);
+	call->conn = conn;
+	call->replies = NULL;
+	call->send_callback = NULL;
+	call->send_private = NULL;
 
-	tevent_queue_stop(conn->sockets.send_queue);
-	if (conn->active_call) {
-		tevent_req_cancel(conn->active_call);
-		conn->active_call = NULL;
+	/* make the call */
+	status = ldapsrv_do_call(call);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(call);
+		return;
 	}
 
-	conn->limits.reason = talloc_strdup(conn, reason);
-	if (conn->limits.reason == NULL) {
-		TALLOC_FREE(conn->sockets.tls);
-		TALLOC_FREE(conn->sockets.sasl);
-		TALLOC_FREE(conn->sockets.raw);
-		stream_terminate_connection(conn->connection, reason);
+	blob = data_blob(NULL, 0);
+
+	if (call->replies == NULL) {
+		talloc_free(call);
 		return;
 	}
 
-	subreq = tstream_disconnect_send(conn,
-					 conn->connection->event.ctx,
-					 conn->sockets.active);
-	if (subreq == NULL) {
-		TALLOC_FREE(conn->sockets.tls);
-		TALLOC_FREE(conn->sockets.sasl);
-		TALLOC_FREE(conn->sockets.raw);
-		stream_terminate_connection(conn->connection, reason);
-		return;
+	/* build all the replies into a single blob */
+	while (call->replies) {
+		DATA_BLOB b;
+		bool ret;
+
+		msg = call->replies->msg;
+		if (!ldap_encode(msg, samba_ldap_control_handlers(), &b, call)) {
+			DEBUG(0,("Failed to encode ldap reply of type %d\n", msg->type));
+			talloc_free(call);
+			return;
+		}
+
+		ret = data_blob_append(call, &blob, b.data, b.length);
+		data_blob_free(&b);
+
+		talloc_set_name_const(blob.data, "Outgoing, encoded LDAP packet");
+
+		if (!ret) {
+			talloc_free(call);
+			return;
+		}
+
+		DLIST_REMOVE(call->replies, call->replies);
 	}
-	tevent_req_set_endtime(subreq,
-			       conn->connection->event.ctx,
-			       conn->limits.endtime);
-	tevent_req_set_callback(subreq, ldapsrv_terminate_connection_done, conn);
+
+	packet_send_callback(conn->packet, blob,
+			     call->send_callback, call->send_private);
+	talloc_free(call);
+	return;
 }
 
-static void ldapsrv_terminate_connection_done(struct tevent_req *subreq)
+/*
+  disable packets on other sockets while processing this one
+ */
+static void ldapsrv_disable_recv(struct ldapsrv_connection *conn)
 {
-	struct ldapsrv_connection *conn =
-		tevent_req_callback_data(subreq,
-		struct ldapsrv_connection);
-	int ret;
-	int sys_errno;
+	struct ldapsrv_packet_interfaces *p;
+	for (p=conn->service->packet_interfaces; p; p=p->next) {
+		if (p->packet != conn->packet) {
+			packet_recv_disable(p->packet);
+		}
+	}
+}
 
-	ret = tstream_disconnect_recv(subreq, &sys_errno);
-	TALLOC_FREE(subreq);
+/*
+  disable packets on other sockets while processing this one
+ */
+static void ldapsrv_enable_recv(struct ldapsrv_connection *conn)
+{
+	struct ldapsrv_packet_interfaces *p;
+	for (p=conn->service->packet_interfaces; p; p=p->next) {
+		if (p->packet != conn->packet) {
+			packet_recv_enable(p->packet);
+		}
+	}
+}
 
-	if (conn->sockets.active == conn->sockets.raw) {
-		TALLOC_FREE(conn->sockets.tls);
-		TALLOC_FREE(conn->sockets.sasl);
-		TALLOC_FREE(conn->sockets.raw);
-		stream_terminate_connection(conn->connection,
-					    conn->limits.reason);
-		return;
+/*
+  decode/process data
+*/
+static NTSTATUS ldapsrv_decode(void *private_data, DATA_BLOB blob)
+{
+	NTSTATUS status;
+	struct ldapsrv_connection *conn = talloc_get_type(private_data,
+							  struct ldapsrv_connection);
+	struct asn1_data *asn1 = asn1_init(conn);
+	struct ldap_message *msg = talloc(conn, struct ldap_message);
+
+	if (asn1 == NULL || msg == NULL) {
+		return NT_STATUS_NO_MEMORY;
 	}
 
-	TALLOC_FREE(conn->sockets.tls);
-	TALLOC_FREE(conn->sockets.sasl);
-	conn->sockets.active = conn->sockets.raw;
-
-	subreq = tstream_disconnect_send(conn,
-					 conn->connection->event.ctx,
-					 conn->sockets.active);
-	if (subreq == NULL) {
-		TALLOC_FREE(conn->sockets.raw);
-		stream_terminate_connection(conn->connection,
-					    conn->limits.reason);
-		return;
+	if (!asn1_load(asn1, blob)) {
+		talloc_free(msg);
+		talloc_free(asn1);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = ldap_decode(asn1, samba_ldap_control_handlers(), msg);
+	if (!NT_STATUS_IS_OK(status)) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list