diff options
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 425 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.h | 7 |
2 files changed, 225 insertions, 207 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index b783e90204..30c430dcba 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -246,42 +246,17 @@ static NTSTATUS dcerpc_check_connect_verifier(DATA_BLOB *blob) } /* - parse a possibly signed blob into a dcerpc request packet structure + parse the authentication information on a dcerpc response packet */ -static NTSTATUS ncacn_pull_request_sign(struct dcerpc_connection *c, - DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - struct ncacn_packet *pkt) +static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX *mem_ctx, + DATA_BLOB *raw_packet, + struct ncacn_packet *pkt) { struct ndr_pull *ndr; NTSTATUS status; struct dcerpc_auth auth; DATA_BLOB auth_blob; - /* non-signed packets are simpler */ - if (!c->security_state.auth_info || - !c->security_state.generic_state) { - return ncacn_pull(c, blob, mem_ctx, pkt); - } - - ndr = ndr_pull_init_flags(c, blob, mem_ctx); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - - if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) { - ndr->flags |= LIBNDR_FLAG_BIGENDIAN; - } - - /* pull the basic packet */ - status = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (pkt->ptype != DCERPC_PKT_RESPONSE) { - return status; - } - if (pkt->auth_length == 0 && c->security_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_CONNECT) { return NT_STATUS_OK; @@ -305,7 +280,7 @@ static NTSTATUS ncacn_pull_request_sign(struct dcerpc_connection *c, return NT_STATUS_NO_MEMORY; } - if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) { + if (!(pkt->drep[0] & DCERPC_DREP_LE)) { ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } @@ -320,13 +295,13 @@ static NTSTATUS ncacn_pull_request_sign(struct dcerpc_connection *c, case DCERPC_AUTH_LEVEL_PRIVACY: status = gensec_unseal_packet(c->security_state.generic_state, mem_ctx, - blob->data + DCERPC_REQUEST_LENGTH, + raw_packet->data + DCERPC_REQUEST_LENGTH, pkt->u.response.stub_and_verifier.length, - blob->data, - blob->length - auth.credentials.length, + raw_packet->data, + raw_packet->length - auth.credentials.length, &auth.credentials); memcpy(pkt->u.response.stub_and_verifier.data, - blob->data + DCERPC_REQUEST_LENGTH, + raw_packet->data + DCERPC_REQUEST_LENGTH, pkt->u.response.stub_and_verifier.length); break; @@ -335,8 +310,8 @@ static NTSTATUS ncacn_pull_request_sign(struct dcerpc_connection *c, mem_ctx, pkt->u.response.stub_and_verifier.data, pkt->u.response.stub_and_verifier.length, - blob->data, - blob->length - auth.credentials.length, + raw_packet->data, + raw_packet->length - auth.credentials.length, &auth.credentials); break; @@ -528,61 +503,128 @@ static NTSTATUS dcerpc_map_reason(uint16_t reason) return NT_STATUS_UNSUCCESSFUL; } -struct dcerpc_request_state { - struct dcerpc_pipe *pipe; - struct ncacn_packet pkt; - DATA_BLOB blob; -}; +/* + mark the dcerpc connection dead. All outstanding requests get an error +*/ +static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status) +{ + /* all pending requests get the error */ + while (conn->pending) { + struct rpc_request *req = conn->pending; + req->state = RPC_REQUEST_DONE; + req->status = status; + DLIST_REMOVE(conn->pending, req); + if (req->async.callback) { + req->async.callback(req); + } + } + + if (conn->bind_private) { + /* a bind was in flight - fail it */ + struct composite_context *c = talloc_get_type(conn->bind_private, struct composite_context); + composite_error(c, status); + } + + if (conn->alter_private) { + /* a alter context was in flight - fail it */ + struct composite_context *c = talloc_get_type(conn->alter_private, struct composite_context); + composite_error(c, status); + } +} /* - Receive a bind reply from the transport + forward declarations of the recv_data handlers for the 3 types of packets we need + to handle */ +static void dcerpc_bind_recv_data(struct dcerpc_connection *conn, struct ncacn_packet *pkt); +static void dcerpc_alter_recv_data(struct dcerpc_connection *conn, struct ncacn_packet *pkt); +static void dcerpc_request_recv_data(struct dcerpc_connection *c, + DATA_BLOB *raw_packet, struct ncacn_packet *pkt); -static void bind_request_recv(struct dcerpc_connection *conn, DATA_BLOB *blob, - NTSTATUS status) +/* + receive a dcerpc reply from the transport. Here we work out what + type of reply it is (normal request, bind or alter context) and + dispatch to the appropriate handler +*/ +static void dcerpc_recv_data(struct dcerpc_connection *conn, DATA_BLOB *blob, NTSTATUS status) { - struct composite_context *c; - struct dcerpc_request_state *state; + struct ncacn_packet pkt; - if (conn->full_request_private == NULL) { - /* it timed out earlier */ - return; + /* the transport may be telling us of a severe error, such as + a dropped socket */ + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(blob); + dcerpc_connection_dead(conn, status); } - c = talloc_get_type(conn->full_request_private, - struct composite_context); - state = talloc_get_type(c->private_data, struct dcerpc_request_state); + /* parse the basic packet to work out what type of response this is */ + status = ncacn_pull(conn, blob, blob->data, &pkt); if (!NT_STATUS_IS_OK(status)) { - composite_error(c, status); + data_blob_free(blob); + dcerpc_connection_dead(conn, status); + } + + switch (pkt.ptype) { + case DCERPC_PKT_BIND_ACK: + case DCERPC_PKT_BIND_NAK: + dcerpc_bind_recv_data(conn, &pkt); + break; + + case DCERPC_PKT_ALTER_RESP: + dcerpc_alter_recv_data(conn, &pkt); + break; + + default: + /* assume its an ordinary request */ + dcerpc_request_recv_data(conn, blob, &pkt); + break; + } + + data_blob_free(blob); +} + + +/* + Receive a bind reply from the transport +*/ +static void dcerpc_bind_recv_data(struct dcerpc_connection *conn, struct ncacn_packet *pkt) +{ + struct composite_context *c; + struct dcerpc_pipe *pipe; + + if (conn->bind_private == NULL) { + /* it timed out earlier */ return; } + c = talloc_get_type(conn->bind_private, struct composite_context); + pipe = talloc_get_type(c->private_data, struct dcerpc_pipe); - c->status = ncacn_pull(conn, blob, state, &state->pkt); - if (!composite_is_ok(c)) return; + /* mark the connection as not waiting for a bind reply */ + conn->bind_private = NULL; - if (state->pkt.ptype == DCERPC_PKT_BIND_NAK) { + if (pkt->ptype == DCERPC_PKT_BIND_NAK) { DEBUG(2,("dcerpc: bind_nak reason %d\n", - state->pkt.u.bind_nak.reject_reason)); - composite_error(c, dcerpc_map_reason(state->pkt.u.bind_nak. + pkt->u.bind_nak.reject_reason)); + composite_error(c, dcerpc_map_reason(pkt->u.bind_nak. reject_reason)); return; } - if ((state->pkt.ptype != DCERPC_PKT_BIND_ACK) || - (state->pkt.u.bind_ack.num_results == 0) || - (state->pkt.u.bind_ack.ctx_list[0].result != 0)) { + if ((pkt->ptype != DCERPC_PKT_BIND_ACK) || + (pkt->u.bind_ack.num_results == 0) || + (pkt->u.bind_ack.ctx_list[0].result != 0)) { composite_error(c, NT_STATUS_UNSUCCESSFUL); return; } - conn->srv_max_xmit_frag = state->pkt.u.bind_ack.max_xmit_frag; - conn->srv_max_recv_frag = state->pkt.u.bind_ack.max_recv_frag; + conn->srv_max_xmit_frag = pkt->u.bind_ack.max_xmit_frag; + conn->srv_max_recv_frag = pkt->u.bind_ack.max_recv_frag; /* the bind_ack might contain a reply set of credentials */ if (conn->security_state.auth_info && - state->pkt.u.bind_ack.auth_info.length) { + pkt->u.bind_ack.auth_info.length) { c->status = ndr_pull_struct_blob( - &state->pkt.u.bind_ack.auth_info, conn, + &pkt->u.bind_ack.auth_info, conn, conn->security_state.auth_info, (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); if (!composite_is_ok(c)) return; @@ -600,75 +642,69 @@ static void bind_timeout_handler(struct event_context *ev, { struct composite_context *ctx = talloc_get_type(private, struct composite_context); - struct dcerpc_request_state *state = - talloc_get_type(ctx->private_data, - struct dcerpc_request_state); + struct dcerpc_pipe *pipe = talloc_get_type(ctx->private_data, struct dcerpc_pipe); - SMB_ASSERT(state->pipe->conn->full_request_private != NULL); - state->pipe->conn->full_request_private = NULL; + SMB_ASSERT(pipe->conn->bind_private != NULL); + pipe->conn->bind_private = NULL; composite_error(ctx, NT_STATUS_IO_TIMEOUT); } +/* + send a async dcerpc bind request +*/ struct composite_context *dcerpc_bind_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const struct dcerpc_syntax_id *syntax, const struct dcerpc_syntax_id *transfer_syntax) { struct composite_context *c; - struct dcerpc_request_state *state; + struct ncacn_packet pkt; + DATA_BLOB blob; c = talloc_zero(mem_ctx, struct composite_context); if (c == NULL) return NULL; - state = talloc(c, struct dcerpc_request_state); - if (state == NULL) { - c->status = NT_STATUS_NO_MEMORY; - goto failed; - } - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->private_data = state; + c->private_data = p; c->event_ctx = p->conn->event_ctx; - state->pipe = p; - p->syntax = *syntax; p->transfer_syntax = *transfer_syntax; - init_ncacn_hdr(p->conn, &state->pkt); + init_ncacn_hdr(p->conn, &pkt); - state->pkt.ptype = DCERPC_PKT_BIND; - state->pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - state->pkt.call_id = p->conn->call_id; - state->pkt.auth_length = 0; + pkt.ptype = DCERPC_PKT_BIND; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.call_id = p->conn->call_id; + pkt.auth_length = 0; - state->pkt.u.bind.max_xmit_frag = 5840; - state->pkt.u.bind.max_recv_frag = 5840; - state->pkt.u.bind.assoc_group_id = 0; - state->pkt.u.bind.num_contexts = 1; - state->pkt.u.bind.ctx_list = + pkt.u.bind.max_xmit_frag = 5840; + pkt.u.bind.max_recv_frag = 5840; + pkt.u.bind.assoc_group_id = 0; + pkt.u.bind.num_contexts = 1; + pkt.u.bind.ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1); - if (state->pkt.u.bind.ctx_list == NULL) { + if (pkt.u.bind.ctx_list == NULL) { c->status = NT_STATUS_NO_MEMORY; goto failed; } - state->pkt.u.bind.ctx_list[0].context_id = p->context_id; - state->pkt.u.bind.ctx_list[0].num_transfer_syntaxes = 1; - state->pkt.u.bind.ctx_list[0].abstract_syntax = p->syntax; - state->pkt.u.bind.ctx_list[0].transfer_syntaxes = &p->transfer_syntax; - state->pkt.u.bind.auth_info = data_blob(NULL, 0); + pkt.u.bind.ctx_list[0].context_id = p->context_id; + pkt.u.bind.ctx_list[0].num_transfer_syntaxes = 1; + pkt.u.bind.ctx_list[0].abstract_syntax = p->syntax; + pkt.u.bind.ctx_list[0].transfer_syntaxes = &p->transfer_syntax; + pkt.u.bind.auth_info = data_blob(NULL, 0); /* construct the NDR form of the packet */ - c->status = ncacn_push_auth(&state->blob, state, &state->pkt, + c->status = ncacn_push_auth(&blob, c, &pkt, p->conn->security_state.auth_info); if (!NT_STATUS_IS_OK(c->status)) { goto failed; } - p->conn->transport.recv_data = bind_request_recv; - p->conn->full_request_private = c; + p->conn->transport.recv_data = dcerpc_recv_data; + p->conn->bind_private = c; - c->status = p->conn->transport.send_request(p->conn, &state->blob, + c->status = p->conn->transport.send_request(p->conn, &blob, True); if (!NT_STATUS_IS_OK(c->status)) { goto failed; @@ -685,6 +721,9 @@ struct composite_context *dcerpc_bind_send(struct dcerpc_pipe *p, return c; } +/* + recv side of async dcerpc bind request +*/ NTSTATUS dcerpc_bind_recv(struct composite_context *ctx) { NTSTATUS result = composite_wait(ctx); @@ -743,6 +782,9 @@ NTSTATUS dcerpc_auth3(struct dcerpc_connection *c, } +/* + return the rpc syntax and transfer syntax given the pipe uuid and version +*/ NTSTATUS dcerpc_init_syntaxes(const char *uuid, uint_t version, struct dcerpc_syntax_id *syntax, struct dcerpc_syntax_id *transfer_syntax) @@ -789,67 +831,58 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p, This function frees the data */ static void dcerpc_request_recv_data(struct dcerpc_connection *c, - DATA_BLOB *data, - NTSTATUS status) + DATA_BLOB *raw_packet, struct ncacn_packet *pkt) { - struct ncacn_packet pkt; struct rpc_request *req; uint_t length; - - if (!NT_STATUS_IS_OK(status)) { - data_blob_free(data); - - /* all pending requests get the error */ - while (c->pending) { - req = c->pending; - req->state = RPC_REQUEST_DONE; - req->status = status; - DLIST_REMOVE(c->pending, req); - if (req->async.callback) { - req->async.callback(req); - } - } - return; - } - - pkt.call_id = 0; - - status = ncacn_pull_request_sign(c, data, data->data, &pkt); - - /* find the matching request. Notice we match before we check - the status. this is ok as a pending call_id can never be - zero */ + NTSTATUS status = NT_STATUS_OK; + + /* + if this is an authenticated connection then parse and check + the auth info. We have to do this before finding the + matching packet, as the request structure might have been + removed due to a timeout, but if it has been we still need + to run the auth routines so that we don't get the sign/seal + info out of step with the server + */ + if (c->security_state.auth_info && c->security_state.generic_state && + pkt->ptype == DCERPC_PKT_RESPONSE) { + status = ncacn_pull_request_auth(c, raw_packet->data, raw_packet, pkt); + } + + /* find the matching request */ for (req=c->pending;req;req=req->next) { - if (pkt.call_id == req->call_id) break; + if (pkt->call_id == req->call_id) break; } if (req == NULL) { - DEBUG(2,("dcerpc_request: unmatched call_id %u in response packet\n", pkt.call_id)); - data_blob_free(data); + DEBUG(2,("dcerpc_request: unmatched call_id %u in response packet\n", pkt->call_id)); return; } - if (!NT_STATUS_IS_OK(status)) { - req->status = status; - goto req_done; - } - - if (pkt.ptype == DCERPC_PKT_FAULT) { - DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt.u.fault.status))); - req->fault_code = pkt.u.fault.status; + if (pkt->ptype == DCERPC_PKT_FAULT) { + DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt->u.fault.status))); + req->fault_code = pkt->u.fault.status; req->status = NT_STATUS_NET_WRITE_FAULT; goto req_done; } - if (pkt.ptype != DCERPC_PKT_RESPONSE) { + if (pkt->ptype != DCERPC_PKT_RESPONSE) { DEBUG(2,("Unexpected packet type %d in dcerpc response\n", - (int)pkt.ptype)); + (int)pkt->ptype)); req->fault_code = DCERPC_FAULT_OTHER; req->status = NT_STATUS_NET_WRITE_FAULT; goto req_done; } - length = pkt.u.response.stub_and_verifier.length; + /* now check the status from the auth routines, and if it failed then fail + this request accordingly */ + if (!NT_STATUS_IS_OK(status)) { + req->status = status; + goto req_done; + } + + length = pkt->u.response.stub_and_verifier.length; if (length > 0) { req->payload.data = talloc_realloc(req, @@ -861,17 +894,16 @@ static void dcerpc_request_recv_data(struct dcerpc_connection *c, goto req_done; } memcpy(req->payload.data+req->payload.length, - pkt.u.response.stub_and_verifier.data, length); + pkt->u.response.stub_and_verifier.data, length); req->payload.length += length; } - if (!(pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { + if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) { c->transport.send_read(c); - data_blob_free(data); return; } - if (!(pkt.drep[0] & DCERPC_DREP_LE)) { + if (!(pkt->drep[0] & DCERPC_DREP_LE)) { req->flags |= DCERPC_PULL_BIGENDIAN; } else { req->flags &= ~DCERPC_PULL_BIGENDIAN; @@ -882,7 +914,6 @@ req_done: /* we've got the full payload */ req->state = RPC_REQUEST_DONE; DLIST_REMOVE(c->pending, req); - data_blob_free(data); if (c->request_queue != NULL) { /* We have to look at shipping further requests before calling @@ -937,7 +968,7 @@ static struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p, { struct rpc_request *req; - p->conn->transport.recv_data = dcerpc_request_recv_data; + p->conn->transport.recv_data = dcerpc_recv_data; req = talloc(p, struct rpc_request); if (req == NULL) { @@ -1487,52 +1518,44 @@ uint32_t dcerpc_auth_level(struct dcerpc_connection *c) /* Receive an alter reply from the transport */ -static void alter_request_recv(struct dcerpc_connection *conn, DATA_BLOB *blob, - NTSTATUS status) +static void dcerpc_alter_recv_data(struct dcerpc_connection *conn, struct ncacn_packet *pkt) { struct composite_context *c; - struct dcerpc_request_state *state; + struct dcerpc_pipe *pipe; - if (conn->full_request_private == NULL) { + if (conn->alter_private == NULL) { /* it timed out earlier */ return; } - c = talloc_get_type(conn->full_request_private, - struct composite_context); - state = talloc_get_type(c->private_data, struct dcerpc_request_state); + c = talloc_get_type(conn->alter_private, struct composite_context); + pipe = talloc_get_type(c->private_data, struct dcerpc_pipe); - if (!NT_STATUS_IS_OK(status)) { - composite_error(c, status); - return; - } - - /* unmarshall the NDR */ - c->status = ncacn_pull(state->pipe->conn, blob, state, &state->pkt); - if (!composite_is_ok(c)) return; + /* mark the connection as not waiting for a alter context reply */ + conn->alter_private = NULL; - if (state->pkt.ptype == DCERPC_PKT_ALTER_RESP && - state->pkt.u.alter_resp.num_results == 1 && - state->pkt.u.alter_resp.ctx_list[0].result != 0) { + if (pkt->ptype == DCERPC_PKT_ALTER_RESP && + pkt->u.alter_resp.num_results == 1 && + pkt->u.alter_resp.ctx_list[0].result != 0) { DEBUG(2,("dcerpc: alter_resp failed - reason %d\n", - state->pkt.u.alter_resp.ctx_list[0].reason)); - composite_error(c, dcerpc_map_reason(state->pkt.u.alter_resp.ctx_list[0].reason)); + pkt->u.alter_resp.ctx_list[0].reason)); + composite_error(c, dcerpc_map_reason(pkt->u.alter_resp.ctx_list[0].reason)); return; } - if (state->pkt.ptype != DCERPC_PKT_ALTER_RESP || - state->pkt.u.alter_resp.num_results == 0 || - state->pkt.u.alter_resp.ctx_list[0].result != 0) { + if (pkt->ptype != DCERPC_PKT_ALTER_RESP || + pkt->u.alter_resp.num_results == 0 || + pkt->u.alter_resp.ctx_list[0].result != 0) { composite_error(c, NT_STATUS_UNSUCCESSFUL); return; } /* the alter_resp might contain a reply set of credentials */ - if (state->pipe->conn->security_state.auth_info && - state->pkt.u.alter_resp.auth_info.length) { + if (pipe->conn->security_state.auth_info && + pkt->u.alter_resp.auth_info.length) { c->status = ndr_pull_struct_blob( - &state->pkt.u.alter_resp.auth_info, state, - state->pipe->conn->security_state.auth_info, + &pkt->u.alter_resp.auth_info, c, + pipe->conn->security_state.auth_info, (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); if (!composite_is_ok(c)) return; } @@ -1549,61 +1572,53 @@ struct composite_context *dcerpc_alter_context_send(struct dcerpc_pipe *p, const struct dcerpc_syntax_id *transfer_syntax) { struct composite_context *c; - struct dcerpc_request_state *state; + struct ncacn_packet pkt; + DATA_BLOB blob; c = talloc_zero(mem_ctx, struct composite_context); if (c == NULL) return NULL; - state = talloc(c, struct dcerpc_request_state); - if (state == NULL) { - c->status = NT_STATUS_NO_MEMORY; - goto failed; - } - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->private_data = state; + c->private_data = p; c->event_ctx = p->conn->event_ctx; - state->pipe = p; - p->syntax = *syntax; p->transfer_syntax = *transfer_syntax; - init_ncacn_hdr(p->conn, &state->pkt); + init_ncacn_hdr(p->conn, &pkt); - state->pkt.ptype = DCERPC_PKT_ALTER; - state->pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - state->pkt.call_id = p->conn->call_id; - state->pkt.auth_length = 0; + pkt.ptype = DCERPC_PKT_ALTER; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.call_id = p->conn->call_id; + pkt.auth_length = 0; - state->pkt.u.alter.max_xmit_frag = 5840; - state->pkt.u.alter.max_recv_frag = 5840; - state->pkt.u.alter.assoc_group_id = 0; - state->pkt.u.alter.num_contexts = 1; - state->pkt.u.alter.ctx_list = talloc_array(mem_ctx, + pkt.u.alter.max_xmit_frag = 5840; + pkt.u.alter.max_recv_frag = 5840; + pkt.u.alter.assoc_group_id = 0; + pkt.u.alter.num_contexts = 1; + pkt.u.alter.ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1); - if (state->pkt.u.alter.ctx_list == NULL) { + if (pkt.u.alter.ctx_list == NULL) { c->status = NT_STATUS_NO_MEMORY; goto failed; } - state->pkt.u.alter.ctx_list[0].context_id = p->context_id; - state->pkt.u.alter.ctx_list[0].num_transfer_syntaxes = 1; - state->pkt.u.alter.ctx_list[0].abstract_syntax = p->syntax; - state->pkt.u.alter.ctx_list[0].transfer_syntaxes = &p->transfer_syntax; - state->pkt.u.alter.auth_info = data_blob(NULL, 0); + pkt.u.alter.ctx_list[0].context_id = p->context_id; + pkt.u.alter.ctx_list[0].num_transfer_syntaxes = 1; + pkt.u.alter.ctx_list[0].abstract_syntax = p->syntax; + pkt.u.alter.ctx_list[0].transfer_syntaxes = &p->transfer_syntax; + pkt.u.alter.auth_info = data_blob(NULL, 0); /* construct the NDR form of the packet */ - c->status = ncacn_push_auth(&state->blob, mem_ctx, &state->pkt, + c->status = ncacn_push_auth(&blob, mem_ctx, &pkt, p->conn->security_state.auth_info); if (!NT_STATUS_IS_OK(c->status)) { goto failed; } - p->conn->transport.recv_data = alter_request_recv; - p->conn->full_request_private = c; + p->conn->transport.recv_data = dcerpc_recv_data; + p->conn->alter_private = c; - c->status = p->conn->transport.send_request(p->conn, &state->blob, - True); + c->status = p->conn->transport.send_request(p->conn, &blob, True); if (!NT_STATUS_IS_OK(c->status)) { goto failed; } diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 85fd36f066..a526ed5a01 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -75,8 +75,11 @@ struct dcerpc_connection { /* Sync requests waiting to be shipped */ struct rpc_request *request_queue; - /* private pointer for pending full requests */ - void *full_request_private; + /* private pointer for pending binds */ + void *bind_private; + + /* private pointer for pending alter context requests */ + void *alter_private; /* the next context_id to be assigned */ uint32_t next_context_id; |