summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/rpc/dcerpc_auth.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c
index 5745a38a8f..1dbc3b8aef 100644
--- a/source4/librpc/rpc/dcerpc_auth.c
+++ b/source4/librpc/rpc/dcerpc_auth.c
@@ -73,7 +73,8 @@ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
struct bind_auth_state {
struct dcerpc_pipe *pipe;
DATA_BLOB credentials;
- BOOL more_processing;
+ BOOL more_processing; /* Is there anything more to do after the
+ * first bind itself received? */
};
static void bind_auth_recv_alter(struct composite_context *creq);
@@ -86,6 +87,16 @@ static void bind_auth_next_step(struct composite_context *c)
struct composite_context *creq;
BOOL more_processing = False;
+ /* 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
+ * feeding it blobs, or else the remote host/attacker might
+ * avoid mutal authentication requirements.
+ *
+ * Likewise, you must not feed GENSEC too much (after the OK),
+ * it doesn't like that either
+ */
+
c->status = gensec_update(sec->generic_state, state,
sec->auth_info->credentials,
&state->credentials);
@@ -112,6 +123,8 @@ static void bind_auth_next_step(struct composite_context *c)
return;
}
+ /* We are demanding a reply, so use a request that will get us one */
+
creq = dcerpc_alter_context_send(state->pipe, state,
&state->pipe->syntax,
&state->pipe->transfer_syntax);
@@ -142,6 +155,8 @@ static void bind_auth_recv_bindreply(struct composite_context *creq)
if (!composite_is_ok(c)) return;
if (!state->more_processing) {
+ /* The first gensec_update has not requested a second run, so
+ * we're done here. */
composite_done(c);
return;
}
@@ -240,6 +255,16 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx,
sec->auth_info->auth_context_id = random();
sec->auth_info->credentials = data_blob(NULL, 0);
+ /* 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
+ * feeding it blobs, or else the remote host/attacker might
+ * avoid mutal authentication requirements.
+ *
+ * Likewise, you must not feed GENSEC too much (after the OK),
+ * it doesn't like that either
+ */
+
c->status = gensec_update(sec->generic_state, state,
sec->auth_info->credentials,
&state->credentials);
@@ -258,6 +283,8 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx,
sec->auth_info->credentials = state->credentials;
+ /* The first request always is a dcerpc_bind. The subsequent ones
+ * depend on gensec results */
creq = dcerpc_bind_send(p, state, &syntax, &transfer_syntax);
if (creq == NULL) {
c->status = NT_STATUS_NO_MEMORY;