****************************************************************************/
struct rpc_pipe_bind_state {
- struct tevent_context *ev;
- struct rpc_pipe_client *cli;
- DATA_BLOB rpc_out;
- bool auth3;
- uint32_t rpc_call_id;
+ struct dcerpc_presentation *pres[1];
+ struct dcerpc_call *call;
};
-static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
-static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
- struct rpc_pipe_bind_state *state,
- DATA_BLOB *credentials);
-static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
- struct rpc_pipe_bind_state *state,
- DATA_BLOB *credentials);
+static void rpc_pipe_bind_done(struct tevent_req *subreq);
struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
{
struct tevent_req *req, *subreq;
struct rpc_pipe_bind_state *state;
- NTSTATUS status;
+ struct gensec_security *gensec = NULL;
+ struct gensec_security **gensec_ptr = NULL;
req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
if (req == NULL) {
(unsigned int)auth->auth_type,
(unsigned int)auth->auth_level ));
- state->ev = ev;
- state->cli = cli;
- state->rpc_call_id = get_rpc_call_id();
+ if (auth->auth_ctx != NULL) {
+ gensec = talloc_get_type_abort(auth->auth_ctx,
+ struct gensec_security);
+ gensec_ptr = &gensec;
+ }
- cli->auth = talloc_move(cli, &auth);
+ auth->sec = dcerpc_security_allocate(auth, cli->conn,
+ auth->auth_type,
+ auth->auth_level,
+ gensec_ptr);
+ if (tevent_req_nomem(auth->sec, req)) {
+ return tevent_req_post(req, ev);
+ }
- /* Marshall the outgoing data. */
- status = create_rpc_bind_req(state, cli,
- cli->auth,
- state->rpc_call_id,
- &cli->abstract_syntax,
- &cli->transfer_syntax,
- &state->rpc_out);
+ cli->auth = talloc_move(cli, &auth);
- if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- goto post_status;
+ state->call = dcerpc_call_allocate(state, cli->assoc, NULL, NULL);
+ if (tevent_req_nomem(state->call, req)) {
+ return tevent_req_post(req, ev);
}
- subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
- DCERPC_PKT_BIND_ACK, state->rpc_call_id);
- if (subreq == NULL) {
- goto fail;
+ state->pres[0] = cli->pres;
+
+ subreq = dcerpc_do_bind_send(state, ev, cli->conn,
+ state->call, cli->auth->sec,
+ ARRAY_SIZE(state->pres),
+ state->pres);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
- tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
- return req;
+ tevent_req_set_callback(subreq, rpc_pipe_bind_done, req);
- post_status:
- tevent_req_nterror(req, status);
- return tevent_req_post(req, ev);
- fail:
- TALLOC_FREE(req);
- return NULL;
+ return req;
}
-static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
+static void rpc_pipe_bind_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
- struct rpc_pipe_bind_state *state = tevent_req_data(
- req, struct rpc_pipe_bind_state);
- struct pipe_auth_data *pauth = state->cli->auth;
- struct gensec_security *gensec_security;
- struct ncacn_packet *pkt = NULL;
- struct dcerpc_auth auth;
- DATA_BLOB auth_token = data_blob_null;
NTSTATUS status;
- status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
+ status = dcerpc_do_bind_recv(subreq);
TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
- rpccli_pipe_txt(talloc_tos(), state->cli),
- nt_errstr(status)));
- tevent_req_nterror(req, status);
- return;
- }
-
- if (state->auth3) {
- tevent_req_done(req);
- return;
- }
-
- if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
- DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
- tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
- return;
- }
-
- if (pkt->ptype == DCERPC_PKT_BIND_ACK) {
- if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
- if (pauth->client_hdr_signing) {
- pauth->hdr_signing = true;
- }
- }
- }
-
- state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
-
- switch(pauth->auth_type) {
-
- case DCERPC_AUTH_TYPE_NONE:
- /* Bind complete. */
- tevent_req_done(req);
- return;
-
- default:
- if (pkt->auth_length == 0) {
- tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
- return;
- }
-
- /* get auth credentials */
- status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
- &pkt->u.bind_ack.auth_info,
- &auth, NULL, true);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
- nt_errstr(status)));
- tevent_req_nterror(req, status);
- return;
- }
-
- if (auth.auth_type != pauth->auth_type) {
- DEBUG(0, (__location__ " Auth type %u mismatch expected %u.\n",
- auth.auth_type, pauth->auth_type));
- tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
- return;
- }
-
- if (auth.auth_level != pauth->auth_level) {
- DEBUG(0, (__location__ " Auth level %u mismatch expected %u.\n",
- auth.auth_level, pauth->auth_level));
- tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
- return;
- }
-
- if (auth.auth_context_id != pauth->auth_context_id) {
- DEBUG(0, (__location__ " Auth context id %u mismatch expected %u.\n",
- (unsigned)auth.auth_context_id,
- (unsigned)pauth->auth_context_id));
- tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
- return;
- }
-
- break;
- }
-
- /*
- * For authenticated binds we may need to do 3 or 4 leg binds.
- */
-
- switch(pauth->auth_type) {
-
- case DCERPC_AUTH_TYPE_NONE:
- /* Bind complete. */
- tevent_req_done(req);
+ if (tevent_req_nterror(req, status)) {
return;
-
- default:
- gensec_security = pauth->auth_ctx;
-
-
- status = gensec_update(gensec_security, state,
- auth.credentials, &auth_token);
- if (NT_STATUS_EQUAL(status,
- NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- status = rpc_bind_next_send(req, state,
- &auth_token);
- } else if (NT_STATUS_IS_OK(status)) {
- if (pauth->hdr_signing) {
- gensec_want_feature(gensec_security,
- GENSEC_FEATURE_SIGN_PKT_HEADER);
- }
-
- if (auth_token.length == 0) {
- /* Bind complete. */
- tevent_req_done(req);
- return;
- }
- status = rpc_bind_finish_send(req, state,
- &auth_token);
- }
- break;
}
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- }
- return;
-}
-
-static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
- struct rpc_pipe_bind_state *state,
- DATA_BLOB *auth_token)
-{
- struct pipe_auth_data *auth = state->cli->auth;
- struct tevent_req *subreq;
- NTSTATUS status;
-
- /* Now prepare the alter context pdu. */
- data_blob_free(&state->rpc_out);
-
- status = create_rpc_alter_context(state, auth,
- state->rpc_call_id,
- &state->cli->abstract_syntax,
- &state->cli->transfer_syntax,
- auth_token,
- &state->rpc_out);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- subreq = rpc_api_pipe_send(state, state->ev, state->cli,
- &state->rpc_out, DCERPC_PKT_ALTER_RESP,
- state->rpc_call_id);
- if (subreq == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
- tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
- return NT_STATUS_OK;
-}
-
-static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
- struct rpc_pipe_bind_state *state,
- DATA_BLOB *auth_token)
-{
- struct pipe_auth_data *auth = state->cli->auth;
- struct tevent_req *subreq;
- NTSTATUS status;
-
- state->auth3 = true;
-
- /* Now prepare the auth3 context pdu. */
- data_blob_free(&state->rpc_out);
-
- status = create_rpc_bind_auth3(state, state->cli, auth,
- state->rpc_call_id,
- auth_token,
- &state->rpc_out);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- subreq = rpc_api_pipe_send(state, state->ev, state->cli,
- &state->rpc_out, DCERPC_PKT_AUTH3,
- state->rpc_call_id);
- if (subreq == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
- tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
- return NT_STATUS_OK;
+ tevent_req_done(req);
}
NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
TALLOC_CTX *frame = talloc_stackframe();
struct tevent_context *ev;
NTSTATUS status = NT_STATUS_OK;
- struct dcerpc_call *call;
- struct tevent_req *subreq;
- struct auth_generic_state *auth_generic_ctx;
- struct gensec_security *gensec = NULL;
- struct gensec_security **gensec_ptr = NULL;
- struct dcerpc_presentation *pres[1];
+ struct tevent_req *req;
ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}
- if (auth->auth_ctx != NULL) {
- gensec = talloc_get_type_abort(auth->auth_ctx,
- struct gensec_security);
- gensec_ptr = &gensec;
- }
-
- cli->sec = dcerpc_security_allocate(cli, cli->conn,
- auth->auth_type,
- auth->auth_level,
- gensec_ptr);
-
- call = dcerpc_call_allocate(frame, cli->assoc, NULL, NULL);
-
- pres[0] = cli->pres;
-
- subreq = dcerpc_do_bind_send(frame, ev, cli->conn, call,
- cli->sec, ARRAY_SIZE(pres), pres);
-
- if (subreq == NULL) {
+ req = rpc_pipe_bind_send(frame, ev, cli, auth);
+ if (req == NULL) {
status = NT_STATUS_NO_MEMORY;
goto fail;
}
- if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
goto fail;
}
- status = dcerpc_do_bind_recv(subreq);
+ status = rpc_pipe_bind_recv(req);
fail:
TALLOC_FREE(frame);
return status;
state->call = dcerpc_call_allocate(state,
hs->rpc_cli->assoc,
- hs->rpc_cli->sec,
+ hs->rpc_cli->auth->sec,
hs->rpc_cli->pres);
if (in_flags & LIBNDR_FLAG_BIGENDIAN) {
&result->transport->stream);
result->pres = dcerpc_presentation_allocate(result, result->conn, table,
&ndr_transfer_syntax_ndr);
- result->sec = dcerpc_security_allocate(result, result->conn,
- DCERPC_AUTH_TYPE_NONE,
- DCERPC_AUTH_LEVEL_NONE,
- NULL);
result->binding_handle = rpccli_bh_create(result, NULL, table);
if (result->binding_handle == NULL) {
&result->transport->stream);
result->pres = dcerpc_presentation_allocate(result, result->conn, table,
&ndr_transfer_syntax_ndr);
- result->sec = dcerpc_security_allocate(result, result->conn,
- DCERPC_AUTH_TYPE_NONE,
- DCERPC_AUTH_LEVEL_NONE,
- NULL);
result->binding_handle = rpccli_bh_create(result, NULL, table);
if (result->binding_handle == NULL) {
tstream_smbXcli_np_use_trans);
result->pres = dcerpc_presentation_allocate(result, result->conn, table,
&ndr_transfer_syntax_ndr);
- result->sec = dcerpc_security_allocate(result, result->conn,
- DCERPC_AUTH_TYPE_NONE,
- DCERPC_AUTH_LEVEL_NONE,
- NULL);
np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
if (np_ref == NULL) {