void rpcbuf_move(RPC_BUFFER *src, RPC_BUFFER **dest) { if ( !src ) { *dest = NULL; return; } prs_switch_type( &src->prs, MARSHALL ); if ( !prs_set_offset(&src->prs, 0) ) return; prs_force_dynamic( &src->prs ); prs_mem_clear( &src->prs ); *dest = src; }
static bool process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p) { uint32 ss_padding_len = 0; size_t data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - (p->hdr.auth_len ? RPC_HDR_AUTH_LEN : 0) - p->hdr.auth_len; if(!p->pipe_bound) { DEBUG(0,("process_request_pdu: rpc request with no bind.\n")); set_incoming_fault(p); return False; } /* * Check if we need to do authentication processing. * This is only done on requests, not binds. */ /* * Read the RPC request header. */ if(!smb_io_rpc_hdr_req("req", &p->hdr_req, rpc_in_p, 0)) { DEBUG(0,("process_request_pdu: failed to unmarshall RPC_HDR_REQ.\n")); set_incoming_fault(p); return False; } switch(p->auth.auth_type) { case PIPE_AUTH_TYPE_NONE: break; case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: case PIPE_AUTH_TYPE_NTLMSSP: { NTSTATUS status; if(!api_pipe_ntlmssp_auth_process(p, rpc_in_p, &ss_padding_len, &status)) { DEBUG(0,("process_request_pdu: failed to do auth processing.\n")); DEBUG(0,("process_request_pdu: error was %s.\n", nt_errstr(status) )); set_incoming_fault(p); return False; } break; } case PIPE_AUTH_TYPE_SCHANNEL: if (!api_pipe_schannel_process(p, rpc_in_p, &ss_padding_len)) { DEBUG(3,("process_request_pdu: failed to do schannel processing.\n")); set_incoming_fault(p); return False; } break; default: DEBUG(0,("process_request_pdu: unknown auth type %u set.\n", (unsigned int)p->auth.auth_type )); set_incoming_fault(p); return False; } /* Now we've done the sign/seal we can remove any padding data. */ if (data_len > ss_padding_len) { data_len -= ss_padding_len; } /* * Check the data length doesn't go over the 15Mb limit. * increased after observing a bug in the Windows NT 4.0 SP6a * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002 */ if(prs_offset(&p->in_data.data) + data_len > MAX_RPC_DATA_SIZE) { DEBUG(0,("process_request_pdu: rpc data buffer too large (%u) + (%u)\n", (unsigned int)prs_data_size(&p->in_data.data), (unsigned int)data_len )); set_incoming_fault(p); return False; } /* * Append the data portion into the buffer and return. */ if(!prs_append_some_prs_data(&p->in_data.data, rpc_in_p, prs_offset(rpc_in_p), data_len)) { DEBUG(0,("process_request_pdu: Unable to append data size %u to parse buffer of size %u.\n", (unsigned int)data_len, (unsigned int)prs_data_size(&p->in_data.data) )); set_incoming_fault(p); return False; } if(p->hdr.flags & RPC_FLG_LAST) { bool ret = False; /* * Ok - we finally have a complete RPC stream. * Call the rpc command to process it. */ /* * Ensure the internal prs buffer size is *exactly* the same * size as the current offset. */ if(!prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data))) { DEBUG(0,("process_request_pdu: Call to prs_set_buffer_size failed!\n")); set_incoming_fault(p); return False; } /* * Set the parse offset to the start of the data and set the * prs_struct to UNMARSHALL. */ prs_set_offset(&p->in_data.data, 0); prs_switch_type(&p->in_data.data, UNMARSHALL); /* * Process the complete data stream here. */ free_pipe_context(p); if(pipe_init_outgoing_data(p)) { ret = api_pipe_request(p); } free_pipe_context(p); /* * We have consumed the whole data stream. Set back to * marshalling and set the offset back to the start of * the buffer to re-use it (we could also do a prs_mem_free() * and then re_init on the next start of PDU. Not sure which * is best here.... JRA. */ prs_switch_type(&p->in_data.data, MARSHALL); prs_set_offset(&p->in_data.data, 0); return ret; } return True; }
static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p) { BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0); size_t data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - (auth_verify ? RPC_HDR_AUTH_LEN : 0) - p->hdr.auth_len; if(!p->pipe_bound) { DEBUG(0,("process_request_pdu: rpc request with no bind.\n")); set_incoming_fault(p); return False; } /* * Check if we need to do authentication processing. * This is only done on requests, not binds. */ /* * Read the RPC request header. */ if(!smb_io_rpc_hdr_req("req", &p->hdr_req, rpc_in_p, 0)) { DEBUG(0,("process_request_pdu: failed to unmarshall RPC_HDR_REQ.\n")); set_incoming_fault(p); return False; } if(p->ntlmssp_auth_validated && !api_pipe_auth_process(p, rpc_in_p)) { DEBUG(0,("process_request_pdu: failed to do auth processing.\n")); set_incoming_fault(p); return False; } if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) { /* * Authentication _was_ requested and it already failed. */ DEBUG(0,("process_request_pdu: RPC request received on pipe %s " "where authentication failed. Denying the request.\n", p->name)); set_incoming_fault(p); return False; } if (p->netsec_auth_validated && !api_pipe_netsec_process(p, rpc_in_p)) { DEBUG(3,("process_request_pdu: failed to do schannel processing.\n")); set_incoming_fault(p); return False; } /* * Check the data length doesn't go over the 15Mb limit. * increased after observing a bug in the Windows NT 4.0 SP6a * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002 */ if(prs_offset(&p->in_data.data) + data_len > 15*1024*1024) { DEBUG(0,("process_request_pdu: rpc data buffer too large (%u) + (%u)\n", (unsigned int)prs_data_size(&p->in_data.data), (unsigned int)data_len )); set_incoming_fault(p); return False; } /* * Append the data portion into the buffer and return. */ if(!prs_append_some_prs_data(&p->in_data.data, rpc_in_p, prs_offset(rpc_in_p), data_len)) { DEBUG(0,("process_request_pdu: Unable to append data size %u to parse buffer of size %u.\n", (unsigned int)data_len, (unsigned int)prs_data_size(&p->in_data.data) )); set_incoming_fault(p); return False; } if(p->hdr.flags & RPC_FLG_LAST) { BOOL ret = False; /* * Ok - we finally have a complete RPC stream. * Call the rpc command to process it. */ /* * Ensure the internal prs buffer size is *exactly* the same * size as the current offset. */ if(!prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data))) { DEBUG(0,("process_request_pdu: Call to prs_set_buffer_size failed!\n")); set_incoming_fault(p); return False; } /* * Set the parse offset to the start of the data and set the * prs_struct to UNMARSHALL. */ prs_set_offset(&p->in_data.data, 0); prs_switch_type(&p->in_data.data, UNMARSHALL); /* * Process the complete data stream here. */ free_pipe_context(p); if(pipe_init_outgoing_data(p)) ret = api_pipe_request(p); free_pipe_context(p); /* * We have consumed the whole data stream. Set back to * marshalling and set the offset back to the start of * the buffer to re-use it (we could also do a prs_mem_free() * and then re_init on the next start of PDU. Not sure which * is best here.... JRA. */ prs_switch_type(&p->in_data.data, MARSHALL); prs_set_offset(&p->in_data.data, 0); return ret; } return True; }