svn commit: samba r11950 - in branches/SAMBA_3_0/source: include rpc_server

jra at samba.org jra at samba.org
Tue Nov 29 02:10:54 GMT 2005


Author: jra
Date: 2005-11-29 02:10:52 +0000 (Tue, 29 Nov 2005)
New Revision: 11950

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

Log:
If we got a connection oriented cancel pdu we would spin processing it.
Fix that, and also add in comments for all possible CL and CO PDU
types. Make sure we process them correctly.
Jeremy.

Modified:
   branches/SAMBA_3_0/source/include/rpc_dce.h
   branches/SAMBA_3_0/source/rpc_server/srv_pipe.c
   branches/SAMBA_3_0/source/rpc_server/srv_pipe_hnd.c


Changeset:
Modified: branches/SAMBA_3_0/source/include/rpc_dce.h
===================================================================
--- branches/SAMBA_3_0/source/include/rpc_dce.h	2005-11-28 22:53:42 UTC (rev 11949)
+++ branches/SAMBA_3_0/source/include/rpc_dce.h	2005-11-29 02:10:52 UTC (rev 11950)
@@ -26,15 +26,27 @@
 /* DCE/RPC packet types */
 
 enum RPC_PKT_TYPE {
-	RPC_REQUEST = 0x00,
-	RPC_RESPONSE = 0x02,
-	RPC_FAULT    = 0x03,
-	RPC_BIND     = 0x0B,
-	RPC_BINDACK  = 0x0C,
-	RPC_BINDNACK = 0x0D,
-	RPC_ALTCONT  = 0x0E,
-	RPC_ALTCONTRESP = 0x0F,
-	RPC_AUTH3 = 0x10 /* not the real name!  this is undocumented! */
+	RPC_REQUEST  = 0x00, 	/* Ordinary request. */
+	RPC_PING     = 0x01,	/* Connectionless is server alive ? */
+	RPC_RESPONSE = 0x02,	/* Ordinary reply. */
+	RPC_FAULT    = 0x03,	/* Fault in processing of call. */
+	RPC_WORKING  = 0x04,	/* Connectionless reply to a ping when server busy. */
+	RPC_NOCALL   = 0x05,	/* Connectionless reply to a ping when server has lost part of clients call. */
+	RPC_REJECT   = 0x06,	/* Refuse a request with a code. */
+	RPC_ACK      = 0x07,	/* Connectionless client to server code. */
+	RPC_CL_CANCEL= 0x08,	/* Connectionless cancel. */
+	RPC_FACK     = 0x09,	/* Connectionless fragment ack. Both client and server send. */
+	RPC_CANCEL_ACK = 0x0A,	/* Server ACK to client cancel request. */
+	RPC_BIND     = 0x0B,	/* Bind to interface. */
+	RPC_BINDACK  = 0x0C,	/* Server ack of bind. */
+	RPC_BINDNACK = 0x0D,	/* Server nack of bind. */
+	RPC_ALTCONT  = 0x0E,	/* Alter auth. */
+	RPC_ALTCONTRESP = 0x0F,	/* Reply to alter auth. */
+	RPC_AUTH3    = 0x10, 	/* not the real name!  this is undocumented! */
+	RPC_SHUTDOWN = 0x11,	/* Server to client request to shutdown. */
+	RPC_CO_CANCEL= 0x12,	/* Connection-oriented cancel request. */
+	RPC_ORPHANED = 0x13	/* Client telling server it's aborting a partially sent request or telling
+				   server to stop sending replies. */
 };
 
 /* DCE/RPC flags */

Modified: branches/SAMBA_3_0/source/rpc_server/srv_pipe.c
===================================================================
--- branches/SAMBA_3_0/source/rpc_server/srv_pipe.c	2005-11-28 22:53:42 UTC (rev 11949)
+++ branches/SAMBA_3_0/source/rpc_server/srv_pipe.c	2005-11-29 02:10:52 UTC (rev 11950)
@@ -892,7 +892,56 @@
 	return True;
 }
 
+#if 0
 /*******************************************************************
+ Marshall a cancel_ack pdu.
+ We should probably check the auth-verifier here.
+*******************************************************************/
+
+BOOL setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p)
+{
+	prs_struct outgoing_pdu;
+	RPC_HDR ack_reply_hdr;
+
+	/* Free any memory in the current return data buffer. */
+	prs_mem_free(&p->out_data.rdata);
+
+	/*
+	 * Marshall directly into the outgoing PDU space. We
+	 * must do this as we need to set to the bind response
+	 * header and are never sending more than one PDU here.
+	 */
+
+	prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
+	prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
+
+	/*
+	 * Initialize a cancel_ack header.
+	 */
+
+	init_rpc_hdr(&ack_reply_hdr, RPC_CANCEL_ACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+			p->hdr.call_id, RPC_HEADER_LEN, 0);
+
+	/*
+	 * Marshall the header into the outgoing PDU.
+	 */
+
+	if(!smb_io_rpc_hdr("", &ack_reply_hdr, &outgoing_pdu, 0)) {
+		DEBUG(0,("setup_cancel_ack_reply: marshalling of RPC_HDR failed.\n"));
+		prs_mem_free(&outgoing_pdu);
+		return False;
+	}
+
+	p->out_data.data_sent_length = 0;
+	p->out_data.current_pdu_len = prs_offset(&outgoing_pdu);
+	p->out_data.current_pdu_sent = 0;
+
+	prs_mem_free(&outgoing_pdu);
+	return True;
+}
+#endif
+
+/*******************************************************************
  Ensure a bind request has the correct abstract & transfer interface.
  Used to reject unknown binds from Win2k.
 *******************************************************************/

Modified: branches/SAMBA_3_0/source/rpc_server/srv_pipe_hnd.c
===================================================================
--- branches/SAMBA_3_0/source/rpc_server/srv_pipe_hnd.c	2005-11-28 22:53:42 UTC (rev 11949)
+++ branches/SAMBA_3_0/source/rpc_server/srv_pipe_hnd.c	2005-11-29 02:10:52 UTC (rev 11950)
@@ -716,6 +716,32 @@
 			(unsigned int)p->hdr.pkt_type ));
 
 	switch (p->hdr.pkt_type) {
+		case RPC_REQUEST:
+			reply = process_request_pdu(p, &rpc_in);
+			break;
+
+		case RPC_PING: /* CL request - ignore... */
+			DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
+				(unsigned int)p->hdr.pkt_type, p->name));
+			break;
+
+		case RPC_RESPONSE: /* No responses here. */
+			DEBUG(0,("process_complete_pdu: Error. RPC_RESPONSE received from client on pipe %s.\n",
+				p->name ));
+			break;
+
+		case RPC_FAULT:
+		case RPC_WORKING: /* CL request - reply to a ping when a call in process. */
+		case RPC_NOCALL: /* CL - server reply to a ping call. */
+		case RPC_REJECT:
+		case RPC_ACK:
+		case RPC_CL_CANCEL:
+		case RPC_FACK:
+		case RPC_CANCEL_ACK:
+			DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
+				(unsigned int)p->hdr.pkt_type, p->name));
+			break;
+
 		case RPC_BIND:
 			/*
 			 * We assume that a pipe bind is only in one pdu.
@@ -724,6 +750,14 @@
 				reply = api_pipe_bind_req(p, &rpc_in);
 			}
 			break;
+
+		case RPC_BINDACK:
+		case RPC_BINDNACK:
+			DEBUG(0,("process_complete_pdu: Error. RPC_BINDACK/RPC_BINDNACK packet type %u received on pipe %s.\n",
+				(unsigned int)p->hdr.pkt_type, p->name));
+			break;
+
+
 		case RPC_ALTCONT:
 			/*
 			 * We assume that a pipe bind is only in one pdu.
@@ -732,6 +766,12 @@
 				reply = api_pipe_alter_context(p, &rpc_in);
 			}
 			break;
+
+		case RPC_ALTCONTRESP:
+			DEBUG(0,("process_complete_pdu: Error. RPC_ALTCONTRESP on pipe %s: Should only be server -> client.\n",
+				p->name));
+			break;
+
 		case RPC_AUTH3:
 			/*
 			 * The third packet in an NTLMSSP auth exchange.
@@ -740,9 +780,38 @@
 				reply = api_pipe_bind_auth3(p, &rpc_in);
 			}
 			break;
-		case RPC_REQUEST:
-			reply = process_request_pdu(p, &rpc_in);
+
+		case RPC_SHUTDOWN:
+			DEBUG(0,("process_complete_pdu: Error. RPC_SHUTDOWN on pipe %s: Should only be server -> client.\n",
+				p->name));
 			break;
+
+		case RPC_CO_CANCEL:
+			/* For now just free all client data and continue processing. */
+			DEBUG(3,("process_complete_pdu: RPC_ORPHANED. Abandoning rpc call.\n"));
+			/* As we never do asynchronous RPC serving, we can never cancel a
+			   call (as far as I know). If we ever did we'd have to send a cancel_ack
+			   reply. For now, just free all client data and continue processing. */
+			reply = True;
+			break;
+#if 0
+			/* Enable this if we're doing async rpc. */
+			/* We must check the call-id matches the outstanding callid. */
+			if(pipe_init_outgoing_data(p)) {
+				/* Send a cancel_ack PDU reply. */
+				/* We should probably check the auth-verifier here. */
+				reply = setup_cancel_ack_reply(p, &rpc_in);
+			}
+			break;
+#endif
+
+		case RPC_ORPHANED:
+			/* We should probably check the auth-verifier here.
+			   For now just free all client data and continue processing. */
+			DEBUG(3,("process_complete_pdu: RPC_ORPHANED. Abandoning rpc call.\n"));
+			reply = True;
+			break;
+
 		default:
 			DEBUG(0,("process_complete_pdu: Unknown rpc type = %u received.\n", (unsigned int)p->hdr.pkt_type ));
 			break;
@@ -815,7 +884,13 @@
 	 */
 
 	if(p->in_data.pdu_needed_len == 0) {
-		return unmarshall_rpc_header(p);
+		ssize_t rret = unmarshall_rpc_header(p);
+		if (rret == -1 || p->in_data.pdu_needed_len > 0) {
+			return rret;
+		}
+		/* If rret == 0 and pdu_needed_len == 0 here we have a PDU that consists
+		   of an RPC_HEADER only. This is a RPC_SHUTDOWN, RPC_CO_CANCEL or RPC_ORPHANED
+		   pdu type. Deal with this in process_complete_pdu(). */
 	}
 
 	/*



More information about the samba-cvs mailing list