s4:libcli/ldap: conversion to tstream and more...

Stefan (metze) Metzmacher metze at samba.org
Mon Jun 22 14:31:04 MDT 2015


Hi,

here're some patches which convert s4:libcli/ldap to tstream.

This allows us to finally remove gensec_socket_init() which
used the socket_context/packet_context.

Please review and push.

Thanks!
metze
-------------- next part --------------
From 8fed0572214650fa4567b41dc505359b1aa3bfe0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 18 Jun 2015 23:18:58 +0200
Subject: [PATCH 01/12] s4:gensec/gssapi: use
 gensec_gssapi_max_{input,wrapped}_size() for all backends

This avoids calls to gensec_gssapi_sig_size() as fallback in
gensec_max_input_size().

gensec_gssapi_sig_size() needs to report the sig size
gensec_{sign,seal}_packet(), which could be different to the
overhead produced by gensec_wrap().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/gensec/gensec_gssapi.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 5582102..fd0f2a1 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -1531,6 +1531,8 @@ static const struct gensec_security_ops gensec_gssapi_spnego_security_ops = {
 	.check_packet	= gensec_gssapi_check_packet,
 	.seal_packet	= gensec_gssapi_seal_packet,
 	.unseal_packet	= gensec_gssapi_unseal_packet,
+	.max_input_size	  = gensec_gssapi_max_input_size,
+	.max_wrapped_size = gensec_gssapi_max_wrapped_size,
 	.wrap           = gensec_gssapi_wrap,
 	.unwrap         = gensec_gssapi_unwrap,
 	.have_feature   = gensec_gssapi_have_feature,
@@ -1556,6 +1558,8 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = {
 	.check_packet	= gensec_gssapi_check_packet,
 	.seal_packet	= gensec_gssapi_seal_packet,
 	.unseal_packet	= gensec_gssapi_unseal_packet,
+	.max_input_size	  = gensec_gssapi_max_input_size,
+	.max_wrapped_size = gensec_gssapi_max_wrapped_size,
 	.wrap           = gensec_gssapi_wrap,
 	.unwrap         = gensec_gssapi_unwrap,
 	.have_feature   = gensec_gssapi_have_feature,
-- 
1.9.1


From 0bbe1e633de0924b4d299622d2c0b2dc83132eca Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 18 Jun 2015 21:07:58 +0200
Subject: [PATCH 02/12] s4:gensec/gssapi: make calculation of
 gensec_gssapi_sig_size() for aes keys more clear

This way the result matches what gss_wrap_iov_length() would return.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/gensec/gensec_gssapi.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index fd0f2a1..b3a4697 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -1470,11 +1470,10 @@ static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, si
 
 	if (gensec_gssapi_state->lucid->protocol == 1) {
 		if (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG) {
-			/*
-			 * TODO: windows uses 76 here, but we don't know
-			 *       gss_wrap works with aes keys yet
-			 */
-			gensec_gssapi_state->sig_size = 76;
+			gensec_gssapi_state->sig_size = 60;
+			if (gensec_gssapi_state->gss_got_flags & GSS_C_DCE_STYLE) {
+				gensec_gssapi_state->sig_size += 16;
+			}
 		} else {
 			gensec_gssapi_state->sig_size = 28;
 		}
-- 
1.9.1


From 259a98886ded42aece818ee47907615d385544be Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 19 Jun 2015 01:07:49 +0200
Subject: [PATCH 03/12] s3:libads/sasl: use gensec_max_{input,wrapped}_size()
 in ads_sasl_spnego_ntlmssp_bind

gensec_sig_size() is for gensec_{sign,seal}_packet() instead of gensec_wrap().

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/libads/sasl.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
index db7335e..720ee78 100644
--- a/source3/libads/sasl.c
+++ b/source3/libads/sasl.c
@@ -250,11 +250,12 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
 	} while (rc == LDAP_SASL_BIND_IN_PROGRESS && !NT_STATUS_IS_OK(nt_status));
 	
 	if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
-		uint32_t sig_size = gensec_sig_size(auth_generic_state->gensec_security, 0);
-		ads->ldap.out.max_unwrapped = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED - sig_size;
-		ads->ldap.out.sig_size = sig_size;
+		size_t max_wrapped = gensec_max_wrapped_size(auth_generic_state->gensec_security);
+		ads->ldap.out.max_unwrapped = gensec_max_input_size(auth_generic_state->gensec_security);
+
+		ads->ldap.out.sig_size = max_wrapped - ads->ldap.out.max_unwrapped;
 		ads->ldap.in.min_wrapped = ads->ldap.out.sig_size;
-		ads->ldap.in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
+		ads->ldap.in.max_wrapped = max_wrapped;
 		status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, auth_generic_state->gensec_security);
 		if (!ADS_ERR_OK(status)) {
 			DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
-- 
1.9.1


From bb29e9cb0f9bae168002b022e18112912dd231a6 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 19 Jun 2015 12:26:55 +0200
Subject: [PATCH 04/12] s4:lib/tls: fix tstream_tls_connect_send() define

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/lib/tls/tls.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/lib/tls/tls.h b/source4/lib/tls/tls.h
index 64ab7c2..3ff009d 100644
--- a/source4/lib/tls/tls.h
+++ b/source4/lib/tls/tls.h
@@ -90,7 +90,7 @@ struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx,
 					     struct tstream_context *plain_stream,
 					     struct tstream_tls_params *tls_params,
 					     const char *location);
-#define tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params); \
+#define tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params) \
 	_tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params, __location__)
 
 int tstream_tls_connect_recv(struct tevent_req *req,
-- 
1.9.1


From cd74b52342cfa1b02fe07cf50dc6d89cd8ba3ee0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 19 Jun 2015 13:30:10 +0200
Subject: [PATCH 05/12] s4:lib/tls: ignore non-existing ca and crl files in
 tstream_tls_params_client()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/lib/tls/tls_tstream.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source4/lib/tls/tls_tstream.c b/source4/lib/tls/tls_tstream.c
index 5b2329b..113e03a 100644
--- a/source4/lib/tls/tls_tstream.c
+++ b/source4/lib/tls/tls_tstream.c
@@ -919,7 +919,7 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	if (ca_file && *ca_file) {
+	if (ca_file && *ca_file && file_exist(ca_file)) {
 		ret = gnutls_certificate_set_x509_trust_file(tlsp->x509_cred,
 							     ca_file,
 							     GNUTLS_X509_FMT_PEM);
@@ -931,7 +931,7 @@ NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx,
 		}
 	}
 
-	if (crl_file && *crl_file) {
+	if (crl_file && *crl_file && file_exist(crl_file)) {
 		ret = gnutls_certificate_set_x509_crl_file(tlsp->x509_cred,
 							   crl_file, 
 							   GNUTLS_X509_FMT_PEM);
-- 
1.9.1


From 226ae2bf092075270be7c1a499dc5904a8a13e5d Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 19 Jun 2015 12:26:06 +0200
Subject: [PATCH 06/12] s4:libcli/ldap: conversion to tstream

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/libcli/ldap/ldap_bind.c   |  65 ++++--
 source4/libcli/ldap/ldap_client.c | 443 +++++++++++++++++++++++++-------------
 source4/libcli/ldap/ldap_client.h |  17 +-
 source4/libcli/ldap/wscript_build |   4 +-
 4 files changed, 357 insertions(+), 172 deletions(-)

diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c
index a96ea9f..daa7662 100644
--- a/source4/libcli/ldap/ldap_bind.c
+++ b/source4/libcli/ldap/ldap_bind.c
@@ -28,7 +28,7 @@
 #include "lib/tls/tls.h"
 #include "auth/gensec/gensec.h"
 #include "auth/gensec/gensec_internal.h" /* TODO: remove this */
-#include "auth/gensec/gensec_socket.h"
+#include "source4/auth/gensec/gensec_tstream.h"
 #include "auth/credentials/credentials.h"
 #include "lib/stream/packet.h"
 #include "param/param.h"
@@ -224,6 +224,27 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
 		NULL 
 	};
 	unsigned int logon_retries = 0;
+	size_t queue_length;
+
+	if (conn->sockets.active == NULL) {
+		status = NT_STATUS_CONNECTION_DISCONNECTED;
+		goto failed;
+	}
+
+	queue_length = tevent_queue_length(conn->sockets.send_queue);
+	if (queue_length != 0) {
+		status = NT_STATUS_INVALID_PARAMETER_MIX;
+		DEBUG(1, ("SASL bind triggered with non empty send_queue[%ju]: %s\n",
+			  queue_length, nt_errstr(status)));
+		goto failed;
+	}
+
+	if (conn->pending != NULL) {
+		status = NT_STATUS_INVALID_PARAMETER_MIX;
+		DEBUG(1, ("SASL bind triggered with pending requests: %s\n",
+			  nt_errstr(status)));
+		goto failed;
+	}
 
 	status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs,
 			      false, NULL, NULL, &sasl_mechs_msgs);
@@ -281,7 +302,7 @@ try_logon_again:
 	/* require Kerberos SIGN/SEAL only if we don't use SSL
 	 * Windows seem not to like double encryption */
 	old_gensec_features = cli_credentials_get_gensec_features(creds);
-	if (tls_enabled(conn->sock)) {
+	if (conn->sockets.active == conn->sockets.tls) {
 		cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL));
 	}
 
@@ -436,27 +457,31 @@ try_logon_again:
 		}
 	}
 
-	talloc_free(tmp_ctx);
+	TALLOC_FREE(tmp_ctx);
 
-	if (NT_STATUS_IS_OK(status)) {
-		struct socket_context *sasl_socket;
-		status = gensec_socket_init(conn->gensec, 
-					    conn,
-					    conn->sock,
-					    conn->event.event_ctx, 
-					    ldap_read_io_handler,
-					    conn,
-					    &sasl_socket);
-		if (!NT_STATUS_IS_OK(status)) goto failed;
-
-		conn->sock = sasl_socket;
-		packet_set_socket(conn->packet, conn->sock);
-
-		conn->bind.type = LDAP_BIND_SASL;
-		conn->bind.creds = creds;
+	if (!NT_STATUS_IS_OK(status)) {
+		goto failed;
 	}
 
-	return status;
+	conn->bind.type = LDAP_BIND_SASL;
+	conn->bind.creds = creds;
+
+	if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) &&
+	    !gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
+		return NT_STATUS_OK;
+	}
+
+	status = gensec_create_tstream(conn->sockets.raw,
+				       conn->gensec,
+				       conn->sockets.raw,
+				       &conn->sockets.sasl);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto failed;
+	}
+
+	conn->sockets.active = conn->sockets.sasl;
+
+	return NT_STATUS_OK;
 
 failed:
 	talloc_free(tmp_ctx);
diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c
index 7c8bb03..e49df9e 100644
--- a/source4/libcli/ldap/ldap_client.c
+++ b/source4/libcli/ldap/ldap_client.c
@@ -25,22 +25,36 @@
 #include "includes.h"
 #include <tevent.h>
 #include "lib/socket/socket.h"
+#include "lib/tsocket/tsocket.h"
+#include "libcli/util/tstream.h"
 #include "../lib/util/asn1.h"
 #include "../lib/util/dlinklist.h"
 #include "libcli/ldap/libcli_ldap.h"
 #include "libcli/ldap/ldap_proto.h"
 #include "libcli/ldap/ldap_client.h"
 #include "libcli/composite/composite.h"
-#include "lib/stream/packet.h"
 #include "lib/tls/tls.h"
 #include "auth/gensec/gensec.h"
 #include "system/time.h"
 #include "param/param.h"
 #include "libcli/resolve/resolve.h"
 
+static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status);
+
+static int ldap_connection_destructor(struct ldap_connection *conn)
+{
+	/*
+	 * NT_STATUS_OK means that callbacks of pending requests are not
+	 * triggered
+	 */
+	ldap_connection_dead(conn, NT_STATUS_OK);
+	return 0;
+}
+
 /**
   create a new ldap_connection stucture. The event context is optional
 */
+
 _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, 
 					     struct loadparm_context *lp_ctx,
 					     struct tevent_context *ev)
@@ -59,6 +73,13 @@ _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx,
 	conn->next_messageid  = 1;
 	conn->event.event_ctx = ev;
 
+	conn->sockets.send_queue = tevent_queue_create(conn,
+					"ldap_connection send_queue");
+	if (conn->sockets.send_queue == NULL) {
+		TALLOC_FREE(conn);
+		return NULL;
+	}
+
 	conn->lp_ctx = lp_ctx;
 
 	/* set a reasonable request timeout */
@@ -66,29 +87,35 @@ _PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx,
 
 	/* explicitly avoid reconnections by default */
 	conn->reconnect.max_retries = 0;
-	
+
+	talloc_set_destructor(conn, ldap_connection_destructor);
 	return conn;
 }
 
 /*
   the connection is dead
 */
-static void ldap_connection_dead(struct ldap_connection *conn)
+static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status)
 {
 	struct ldap_request *req;
 
-	talloc_free(conn->sock);  /* this will also free event.fde */
-	talloc_free(conn->packet);
-	conn->sock = NULL;
-	conn->event.fde = NULL;
-	conn->packet = NULL;
+	tevent_queue_stop(conn->sockets.send_queue);
+	TALLOC_FREE(conn->sockets.recv_subreq);
+	conn->sockets.active = NULL;
+	TALLOC_FREE(conn->sockets.sasl);
+	TALLOC_FREE(conn->sockets.tls);
+	TALLOC_FREE(conn->sockets.raw);
 
 	/* return an error for any pending request ... */
 	while (conn->pending) {
 		req = conn->pending;
 		DLIST_REMOVE(req->conn->pending, req);
+		req->conn = NULL;
 		req->state = LDAP_REQUEST_DONE;
-		req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
+		if (NT_STATUS_IS_OK(status)) {
+			continue;
+		}
+		req->status = status;
 		if (req->async.fn) {
 			req->async.fn(req);
 		}
@@ -100,11 +127,9 @@ static void ldap_reconnect(struct ldap_connection *conn);
 /*
   handle packet errors
 */
-static void ldap_error_handler(void *private_data, NTSTATUS status)
+static void ldap_error_handler(struct ldap_connection *conn, NTSTATUS status)
 {
-	struct ldap_connection *conn = talloc_get_type(private_data, 
-						       struct ldap_connection);
-	ldap_connection_dead(conn);
+	ldap_connection_dead(conn, status);
 
 	/* but try to reconnect so that the ldb client can go on */
 	ldap_reconnect(conn);
@@ -130,7 +155,7 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message
 	if (req == NULL) {
 		DEBUG(0,("ldap: no matching message id for %u\n",
 			 msg->messageid));
-		talloc_free(msg);
+		TALLOC_FREE(msg);
 		return;
 	}
 
@@ -138,6 +163,7 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message
 	for (i=0; msg->controls && msg->controls[i]; i++) {
 		if (!msg->controls_decoded[i] && 
 		    msg->controls[i]->critical) {
+			TALLOC_FREE(msg);
 			req->status = NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION);
 			req->state = LDAP_REQUEST_DONE;
 			DLIST_REMOVE(conn->pending, req);
@@ -149,10 +175,10 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message
 	}
 
 	/* add to the list of replies received */
-	talloc_steal(req, msg);
 	req->replies = talloc_realloc(req, req->replies, 
 				      struct ldap_message *, req->num_replies+1);
 	if (req->replies == NULL) {
+		TALLOC_FREE(msg);
 		req->status = NT_STATUS_NO_MEMORY;
 		req->state = LDAP_REQUEST_DONE;
 		DLIST_REMOVE(conn->pending, req);
@@ -178,64 +204,120 @@ static void ldap_match_message(struct ldap_connection *conn, struct ldap_message
 	}
 }
 
+static void ldap_connection_recv_done(struct tevent_req *subreq);
+
+static void ldap_connection_recv_next(struct ldap_connection *conn)
+{
+	struct tevent_req *subreq = NULL;
+
+	if (conn->sockets.recv_subreq != NULL) {
+		return;
+	}
+
+	if (conn->sockets.active == NULL) {
+		return;
+	}
+
+	if (conn->pending == NULL) {
+		return;
+	}
+
+	/*
+	 * The minimun size of a LDAP pdu is 7 bytes
+	 *
+	 * dumpasn1 -hh ldap-unbind-min.dat
+	 *
+	 *     <30 05 02 01 09 42 00>
+	 *    0    5: SEQUENCE {
+	 *     <02 01 09>
+	 *    2    1:   INTEGER 9
+	 *     <42 00>
+	 *    5    0:   [APPLICATION 2]
+	 *          :     Error: Object has zero length.
+	 *          :   }
+	 *
+	 * dumpasn1 -hh ldap-unbind-windows.dat
+	 *
+	 *     <30 84 00 00 00 05 02 01 09 42 00>
+	 *    0    5: SEQUENCE {
+	 *     <02 01 09>
+	 *    6    1:   INTEGER 9
+	 *     <42 00>
+	 *    9    0:   [APPLICATION 2]
+	 *          :     Error: Object has zero length.
+	 *          :   }
+	 *
+	 * This means using an initial read size
+	 * of 7 is ok.
+	 */
+	subreq = tstream_read_pdu_blob_send(conn,
+					    conn->event.event_ctx,
+					    conn->sockets.active,
+					    7, /* initial_read_size */
+					    ldap_full_packet,
+					    conn);
+	if (subreq == NULL) {
+		ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
+		return;
+	}
+	tevent_req_set_callback(subreq, ldap_connection_recv_done, conn);
+	conn->sockets.recv_subreq = subreq;
+	return;
+}
 
 /*
   decode/process LDAP data
 */
-static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob)
+static void ldap_connection_recv_done(struct tevent_req *subreq)
 {
 	NTSTATUS status;
-	struct ldap_connection *conn = talloc_get_type(private_data, 
-						       struct ldap_connection);
-	struct ldap_message *msg = talloc(conn, struct ldap_message);
-	struct asn1_data *asn1 = asn1_init(conn);
-
-	if (asn1 == NULL || msg == NULL) {
-		return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+	struct ldap_connection *conn =
+		tevent_req_callback_data(subreq,
+		struct ldap_connection);
+	struct ldap_message *msg;
+	struct asn1_data *asn1;
+	DATA_BLOB blob;
+
+	msg = talloc_zero(conn, struct ldap_message);
+	if (msg == NULL) {
+		ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
+		return;
 	}
 
-	if (!asn1_load(asn1, blob)) {
-		talloc_free(msg);
-		talloc_free(asn1);
-		return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
+	asn1 = asn1_init(conn);
+	if (asn1 == NULL) {
+		TALLOC_FREE(msg);
+		ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
+		return;
 	}
-	
-	status = ldap_decode(asn1, samba_ldap_control_handlers(), msg);
+
+	conn->sockets.recv_subreq = NULL;
+
+	status = tstream_read_pdu_blob_recv(subreq,
+					    asn1,
+					    &blob);
+	TALLOC_FREE(subreq);
 	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(msg);
 		asn1_free(asn1);
-		return status;
+		ldap_error_handler(conn, status);
+		return;
 	}
 
-	ldap_match_message(conn, msg);
+	asn1_load_nocopy(asn1, blob.data, blob.length);
 
-	data_blob_free(&blob);
+	status = ldap_decode(asn1, samba_ldap_control_handlers(), msg);
 	asn1_free(asn1);
-	return NT_STATUS_OK;
-}
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(msg);
+		ldap_error_handler(conn, status);
+		return;
+	}
 
-/* Handle read events, from the GENSEC socket callback, or real events */
-void ldap_read_io_handler(void *private_data, uint16_t flags) 
-{
-	struct ldap_connection *conn = talloc_get_type(private_data, 
-						       struct ldap_connection);
-	packet_recv(conn->packet);
-}
+	ldap_match_message(conn, msg);
+	ldap_connection_recv_next(conn);
 
-/*
-  handle ldap socket events
-*/
-static void ldap_io_handler(struct tevent_context *ev, struct tevent_fd *fde, 
-			    uint16_t flags, void *private_data)
-{
-	struct ldap_connection *conn = talloc_get_type(private_data, 
-						       struct ldap_connection);
-	if (flags & TEVENT_FD_WRITE) {
-		packet_queue_run(conn->packet);
-		if (!tls_enabled(conn->sock)) return;
-	}
-	if (flags & TEVENT_FD_READ) {
-		ldap_read_io_handler(private_data, flags);
-	}
+	return;
 }
 
 /*
@@ -284,6 +366,10 @@ static NTSTATUS ldap_parse_basic_url(TALLOC_CTX *mem_ctx, const char *url,
 struct ldap_connect_state {
 	struct composite_context *ctx;
 	struct ldap_connection *conn;
+	struct socket_context *sock;
+	struct tstream_context *raw;
+	struct tstream_tls_params *tls_params;
+	struct tstream_context *tls;
 };
 
 static void ldap_connect_recv_unix_conn(struct composite_context *ctx);
@@ -327,11 +413,11 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con
 		struct socket_address *unix_addr;
 		char path[1025];
 	
-		NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &conn->sock, 0);
+		NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &state->sock, 0);
 		if (!NT_STATUS_IS_OK(status)) {
 			return NULL;
 		}
-		talloc_steal(conn, conn->sock);
+		talloc_steal(state, state->sock);
 		SMB_ASSERT(sizeof(protocol)>10);
 		SMB_ASSERT(sizeof(path)>1024);
 	
@@ -354,29 +440,53 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con
 		}
 
 		rfc1738_unescape(path);
-	
-		unix_addr = socket_address_from_strings(conn, conn->sock->backend_name, 
+
+		unix_addr = socket_address_from_strings(state, state->sock->backend_name,
 							path, 0);
-		if (!unix_addr) {
-			return NULL;
+		if (composite_nomem(unix_addr, result)) {
+			return result;
 		}
 
-		ctx = socket_connect_send(conn->sock, NULL, unix_addr, 
-					  0, conn->event.event_ctx);
+
+		ctx = socket_connect_send(state->sock, NULL, unix_addr,
+					  0, result->event_ctx);
 		ctx->async.fn = ldap_connect_recv_unix_conn;
 		ctx->async.private_data = state;
 		return result;
 	} else {
 		NTSTATUS status = ldap_parse_basic_url(conn, url, &conn->host,
 							  &conn->port, &conn->ldaps);
-		if (!NT_STATUS_IS_OK(state->ctx->status)) {
-			composite_error(state->ctx, status);
+		if (!NT_STATUS_IS_OK(status)) {
+			composite_error(result, status);
 			return result;
 		}
-		
+
+		if (conn->ldaps) {
+			char *ca_file = lpcfg_tls_cafile(state, conn->lp_ctx);
+			char *crl_file = lpcfg_tls_crlfile(state, conn->lp_ctx);
+
+			if (!ca_file || !*ca_file) {
+				composite_error(result,
+						NT_STATUS_INVALID_PARAMETER_MIX);
+				return result;
+			}
+
+			status = tstream_tls_params_client(state,
+							   ca_file,
+							   crl_file,
+							   &state->tls_params);
+			if (!NT_STATUS_IS_OK(status)) {
+				composite_error(result, status);
+				return result;
+			}
+		}
+
 		ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port,
-						lpcfg_resolve_context(conn->lp_ctx), conn->event.event_ctx);
-		if (ctx == NULL) goto failed;
+						lpcfg_resolve_context(conn->lp_ctx),
+						result->event_ctx);
+		if (composite_nomem(ctx, result)) {
+			return result;
+		}
 
 		ctx->async.fn = ldap_connect_recv_tcp_conn;
 		ctx->async.private_data = state;
@@ -387,72 +497,80 @@ _PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *con
 	return NULL;
 }
 
+static void ldap_connect_got_tls(struct tevent_req *subreq);
+
 static void ldap_connect_got_sock(struct composite_context *ctx, 
-				  struct ldap_connection *conn) 
+				  struct ldap_connection *conn)
 {
-	/* setup a handler for events on this socket */
-	conn->event.fde = tevent_add_fd(conn->event.event_ctx, conn->sock,
-					socket_get_fd(conn->sock),
-					TEVENT_FD_READ, ldap_io_handler, conn);
-	if (conn->event.fde == NULL) {
-		composite_error(ctx, NT_STATUS_INTERNAL_ERROR);
-		return;
-	}
+	struct ldap_connect_state *state =
+		talloc_get_type_abort(ctx->private_data,
+		struct ldap_connect_state);
+	struct tevent_req *subreq = NULL;
+	int fd;
+	int ret;
 
-	tevent_fd_set_close_fn(conn->event.fde, socket_tevent_fd_close_fn);
-	socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE);
+	socket_set_flags(state->sock, SOCKET_FLAG_NOCLOSE);
+	fd = socket_get_fd(state->sock);
+	TALLOC_FREE(state->sock);
 
-	talloc_steal(conn, conn->sock);
-	if (conn->ldaps) {
-		struct socket_context *tls_socket;
-		char *cafile = lpcfg_tls_cafile(conn->sock, conn->lp_ctx);
+	smb_set_close_on_exec(fd);
+	set_blocking(fd, false);
 
-		if (!cafile || !*cafile) {
-			talloc_free(conn->sock);
-			return;
-		}
-
-		tls_socket = tls_init_client(conn->sock, conn->event.fde, cafile);
-		talloc_free(cafile);
-
-		if (tls_socket == NULL) {
-			talloc_free(conn->sock);
-			return;
-		}
+	ret = tstream_bsd_existing_socket(state, fd, &state->raw);
+	if (ret == -1) {
+		NTSTATUS status = map_nt_error_from_unix_common(errno);
+		composite_error(state->ctx, status);
+		return;
+	}
 
-		conn->sock = talloc_steal(conn, tls_socket);
+	if (!conn->ldaps) {
+		conn->sockets.raw = talloc_move(conn, &state->raw);
+		conn->sockets.active = conn->sockets.raw;
+		composite_done(state->ctx);
+		return;
 	}
 
-	conn->packet = packet_init(conn);
-	if (conn->packet == NULL) {
-		talloc_free(conn->sock);
+	subreq = tstream_tls_connect_send(state, state->ctx->event_ctx,
+					  state->raw, state->tls_params);
+	if (composite_nomem(subreq, state->ctx)) {
 		return;
 	}
+	tevent_req_set_callback(subreq, ldap_connect_got_tls, state);
+}
 
-	packet_set_private(conn->packet, conn);
-	packet_set_socket(conn->packet, conn->sock);
-	packet_set_callback(conn->packet, ldap_recv_handler);
-	packet_set_full_request(conn->packet, ldap_full_packet);
-	packet_set_error_handler(conn->packet, ldap_error_handler);
-	packet_set_event_context(conn->packet, conn->event.event_ctx);
-	packet_set_fde(conn->packet, conn->event.fde);
-/*	packet_set_serialise(conn->packet); */
+static void ldap_connect_got_tls(struct tevent_req *subreq)
+{
+	struct ldap_connect_state *state =
+		tevent_req_callback_data(subreq,
+		struct ldap_connect_state);
+	int err;
+	int ret;
 
-	if (conn->ldaps) {
-		packet_set_unreliable_select(conn->packet);
+	ret = tstream_tls_connect_recv(subreq, &err, state, &state->tls);
+	TALLOC_FREE(subreq);
+	if (ret == -1) {
+		NTSTATUS status = map_nt_error_from_unix_common(err);
+		composite_error(state->ctx, status);
+		return;
 	}
 
-	composite_done(ctx);
+	talloc_steal(state->tls, state->tls_params);
+
+	state->conn->sockets.raw = talloc_move(state->conn, &state->raw);
+	state->conn->sockets.tls = talloc_move(state->conn->sockets.raw,
+					       &state->tls);
+	state->conn->sockets.active = state->conn->sockets.tls;
+	composite_done(state->ctx);
 }
 
 static void ldap_connect_recv_tcp_conn(struct composite_context *ctx)
 {
 	struct ldap_connect_state *state =
-		talloc_get_type(ctx->async.private_data,
-				struct ldap_connect_state);
+		talloc_get_type_abort(ctx->async.private_data,
+		struct ldap_connect_state);
 	struct ldap_connection *conn = state->conn;
 	uint16_t port;
-	NTSTATUS status = socket_connect_multi_recv(ctx, state, &conn->sock,
+	NTSTATUS status = socket_connect_multi_recv(ctx, state, &state->sock,
 						       &port);
 	if (!NT_STATUS_IS_OK(status)) {
 		composite_error(state->ctx, status);
@@ -465,8 +583,8 @@ static void ldap_connect_recv_tcp_conn(struct composite_context *ctx)
 static void ldap_connect_recv_unix_conn(struct composite_context *ctx)
 {
 	struct ldap_connect_state *state =
-		talloc_get_type(ctx->async.private_data,
-				struct ldap_connect_state);
+		talloc_get_type_abort(ctx->async.private_data,
+		struct ldap_connect_state);
 	struct ldap_connection *conn = state->conn;
 
 	NTSTATUS status = socket_connect_recv(ctx);
@@ -533,7 +651,7 @@ static void ldap_reconnect(struct ldap_connection *conn)
 	/* rebind */
 	status = ldap_rebind(conn);
 	if ( ! NT_STATUS_IS_OK(status)) {
-		ldap_connection_dead(conn);
+		ldap_connection_dead(conn, status);
 	}
 }
 
@@ -552,7 +670,10 @@ static int ldap_request_destructor(struct ldap_request *req)
 static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer *te, 
 				      struct timeval t, void *private_data)
 {
-	struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
+	struct ldap_request *req =
+		talloc_get_type_abort(private_data,
+		struct ldap_request);
+
 	req->status = NT_STATUS_IO_TIMEOUT;
 	if (req->state == LDAP_REQUEST_PENDING) {
 		DLIST_REMOVE(req->conn->pending, req);
@@ -570,26 +691,17 @@ static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer
 static void ldap_request_failed_complete(struct tevent_context *ev, struct tevent_timer *te,
 				      struct timeval t, void *private_data)
 {
-	struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
-	if (req->async.fn) {
-		req->async.fn(req);
-	}
-}
+	struct ldap_request *req =
+		talloc_get_type_abort(private_data,
+		struct ldap_request);
 
-/*
-  called on completion of a one-way ldap request
-*/
-static void ldap_request_oneway_complete(void *private_data)
-{
-	struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
-	if (req->state == LDAP_REQUEST_PENDING) {
-		DLIST_REMOVE(req->conn->pending, req);
-	}
-	req->state = LDAP_REQUEST_DONE;
 	if (req->async.fn) {
 		req->async.fn(req);
 	}
 }
+
+static void ldap_request_written(struct tevent_req *subreq);
+
 /*
   send a ldap message - async interface
 */
@@ -598,12 +710,12 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
 {
 	struct ldap_request *req;
 	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-	packet_send_callback_fn_t send_callback = NULL;
+	struct tevent_req *subreq = NULL;
 
 	req = talloc_zero(conn, struct ldap_request);
 	if (req == NULL) return NULL;
 
-	if (conn->sock == NULL) {
+	if (conn->sockets.active == NULL) {
 		status = NT_STATUS_INVALID_CONNECTION;
 		goto failed;
 	}
@@ -628,25 +740,31 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
 		goto failed;		
 	}
 
-	if (req->type == LDAP_TAG_AbandonRequest ||
-	    req->type == LDAP_TAG_UnbindRequest) {
-		send_callback = ldap_request_oneway_complete;
+	/* put a timeout on the request */
+	req->time_event = tevent_add_timer(conn->event.event_ctx, req,
+					   timeval_current_ofs(conn->timeout, 0),
+					   ldap_request_timeout, req);
+	if (req->time_event == NULL) {
+		status = NT_STATUS_NO_MEMORY;
+		goto failed;
 	}
 
-	status = packet_send_callback(conn->packet, req->data,
-				      send_callback, req);
-	if (!NT_STATUS_IS_OK(status)) {
+	req->write_iov.iov_base = req->data.data;
+	req->write_iov.iov_len = req->data.length;
+
+	subreq = tstream_writev_queue_send(req, conn->event.event_ctx,
+					   conn->sockets.active,
+					   conn->sockets.send_queue,
+					   &req->write_iov, 1);
+	if (subreq == NULL) {
+		status = NT_STATUS_NO_MEMORY;
 		goto failed;
 	}
+	tevent_req_set_callback(subreq, ldap_request_written, req);
 
 	req->state = LDAP_REQUEST_PENDING;
 	DLIST_ADD(conn->pending, req);
 
-	/* put a timeout on the request */
-	req->time_event = tevent_add_timer(conn->event.event_ctx, req,
-					   timeval_current_ofs(conn->timeout, 0),
-					   ldap_request_timeout, req);
-
 	return req;
 
 failed:
@@ -658,6 +776,38 @@ failed:
 	return req;
 }
 
+static void ldap_request_written(struct tevent_req *subreq)
+{
+	struct ldap_request *req =
+		tevent_req_callback_data(subreq,
+		struct ldap_request);
+	int err;
+	ssize_t ret;
+
+	ret = tstream_writev_queue_recv(subreq, &err);
+	TALLOC_FREE(subreq);
+	if (ret == -1) {
+		NTSTATUS error = map_nt_error_from_unix_common(err);
+		ldap_error_handler(req->conn, error);
+		return;
+	}
+
+	if (req->type == LDAP_TAG_AbandonRequest ||
+	    req->type == LDAP_TAG_UnbindRequest)
+	{
+		if (req->state == LDAP_REQUEST_PENDING) {
+			DLIST_REMOVE(req->conn->pending, req);
+		}
+		req->state = LDAP_REQUEST_DONE;
+		if (req->async.fn) {
+			req->async.fn(req);
+		}
+		return;
+	}
+
+	ldap_connection_recv_next(req->conn);
+}
+
 
 /*
   wait for a request to complete
@@ -667,6 +817,7 @@ _PUBLIC_ NTSTATUS ldap_request_wait(struct ldap_request *req)
 {
 	while (req->state < LDAP_REQUEST_DONE) {
 		if (tevent_loop_once(req->conn->event.event_ctx) != 0) {
+			req->state = LDAP_REQUEST_ERROR;
 			req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
 			break;
 		}
diff --git a/source4/libcli/ldap/ldap_client.h b/source4/libcli/ldap/ldap_client.h
index 3b4da6b..e2b1b30 100644
--- a/source4/libcli/ldap/ldap_client.h
+++ b/source4/libcli/ldap/ldap_client.h
@@ -20,6 +20,7 @@
 */
 
 
+#include "system/network.h" /* for struct iovec */
 #include "libcli/ldap/libcli_ldap.h"
 
 enum ldap_request_state { LDAP_REQUEST_SEND=1, LDAP_REQUEST_PENDING=2, LDAP_REQUEST_DONE=3, LDAP_REQUEST_ERROR=4 };
@@ -39,6 +40,8 @@ struct ldap_request {
 
 	NTSTATUS status;
 	DATA_BLOB data;
+	struct iovec write_iov;
+
 	struct {
 		void (*fn)(struct ldap_request *);
 		void *private_data;
@@ -50,7 +53,16 @@ struct ldap_request {
 
 /* main context for a ldap client connection */
 struct ldap_connection {
-	struct socket_context *sock;
+	struct {
+		struct tstream_context *raw;
+		struct tstream_context *tls;
+		struct tstream_context *sasl;
+		struct tstream_context *active;
+
+		struct tevent_queue *send_queue;
+		struct tevent_req *recv_subreq;
+	} sockets;
+
 	struct loadparm_context *lp_ctx;
 
 	char *host;
@@ -89,10 +101,7 @@ struct ldap_connection {
 
 	struct {
 		struct tevent_context *event_ctx;
-		struct tevent_fd *fde;
 	} event;
-
-	struct packet_context *packet;
 };
 
 struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, 
diff --git a/source4/libcli/ldap/wscript_build b/source4/libcli/ldap/wscript_build
index f7afec7..f79cc2b 100644
--- a/source4/libcli/ldap/wscript_build
+++ b/source4/libcli/ldap/wscript_build
@@ -3,9 +3,9 @@
 bld.SAMBA_LIBRARY('cli-ldap',
                   source='ldap_client.c ldap_bind.c ldap_ildap.c ldap_controls.c',
                   autoproto='ldap_proto.h',
-                  public_deps='errors tevent LIBPACKET',
+                  public_deps='errors tevent',
                   public_headers='libcli_ldap.h:ldap-util.h',
-                  deps='cli_composite samba_socket NDR_SAMR LIBTLS ndr LP_RESOLVE gensec cli-ldap-common',
+                  deps='cli_composite LIBSAMBA_TSOCKET samba_socket NDR_SAMR LIBTLS ndr LP_RESOLVE gensec cli-ldap-common',
                   private_library=True
                   )
 
-- 
1.9.1


From f3f985b24a14a7da00119e313f75617ec4f4f50e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 19 Jun 2015 13:30:54 +0200
Subject: [PATCH 07/12] s4:auth/gensec: remove unused and untested cyrus_sasl
 module

There's not a high chance that this module worked at all.

Requesting SASL_SSF in order to get the max input length
is completely broken.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/gensec/cyrus_sasl.c  | 454 --------------------------------------
 source4/auth/gensec/wscript_build |  10 -
 source4/auth/wscript_configure    |   4 -
 3 files changed, 468 deletions(-)
 delete mode 100644 source4/auth/gensec/cyrus_sasl.c

diff --git a/source4/auth/gensec/cyrus_sasl.c b/source4/auth/gensec/cyrus_sasl.c
deleted file mode 100644
index 72acc52..0000000
--- a/source4/auth/gensec/cyrus_sasl.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
- 
-   Connect GENSEC to an external SASL lib
-
-   Copyright (C) Andrew Bartlett <abartlet at samba.org> 2006
-   
-   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 "includes.h"
-#include "lib/tsocket/tsocket.h"
-#include "auth/credentials/credentials.h"
-#include "auth/gensec/gensec.h"
-#include "auth/gensec/gensec_internal.h"
-#include "auth/gensec/gensec_proto.h"
-#include "auth/gensec/gensec_toplevel_proto.h"
-#include <sasl/sasl.h>
-
-NTSTATUS gensec_sasl_init(void);
-
-struct gensec_sasl_state {
-	sasl_conn_t *conn;
-	int step;
-	bool wrap;
-};
-
-static NTSTATUS sasl_nt_status(int sasl_ret) 
-{
-	switch (sasl_ret) {
-	case SASL_CONTINUE:
-		return NT_STATUS_MORE_PROCESSING_REQUIRED;
-	case SASL_NOMEM:
-		return NT_STATUS_NO_MEMORY;
-	case SASL_BADPARAM:
-	case SASL_NOMECH:
-		return NT_STATUS_INVALID_PARAMETER;
-	case SASL_BADMAC:
-		return NT_STATUS_ACCESS_DENIED;
-	case SASL_OK:
-		return NT_STATUS_OK;
-	default:
-		return NT_STATUS_UNSUCCESSFUL;
-	}
-}
-
-static int gensec_sasl_get_user(void *context, int id,
-				const char **result, unsigned *len)
-{
-	struct gensec_security *gensec_security = talloc_get_type(context, struct gensec_security);
-	const char *username = cli_credentials_get_username(gensec_get_credentials(gensec_security));
-	if (id != SASL_CB_USER && id != SASL_CB_AUTHNAME) {
-		return SASL_FAIL;
-	}
-	
-	*result = username;
-	return SASL_OK;
-}
-
-static int gensec_sasl_get_realm(void *context, int id,
-				 const char **availrealms,
-				 const char **result)
-{
-	struct gensec_security *gensec_security = talloc_get_type(context, struct gensec_security);
-	const char *realm = cli_credentials_get_realm(gensec_get_credentials(gensec_security));
-	int i;
-	if (id != SASL_CB_GETREALM) {
-		return SASL_FAIL;
-	}
-
-	for (i=0; availrealms && availrealms[i]; i++) {
-		if (strcasecmp_m(realm, availrealms[i]) == 0) {
-			result[i] = availrealms[i];
-			return SASL_OK;
-		}
-	}
-	/* None of the realms match, so lets not specify one */
-	*result = "";
-	return SASL_OK;
-}
-
-static int gensec_sasl_get_password(sasl_conn_t *conn, void *context, int id,
-			     sasl_secret_t **psecret)
-{
-	struct gensec_security *gensec_security = talloc_get_type(context, struct gensec_security);
-	const char *password = cli_credentials_get_password(gensec_get_credentials(gensec_security));
-	
-	sasl_secret_t *secret;
-	if (!password) {
-		*psecret = NULL;
-		return SASL_OK;
-	}
-	secret = talloc_size(gensec_security, sizeof(sasl_secret_t)+strlen(password)+1);
-	if (!secret) {
-		return SASL_NOMEM;
-	}
-	secret->len = strlen(password);
-	strlcpy((char*)secret->data, password, secret->len+1);
-	*psecret = secret;
-	return SASL_OK;
-}
-
-static int gensec_sasl_dispose(struct gensec_sasl_state *gensec_sasl_state)
-{
-	sasl_dispose(&gensec_sasl_state->conn);
-	return SASL_OK;
-}
-
-typedef int (*__gensec_sasl_callback_t)(void);
-
-static NTSTATUS gensec_sasl_client_start(struct gensec_security *gensec_security)
-{
-	struct gensec_sasl_state *gensec_sasl_state;
-	const char *service = gensec_get_target_service(gensec_security);
-	const char *target_name = gensec_get_target_hostname(gensec_security);
-	const struct tsocket_address *tlocal_addr = gensec_get_local_address(gensec_security);
-	const struct tsocket_address *tremote_addr = gensec_get_remote_address(gensec_security);
-	char *local_addr = NULL;
-	char *remote_addr = NULL;
-	int sasl_ret;
-
-	sasl_callback_t *callbacks;
-
-	gensec_sasl_state = talloc_zero(gensec_security, struct gensec_sasl_state);
-	if (!gensec_sasl_state) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	callbacks = talloc_array(gensec_sasl_state, sasl_callback_t, 5);
-	callbacks[0].id = SASL_CB_USER;
-	callbacks[0].proc = (__gensec_sasl_callback_t)gensec_sasl_get_user;
-	callbacks[0].context = gensec_security;
-
-	callbacks[1].id = SASL_CB_AUTHNAME;
-	callbacks[1].proc = (__gensec_sasl_callback_t)gensec_sasl_get_user;
-	callbacks[1].context = gensec_security;
-
-	callbacks[2].id = SASL_CB_GETREALM;
-	callbacks[2].proc = (__gensec_sasl_callback_t)gensec_sasl_get_realm;
-	callbacks[2].context = gensec_security;
-
-	callbacks[3].id = SASL_CB_PASS;
-	callbacks[3].proc = (__gensec_sasl_callback_t)gensec_sasl_get_password;
-	callbacks[3].context = gensec_security;
-
-	callbacks[4].id = SASL_CB_LIST_END;
-	callbacks[4].proc = NULL;
-	callbacks[4].context = NULL;
-
-	gensec_security->private_data = gensec_sasl_state;
-
-	if (tlocal_addr) {
-		local_addr = talloc_asprintf(gensec_sasl_state,
-				"%s;%d",
-				tsocket_address_inet_addr_string(tlocal_addr, gensec_sasl_state),
-				tsocket_address_inet_port(tlocal_addr));
-	}
-
-	if (tremote_addr) {
-		remote_addr = talloc_asprintf(gensec_sasl_state,
-				"%s;%d",
-				tsocket_address_inet_addr_string(tremote_addr, gensec_sasl_state),
-				tsocket_address_inet_port(tremote_addr));
-	}
-	gensec_sasl_state->step = 0;
-
-	sasl_ret = sasl_client_new(service,
-				   target_name,
-				   local_addr, remote_addr, callbacks, 0,
-				   &gensec_sasl_state->conn);
-	
-	if (sasl_ret == SASL_OK) {
-		sasl_security_properties_t props;
-		talloc_set_destructor(gensec_sasl_state, gensec_sasl_dispose);
-		
-		ZERO_STRUCT(props);
-		if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
-			props.min_ssf = 1;
-			props.max_ssf = 1;
-			props.maxbufsize = 65536;
-			gensec_sasl_state->wrap = true;
-		}
-		if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
-			props.min_ssf = 40;
-			props.max_ssf = UINT_MAX;
-			props.maxbufsize = 65536;
-			gensec_sasl_state->wrap = true;
-		}
-
-		sasl_ret = sasl_setprop(gensec_sasl_state->conn, SASL_SEC_PROPS, &props);
-	}
-	if (sasl_ret != SASL_OK) {
-		DEBUG(1, ("GENSEC SASL: client_new failed: %s\n", sasl_errdetail(gensec_sasl_state->conn)));
-	}
-	return sasl_nt_status(sasl_ret);
-}
-
-static NTSTATUS gensec_sasl_update(struct gensec_security *gensec_security, 
-				   TALLOC_CTX *out_mem_ctx, 
-				   struct tevent_context *ev,
-				   const DATA_BLOB in, DATA_BLOB *out) 
-{
-	struct gensec_sasl_state *gensec_sasl_state = talloc_get_type(gensec_security->private_data,
-								      struct gensec_sasl_state);
-	int sasl_ret;
-	const char *out_data;
-	unsigned int out_len;
-
-	if (gensec_sasl_state->step == 0) {
-		const char *mech;
-		sasl_ret = sasl_client_start(gensec_sasl_state->conn, gensec_security->ops->sasl_name, 
-					     NULL, &out_data, &out_len, &mech);
-	} else {
-		sasl_ret = sasl_client_step(gensec_sasl_state->conn,
-					    (char*)in.data, in.length, NULL,
-					    &out_data, &out_len);
-	}
-	if (sasl_ret == SASL_OK || sasl_ret == SASL_CONTINUE) {
-		*out = data_blob_talloc(out_mem_ctx, out_data, out_len);
-	} else {
-		DEBUG(1, ("GENSEC SASL: step %d update failed: %s\n", gensec_sasl_state->step, 
-			  sasl_errdetail(gensec_sasl_state->conn)));
-	}
-	gensec_sasl_state->step++;
-	return sasl_nt_status(sasl_ret);
-}
-
-static NTSTATUS gensec_sasl_unwrap_packets(struct gensec_security *gensec_security, 
-					TALLOC_CTX *out_mem_ctx, 
-					const DATA_BLOB *in, 
-					DATA_BLOB *out,
-					size_t *len_processed) 
-{
-	struct gensec_sasl_state *gensec_sasl_state = talloc_get_type(gensec_security->private_data,
-								      struct gensec_sasl_state);
-	const char *out_data;
-	unsigned int out_len;
-
-	int sasl_ret = sasl_decode(gensec_sasl_state->conn,
-				   (char*)in->data, in->length, &out_data,
-				   &out_len);
-	if (sasl_ret == SASL_OK) {
-		*out = data_blob_talloc(out_mem_ctx, out_data, out_len);
-		*len_processed = in->length;
-	} else {
-		DEBUG(1, ("GENSEC SASL: unwrap failed: %s\n", sasl_errdetail(gensec_sasl_state->conn)));
-	}
-	return sasl_nt_status(sasl_ret);
-
-}
-
-static NTSTATUS gensec_sasl_wrap_packets(struct gensec_security *gensec_security, 
-					TALLOC_CTX *out_mem_ctx, 
-					const DATA_BLOB *in, 
-					DATA_BLOB *out,
-					size_t *len_processed) 
-{
-	struct gensec_sasl_state *gensec_sasl_state = talloc_get_type(gensec_security->private_data,
-								      struct gensec_sasl_state);
-	const char *out_data;
-	unsigned int out_len;
-	unsigned len_permitted;
-	int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF,
-			(const void**)&len_permitted);
-	if (sasl_ret != SASL_OK) {
-		return sasl_nt_status(sasl_ret);
-	}
-	len_permitted = MIN(len_permitted, in->length);
-
-	sasl_ret = sasl_encode(gensec_sasl_state->conn,
-			       (char*)in->data, len_permitted, &out_data,
-			       &out_len);
-	if (sasl_ret == SASL_OK) {
-		*out = data_blob_talloc(out_mem_ctx, out_data, out_len);
-		*len_processed = in->length;
-	} else {
-		DEBUG(1, ("GENSEC SASL: wrap failed: %s\n", sasl_errdetail(gensec_sasl_state->conn)));
-	}
-	return sasl_nt_status(sasl_ret);
-}
-
-/* Try to figure out what features we actually got on the connection */
-static bool gensec_sasl_have_feature(struct gensec_security *gensec_security, 
-				     uint32_t feature) 
-{
-	struct gensec_sasl_state *gensec_sasl_state = talloc_get_type(gensec_security->private_data,
-								      struct gensec_sasl_state);
-	sasl_ssf_t ssf;
-	int sasl_ret;
-
-	/* If we did not elect to wrap, then we have neither sign nor seal, no matter what the SSF claims */
-	if (!gensec_sasl_state->wrap) {
-		return false;
-	}
-	
-	sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF,
-			(const void**)&ssf);
-	if (sasl_ret != SASL_OK) {
-		return false;
-	}
-	if (feature & GENSEC_FEATURE_SIGN) {
-		if (ssf == 0) {
-			return false;
-		}
-		if (ssf >= 1) {
-			return true;
-		}
-	}
-	if (feature & GENSEC_FEATURE_SEAL) {
-		if (ssf <= 1) {
-			return false;
-		}
-		if (ssf > 1) {
-			return true;
-		}
-	}
-	return false;
-}
-
-/* This could in theory work with any SASL mech */
-static const struct gensec_security_ops gensec_sasl_security_ops = {
-	.name             = "sasl-DIGEST-MD5",
-	.sasl_name        = "DIGEST-MD5",
-	.client_start     = gensec_sasl_client_start,
-	.update 	  = gensec_sasl_update,
-	.wrap_packets     = gensec_sasl_wrap_packets,
-	.unwrap_packets   = gensec_sasl_unwrap_packets,
-	.have_feature     = gensec_sasl_have_feature,
-	.enabled          = true,
-	.priority         = GENSEC_SASL
-};
-
-static int gensec_sasl_log(void *context, 
-		    int sasl_log_level,
-		    const char *message) 
-{
-	int dl;
-	switch (sasl_log_level) {
-	case SASL_LOG_NONE:
-		dl = 0;
-		break;
-	case SASL_LOG_ERR:
-		dl = 1;
-		break;
-	case SASL_LOG_FAIL:
-		dl = 2;
-		break;
-	case SASL_LOG_WARN:
-		dl = 3;
-		break;
-	case SASL_LOG_NOTE:
-		dl = 5;
-		break;
-	case SASL_LOG_DEBUG:
-		dl = 10;
-		break;
-	case SASL_LOG_TRACE:
-		dl = 11;
-		break;
-#if DEBUG_PASSWORD
-	case SASL_LOG_PASS:
-		dl = 100;
-		break;
-#endif
-	default:
-		dl = 0;
-		break;
-	}
-	DEBUG(dl, ("gensec_sasl: %s\n", message));
-
-	return SASL_OK;
-}
-
-NTSTATUS gensec_sasl_init(void)
-{
-	NTSTATUS ret;
-	int sasl_ret;
-#if 0
-	int i;
-	const char **sasl_mechs;
-#endif
-	
-	static const sasl_callback_t callbacks[] = {
-		{ 
-			.id = SASL_CB_LOG,
-			.proc = (__gensec_sasl_callback_t)gensec_sasl_log,
-			.context = NULL,
-		},
-		{
-			.id = SASL_CB_LIST_END,
-			.proc = NULL,
-			.context = NULL,
-		}
-	};
-	sasl_ret = sasl_client_init(callbacks);
-	
-	if (sasl_ret == SASL_NOMECH) {
-		/* Nothing to do here */
-		return NT_STATUS_OK;
-	}
-
-	if (sasl_ret != SASL_OK) {
-		return sasl_nt_status(sasl_ret);
-	}
-
-	/* For now, we just register DIGEST-MD5 */
-#if 1
-	ret = gensec_register(&gensec_sasl_security_ops);
-	if (!NT_STATUS_IS_OK(ret)) {
-		DEBUG(0,("Failed to register '%s' gensec backend!\n",
-			 gensec_sasl_security_ops.name));
-		return ret;
-	}
-#else
-	sasl_mechs = sasl_global_listmech();
-	for (i = 0; sasl_mechs && sasl_mechs[i]; i++) {
-		const struct gensec_security_ops *oldmech;
-		struct gensec_security_ops *newmech;
-		oldmech = gensec_security_by_sasl_name(NULL, sasl_mechs[i]);
-		if (oldmech) {
-			continue;
-		}
-		newmech = talloc(talloc_autofree_context(), struct gensec_security_ops);
-		if (!newmech) {
-			return NT_STATUS_NO_MEMORY;
-		}
-		*newmech = gensec_sasl_security_ops;
-		newmech->sasl_name = talloc_strdup(newmech, sasl_mechs[i]);
-		newmech->name = talloc_asprintf(newmech, "sasl-%s", sasl_mechs[i]);
-		if (!newmech->sasl_name || !newmech->name) {
-			return NT_STATUS_NO_MEMORY;
-		}
-
-		ret = gensec_register(newmech);
-		if (!NT_STATUS_IS_OK(ret)) {
-			DEBUG(0,("Failed to register '%s' gensec backend!\n",
-				 gensec_sasl_security_ops.name));
-			return ret;
-		}
-	}
-#endif
-	return NT_STATUS_OK;
-}
diff --git a/source4/auth/gensec/wscript_build b/source4/auth/gensec/wscript_build
index 097a740..46915f0 100755
--- a/source4/auth/gensec/wscript_build
+++ b/source4/auth/gensec/wscript_build
@@ -22,16 +22,6 @@ bld.SAMBA_MODULE('gensec_gssapi',
 	deps='gssapi samba-credentials authkrb5 com_err gensec_util'
 	)
 
-
-bld.SAMBA_MODULE('cyrus_sasl',
-	source='cyrus_sasl.c',
-	subsystem='gensec',
-	init_function='gensec_sasl_init',
-	deps='samba-credentials sasl2',
-	enabled=bld.CONFIG_SET('HAVE_SASL')
-	)
-
-
 bld.SAMBA_PYTHON('pygensec',
 	source='pygensec.c',
 	deps='gensec pytalloc-util pyparam_util',
diff --git a/source4/auth/wscript_configure b/source4/auth/wscript_configure
index 1d26cde..d25cc0b 100644
--- a/source4/auth/wscript_configure
+++ b/source4/auth/wscript_configure
@@ -2,7 +2,3 @@
 
 conf.CHECK_HEADERS('security/pam_appl.h')
 conf.CHECK_FUNCS_IN('pam_start', 'pam', checklibc=True)
-
-if (conf.CHECK_HEADERS('sasl/sasl.h') and
-    conf.CHECK_FUNCS_IN('sasl_client_init', 'sasl2')):
-    conf.DEFINE('HAVE_SASL', 1)
-- 
1.9.1


From 22abce6e7388c7fb010afa157af086902eda8f46 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 19 Jun 2015 13:47:29 +0200
Subject: [PATCH 08/12] s4:auth/gensec: remove unused include of
 lib/socket/socket.h

---
 source4/auth/gensec/gensec_krb5.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index 362108e..b1ecd18 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -27,7 +27,6 @@
 #include "system/kerberos.h"
 #include "auth/kerberos/kerberos.h"
 #include "auth/auth.h"
-#include "lib/socket/socket.h"
 #include "lib/tsocket/tsocket.h"
 #include "librpc/gen_ndr/dcerpc.h"
 #include "auth/credentials/credentials.h"
-- 
1.9.1


From fee35de9172b157d987ecbb496044e9f8fc33b00 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 19 Jun 2015 12:46:27 +0200
Subject: [PATCH 09/12] s4:auth/gensec: remove unused gensec_socket_init()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/gensec/gensec_socket.h |  28 ---
 source4/auth/gensec/socket.c        | 435 ------------------------------------
 source4/auth/gensec/wscript_build   |   2 +-
 3 files changed, 1 insertion(+), 464 deletions(-)
 delete mode 100644 source4/auth/gensec/gensec_socket.h
 delete mode 100644 source4/auth/gensec/socket.c

diff --git a/source4/auth/gensec/gensec_socket.h b/source4/auth/gensec/gensec_socket.h
deleted file mode 100644
index bb12cc0..0000000
--- a/source4/auth/gensec/gensec_socket.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-   Unix SMB/CIFS implementation.
-
-   GENSEC socket interface
-
-   Copyright (C) Andrew Bartlett 2006
-
-   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/>.
-*/
-
-NTSTATUS gensec_socket_init(struct gensec_security *gensec_security,
-			    TALLOC_CTX *mem_ctx,
-			    struct socket_context *current_socket,
-			    struct tevent_context *ev,
-			    void (*recv_handler)(void *, uint16_t),
-			    void *recv_private,
-			    struct socket_context **new_socket);
diff --git a/source4/auth/gensec/socket.c b/source4/auth/gensec/socket.c
deleted file mode 100644
index c89e080..0000000
--- a/source4/auth/gensec/socket.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-
-   GENSEC socket interface
-
-   Copyright (C) Andrew Bartlett 2006
- 
-   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 "includes.h"
-#include "lib/events/events.h"
-#include "lib/socket/socket.h"
-#include "lib/stream/packet.h"
-#include "auth/gensec/gensec.h"
-#include "auth/gensec/gensec_proto.h"
-#include "auth/gensec/gensec_socket.h"
-
-static const struct socket_ops gensec_socket_ops;
-
-struct gensec_socket {
-	struct gensec_security *gensec_security;
-	struct socket_context *socket;
-	struct tevent_context *ev;
-	struct packet_context *packet;
-	DATA_BLOB read_buffer;  /* SASL packets are turned into liniarlised data here, for reading */
-	size_t orig_send_len;
-	bool eof;
-	NTSTATUS error;
-	bool interrupted;
-	void (*recv_handler)(void *, uint16_t);
-	void *recv_private;
-	int in_extra_read;
-	bool wrap; /* Should we be wrapping on this socket at all? */
-};
-
-static NTSTATUS gensec_socket_init_fn(struct socket_context *sock)
-{
-	switch (sock->type) {
-	case SOCKET_TYPE_STREAM:
-		break;
-	default:
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	sock->backend_name = "gensec";
-
-	return NT_STATUS_OK;
-}
-
-static NTSTATUS gensec_socket_full_request(void *private_data, DATA_BLOB blob, size_t *size)
-{
-	struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket);
-	struct gensec_security *gensec_security = gensec_socket->gensec_security;
-	return gensec_packet_full_request(gensec_security, blob, size);
-}
-
-/* Try to figure out how much data is waiting to be read */
-static NTSTATUS gensec_socket_pending(struct socket_context *sock, size_t *npending) 
-{
-	struct gensec_socket *gensec_socket = talloc_get_type(sock->private_data, struct gensec_socket);
-	if (!gensec_socket->wrap) {
-		return socket_pending(gensec_socket->socket, npending);
-	}
-
-	if (gensec_socket->read_buffer.length > 0) {
-		*npending = gensec_socket->read_buffer.length;
-		return NT_STATUS_OK;
-	}
-
-	/* This is a lie.  We hope the decrypted data will always be
-	 * less than this value, so the application just gets a short
-	 * read.  Without reading and decrypting it, we can't tell.
-	 * If the SASL mech does compression, then we just need to
-	 * manually trigger read events */
-	return socket_pending(gensec_socket->socket, npending);
-}      
-
-/* Note if an error occours, so we can return it up the stack */
-static void gensec_socket_error_handler(void *private_data, NTSTATUS status)
-{
-	struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket);
-	if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) {
-		gensec_socket->eof = true;
-	} else {
-		gensec_socket->error = status;
-	}
-}
-
-static void gensec_socket_trigger_read(struct tevent_context *ev, 
-				       struct tevent_timer *te, 
-				       struct timeval t, void *private_data)
-{
-	struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket);
-
-	gensec_socket->in_extra_read++;
-	gensec_socket->recv_handler(gensec_socket->recv_private, TEVENT_FD_READ);
-	gensec_socket->in_extra_read--;
-
-	/* It may well be that, having run the recv handler, we still
-	 * have even more data waiting for us! 
-	 */
-	if (gensec_socket->read_buffer.length > 0) {
-		/* Schedule this funcion to run again */
-		tevent_add_timer(gensec_socket->ev, gensec_socket, timeval_zero(), 
-				gensec_socket_trigger_read, gensec_socket);
-	}
-}
-
-/* These two routines could be changed to use a circular buffer of
- * some kind, or linked lists, or ... */
-static NTSTATUS gensec_socket_recv(struct socket_context *sock, void *buf,
-				   size_t wantlen, size_t *nread) 
-{
-	struct gensec_socket *gensec_socket = talloc_get_type(sock->private_data, struct gensec_socket);
-
-	if (!gensec_socket->wrap) {
-		return socket_recv(gensec_socket->socket, buf, wantlen, nread);
-	}
-
-	gensec_socket->error = NT_STATUS_OK;
-
-	if (gensec_socket->read_buffer.length == 0) {
-		/* Process any data on the socket, into the read buffer. At
-		 * this point, the socket is not available for read any
-		 * longer */
-		packet_recv(gensec_socket->packet);
-
-		if (gensec_socket->eof) {
-			*nread = 0;
-			return NT_STATUS_OK;
-		}
-		
-		if (!NT_STATUS_IS_OK(gensec_socket->error)) {
-			return gensec_socket->error;
-		}
-
-		if (gensec_socket->read_buffer.length == 0) {
-			/* Clearly we don't have the entire SASL packet yet,
-			 * so it has not been written into the buffer */
-			*nread = 0;
-			return STATUS_MORE_ENTRIES;
-		}
-	}
-
-
-	*nread = MIN(wantlen, gensec_socket->read_buffer.length);
-	memcpy(buf, gensec_socket->read_buffer.data, *nread);
-
-	if (gensec_socket->read_buffer.length > *nread) {
-		memmove(gensec_socket->read_buffer.data, 
-			gensec_socket->read_buffer.data + *nread, 
-			gensec_socket->read_buffer.length - *nread);
-	}
-
-	gensec_socket->read_buffer.length -= *nread;
-	gensec_socket->read_buffer.data = talloc_realloc(gensec_socket, 
-							 gensec_socket->read_buffer.data, 
-							 uint8_t, 
-							 gensec_socket->read_buffer.length);
-
-	if (gensec_socket->read_buffer.length && 
-	    gensec_socket->in_extra_read == 0 && 
-	    gensec_socket->recv_handler) {
-		/* Manually call a read event, to get this moving
-		 * again (as the socket should be dry, so the normal
-		 * event handler won't trigger) */
-		tevent_add_timer(gensec_socket->ev, gensec_socket, timeval_zero(), 
-				gensec_socket_trigger_read, gensec_socket);
-	}
-
-	return NT_STATUS_OK;
-}
-
-/* Completed SASL packet callback.  When we have a 'whole' SASL
- * packet, decrypt it, and add it to the read buffer
- *
- * This function (and anything under it) MUST NOT call the event system
- */
-static NTSTATUS gensec_socket_unwrap(void *private_data, DATA_BLOB blob)
-{
-	struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket);
-	DATA_BLOB unwrapped;
-	NTSTATUS nt_status;
-	TALLOC_CTX *mem_ctx;
-	size_t packet_size;
-
-	mem_ctx = talloc_new(gensec_socket);
-	if (!mem_ctx) {
-		return NT_STATUS_NO_MEMORY;
-	}
-	nt_status = gensec_unwrap_packets(gensec_socket->gensec_security, 
-					  mem_ctx,
-					  &blob, &unwrapped, 
-					  &packet_size);
-	if (!NT_STATUS_IS_OK(nt_status)) {
-		talloc_free(mem_ctx);
-		return nt_status;
-	}
-
-	if (packet_size != blob.length) {
-		DEBUG(0, ("gensec_socket_unwrap: Did not consume entire packet!\n"));
-		talloc_free(mem_ctx);
-		return NT_STATUS_INTERNAL_ERROR;
-	}
-
-	/* We could change this into a linked list, and have
-	 * gensec_socket_recv() and gensec_socket_pending() walk the
-	 * linked list */
-
-	if (!data_blob_append(gensec_socket, &gensec_socket->read_buffer, 
-				     unwrapped.data, unwrapped.length)) {
-		talloc_free(mem_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	talloc_free(mem_ctx);
-	return NT_STATUS_OK;
-}
-
-/* when the data is sent, we know we have not been interrupted */
-static void send_callback(void *private_data)
-{
-	struct gensec_socket *gensec_socket = talloc_get_type(private_data, struct gensec_socket);
-	gensec_socket->interrupted = false;
-}
-
-/*
-  send data, but only as much as we allow in one packet.  
-
-  If this returns STATUS_MORE_ENTRIES, the caller must retry with
-  exactly the same data, or a NULL blob.
-*/
-static NTSTATUS gensec_socket_send(struct socket_context *sock, 
-				   const DATA_BLOB *blob, size_t *sendlen)
-{
-	NTSTATUS nt_status;
-	struct gensec_socket *gensec_socket = talloc_get_type(sock->private_data, struct gensec_socket);
-	DATA_BLOB wrapped;
-	TALLOC_CTX *mem_ctx;
-
-	if (!gensec_socket->wrap) {
-		return socket_send(gensec_socket->socket, blob, sendlen);
-	}
-
-	*sendlen = 0;
-
-	/* We have have been interupted, so the caller should be
-	 * giving us the same data again.  */
-	if (gensec_socket->interrupted) {
-		packet_queue_run(gensec_socket->packet);
-
-		if (!NT_STATUS_IS_OK(gensec_socket->error)) {
-			return gensec_socket->error;
-		} else if (gensec_socket->interrupted) {
-			return STATUS_MORE_ENTRIES;
-		} else {
-			*sendlen = gensec_socket->orig_send_len;
-			gensec_socket->orig_send_len = 0;
-			return NT_STATUS_OK;
-		}
-	}
-
-	mem_ctx = talloc_new(gensec_socket);
-	if (!mem_ctx) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	nt_status = gensec_wrap_packets(gensec_socket->gensec_security, 
-					mem_ctx,
-					blob, &wrapped, 
-					&gensec_socket->orig_send_len);
-	if (!NT_STATUS_IS_OK(nt_status)) {
-		talloc_free(mem_ctx);
-		return nt_status;
-	}
-	
-	gensec_socket->interrupted = true;
-	gensec_socket->error = NT_STATUS_OK;
-
-	nt_status = packet_send_callback(gensec_socket->packet, 
-					 wrapped,
-					 send_callback, gensec_socket);
-
-	talloc_free(mem_ctx);
-
-	packet_queue_run(gensec_socket->packet);
-
-	if (!NT_STATUS_IS_OK(gensec_socket->error)) {
-		return gensec_socket->error;
-	} else if (gensec_socket->interrupted) {
-		return STATUS_MORE_ENTRIES;
-	} else {
-		*sendlen = gensec_socket->orig_send_len;
-		gensec_socket->orig_send_len = 0;
-		return NT_STATUS_OK;
-	}
-}
-
-/* Turn a normal socket into a potentially GENSEC wrapped socket */
-/* CAREFUL: this function will steal 'current_socket' */
-
-NTSTATUS gensec_socket_init(struct gensec_security *gensec_security,
-			    TALLOC_CTX *mem_ctx,
-			    struct socket_context *current_socket,
-			    struct tevent_context *ev,
-			    void (*recv_handler)(void *, uint16_t),
-			    void *recv_private,
-			    struct socket_context **new_socket)
-{
-	struct gensec_socket *gensec_socket;
-	struct socket_context *new_sock;
-	NTSTATUS nt_status;
-
-	nt_status = socket_create_with_ops(mem_ctx, &gensec_socket_ops, &new_sock, 
-					   SOCKET_TYPE_STREAM, current_socket->flags | SOCKET_FLAG_ENCRYPT);
-	if (!NT_STATUS_IS_OK(nt_status)) {
-		*new_socket = NULL;
-		return nt_status;
-	}
-
-	new_sock->state = current_socket->state;
-
-	gensec_socket = talloc(new_sock, struct gensec_socket);
-	if (gensec_socket == NULL) {
-		*new_socket = NULL;
-		talloc_free(new_sock);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	new_sock->private_data       = gensec_socket;
-	gensec_socket->socket        = current_socket;
-
-	/* Nothing to do here, if we are not actually wrapping on this socket */
-	if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) &&
-	    !gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
-		
-		gensec_socket->wrap = false;
-		talloc_steal(gensec_socket, current_socket);
-		*new_socket = new_sock;
-		return NT_STATUS_OK;
-	}
-
-	gensec_socket->gensec_security = gensec_security;
-
-	gensec_socket->wrap          = true;
-	gensec_socket->eof           = false;
-	gensec_socket->error         = NT_STATUS_OK;
-	gensec_socket->interrupted   = false;
-	gensec_socket->in_extra_read = 0;
-
-	gensec_socket->read_buffer   = data_blob(NULL, 0);
-
-	gensec_socket->recv_handler  = recv_handler;
-	gensec_socket->recv_private  = recv_private;
-	gensec_socket->ev            = ev;
-
-	gensec_socket->packet = packet_init(gensec_socket);
-	if (gensec_socket->packet == NULL) {
-		*new_socket = NULL;
-		talloc_free(new_sock);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	packet_set_private(gensec_socket->packet, gensec_socket);
-	packet_set_socket(gensec_socket->packet, gensec_socket->socket);
-	packet_set_callback(gensec_socket->packet, gensec_socket_unwrap);
-	packet_set_full_request(gensec_socket->packet, gensec_socket_full_request);
-	packet_set_error_handler(gensec_socket->packet, gensec_socket_error_handler);
-	packet_set_serialise(gensec_socket->packet);
-
-	/* TODO: full-request that knows about maximum packet size */
-
-	talloc_steal(gensec_socket, current_socket);
-	*new_socket = new_sock;
-	return NT_STATUS_OK;
-}
-
-
-static NTSTATUS gensec_socket_set_option(struct socket_context *sock, const char *option, const char *val)
-{
-	set_socket_options(socket_get_fd(sock), option);
-	return NT_STATUS_OK;
-}
-
-static char *gensec_socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx)
-{
-	struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket);
-	return socket_get_peer_name(gensec->socket, mem_ctx);
-}
-
-static struct socket_address *gensec_socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
-{
-	struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket);
-	return socket_get_peer_addr(gensec->socket, mem_ctx);
-}
-
-static struct socket_address *gensec_socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
-{
-	struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket);
-	return socket_get_my_addr(gensec->socket, mem_ctx);
-}
-
-static int gensec_socket_get_fd(struct socket_context *sock)
-{
-	struct gensec_socket *gensec = talloc_get_type(sock->private_data, struct gensec_socket);
-	return socket_get_fd(gensec->socket);
-}
-
-static const struct socket_ops gensec_socket_ops = {
-	.name			= "gensec",
-	.fn_init		= gensec_socket_init_fn,
-	.fn_recv		= gensec_socket_recv,
-	.fn_send		= gensec_socket_send,
-	.fn_pending		= gensec_socket_pending,
-
-	.fn_set_option		= gensec_socket_set_option,
-
-	.fn_get_peer_name	= gensec_socket_get_peer_name,
-	.fn_get_peer_addr	= gensec_socket_get_peer_addr,
-	.fn_get_my_addr		= gensec_socket_get_my_addr,
-	.fn_get_fd		= gensec_socket_get_fd
-};
-
diff --git a/source4/auth/gensec/wscript_build b/source4/auth/gensec/wscript_build
index 46915f0..3c7cc2e 100755
--- a/source4/auth/gensec/wscript_build
+++ b/source4/auth/gensec/wscript_build
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 bld.SAMBA_SUBSYSTEM('gensec_util',
-                    source='socket.c gensec_tstream.c',
+                    source='gensec_tstream.c',
                     deps='tevent-util tevent samba-util LIBTSOCKET',
                     autoproto='gensec_proto.h')
 
-- 
1.9.1


From 492dc521d22c890c112433528c8b595676e34305 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 19 Jun 2015 12:47:10 +0200
Subject: [PATCH 10/12] auth/gensec: remove unused gensec_[un]wrap_packets()
 hooks

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 auth/gensec/gensec.h          |  21 --------
 auth/gensec/gensec_internal.h |  12 -----
 auth/gensec/gensec_util.c     | 116 ------------------------------------------
 auth/gensec/spnego.c          |  56 --------------------
 auth/gensec/wscript_build     |   2 +-
 5 files changed, 1 insertion(+), 206 deletions(-)

diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h
index 0d3a29c..d09813e 100644
--- a/auth/gensec/gensec.h
+++ b/auth/gensec/gensec.h
@@ -107,30 +107,9 @@ const struct gensec_critical_sizes *gensec_interface_version(void);
 /* Socket wrapper */
 
 struct gensec_security;
-struct socket_context;
 struct auth4_context;
 struct auth_user_info_dc;
 
-/* These functions are for use here only (public because SPNEGO must
- * use them for recursion) */
-NTSTATUS gensec_wrap_packets(struct gensec_security *gensec_security,
-			     TALLOC_CTX *mem_ctx,
-			     const DATA_BLOB *in,
-			     DATA_BLOB *out,
-			     size_t *len_processed);
-/* These functions are for use here only (public because SPNEGO must
- * use them for recursion) */
-NTSTATUS gensec_unwrap_packets(struct gensec_security *gensec_security,
-			       TALLOC_CTX *mem_ctx,
-			       const DATA_BLOB *in,
-			       DATA_BLOB *out,
-			       size_t *len_processed);
-
-/* These functions are for use here only (public because SPNEGO must
- * use them for recursion) */
-NTSTATUS gensec_packet_full_request(struct gensec_security *gensec_security,
-				    DATA_BLOB blob, size_t *size);
-
 struct loadparm_context;
 
 NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx,
diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h
index c04164a..45a66f8 100644
--- a/auth/gensec/gensec_internal.h
+++ b/auth/gensec/gensec_internal.h
@@ -74,18 +74,6 @@ struct gensec_security_ops {
 			   TALLOC_CTX *mem_ctx,
 			   const DATA_BLOB *in,
 			   DATA_BLOB *out);
-	NTSTATUS (*wrap_packets)(struct gensec_security *gensec_security,
-				 TALLOC_CTX *mem_ctx,
-				 const DATA_BLOB *in,
-				 DATA_BLOB *out,
-				 size_t *len_processed);
-	NTSTATUS (*unwrap_packets)(struct gensec_security *gensec_security,
-				   TALLOC_CTX *mem_ctx,
-				   const DATA_BLOB *in,
-				   DATA_BLOB *out,
-				   size_t *len_processed);
-	NTSTATUS (*packet_full_request)(struct gensec_security *gensec_security,
-					DATA_BLOB blob, size_t *size);
 	NTSTATUS (*session_key)(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx,
 				DATA_BLOB *session_key);
 	NTSTATUS (*session_info)(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx,
diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c
index b8e38b7..8ef4b25 100644
--- a/auth/gensec/gensec_util.c
+++ b/auth/gensec/gensec_util.c
@@ -68,122 +68,6 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
 }
 
 /*
- * These functions are for use in the deprecated
- * gensec_socket code (public because SPNEGO must
- * use them for recursion)
- */
-_PUBLIC_ NTSTATUS gensec_wrap_packets(struct gensec_security *gensec_security,
-			     TALLOC_CTX *mem_ctx,
-			     const DATA_BLOB *in,
-			     DATA_BLOB *out,
-			     size_t *len_processed)
-{
-	if (!gensec_security->ops->wrap_packets) {
-		NTSTATUS nt_status;
-		size_t max_input_size;
-		DATA_BLOB unwrapped, wrapped;
-		max_input_size = gensec_max_input_size(gensec_security);
-		unwrapped = data_blob_const(in->data, MIN(max_input_size, (size_t)in->length));
-
-		nt_status = gensec_wrap(gensec_security,
-					mem_ctx,
-					&unwrapped, &wrapped);
-		if (!NT_STATUS_IS_OK(nt_status)) {
-			return nt_status;
-		}
-
-		*out = data_blob_talloc(mem_ctx, NULL, 4);
-		if (!out->data) {
-			return NT_STATUS_NO_MEMORY;
-		}
-		RSIVAL(out->data, 0, wrapped.length);
-
-		if (!data_blob_append(mem_ctx, out, wrapped.data, wrapped.length)) {
-			return NT_STATUS_NO_MEMORY;
-		}
-		*len_processed = unwrapped.length;
-		return NT_STATUS_OK;
-	}
-	return gensec_security->ops->wrap_packets(gensec_security, mem_ctx, in, out,
-						  len_processed);
-}
-
-/*
- * These functions are for use in the deprecated
- * gensec_socket code (public because SPNEGO must
- * use them for recursion)
- */
-NTSTATUS gensec_unwrap_packets(struct gensec_security *gensec_security,
-					TALLOC_CTX *mem_ctx,
-					const DATA_BLOB *in,
-					DATA_BLOB *out,
-					size_t *len_processed)
-{
-	if (!gensec_security->ops->unwrap_packets) {
-		DATA_BLOB wrapped;
-		NTSTATUS nt_status;
-		size_t packet_size;
-		if (in->length < 4) {
-			/* Missing the header we already had! */
-			DEBUG(0, ("Asked to unwrap packet of bogus length!  How did we get the short packet?!\n"));
-			return NT_STATUS_INVALID_PARAMETER;
-		}
-
-		packet_size = RIVAL(in->data, 0);
-
-		wrapped = data_blob_const(in->data + 4, packet_size);
-
-		if (wrapped.length > (in->length - 4)) {
-			DEBUG(0, ("Asked to unwrap packed of bogus length %d > %d!  How did we get this?!\n",
-				  (int)wrapped.length, (int)(in->length - 4)));
-			return NT_STATUS_INTERNAL_ERROR;
-		}
-
-		nt_status = gensec_unwrap(gensec_security,
-					  mem_ctx,
-					  &wrapped, out);
-		if (!NT_STATUS_IS_OK(nt_status)) {
-			return nt_status;
-		}
-
-		*len_processed = packet_size + 4;
-		return nt_status;
-	}
-	return gensec_security->ops->unwrap_packets(gensec_security, mem_ctx, in, out,
-						    len_processed);
-}
-
-/*
- * These functions are for use in the deprecated
- * gensec_socket code (public because SPNEGO must
- * use them for recursion)
- */
-NTSTATUS gensec_packet_full_request(struct gensec_security *gensec_security,
-				    DATA_BLOB blob, size_t *size)
-{
-	if (gensec_security->ops->packet_full_request) {
-		return gensec_security->ops->packet_full_request(gensec_security,
-								 blob, size);
-	}
-	if (gensec_security->ops->unwrap_packets) {
-		if (blob.length) {
-			*size = blob.length;
-			return NT_STATUS_OK;
-		}
-		return STATUS_MORE_ENTRIES;
-	}
-
-	if (blob.length < 4) {
-		return STATUS_MORE_ENTRIES;
-	}
-	*size = 4 + RIVAL(blob.data, 0);
-	if (*size > blob.length) {
-		return STATUS_MORE_ENTRIES;
-	}
-	return NT_STATUS_OK;
-}
-
-/*
   magic check a GSS-API wrapper packet for an Kerberos OID
 */
 static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid)
diff --git a/auth/gensec/spnego.c b/auth/gensec/spnego.c
index 20cacdb..85c70e1 100644
--- a/auth/gensec/spnego.c
+++ b/auth/gensec/spnego.c
@@ -221,59 +221,6 @@ static NTSTATUS gensec_spnego_unwrap(struct gensec_security *gensec_security,
 			     mem_ctx, in, out);
 }
 
-static NTSTATUS gensec_spnego_wrap_packets(struct gensec_security *gensec_security, 
-					   TALLOC_CTX *mem_ctx, 
-					   const DATA_BLOB *in, 
-					   DATA_BLOB *out,
-					   size_t *len_processed) 
-{
-	struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data;
-
-	if (spnego_state->state_position != SPNEGO_DONE 
-	    && spnego_state->state_position != SPNEGO_FALLBACK) {
-		DEBUG(1, ("gensec_spnego_wrap: wrong state for wrap\n"));
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	return gensec_wrap_packets(spnego_state->sub_sec_security, 
-				   mem_ctx, in, out,
-				   len_processed);
-}
-
-static NTSTATUS gensec_spnego_packet_full_request(struct gensec_security *gensec_security, 
-					     	DATA_BLOB blob, size_t *size)
-{
-	struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data;
-
-	if (spnego_state->state_position != SPNEGO_DONE 
-	    && spnego_state->state_position != SPNEGO_FALLBACK) {
-		DEBUG(1, ("gensec_spnego_unwrap: wrong state for unwrap\n"));
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	return gensec_packet_full_request(spnego_state->sub_sec_security, 
-					  blob, size);
-}
-
-static NTSTATUS gensec_spnego_unwrap_packets(struct gensec_security *gensec_security, 
-					     TALLOC_CTX *mem_ctx, 
-					     const DATA_BLOB *in, 
-					     DATA_BLOB *out,
-					     size_t *len_processed) 
-{
-	struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data;
-
-	if (spnego_state->state_position != SPNEGO_DONE 
-	    && spnego_state->state_position != SPNEGO_FALLBACK) {
-		DEBUG(1, ("gensec_spnego_unwrap: wrong state for unwrap\n"));
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	return gensec_unwrap_packets(spnego_state->sub_sec_security, 
-				     mem_ctx, in, out,
-				     len_processed);
-}
-
 static size_t gensec_spnego_sig_size(struct gensec_security *gensec_security, size_t data_size) 
 {
 	struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data;
@@ -1384,11 +1331,8 @@ static const struct gensec_security_ops gensec_spnego_security_ops = {
 	.max_input_size	  = gensec_spnego_max_input_size,
 	.check_packet	  = gensec_spnego_check_packet,
 	.unseal_packet	  = gensec_spnego_unseal_packet,
-	.packet_full_request = gensec_spnego_packet_full_request,
 	.wrap             = gensec_spnego_wrap,
 	.unwrap           = gensec_spnego_unwrap,
-	.wrap_packets     = gensec_spnego_wrap_packets,
-	.unwrap_packets   = gensec_spnego_unwrap_packets,
 	.session_key	  = gensec_spnego_session_key,
 	.session_info     = gensec_spnego_session_info,
 	.want_feature     = gensec_spnego_want_feature,
diff --git a/auth/gensec/wscript_build b/auth/gensec/wscript_build
index e6d179b..e4c4a08 100755
--- a/auth/gensec/wscript_build
+++ b/auth/gensec/wscript_build
@@ -3,7 +3,7 @@ bld.SAMBA_LIBRARY('gensec',
 	source='gensec.c gensec_start.c gensec_util.c',
 	pc_files='gensec.pc',
 	autoproto='gensec_toplevel_proto.h',
-	public_deps='tevent-util samba-util errors LIBPACKET auth_system_session samba-modules gensec_util asn1util',
+	public_deps='tevent-util samba-util errors auth_system_session samba-modules gensec_util asn1util',
 	public_headers='gensec.h',
 	deps='com_err',
 	vnum='0.0.1'
-- 
1.9.1


From e798b83051d80beb1884bdb2fae266430d8d8e26 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 20 Jun 2015 16:54:33 +0200
Subject: [PATCH 11/12] s3:ntlm_auth: don't start gensec backend twice

ntlm_auth_start_ntlmssp_server() was used in two cases
and both call gensec_start_mech_by_oid() again.
So we remove gensec_start_mech_by_oid() and rename the function
to ntlm_auth_prepare_gensec_server.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/utils/ntlm_auth.c | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index ca13481..a5fd249 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -1027,9 +1027,9 @@ static struct auth4_context *make_auth4_context_ntlm_auth(TALLOC_CTX *mem_ctx, b
 	return auth4_context;
 }
 
-static NTSTATUS ntlm_auth_start_ntlmssp_server(TALLOC_CTX *mem_ctx,
-					       struct loadparm_context *lp_ctx,
-					       struct gensec_security **gensec_security_out)
+static NTSTATUS ntlm_auth_prepare_gensec_server(TALLOC_CTX *mem_ctx,
+						struct loadparm_context *lp_ctx,
+						struct gensec_security **gensec_security_out)
 {
 	struct gensec_security *gensec_security;
 	NTSTATUS nt_status;
@@ -1135,12 +1135,6 @@ static NTSTATUS ntlm_auth_start_ntlmssp_server(TALLOC_CTX *mem_ctx,
 	talloc_unlink(tmp_ctx, gensec_settings);
 	talloc_unlink(tmp_ctx, auth4_context);
 
-	nt_status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_NTLMSSP);
-	if (!NT_STATUS_IS_OK(nt_status)) {
-		TALLOC_FREE(tmp_ctx);
-		return nt_status;
-	}
-	
 	*gensec_security_out = talloc_steal(mem_ctx, gensec_security);
 	TALLOC_FREE(tmp_ctx);
 	return NT_STATUS_OK;
@@ -1541,8 +1535,8 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
 		case GSS_SPNEGO_SERVER:
 		case SQUID_2_5_NTLMSSP:
 		{
-			nt_status = ntlm_auth_start_ntlmssp_server(state, lp_ctx,
-								   &state->gensec_state);
+			nt_status = ntlm_auth_prepare_gensec_server(state, lp_ctx,
+								    &state->gensec_state);
 			if (!NT_STATUS_IS_OK(nt_status)) {
 				x_fprintf(x_stdout, "BH GENSEC mech failed to start: %s\n", nt_errstr(nt_status));
 				talloc_free(mem_ctx);
-- 
1.9.1


From 6ae27453a5f985be04a4b47a36d78e7fe55e9a2b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 19 Jun 2015 00:35:29 +0200
Subject: [PATCH 12/12] s4:selftest: run rpc.echo tests also with krb5
 krb5,sign krb5,seal

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/selftest/tests.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index da3cb98..c3f819e 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -187,7 +187,7 @@ for env in ["ad_dc_ntvfs", "fl2000dc", "fl2003dc", "fl2008r2dc", "ad_dc"]:
         plansmbtorture4testsuite('rpc.echo', env, ["%s:$SERVER[]" % (transport,), '-U$USERNAME%$PASSWORD', '--workgroup=$DOMAIN'], "samba4.rpc.echo on %s" % (transport, ))
 
         # Echo tests test bulk Kerberos encryption of DCE/RPC
-        for bindoptions in ["connect", "spnego", "spnego,sign", "spnego,seal"] + validate_list + ["padcheck", "bigendian", "bigendian,seal"]:
+        for bindoptions in ["connect", "krb5", "krb5,sign", "krb5,seal", "spnego", "spnego,sign", "spnego,seal"] + validate_list + ["padcheck", "bigendian", "bigendian,seal"]:
             echooptions = "--option=socket:testnonblock=True --option=torture:quick=yes -k yes"
             plansmbtorture4testsuite('rpc.echo', env, ["%s:$SERVER[%s]" % (transport, bindoptions), echooptions, '-U$USERNAME%$PASSWORD', '--workgroup=$DOMAIN'], "samba4.rpc.echo on %s with %s and %s" % (transport, bindoptions, echooptions))
     plansmbtorture4testsuite("net.api.become.dc", env, '$SERVER[%s] -U$USERNAME%%$PASSWORD -W$DOMAIN' % validate)
-- 
1.9.1
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20150622/15f25911/attachment.pgp>


More information about the samba-technical mailing list