summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc/dcerpc_util.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-05-07 18:11:47 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:05:42 -0500
commit5f36534629f7f755c7ad8681ec2322baa50f5504 (patch)
tree22e736635c7fb34d3a69f116affdc8425fb121d8 /source4/librpc/rpc/dcerpc_util.c
parentceb1d661727a14fef54ce210d0d97f4417f1b132 (diff)
downloadsamba-5f36534629f7f755c7ad8681ec2322baa50f5504.tar.gz
samba-5f36534629f7f755c7ad8681ec2322baa50f5504.tar.bz2
samba-5f36534629f7f755c7ad8681ec2322baa50f5504.zip
r15500: Add support for interactive prompting on bad passwords to the RPC libraries.
This support requires that the bind_ack and alter_ack recv functions also be send the DCE/RPC fault. This would be best done by having the ack run as a normal RPC reply callback, but this isn't easily possible for now. Andrew Bartlett (This used to be commit be6dde22fe728d64d47875699d3421c6d8d872a4)
Diffstat (limited to 'source4/librpc/rpc/dcerpc_util.c')
-rw-r--r--source4/librpc/rpc/dcerpc_util.c120
1 files changed, 35 insertions, 85 deletions
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index 6c8ed7ecd8..158c5e3fe0 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -976,14 +976,12 @@ struct pipe_auth_state {
struct dcerpc_binding *binding;
const struct dcerpc_interface_table *table;
struct cli_credentials *credentials;
+ uint8_t next_auth_type;
+ BOOL try_ntlm_fallback;
};
-static void continue_auth_schannel(struct composite_context *ctx);
-static void continue_auth(struct composite_context *ctx);
-static void continue_auth_none(struct composite_context *ctx);
-static void continue_ntlmssp_connection(struct composite_context *ctx);
-static void continue_spnego_after_wrong_pass(struct composite_context *ctx);
+static void continue_new_auth_bind(struct composite_context *ctx);
/*
@@ -1002,52 +1000,44 @@ static void continue_auth_schannel(struct composite_context *ctx)
/*
- Stage 2 of pipe_auth: Receive result of authenticated bind request
-*/
-static void continue_auth(struct composite_context *ctx)
-{
- struct composite_context *c = talloc_get_type(ctx->async.private_data,
- struct composite_context);
-
- c->status = dcerpc_bind_auth_recv(ctx);
- if (!composite_is_ok(c)) return;
-
- composite_done(c);
-}
-/*
Stage 2 of pipe_auth: Receive result of authenticated bind request, but handle fallbacks:
SPNEGO -> NTLMSSP
*/
-static void continue_auth_auto(struct composite_context *ctx)
+static void continue_recv_bind(struct composite_context *ctx)
{
+ NTSTATUS status;
struct composite_context *c = talloc_get_type(ctx->async.private_data,
struct composite_context);
+ struct pipe_auth_state *s = talloc_get_type(c->private_data, struct pipe_auth_state);
- c->status = dcerpc_bind_auth_recv(ctx);
- if (NT_STATUS_EQUAL(c->status, NT_STATUS_INVALID_PARAMETER)) {
- struct pipe_auth_state *s = talloc_get_type(c->private_data, struct pipe_auth_state);
+ status = dcerpc_bind_auth_recv(ctx);
+ if (s->try_ntlm_fallback && NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
struct composite_context *sec_conn_req;
-
+ s->try_ntlm_fallback = False;
+ s->next_auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
/* send a request for secondary rpc connection */
sec_conn_req = dcerpc_secondary_connection_send(s->pipe,
s->binding);
if (composite_nomem(sec_conn_req, c)) return;
- composite_continue(c, sec_conn_req, continue_ntlmssp_connection, c);
+ composite_continue(c, sec_conn_req, continue_new_auth_bind, c);
return;
- } else if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) {
- struct pipe_auth_state *s = talloc_get_type(c->private_data, struct pipe_auth_state);
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
struct composite_context *sec_conn_req;
if (cli_credentials_wrong_password(s->credentials)) {
+ s->next_auth_type = DCERPC_AUTH_TYPE_SPNEGO;
/* send a request for secondary rpc connection */
sec_conn_req = dcerpc_secondary_connection_send(s->pipe,
s->binding);
if (composite_nomem(sec_conn_req, c)) return;
- composite_continue(c, sec_conn_req, continue_spnego_after_wrong_pass, c);
+ composite_continue(c, sec_conn_req, continue_new_auth_bind, c);
+
+ return;
}
}
+ c->status = status;
if (!composite_is_ok(c)) return;
@@ -1055,44 +1045,14 @@ static void continue_auth_auto(struct composite_context *ctx)
}
/*
- Stage 3 of pipe_auth (fallback to NTLMSSP case): Receive secondary
- rpc connection (the first one can't be used any more, due to the
- bind nak) and perform authenticated bind request
-*/
-static void continue_ntlmssp_connection(struct composite_context *ctx)
-{
- struct composite_context *c;
- struct pipe_auth_state *s;
- struct composite_context *auth_req;
- struct dcerpc_pipe *p2;
-
- c = talloc_get_type(ctx->async.private_data, struct composite_context);
- s = talloc_get_type(c->private_data, struct pipe_auth_state);
-
- /* receive secondary rpc connection */
- c->status = dcerpc_secondary_connection_recv(ctx, &p2);
- talloc_steal(s, p2);
- talloc_steal(p2, s->pipe);
- s->pipe = p2;
+ Stage 3 of pipe_auth (fallback to NTLMSSP case/SPNEGO password retry case):
+
+ Receive secondary rpc connection (the first one can't be used any
+ more, due to the bind nak) and perform authenticated bind request
- if (!composite_is_ok(c)) return;
-
- /* initiate a authenticated bind */
- auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
- s->credentials, DCERPC_AUTH_TYPE_NTLMSSP,
- dcerpc_auth_level(s->pipe->conn),
- s->table->authservices->names[0]);
- if (composite_nomem(auth_req, c)) return;
-
- composite_continue(c, auth_req, continue_auth, c);
-}
-
-/*
- Stage 3 of pipe_auth (retry on wrong password): Receive secondary
- rpc connection (the first one can't be used any more, due to the
- bind nak) and perform authenticated bind request
+ Calls back to stage 2 to process the response.
*/
-static void continue_spnego_after_wrong_pass(struct composite_context *ctx)
+static void continue_new_auth_bind(struct composite_context *ctx)
{
struct composite_context *c;
struct pipe_auth_state *s;
@@ -1104,27 +1064,25 @@ static void continue_spnego_after_wrong_pass(struct composite_context *ctx)
/* receive secondary rpc connection */
c->status = dcerpc_secondary_connection_recv(ctx, &p2);
- talloc_steal(s, p2);
- talloc_steal(p2, s->pipe);
s->pipe = p2;
if (!composite_is_ok(c)) return;
/* initiate a authenticated bind */
auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
- s->credentials, DCERPC_AUTH_TYPE_SPNEGO,
+ s->credentials, s->next_auth_type,
dcerpc_auth_level(s->pipe->conn),
s->table->authservices->names[0]);
if (composite_nomem(auth_req, c)) return;
- composite_continue(c, auth_req, continue_auth, c);
+ composite_continue(c, auth_req, continue_recv_bind, c);
}
/*
Stage 2 of pipe_auth: Receive result of non-authenticated bind request
*/
-static void continue_auth_none(struct composite_context *ctx)
+static void continue_auth_recv_none(struct composite_context *ctx)
{
struct composite_context *c = talloc_get_type(ctx->async.private_data,
struct composite_context);
@@ -1225,29 +1183,23 @@ struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p,
} else if (s->binding->flags & DCERPC_AUTH_NTLM) {
auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
} else {
- auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
- s->credentials, DCERPC_AUTH_TYPE_SPNEGO,
- dcerpc_auth_level(conn),
- s->table->authservices->names[0]);
- if (composite_nomem(auth_req, c)) return c;
-
- composite_continue(c, auth_req, continue_auth_auto, c);
- return c;
+ auth_type = DCERPC_AUTH_TYPE_SPNEGO;
+ s->try_ntlm_fallback = True;
}
-
+
auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table,
- s->credentials, auth_type,
+ s->credentials, DCERPC_AUTH_TYPE_SPNEGO,
dcerpc_auth_level(conn),
s->table->authservices->names[0]);
if (composite_nomem(auth_req, c)) return c;
- composite_continue(c, auth_req, continue_auth, c);
+ composite_continue(c, auth_req, continue_recv_bind, c);
} else {
auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe, s->table);
if (composite_nomem(auth_none_req, c)) return c;
- composite_continue(c, auth_none_req, continue_auth_none, c);
+ composite_continue(c, auth_none_req, continue_auth_recv_none, c);
}
return c;
@@ -1261,7 +1213,7 @@ struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p,
supllied, as it rebinds to a new pipe due to authentication fallback
*/
-NTSTATUS dcerpc_pipe_auth_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
+NTSTATUS dcerpc_pipe_auth_recv(struct composite_context *c,
struct dcerpc_pipe **p)
{
NTSTATUS status;
@@ -1274,7 +1226,6 @@ NTSTATUS dcerpc_pipe_auth_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
DEBUG(0, ("Failed to bind to uuid %s - %s\n", uuid_str, nt_errstr(status)));
talloc_free(uuid_str);
} else {
- talloc_steal(mem_ctx, s->pipe);
*p = s->pipe;
}
@@ -1288,8 +1239,7 @@ NTSTATUS dcerpc_pipe_auth_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
This may change *p, as it rebinds to a new pipe due to authentication fallback
*/
-NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx,
- struct dcerpc_pipe **p,
+NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe **p,
struct dcerpc_binding *binding,
const struct dcerpc_interface_table *table,
struct cli_credentials *credentials)
@@ -1297,7 +1247,7 @@ NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx,
struct composite_context *c;
c = dcerpc_pipe_auth_send(*p, binding, table, credentials);
- return dcerpc_pipe_auth_recv(c, mem_ctx, p);
+ return dcerpc_pipe_auth_recv(c, p);
}