static bool api_pipe_request(struct pipes_struct *p, struct ncacn_packet *pkt) { bool ret = False; struct pipe_rpc_fns *pipe_fns; if (!p->pipe_bound) { DEBUG(1, ("Pipe not bound!\n")); data_blob_free(&p->out_data.rdata); return false; } if (!become_authenticated_pipe_user(p->session_info)) { DEBUG(1, ("Failed to become pipe user!\n")); data_blob_free(&p->out_data.rdata); return false; } /* get the set of RPC functions for this context */ pipe_fns = find_pipe_fns_by_context(p->contexts, pkt->u.request.context_id); if ( pipe_fns ) { TALLOC_CTX *frame = talloc_stackframe(); DEBUG(5, ("Requested %s rpc service\n", ndr_interface_name(&pipe_fns->syntax.uuid, pipe_fns->syntax.if_version))); ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds, &pipe_fns->syntax); TALLOC_FREE(frame); } else { DEBUG(0, ("No rpc function table associated with context " "[%d]\n", pkt->u.request.context_id)); } unbecome_authenticated_pipe_user(); return ret; }
static bool srv_pipe_check_verification_trailer(struct pipes_struct *p, struct ncacn_packet *pkt, struct pipe_rpc_fns *pipe_fns) { TALLOC_CTX *frame = talloc_stackframe(); struct dcerpc_sec_verification_trailer *vt = NULL; const uint32_t bitmask1 = p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0; const struct dcerpc_sec_vt_pcontext pcontext = { .abstract_syntax = pipe_fns->syntax, .transfer_syntax = ndr_transfer_syntax_ndr, }; const struct dcerpc_sec_vt_header2 header2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt); struct ndr_pull *ndr; enum ndr_err_code ndr_err; bool ret = false; ndr = ndr_pull_init_blob(&p->in_data.data, frame); if (ndr == NULL) { goto done; } ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { goto done; } ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1, &pcontext, &header2); done: TALLOC_FREE(frame); return ret; } /**************************************************************************** Find the correct RPC function to call for this request. If the pipe is authenticated then become the correct UNIX user before doing the call. ****************************************************************************/ static bool api_pipe_request(struct pipes_struct *p, struct ncacn_packet *pkt) { TALLOC_CTX *frame = talloc_stackframe(); bool ret = False; struct pipe_rpc_fns *pipe_fns; if (!p->pipe_bound) { DEBUG(1, ("Pipe not bound!\n")); data_blob_free(&p->out_data.rdata); TALLOC_FREE(frame); return false; } /* get the set of RPC functions for this context */ pipe_fns = find_pipe_fns_by_context(p->contexts, pkt->u.request.context_id); if (pipe_fns == NULL) { DEBUG(0, ("No rpc function table associated with context " "[%d]\n", pkt->u.request.context_id)); data_blob_free(&p->out_data.rdata); TALLOC_FREE(frame); return false; } if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) { DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n")); setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED)); data_blob_free(&p->out_data.rdata); TALLOC_FREE(frame); return true; } if (!become_authenticated_pipe_user(p->session_info)) { DEBUG(1, ("Failed to become pipe user!\n")); data_blob_free(&p->out_data.rdata); TALLOC_FREE(frame); return false; } DEBUG(5, ("Requested %s rpc service\n", ndr_interface_name(&pipe_fns->syntax.uuid, pipe_fns->syntax.if_version))); ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds, &pipe_fns->syntax); unbecome_authenticated_pipe_user(); TALLOC_FREE(frame); return ret; }