diff options
-rw-r--r-- | source3/include/proto.h | 3 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 274 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe_hnd.c | 101 |
3 files changed, 0 insertions, 378 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 6bc656824d..a8fa4c1977 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5169,9 +5169,6 @@ NTSTATUS rpc_srv_register(int version, const char *clnt, bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax); bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt); bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt); -bool api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in, - uint32 *p_ss_padding_len, NTSTATUS *pstatus); -bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len); void free_pipe_rpc_context( PIPE_RPC_FNS *list ); bool api_pipe_request(pipes_struct *p, struct ncacn_packet *pkt); diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 74c67f3832..559ac5d4ba 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2055,280 +2055,6 @@ bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt) } /**************************************************************************** - Deal with NTLMSSP sign & seal processing on an RPC request. -****************************************************************************/ - -bool api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in, - uint32 *p_ss_padding_len, NTSTATUS *pstatus) -{ - RPC_HDR_AUTH auth_info; - uint32 auth_len = p->hdr.auth_len; - uint32 save_offset = prs_offset(rpc_in); - struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state; - unsigned char *data = NULL; - size_t data_len; - unsigned char *full_packet_data = NULL; - size_t full_packet_data_len; - DATA_BLOB auth_blob; - - *pstatus = NT_STATUS_OK; - - if (p->auth.auth_level == DCERPC_AUTH_LEVEL_NONE || p->auth.auth_level == DCERPC_AUTH_LEVEL_CONNECT) { - return True; - } - - if (!a) { - *pstatus = NT_STATUS_INVALID_PARAMETER; - return False; - } - - /* Ensure there's enough data for an authenticated request. */ - if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN - + auth_len > p->hdr.frag_len) { - DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len %u is too large.\n", - (unsigned int)auth_len )); - *pstatus = NT_STATUS_INVALID_PARAMETER; - return False; - } - - /* - * We need the full packet data + length (minus auth stuff) as well as the packet data + length - * after the RPC header. - * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal - * functions as NTLMv2 checks the rpc headers also. - * Both of these values include any auth_pad_len bytes. - */ - - data = (unsigned char *)(prs_data_p(rpc_in) + RPC_HDR_REQ_LEN); - data_len = (size_t)(p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - RPC_HDR_AUTH_LEN - auth_len); - - full_packet_data = p->in_data.pdu.data; - full_packet_data_len = p->hdr.frag_len - auth_len; - - /* Pull the auth header and the following data into a blob. */ - /* NB. The offset of the auth_header is relative to the *end* - * of the packet, not the start. Also, the length of the - * data in rpc_in_p is p->hdr.frag_len - RPC_HEADER_LEN, - * as the RPC header isn't included in rpc_in_p. */ - if(!prs_set_offset(rpc_in, - p->hdr.frag_len - RPC_HEADER_LEN - - RPC_HDR_AUTH_LEN - auth_len)) { - DEBUG(0,("api_pipe_ntlmssp_auth_process: cannot move " - "offset to %u.\n", - (unsigned int)(p->hdr.frag_len - - RPC_HDR_AUTH_LEN - auth_len) )); - *pstatus = NT_STATUS_INVALID_PARAMETER; - return False; - } - - if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) { - DEBUG(0,("api_pipe_ntlmssp_auth_process: failed to " - "unmarshall RPC_HDR_AUTH.\n")); - *pstatus = NT_STATUS_INVALID_PARAMETER; - return False; - } - - /* Ensure auth_pad_len fits into the packet. */ - if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len + - RPC_HDR_AUTH_LEN + auth_len > p->hdr.frag_len) { - DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_info.auth_pad_len " - "too large (%u), auth_len (%u), frag_len = (%u).\n", - (unsigned int)auth_info.auth_pad_len, - (unsigned int)auth_len, - (unsigned int)p->hdr.frag_len )); - *pstatus = NT_STATUS_INVALID_PARAMETER; - return False; - } - - auth_blob.data = (unsigned char *)prs_data_p(rpc_in) + prs_offset(rpc_in); - auth_blob.length = auth_len; - - switch (p->auth.auth_level) { - case DCERPC_AUTH_LEVEL_PRIVACY: - /* Data is encrypted. */ - *pstatus = auth_ntlmssp_unseal_packet(a, - data, data_len, - full_packet_data, - full_packet_data_len, - &auth_blob); - if (!NT_STATUS_IS_OK(*pstatus)) { - return False; - } - break; - case DCERPC_AUTH_LEVEL_INTEGRITY: - /* Data is signed. */ - *pstatus = auth_ntlmssp_check_packet(a, - data, data_len, - full_packet_data, - full_packet_data_len, - &auth_blob); - if (!NT_STATUS_IS_OK(*pstatus)) { - return False; - } - break; - default: - *pstatus = NT_STATUS_INVALID_PARAMETER; - return False; - } - - /* - * Return the current pointer to the data offset. - */ - - if(!prs_set_offset(rpc_in, save_offset)) { - DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n", - (unsigned int)save_offset )); - *pstatus = NT_STATUS_INVALID_PARAMETER; - return False; - } - - /* - * Remember the padding length. We must remove it from the real data - * stream once the sign/seal is done. - */ - - *p_ss_padding_len = auth_info.auth_pad_len; - - return True; -} - -/**************************************************************************** - Deal with schannel processing on an RPC request. -****************************************************************************/ - -bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len) -{ - uint32 data_len; - uint32 auth_len; - uint32 save_offset = prs_offset(rpc_in); - RPC_HDR_AUTH auth_info; - DATA_BLOB blob; - NTSTATUS status; - uint8_t *data; - - auth_len = p->hdr.auth_len; - - if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN || - auth_len > RPC_HEADER_LEN + - RPC_HDR_REQ_LEN + - RPC_HDR_AUTH_LEN + - auth_len) { - DEBUG(0,("Incorrect auth_len %u.\n", (unsigned int)auth_len )); - return False; - } - - /* - * The following is that length of the data we must verify or unseal. - * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN - * preceeding the auth_data, but does include the auth_pad_len bytes. - */ - - if (p->hdr.frag_len < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN + auth_len) { - DEBUG(0,("Incorrect frag %u, auth %u.\n", - (unsigned int)p->hdr.frag_len, - (unsigned int)auth_len )); - return False; - } - - data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - - RPC_HDR_AUTH_LEN - auth_len; - - DEBUG(5,("data %d auth %d\n", data_len, auth_len)); - - /* Pull the auth header and the following data into a blob. */ - /* NB. The offset of the auth_header is relative to the *end* - * of the packet, not the start. Also, the length of the - * data in rpc_in_p is p->hdr.frag_len - RPC_HEADER_LEN, - * as the RPC header isn't included in rpc_in_p. */ - if(!prs_set_offset(rpc_in, - p->hdr.frag_len - RPC_HEADER_LEN - - RPC_HDR_AUTH_LEN - auth_len)) { - DEBUG(0,("api_pipe_schannel_process: cannot move " - "offset to %u.\n", - (unsigned int)(p->hdr.frag_len - - RPC_HDR_AUTH_LEN - auth_len) )); - return False; - } - - if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) { - DEBUG(0,("api_pipe_schannel_process: failed to " - "unmarshall RPC_HDR_AUTH.\n")); - return False; - } - - /* Ensure auth_pad_len fits into the packet. */ - if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len + - RPC_HDR_AUTH_LEN + auth_len > p->hdr.frag_len) { - DEBUG(0,("api_pipe_schannel_process: auth_info.auth_pad_len " - "too large (%u), auth_len (%u), frag_len = (%u).\n", - (unsigned int)auth_info.auth_pad_len, - (unsigned int)auth_len, - (unsigned int)p->hdr.frag_len )); - return False; - } - - if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { - DEBUG(0,("Invalid auth info %d on schannel\n", - auth_info.auth_type)); - return False; - } - - blob = data_blob_const(prs_data_p(rpc_in) + prs_offset(rpc_in), auth_len); - - if (DEBUGLEVEL >= 10) { - dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob); - } - - data = (uint8_t *)prs_data_p(rpc_in)+RPC_HDR_REQ_LEN; - - switch (auth_info.auth_level) { - case DCERPC_AUTH_LEVEL_PRIVACY: - status = netsec_incoming_packet(p->auth.a_u.schannel_auth, - talloc_tos(), - true, - data, - data_len, - &blob); - break; - case DCERPC_AUTH_LEVEL_INTEGRITY: - status = netsec_incoming_packet(p->auth.a_u.schannel_auth, - talloc_tos(), - false, - data, - data_len, - &blob); - break; - default: - status = NT_STATUS_INTERNAL_ERROR; - break; - } - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("failed to unseal packet: %s\n", nt_errstr(status))); - return false; - } - - /* - * Return the current pointer to the data offset. - */ - - if(!prs_set_offset(rpc_in, save_offset)) { - DEBUG(0,("failed to set offset back to %u\n", - (unsigned int)save_offset )); - return False; - } - - /* - * Remember the padding length. We must remove it from the real data - * stream once the sign/seal is done. - */ - - *p_ss_padding_len = auth_info.auth_pad_len; - - return True; -} - -/**************************************************************************** Find the set of RPC functions associated with this context_id ****************************************************************************/ diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 0ac9072f3e..cf7fe75f63 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -145,107 +145,6 @@ static bool get_pdu_size(pipes_struct *p) } /**************************************************************************** - Unmarshalls a new PDU header. Assumes the raw header data is in current pdu. -****************************************************************************/ - -static bool unmarshall_rpc_header(pipes_struct *p) -{ - /* - * Unmarshall the header to determine the needed length. - */ - - prs_struct rpc_in; - - prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL); - prs_set_endian_data( &rpc_in, p->endian); - - prs_give_memory( &rpc_in, (char *)&p->in_data.pdu.data[0], - p->in_data.pdu.length, False); - - /* - * Unmarshall the header. - * This also sets the endian flag in rpc_in. - */ - - if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) { - DEBUG(0, ("unmarshall_rpc_header: " - "failed to unmarshall RPC_HDR.\n")); - set_incoming_fault(p); - prs_mem_free(&rpc_in); - return false; - } - - /* - * Validate the RPC header. - */ - - if(p->hdr.major != 5 && p->hdr.minor != 0) { - DEBUG(0, ("unmarshall_rpc_header: " - "invalid major/minor numbers in RPC_HDR.\n")); - set_incoming_fault(p); - prs_mem_free(&rpc_in); - return false; - } - - /* - * If there's not data in the incoming buffer this should be the - * start of a new RPC. - */ - - if(prs_offset(&p->in_data.data) == 0) { - - /* - * AS/U doesn't set FIRST flag in a BIND packet it seems. - */ - - if ((p->hdr.pkt_type == DCERPC_PKT_REQUEST) && - !(p->hdr.flags & DCERPC_PFC_FLAG_FIRST)) { - /* - * Ensure that the FIRST flag is set. - * If not then we have a stream missmatch. - */ - - DEBUG(0, ("unmarshall_rpc_header: " - "FIRST flag not set in first PDU !\n")); - set_incoming_fault(p); - prs_mem_free(&rpc_in); - return false; - } - - /* - * If this is the first PDU then set the endianness - * flag in the pipe. We will need this when parsing all - * data in this RPC. - */ - - p->endian = rpc_in.bigendian_data; - - DEBUG(5, ("unmarshall_rpc_header: using %sendian RPC\n", - p->endian == RPC_LITTLE_ENDIAN ? "little-" : "big-" )); - - } else { - - /* - * If this is *NOT* the first PDU then check the endianness - * flag in the pipe is the same as that in the PDU. - */ - - if (p->endian != rpc_in.bigendian_data) { - DEBUG(0, ("unmarshall_rpc_header: FIRST endianness " - "flag (%d) different in next PDU !\n", - (int)p->endian)); - set_incoming_fault(p); - prs_mem_free(&rpc_in); - return false; - } - } - - DEBUG(10, ("unmarshall_rpc_header: type = %u, flags = %u\n", - (unsigned int)p->hdr.pkt_type, (unsigned int)p->hdr.flags)); - return true; -} - -/**************************************************************************** Call this to free any talloc'ed memory. Do this after processing a complete incoming and outgoing request (multiple incoming/outgoing PDU's). |