r1057: added rpc packet logging for packets that generate rpc faults. This
authorAndrew Tridgell <tridge@samba.org>
Mon, 7 Jun 2004 03:13:38 +0000 (03:13 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:56:35 +0000 (12:56 -0500)
makes it much easier to develop the IDL for new requests, especially
for sealed pipes, where ethereal cannot easily extract the data.
(This used to be commit 0cde043592d2d2439cf0cd8bf113545e78be5dfd)

source4/rpc_server/dcerpc_server.c

index 2c0db1508140a1abe66edfa8ec5204333d13b0a5..a084477b3614de7f49e6496f03f022dd423e8ee7 100644 (file)
@@ -552,6 +552,40 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
 }
 
 
+/*
+  log a rpc packet in a format suitable for ndrdump. This is especially useful
+  for sealed packets, where ethereal cannot easily see the contents
+
+  this triggers on a debug level of >= 10
+*/
+static void log_rpc_packet(const struct dcesrv_interface *iface, 
+                          uint32_t opnum, uint32_t flags, DATA_BLOB *pkt)
+{
+       const int num_examples = 20;
+       int i;
+
+       if (DEBUGLEVEL < 10) return;
+
+       for (i=0;i<num_examples;i++) {
+               char *name=NULL;
+               asprintf(&name, "%s/rpclog/%s-%u.%d.%s", 
+                        lp_lockdir(), iface->ndr->name, opnum, i,
+                        (flags&NDR_IN)?"in":"out");
+               if (name == NULL) {
+                       return;
+               }
+               if (!file_exist(name, NULL)) {
+                       if (file_save(name, pkt->data, pkt->length)) {
+                               DEBUG(10,("Logged rpc packet to %s\n", name));
+                       }
+                       free(name);
+                       break;
+               }
+               free(name);
+       }
+}
+
+
 /*
   handle a dcerpc request packet
 */
@@ -593,6 +627,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
        /* unravel the NDR for the packet */
        status = call->conn->iface->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r);
        if (!NT_STATUS_IS_OK(status)) {
+               log_rpc_packet(call->conn->iface, opnum, NDR_IN, 
+                              &call->pkt.u.request.stub_and_verifier);
                return dcesrv_fault(call, DCERPC_FAULT_NDR);
        }
 
@@ -601,6 +637,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
        /* call the dispatch function */
        status = call->conn->iface->dispatch(call, call->mem_ctx, r);
        if (!NT_STATUS_IS_OK(status)) {
+               log_rpc_packet(call->conn->iface, opnum, NDR_IN, 
+                              &call->pkt.u.request.stub_and_verifier);
                return dcesrv_fault(call, call->fault_code);
        }