Hi List,

Some of you working with mapiproxy may have noticed Outlook sometimes
drop MAPI connections unexpectedly - showing notification pop-up
mentioning network connection problem.

The bug (presumably) shows up when Outlook <-> mapiproxy <-> Exchange
communication is too slow. If Outlook doesn't receive information fast
enough, it will bind another rpc connection using the assoc_group_id of
an existing one.

Problem: Samba4 does not support assoc_group_id and always return
0x12345678, which made impossible for mapiproxy to transparently relay
assoc_group_id from client to server.

After a whole week of work and valuable help from Stefan Metzemacher, I
can finally come back with a *not yet* perfect but quite reliable
solution.

1. Apply the following patch to your samba4 git tree:
http://gitweb.samba.org/?p=metze/samba/wip.git;a=commitdiff;h=79fd9f7332bf72188dcb90bd3c551007f4e1324f

2. Apply the attached patch to openchange trunk

3. Edit smb.conf and add the following parametric option:
dcesrv:assoc group checking = false

This will make Outlook connections persistent and you shouldn't anymore
have network connection problem.

However, it sounds like mapiproxy/samba4 sends something back to Outlook
which make Outlook believes it can open an EMSMDB connection using the
NSPI assoc_group_id. Exchange doesn't appreciate and return a bind_nack
with undefined error 0.

This latest issue shouldn't however impact mapiproxy
performances/reliability.

Cheers,
Julien.

-- 
Julien Kerihuel
[EMAIL PROTECTED]
OpenChange Project Manager

GPG Fingerprint: 0B55 783D A781 6329 108A  B609 7EF6 FE11 A35F 1F79

Index: mapiproxy/dcesrv_mapiproxy.c
===================================================================
--- mapiproxy/dcesrv_mapiproxy.c	(revision 895)
+++ mapiproxy/dcesrv_mapiproxy.c	(working copy)
@@ -70,7 +70,7 @@
 	binding = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "binding");
 	machine_account = lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "use_machine_account", false);
 
-	private = talloc(dce_call->conn, struct dcesrv_mapiproxy_private);
+	private = talloc(dce_call->context, struct dcesrv_mapiproxy_private);
 	if (!private) {
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -129,13 +129,45 @@
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	status = dcerpc_pipe_connect(private,
-				     &(private->c_pipe), binding, table,
-				     credentials, dce_call->event_ctx,
-				     dce_call->conn->dce_ctx->lp_ctx);
-	talloc_free(credentials);
-	if (!NT_STATUS_IS_OK(status)) {
-		return status;
+	if (dce_call->pkt.u.bind.assoc_group_id) {
+		struct dcerpc_binding		*b;
+		struct composite_context	*pipe_conn_req;
+
+		/* parse binding string to the structure */
+		status = dcerpc_parse_binding(dce_call->context, binding, &b);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", binding));
+			return status;
+		}
+		
+		DEBUG(3, ("Using binding %s\n", dcerpc_binding_string(dce_call->context, b)));
+		
+		/*
+		   start connecting to a rpc pipe after binding structure
+		   is established
+		*/
+		b->assoc_group_id = dce_call->pkt.u.bind.assoc_group_id;
+		pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table,
+							   credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
+
+		status = dcerpc_pipe_connect_b_recv(pipe_conn_req, dce_call->context, &(private->c_pipe));
+
+		talloc_free(credentials);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+ 		
+	} else {
+		status = dcerpc_pipe_connect(dce_call->context,
+					     &(private->c_pipe), binding, table,
+					     credentials, dce_call->event_ctx,
+					     dce_call->conn->dce_ctx->lp_ctx);
+
+		talloc_free(credentials);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+		dce_call->context->assoc_group_id = private->c_pipe->assoc_group_id;
 	}
 
 	DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: CONNECTED\n"));
@@ -162,8 +194,11 @@
 
 	if (private) {
 		talloc_free(private->c_pipe);
+		talloc_free(private);
 	}
 
+	talloc_free(context);
+
 	return;
 }
 
@@ -275,6 +310,7 @@
 	mapiproxy_module_push(dce_call, mem_ctx, (void *)r);
 
 	ndr_err = table->calls[opnum].ndr_push(push, NDR_OUT, r);
+
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 		DEBUG(0, ("mapiproxy: mapiproxy_ndr_push: ERROR\n"));
 		dce_call->fault_code = DCERPC_FAULT_NDR;
@@ -323,7 +359,7 @@
 		return NT_STATUS_NET_WRITE_FAULT;
 	}
 
-	DEBUG(5, ("mapiproxy::mapiproxy_op_dispatch: %s(0x%x): %zd bytes\n", 
+	DEBUG(5, ("mapiproxy::mapiproxy_op_dispatch: %s(0x%x): %zd bytes\n",
 		  table->calls[opnum].name, opnum, table->calls[opnum].struct_size));
 
 	if (private->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_IN) {
Index: mapiproxy/dcesrv_mapiproxy.h
===================================================================
--- mapiproxy/dcesrv_mapiproxy.h	(revision 895)
+++ mapiproxy/dcesrv_mapiproxy.h	(working copy)
@@ -51,6 +51,9 @@
 	char			*exchname;
 };
 
+/* Forward declarations */
+struct composite_context;
+
 #define MAXHOSTNAMELEN	255
 #define	SERVERNAME      "/cn=Servers/cn="
 

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
devel mailing list
[email protected]
http://mailman.openchange.org/listinfo/devel

Reply via email to