summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/include/rpc_dce.h10
-rw-r--r--source3/rpc_parse/parse_rpc.c20
-rw-r--r--source3/rpc_server/srv_pipe_srv.c69
4 files changed, 98 insertions, 2 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 234e51d184..7fbab12362 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2061,6 +2061,7 @@ BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth);
void init_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum);
BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_fault(char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth);
void init_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
uint16 max_tsize, uint16 max_rsize,
uint8 auth_type, uint8 auth_level,
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h
index 19527ca6e2..4e7b3f0437 100644
--- a/source3/include/rpc_dce.h
+++ b/source3/include/rpc_dce.h
@@ -45,6 +45,7 @@ enum RPC_PKT_TYPE
/* DCE/RPC flags */
#define RPC_FLG_FIRST 0x01
#define RPC_FLG_LAST 0x02
+#define RPC_FLG_NOCALL 0x20
/* NTLMSSP message types */
enum NTLM_MESSAGE_TYPE
@@ -157,6 +158,15 @@ typedef struct rpc_hdr_resp_info
#define RPC_HDR_RESP_LEN 8
+/* RPC_HDR_FAULT - fault rpc header */
+typedef struct rpc_hdr_fault_info
+{
+ uint32 status;
+ uint32 reserved; /* 0x0000 0000 */
+} RPC_HDR_FAULT;
+
+#define RPC_HDR_FAULT_LEN 8
+
/* this seems to be the same string name depending on the name of the pipe,
* but is more likely to be linked to the interface name
* "srvsvc", "\\PIPE\\ntsvcs"
diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c
index 54d3eea74d..48d64972bf 100644
--- a/source3/rpc_parse/parse_rpc.c
+++ b/source3/rpc_parse/parse_rpc.c
@@ -494,6 +494,26 @@ BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int dept
}
/*******************************************************************
+ Reads or writes an RPC_HDR_FAULT structure.
+********************************************************************/
+
+BOOL smb_io_rpc_hdr_fault(char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr_fault");
+ depth++;
+
+ if(!prs_uint32("status ", ps, depth, &rpc->status))
+ return False;
+ if(!prs_uint32("reserved", ps, depth, &rpc->reserved))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
Init an RPC_HDR_AUTHA structure.
********************************************************************/
diff --git a/source3/rpc_server/srv_pipe_srv.c b/source3/rpc_server/srv_pipe_srv.c
index 86cc9e47e6..d4d313b803 100644
--- a/source3/rpc_server/srv_pipe_srv.c
+++ b/source3/rpc_server/srv_pipe_srv.c
@@ -583,6 +583,68 @@ static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd)
}
/*******************************************************************
+ Marshall a fault pdu.
+*******************************************************************/
+
+static BOOL setup_fault_pdu(pipes_struct *p)
+{
+ prs_struct outgoing_pdu;
+ RPC_HDR fault_hdr;
+ RPC_HDR_RESP hdr_resp;
+ RPC_HDR_FAULT fault_resp;
+
+ /*
+ * 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, 4, MARSHALL);
+ prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
+
+ /*
+ * Initialize a fault header.
+ */
+
+ init_rpc_hdr(&fault_hdr, RPC_FAULT, RPC_FLG_FIRST | RPC_FLG_LAST | RPC_FLG_NOCALL,
+ p->hdr.call_id, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_FAULT_LEN, 0);
+
+ /*
+ * Initialize the HDR_RESP and FAULT parts of the PDU.
+ */
+
+ memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
+
+ fault_resp.status = 0x1c010002;
+ fault_resp.reserved = 0;
+
+ /*
+ * Marshall the header into the outgoing PDU.
+ */
+
+ if(!smb_io_rpc_hdr("", &fault_hdr, &outgoing_pdu, 0)) {
+ DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n"));
+ return False;
+ }
+
+ if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n"));
+ return False;
+ }
+
+ if(!smb_io_rpc_hdr_fault("fault", &fault_resp, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_FAULT.\n"));
+ 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;
+
+ return True;
+}
+
+/*******************************************************************
Respond to a pipe bind request.
*******************************************************************/
@@ -1052,6 +1114,7 @@ BOOL rpc_command(pipes_struct *p, char *input_data, int data_len)
break;
case RPC_REQUEST:
if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) {
+
/* authentication _was_ requested
and it failed. sorry, no deal!
*/
@@ -1072,8 +1135,10 @@ authentication failed. Denying the request.\n", p->name));
break;
}
- if (!reply)
- DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n"));
+ if (!reply) {
+ DEBUG(3,("rpc_command: DCE/RPC fault sent on pipe %s\n", p->pipe_srv_name));
+ reply = setup_fault_pdu(p);
+ }
return reply;
}