summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc/dcerpc_auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/librpc/rpc/dcerpc_auth.c')
-rw-r--r--source4/librpc/rpc/dcerpc_auth.c71
1 files changed, 41 insertions, 30 deletions
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c
index 443c7587e72..15a843b4ef5 100644
--- a/source4/librpc/rpc/dcerpc_auth.c
+++ b/source4/librpc/rpc/dcerpc_auth.c
@@ -124,7 +124,8 @@ _PUBLIC_ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
struct bind_auth_state {
struct dcerpc_pipe *pipe;
- DATA_BLOB credentials;
+ struct dcerpc_auth out_auth_info;
+ struct dcerpc_auth in_auth_info;
bool more_processing; /* Is there anything more to do after the
* first bind itself received? */
};
@@ -141,6 +142,12 @@ static void bind_auth_next_step(struct composite_context *c)
state = talloc_get_type(c->private_data, struct bind_auth_state);
sec = &state->pipe->conn->security_state;
+ state->out_auth_info = (struct dcerpc_auth) {
+ .auth_type = sec->auth_type,
+ .auth_level = sec->auth_level,
+ .auth_context_id = sec->auth_context_id,
+ };
+
/* The status value here, from GENSEC is vital to the security
* of the system. Even if the other end accepts, if GENSEC
* claims 'MORE_PROCESSING_REQUIRED' then you must keep
@@ -156,16 +163,14 @@ static void bind_auth_next_step(struct composite_context *c)
c->status = gensec_update_ev(sec->generic_state, state,
state->pipe->conn->event_ctx,
- sec->auth_info->credentials,
- &state->credentials);
+ state->in_auth_info.credentials,
+ &state->out_auth_info.credentials);
if (state->pipe->timed_out) {
composite_error(c, NT_STATUS_IO_TIMEOUT);
return;
}
state->pipe->inhibit_timeout_processing = false;
- data_blob_free(&sec->auth_info->credentials);
-
if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
more_processing = true;
c->status = NT_STATUS_OK;
@@ -173,18 +178,21 @@ static void bind_auth_next_step(struct composite_context *c)
if (!composite_is_ok(c)) return;
- if (state->credentials.length == 0) {
+ if (state->out_auth_info.credentials.length == 0) {
composite_done(c);
return;
}
- sec->auth_info->credentials = state->credentials;
+ state->in_auth_info = (struct dcerpc_auth) {
+ .auth_type = DCERPC_AUTH_TYPE_NONE,
+ };
+ sec->tmp_auth_info.in = &state->in_auth_info;
+ sec->tmp_auth_info.mem = state;
+ sec->tmp_auth_info.out = &state->out_auth_info;
if (!more_processing) {
/* NO reply expected, so just send it */
c->status = dcerpc_auth3(state->pipe, state);
- data_blob_free(&state->credentials);
- sec->auth_info->credentials = data_blob(NULL, 0);
if (!composite_is_ok(c)) return;
composite_done(c);
@@ -197,8 +205,6 @@ static void bind_auth_next_step(struct composite_context *c)
state->pipe,
&state->pipe->syntax,
&state->pipe->transfer_syntax);
- data_blob_free(&state->credentials);
- sec->auth_info->credentials = data_blob(NULL, 0);
if (composite_nomem(subreq, c)) return;
tevent_req_set_callback(subreq, bind_auth_recv_alter, c);
}
@@ -209,6 +215,11 @@ static void bind_auth_recv_alter(struct tevent_req *subreq)
struct composite_context *c =
tevent_req_callback_data(subreq,
struct composite_context);
+ struct bind_auth_state *state = talloc_get_type(c->private_data,
+ struct bind_auth_state);
+ struct dcecli_security *sec = &state->pipe->conn->security_state;
+
+ ZERO_STRUCT(sec->tmp_auth_info);
c->status = dcerpc_alter_context_recv(subreq);
TALLOC_FREE(subreq);
@@ -225,14 +236,15 @@ static void bind_auth_recv_bindreply(struct tevent_req *subreq)
struct composite_context);
struct bind_auth_state *state = talloc_get_type(c->private_data,
struct bind_auth_state);
+ struct dcecli_security *sec = &state->pipe->conn->security_state;
+
+ ZERO_STRUCT(sec->tmp_auth_info);
c->status = dcerpc_bind_recv(subreq);
TALLOC_FREE(subreq);
if (!composite_is_ok(c)) return;
if (state->pipe->conn->flags & DCERPC_HEADER_SIGNING) {
- struct dcecli_security *sec = &state->pipe->conn->security_state;
-
gensec_want_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER);
}
@@ -362,15 +374,11 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx,
*/
sec->auth_context_id = 1;
- sec->auth_info = talloc(p, struct dcerpc_auth);
- if (composite_nomem(sec->auth_info, c)) return c;
-
- sec->auth_info->auth_type = sec->auth_type;
- sec->auth_info->auth_level = sec->auth_level,
- sec->auth_info->auth_pad_length = 0;
- sec->auth_info->auth_reserved = 0;
- sec->auth_info->auth_context_id = sec->auth_context_id;
- sec->auth_info->credentials = data_blob(NULL, 0);
+ state->out_auth_info = (struct dcerpc_auth) {
+ .auth_type = sec->auth_type,
+ .auth_level = sec->auth_level,
+ .auth_context_id = sec->auth_context_id,
+ };
/* The status value here, from GENSEC is vital to the security
* of the system. Even if the other end accepts, if GENSEC
@@ -386,8 +394,8 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx,
state->pipe->timed_out = false;
c->status = gensec_update_ev(sec->generic_state, state,
p->conn->event_ctx,
- sec->auth_info->credentials,
- &state->credentials);
+ data_blob_null,
+ &state->out_auth_info.credentials);
if (state->pipe->timed_out) {
composite_error(c, NT_STATUS_IO_TIMEOUT);
return c;
@@ -403,25 +411,28 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx,
state->more_processing = NT_STATUS_EQUAL(c->status,
NT_STATUS_MORE_PROCESSING_REQUIRED);
- if (state->credentials.length == 0) {
+ if (state->out_auth_info.credentials.length == 0) {
composite_done(c);
return c;
}
- sec->auth_info->credentials = state->credentials;
-
if (gensec_have_feature(sec->generic_state, GENSEC_FEATURE_SIGN_PKT_HEADER)) {
- if (auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
+ if (sec->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
state->pipe->conn->flags |= DCERPC_PROPOSE_HEADER_SIGNING;
}
}
+ state->in_auth_info = (struct dcerpc_auth) {
+ .auth_type = DCERPC_AUTH_TYPE_NONE,
+ };
+ sec->tmp_auth_info.in = &state->in_auth_info;
+ sec->tmp_auth_info.mem = state;
+ sec->tmp_auth_info.out = &state->out_auth_info;
+
/* The first request always is a dcerpc_bind. The subsequent ones
* depend on gensec results */
subreq = dcerpc_bind_send(state, p->conn->event_ctx, p,
&syntax, &transfer_syntax);
- data_blob_free(&state->credentials);
- sec->auth_info->credentials = data_blob(NULL, 0);
if (composite_nomem(subreq, c)) return c;
tevent_req_set_callback(subreq, bind_auth_recv_bindreply, c);