diff options
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/include/rpc_dce.h | 10 | ||||
-rw-r--r-- | source3/rpc_parse/parse_rpc.c | 20 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe_srv.c | 69 |
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; } |