[PATCH] Clean up cli_pipe to find the auth footer once only.

Andrew Bartlett abartlet at samba.org
Wed Jul 16 02:26:21 GMT 2003


On Tue, Jul 15, 2003 at 09:33:28PM +0000, jerry at samba.org wrote:
> 
> Date:	Tue Jul 15 21:33:28 2003
> Author:	jerry
> 
> Update of /data/cvs/samba/source/rpc_client
> In directory dp.samba.org:/tmp/cvs-serv31805/rpc_client
> 
> Modified Files:
>       Tag: SAMBA_3_0
> 	cli_pipe.c 
> Log Message:
> fix schannel processing on fragmented PDUs.  'net rpc vampire' works again.

Thankyou very much for finding this - my test domain didn't seem to give
me the fragmentated PDUs.

I've tried to fix this for the generic case - it looks like the NTLMSSP case 
never coped with fragmented PDUs, hence the introduction of this bug.

What I'm trying to do in the attached patch is ensure we try to find the
authentication footer only once...

Could you please check this against your test domains?

Andrew Bartlett
-------------- next part --------------
Index: rpc_client/cli_pipe.c
===================================================================
RCS file: /home/cvs/samba/source/rpc_client/cli_pipe.c,v
retrieving revision 1.79.2.28
diff -u -r1.79.2.28 cli_pipe.c
--- rpc_client/cli_pipe.c	15 Jul 2003 21:33:28 -0000	1.79.2.28
+++ rpc_client/cli_pipe.c	16 Jul 2003 02:17:29 -0000
@@ -185,6 +185,10 @@
 
 	RPC_HDR_AUTH rhdr_auth; 
 
+	char *dp = prs_data_p(rdata) + fragment_start + len -
+		RPC_HDR_AUTH_LEN - auth_len;
+	prs_struct auth_verf;
+
 	*pauth_padding_len = 0;
 
 	if (auth_len == 0) {
@@ -204,30 +208,29 @@
 		 BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN), 
 		 BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL)));
 
-	{
-		int auth_type;
-		int auth_level;
-		char *dp = prs_data_p(rdata) + fragment_start + len -
-					RPC_HDR_AUTH_LEN - auth_len;
-		prs_struct auth_verf;
-
-		if (dp - prs_data_p(rdata) > prs_data_size(rdata)) {
-			DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n"));
-			return False;
-		}
-
-		DEBUG(10,("rpc_auth_pipe: packet:\n"));
-		dump_data(100, dp, auth_len);
-
-		prs_init(&auth_verf, RPC_HDR_AUTH_LEN, cli->mem_ctx, UNMARSHALL);
-
-		/* The endinness must be preserved. JRA. */
-		prs_set_endian_data( &auth_verf, rdata->bigendian_data);
+	if (dp - prs_data_p(rdata) > prs_data_size(rdata)) {
+		DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n"));
+		return False;
+	}
 
-		prs_copy_data_in(&auth_verf, dp, RPC_HDR_AUTH_LEN);
-		prs_set_offset(&auth_verf, 0);
+	DEBUG(10,("rpc_auth_pipe: packet:\n"));
+	dump_data(100, dp, auth_len);
 
+	prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL);
+	
+	/* The endinness must be preserved. JRA. */
+	prs_set_endian_data( &auth_verf, rdata->bigendian_data);
+	
+	/* Point this new parse struct at the auth section of the main 
+	   parse struct - rather than copying it.  Avoids needing to
+	   free it on every error
+	*/
+	prs_give_memory(&auth_verf, dp, RPC_HDR_AUTH_LEN + auth_len, False /* not dynamic */);
+	prs_set_offset(&auth_verf, 0);
 
+	{
+		int auth_type;
+		int auth_level;
 		if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) {
 			DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n"));
 			return False;
@@ -254,20 +257,21 @@
 
 	if (pkt_type == RPC_BINDACK) {
 		if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
-			char *dp = prs_data_p(rdata) + len - auth_len;
-			
-			if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
-				DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
-				return False;
-			}
+			/* copy the next auth_len bytes into a buffer for 
+			   later use */
+
+			DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len);
 			
 			/* save the reply away, for use a little later */
+			prs_copy_data_out(ntlmssp_verf.data, &auth_verf, auth_len);
+
+
 			return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state, 
-									      data_blob(dp, auth_len))));
-		}
-		if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
-			/* nothing to do here - we don't seem to be able to validate the
-			   bindack based on VL's comments */
+									      ntlmssp_verf)));
+		} 
+		else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
+			/* nothing to do here - we don't seem to be able to 
+			   validate the bindack based on VL's comments */
 			return True;
 		}
 	}
@@ -277,19 +281,12 @@
 		DATA_BLOB sig;
 		if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) ||
 		    (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) {
-			char *dp = prs_data_p(rdata) + len - auth_len;
-			
-			if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
-				DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
-				return False;
-			}
-			
 			if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) {
 				DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len));
 				return False;
 			}
-			
-			sig = data_blob(dp, auth_len);
+			sig = data_blob(NULL, auth_len);
+			prs_copy_data_out(sig.data, &auth_verf, auth_len);
 		}
 	
 		/*
@@ -308,8 +305,8 @@
 				return False;
 			}
 			nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state, 
-						     reply_data, data_len,
-						     &sig);
+								 reply_data, data_len,
+								 &sig);
 		} 
 		else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
 			nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state, 
@@ -328,34 +325,16 @@
 
 	if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
 		RPC_AUTH_NETSEC_CHK chk;
-		prs_struct netsec_verf;
-
-		char *dp = prs_data_p(rdata) + fragment_start + len - auth_len;
-		
-		if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
-			DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
-			return False;
-		}
 
 		if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) {
 			DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len));
 			return False;
 		}
 
-		prs_init(&netsec_verf, RPC_AUTH_NETSEC_CHK_LEN, 
-			 cli->mem_ctx, UNMARSHALL);
-
-		/* The endinness must be preserved. JRA. */
-		prs_set_endian_data( &netsec_verf, rdata->bigendian_data);
-
-		prs_copy_data_in(&netsec_verf, dp, auth_len);
-		prs_set_offset(&netsec_verf, 0);
-
 		if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", 
-						&chk, &netsec_verf, 0)) {
+						&chk, &auth_verf, 0)) {
 			DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling "
 				  "RPC_AUTH_NETSECK_CHK failed\n"));
-			prs_mem_free(&netsec_verf);
 			return False;
 		}
 
@@ -364,13 +343,11 @@
 				   SENDER_IS_ACCEPTOR,
 				   &chk, reply_data, data_len)) {
 			DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n"));
-			prs_mem_free(&netsec_verf);
 			return False;
 		}
 
 		cli->auth_info.seq_num++;
 
-		prs_mem_free(&netsec_verf);
 	}
 	return True;
 }


More information about the samba-technical mailing list