svn commit: samba r15504 - in branches/SAMBA_4_0/source: libnet librpc/rpc torture/rpc

abartlet at samba.org abartlet at samba.org
Sun May 7 19:55:15 GMT 2006


Author: abartlet
Date: 2006-05-07 19:55:14 +0000 (Sun, 07 May 2006)
New Revision: 15504

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=15504

Log:
Revert -r 15500 and -r 15503 until I'm awake, and can get my head
around the mess that is composite functions...

Async might be all the rage, but it's bloody painful to debug.

Andrew Bartlett

Modified:
   branches/SAMBA_4_0/source/libnet/libnet_join.c
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc.c
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc_connect.c
   branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c
   branches/SAMBA_4_0/source/torture/rpc/bind.c


Changeset:
Modified: branches/SAMBA_4_0/source/libnet/libnet_join.c
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_join.c	2006-05-07 19:36:06 UTC (rev 15503)
+++ branches/SAMBA_4_0/source/libnet/libnet_join.c	2006-05-07 19:55:14 UTC (rev 15504)
@@ -482,7 +482,7 @@
 
 	samr_pipe = connect_with_info->out.dcerpc_pipe;
 
-	status = dcerpc_pipe_auth(&samr_pipe,
+	status = dcerpc_pipe_auth(tmp_ctx, &samr_pipe,
 				  connect_with_info->out.dcerpc_pipe->binding, 
 				  &dcerpc_table_samr, ctx->cred);
 	if (!NT_STATUS_IS_OK(status)) {

Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc.c
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc.c	2006-05-07 19:36:06 UTC (rev 15503)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc.c	2006-05-07 19:55:14 UTC (rev 15504)
@@ -490,20 +490,6 @@
 }
 
 /*
-  map a fault reason to a NTSTATUS
-*/
-static NTSTATUS dcerpc_map_fault(uint32_t status)
-{
-	switch (status) {
-	case DCERPC_FAULT_OP_RNG_ERROR:
-		return NT_STATUS_ILLEGAL_FUNCTION;
-	case DCERPC_FAULT_ACCESS_DENIED:
-		return NT_STATUS_ACCESS_DENIED;
-	}
-	return NT_STATUS_NET_WRITE_FAULT;
-}
-
-/*
   mark the dcerpc connection dead. All outstanding requests get an error
 */
 static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status)
@@ -569,19 +555,27 @@
 		dcerpc_connection_dead(conn, status);
 	}
 
-	if (conn->bind_private) {
-		talloc_steal(conn->bind_private, blob->data);
-		dcerpc_bind_recv_data(conn, &pkt);
-		return;
-	}
-	if (conn->alter_private) {
-		talloc_steal(conn->alter_private, blob->data);
-		dcerpc_alter_recv_data(conn, &pkt);
-		return;
-	}
+	switch (pkt.ptype) {
+	case DCERPC_PKT_BIND_NAK:
+	case DCERPC_PKT_BIND_ACK:
+		if (conn->bind_private) {
+			talloc_steal(conn->bind_private, blob->data);
+			dcerpc_bind_recv_data(conn, &pkt);
+		}
+		break;
 
-	/* assume its an ordinary request */
-	dcerpc_request_recv_data(conn, blob, &pkt);
+	case DCERPC_PKT_ALTER_RESP:
+		if (conn->alter_private) {
+			talloc_steal(conn->alter_private, blob->data);
+			dcerpc_alter_recv_data(conn, &pkt);
+		}
+		break;
+
+	default:
+		/* assume its an ordinary request */
+		dcerpc_request_recv_data(conn, blob, &pkt);
+		break;
+	}
 }
 
 
@@ -597,13 +591,6 @@
 	/* mark the connection as not waiting for a bind reply */
 	conn->bind_private = NULL;
 
-	if (pkt->ptype == DCERPC_PKT_FAULT) {
-		DEBUG(2,("dcerpc: bind faulted: reason %s\n",
-			 dcerpc_errstr(c, pkt->u.fault.status)));
-		composite_error(c, dcerpc_map_fault(pkt->u.fault.status));
-		return;
-	}
-
 	if (pkt->ptype == DCERPC_PKT_BIND_NAK) {
 		DEBUG(2,("dcerpc: bind_nak reason %d\n",
 			 pkt->u.bind_nak.reject_reason));
@@ -1541,13 +1528,6 @@
 	/* mark the connection as not waiting for a alter context reply */
 	conn->alter_private = NULL;
 
-	if (pkt->ptype == DCERPC_PKT_FAULT) {
-		DEBUG(2,("dcerpc: alter context faulted: reason %s\n",
-			 dcerpc_errstr(c, pkt->u.fault.status)));
-		composite_error(c, dcerpc_map_fault(pkt->u.fault.status));
-		return;
-	}
-
 	if (pkt->ptype == DCERPC_PKT_ALTER_RESP &&
 	    pkt->u.alter_resp.num_results == 1 &&
 	    pkt->u.alter_resp.ctx_list[0].result != 0) {

Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc_connect.c
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc_connect.c	2006-05-07 19:36:06 UTC (rev 15503)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc_connect.c	2006-05-07 19:55:14 UTC (rev 15504)
@@ -764,7 +764,7 @@
 						      struct composite_context);
 	struct pipe_connect_state *s = talloc_get_type(c->private_data, struct pipe_connect_state);
 
-	c->status = dcerpc_pipe_auth_recv(s, &s->pipe);
+	c->status = dcerpc_pipe_auth_recv(ctx, s, &s->pipe);
 	if (!composite_is_ok(c)) return;
 
 	composite_done(c);
@@ -1170,8 +1170,7 @@
 	s = talloc_get_type(c->private_data, struct sec_conn_state);
 
 	if (NT_STATUS_IS_OK(status)) {
-		talloc_steal(s->pipe, s->pipe2);
-		*p2 = s->pipe2;
+		*p2 = talloc_steal(s->pipe, s->pipe2);
 	}
 
 	talloc_free(c);

Modified: branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c
===================================================================
--- branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c	2006-05-07 19:36:06 UTC (rev 15503)
+++ branches/SAMBA_4_0/source/librpc/rpc/dcerpc_util.c	2006-05-07 19:55:14 UTC (rev 15504)
@@ -976,12 +976,14 @@
 	struct dcerpc_binding *binding;
 	const struct dcerpc_interface_table *table;
 	struct cli_credentials *credentials;
-	uint8_t auth_type;
-	BOOL try_ntlm_fallback;
 };
 
 
-static void continue_new_auth_bind(struct composite_context *ctx);
+static void continue_auth_schannel(struct composite_context *ctx);
+static void continue_auth(struct composite_context *ctx);
+static void continue_auth_none(struct composite_context *ctx);
+static void continue_ntlmssp_connection(struct composite_context *ctx);
+static void continue_spnego_after_wrong_pass(struct composite_context *ctx);
 
 
 /*
@@ -1000,32 +1002,42 @@
 
 
 /*
+  Stage 2 of pipe_auth: Receive result of authenticated bind request
+*/
+static void continue_auth(struct composite_context *ctx)
+{
+	struct composite_context *c = talloc_get_type(ctx->async.private_data,
+						      struct composite_context);
+
+	c->status = dcerpc_bind_auth_recv(ctx);
+	if (!composite_is_ok(c)) return;
+	
+	composite_done(c);
+}
+/*
   Stage 2 of pipe_auth: Receive result of authenticated bind request, but handle fallbacks:
   SPNEGO -> NTLMSSP
 */
-static void continue_recv_bind(struct composite_context *ctx)
+static void continue_auth_auto(struct composite_context *ctx)
 {
-	NTSTATUS status;
 	struct composite_context *c = talloc_get_type(ctx->async.private_data,
 						      struct composite_context);
-	struct pipe_auth_state *s = talloc_get_type(c->private_data, struct pipe_auth_state);
 
-	status = dcerpc_bind_auth_recv(ctx);
-	if (s->auth_type == DCERPC_AUTH_TYPE_SPNEGO
-	    && s->try_ntlm_fallback
-	    && NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+	c->status = dcerpc_bind_auth_recv(ctx);
+	if (NT_STATUS_EQUAL(c->status, NT_STATUS_INVALID_PARAMETER)) {
+		struct pipe_auth_state *s = talloc_get_type(c->private_data, struct pipe_auth_state);
 		struct composite_context *sec_conn_req;
-		s->try_ntlm_fallback = False;
-		s->auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
+
 		/* send a request for secondary rpc connection */
 		sec_conn_req = dcerpc_secondary_connection_send(s->pipe,
 								s->binding);
 		if (composite_nomem(sec_conn_req, c)) return;
 		
-		composite_continue(c, sec_conn_req, continue_new_auth_bind, c);
+		composite_continue(c, sec_conn_req, continue_ntlmssp_connection, c);
 		
 		return;
-	} else if (s->auth_type == DCERPC_AUTH_TYPE_SPNEGO && NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+	} else if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) {
+		struct pipe_auth_state *s = talloc_get_type(c->private_data, struct pipe_auth_state);
 		struct composite_context *sec_conn_req;
 		if (cli_credentials_wrong_password(s->credentials)) {
 			/* send a request for secondary rpc connection */
@@ -1033,12 +1045,9 @@
 									s->binding);
 			if (composite_nomem(sec_conn_req, c)) return;
 			
-			composite_continue(c, sec_conn_req, continue_new_auth_bind, c);
-
-			return;
+			composite_continue(c, sec_conn_req, continue_spnego_after_wrong_pass, c);
 		}
 	}
-	c->status = status;
 
 	if (!composite_is_ok(c)) return;
 	
@@ -1046,14 +1055,44 @@
 }
 
 /*
-  Stage 3 of pipe_auth (fallback to NTLMSSP case/SPNEGO password retry case): 
-  
-  Receive secondary rpc connection (the first one can't be used any
-  more, due to the bind nak) and perform authenticated bind request
+  Stage 3 of pipe_auth (fallback to NTLMSSP case): Receive secondary
+  rpc connection (the first one can't be used any more, due to the
+  bind nak) and perform authenticated bind request
+*/
+static void continue_ntlmssp_connection(struct composite_context *ctx)
+{
+	struct composite_context *c;
+	struct pipe_auth_state *s;
+	struct composite_context *auth_req;
+	struct dcerpc_pipe *p2;
 
-  Calls back to stage 2 to process the response.
+	c = talloc_get_type(ctx->async.private_data, struct composite_context);
+	s = talloc_get_type(c->private_data, struct pipe_auth_state);
+
+	/* receive secondary rpc connection */
+	c->status = dcerpc_secondary_connection_recv(ctx, &p2);
+	talloc_steal(s, p2);
+	talloc_steal(p2, s->pipe);
+	s->pipe = p2;
+
+	if (!composite_is_ok(c)) return;
+
+	/* initiate a authenticated bind */
+	auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
+					 s->credentials, DCERPC_AUTH_TYPE_NTLMSSP,
+					 dcerpc_auth_level(s->pipe->conn),
+					 s->table->authservices->names[0]);
+	if (composite_nomem(auth_req, c)) return;
+		
+	composite_continue(c, auth_req, continue_auth, c);
+}
+
+/*
+  Stage 3 of pipe_auth (retry on wrong password): Receive secondary
+  rpc connection (the first one can't be used any more, due to the
+  bind nak) and perform authenticated bind request
 */
-static void continue_new_auth_bind(struct composite_context *ctx)
+static void continue_spnego_after_wrong_pass(struct composite_context *ctx)
 {
 	struct composite_context *c;
 	struct pipe_auth_state *s;
@@ -1065,25 +1104,27 @@
 
 	/* receive secondary rpc connection */
 	c->status = dcerpc_secondary_connection_recv(ctx, &p2);
+	talloc_steal(s, p2);
+	talloc_steal(p2, s->pipe);
 	s->pipe = p2;
 
 	if (!composite_is_ok(c)) return;
 
 	/* initiate a authenticated bind */
 	auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
-					 s->credentials, s->auth_type,
+					 s->credentials, DCERPC_AUTH_TYPE_SPNEGO,
 					 dcerpc_auth_level(s->pipe->conn),
 					 s->table->authservices->names[0]);
 	if (composite_nomem(auth_req, c)) return;
 		
-	composite_continue(c, auth_req, continue_recv_bind, c);
+	composite_continue(c, auth_req, continue_auth, c);
 }
 
 
 /*
   Stage 2 of pipe_auth: Receive result of non-authenticated bind request
 */
-static void continue_auth_recv_none(struct composite_context *ctx)
+static void continue_auth_none(struct composite_context *ctx)
 {
 	struct composite_context *c = talloc_get_type(ctx->async.private_data,
 						      struct composite_context);
@@ -1158,6 +1199,8 @@
 		 * connection is not signed or sealed.  For that case
 		 * we rely on the already authenticated CIFS connection
 		 */
+		
+		uint8_t auth_type;
 
 		if ((conn->flags & (DCERPC_SIGN|DCERPC_SEAL)) == 0) {
 			/*
@@ -1171,34 +1214,40 @@
 		}
 
 		if (s->binding->flags & DCERPC_AUTH_SPNEGO) {
-			s->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
+			auth_type = DCERPC_AUTH_TYPE_SPNEGO;
 
 		} else if (s->binding->flags & DCERPC_AUTH_KRB5) {
-			s->auth_type = DCERPC_AUTH_TYPE_KRB5;
+			auth_type = DCERPC_AUTH_TYPE_KRB5;
 
 		} else if (s->binding->flags & DCERPC_SCHANNEL) {
-			s->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
+			auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
 
 		} else if (s->binding->flags & DCERPC_AUTH_NTLM) {
-			s->auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
+			auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
 		} else {
-			s->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
-			s->try_ntlm_fallback = True;
+			auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
+							 s->credentials, DCERPC_AUTH_TYPE_SPNEGO,
+							 dcerpc_auth_level(conn),
+							 s->table->authservices->names[0]);
+			if (composite_nomem(auth_req, c)) return c;
+			
+			composite_continue(c, auth_req, continue_auth_auto, c);
+			return c;
 		}
-
+		
 		auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
-						 s->credentials, s->auth_type,
+						 s->credentials, auth_type,
 						 dcerpc_auth_level(conn),
 						 s->table->authservices->names[0]);
 		if (composite_nomem(auth_req, c)) return c;
 		
-		composite_continue(c, auth_req, continue_recv_bind, c);
+		composite_continue(c, auth_req, continue_auth, c);
 
 	} else {
 		auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe, s->table);
 		if (composite_nomem(auth_none_req, c)) return c;
 
-		composite_continue(c, auth_none_req, continue_auth_recv_none, c);
+		composite_continue(c, auth_none_req, continue_auth_none, c);
 	}
 
 	return c;
@@ -1212,7 +1261,7 @@
   supllied, as it rebinds to a new pipe due to authentication fallback
 
 */
-NTSTATUS dcerpc_pipe_auth_recv(struct composite_context *c, 
+NTSTATUS dcerpc_pipe_auth_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, 
 			       struct dcerpc_pipe **p)
 {
 	NTSTATUS status;
@@ -1225,6 +1274,7 @@
 		DEBUG(0, ("Failed to bind to uuid %s - %s\n", uuid_str, nt_errstr(status)));
 		talloc_free(uuid_str);
 	} else {
+		talloc_steal(mem_ctx, s->pipe);
 		*p = s->pipe;
 	}
 
@@ -1238,7 +1288,8 @@
 
    This may change *p, as it rebinds to a new pipe due to authentication fallback
 */
-NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe **p, 
+NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx,
+			  struct dcerpc_pipe **p, 
 			  struct dcerpc_binding *binding,
 			  const struct dcerpc_interface_table *table,
 			  struct cli_credentials *credentials)
@@ -1246,7 +1297,7 @@
 	struct composite_context *c;
 
 	c = dcerpc_pipe_auth_send(*p, binding, table, credentials);
-	return dcerpc_pipe_auth_recv(c, p);
+	return dcerpc_pipe_auth_recv(c, mem_ctx, p);
 }
 
 

Modified: branches/SAMBA_4_0/source/torture/rpc/bind.c
===================================================================
--- branches/SAMBA_4_0/source/torture/rpc/bind.c	2006-05-07 19:36:06 UTC (rev 15503)
+++ branches/SAMBA_4_0/source/torture/rpc/bind.c	2006-05-07 19:55:14 UTC (rev 15504)
@@ -63,7 +63,7 @@
 		return False;
 	}
 
-	status = dcerpc_pipe_auth(&p, binding, &dcerpc_table_lsarpc, cmdline_credentials);
+	status = dcerpc_pipe_auth(mem_ctx, &p, binding, &dcerpc_table_lsarpc, cmdline_credentials);
 
 	if (NT_STATUS_IS_OK(status)) {
 		printf("(incorrectly) allowed re-bind to uuid %s - %s\n", 



More information about the samba-cvs mailing list