diff options
author | Stefan Metzmacher <metze@samba.org> | 2017-05-22 20:44:40 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2017-06-27 16:57:45 +0200 |
commit | ddd7ac68ccae8b4df6c6a65b3dad20e21924f538 (patch) | |
tree | 4cbdc5640e86f6a0f08bb6c318ba567f430fc37f /libcli/auth | |
parent | 1421abfc733247a6b71eefd819dfeae7151a6d78 (diff) | |
download | samba-ddd7ac68ccae8b4df6c6a65b3dad20e21924f538.tar.gz |
libcli/auth: pass an array of nt_hashes to netlogon_creds_cli_auth*()
This way the caller can pass more than 2 hashes and can only
know which hash was used for a successful connection.
We allow up to 4 hashes (next, current, old, older).
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12782
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'libcli/auth')
-rw-r--r-- | libcli/auth/netlogon_creds_cli.c | 58 | ||||
-rw-r--r-- | libcli/auth/netlogon_creds_cli.h | 12 |
2 files changed, 44 insertions, 26 deletions
diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c index fcab81491c6..fabb2653483 100644 --- a/libcli/auth/netlogon_creds_cli.c +++ b/libcli/auth/netlogon_creds_cli.c @@ -943,9 +943,10 @@ struct netlogon_creds_cli_auth_state { struct tevent_context *ev; struct netlogon_creds_cli_context *context; struct dcerpc_binding_handle *binding_handle; - struct samr_Password current_nt_hash; - struct samr_Password previous_nt_hash; - struct samr_Password used_nt_hash; + uint8_t num_nt_hashes; + uint8_t idx_nt_hashes; + const struct samr_Password * const *nt_hashes; + const struct samr_Password *used_nt_hash; char *srv_name_slash; uint32_t current_flags; struct netr_Credential client_challenge; @@ -957,7 +958,6 @@ struct netlogon_creds_cli_auth_state { bool try_auth3; bool try_auth2; bool require_auth2; - bool try_previous_nt_hash; struct netlogon_creds_cli_locked_state *locked_state; }; @@ -968,8 +968,8 @@ struct tevent_req *netlogon_creds_cli_auth_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct netlogon_creds_cli_context *context, struct dcerpc_binding_handle *b, - struct samr_Password current_nt_hash, - const struct samr_Password *previous_nt_hash) + uint8_t num_nt_hashes, + const struct samr_Password * const *nt_hashes) { struct tevent_req *req; struct netlogon_creds_cli_auth_state *state; @@ -985,12 +985,19 @@ struct tevent_req *netlogon_creds_cli_auth_send(TALLOC_CTX *mem_ctx, state->ev = ev; state->context = context; state->binding_handle = b; - state->current_nt_hash = current_nt_hash; - if (previous_nt_hash != NULL) { - state->previous_nt_hash = *previous_nt_hash; - state->try_previous_nt_hash = true; + if (num_nt_hashes < 1) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); + } + if (num_nt_hashes > 4) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); + return tevent_req_post(req, ev); } + state->num_nt_hashes = num_nt_hashes; + state->idx_nt_hashes = 0; + state->nt_hashes = nt_hashes; + if (context->db.locked_state != NULL) { tevent_req_nterror(req, NT_STATUS_LOCK_NOT_GRANTED); return tevent_req_post(req, ev); @@ -1020,7 +1027,7 @@ struct tevent_req *netlogon_creds_cli_auth_send(TALLOC_CTX *mem_ctx, state->require_auth2 = true; } - state->used_nt_hash = state->current_nt_hash; + state->used_nt_hash = state->nt_hashes[state->idx_nt_hashes]; state->current_flags = context->client.proposed_flags; if (context->db.g_ctx != NULL) { @@ -1142,7 +1149,7 @@ static void netlogon_creds_cli_auth_challenge_done(struct tevent_req *subreq) state->context->client.type, &state->client_challenge, &state->server_challenge, - &state->used_nt_hash, + state->used_nt_hash, &state->client_credential, state->current_flags); if (tevent_req_nomem(state->creds, req)) { @@ -1284,7 +1291,8 @@ static void netlogon_creds_cli_auth_srvauth_done(struct tevent_req *subreq) return; } - if (!state->try_previous_nt_hash) { + state->idx_nt_hashes += 1; + if (state->idx_nt_hashes >= state->num_nt_hashes) { /* * we already retried, giving up... */ @@ -1295,8 +1303,7 @@ static void netlogon_creds_cli_auth_srvauth_done(struct tevent_req *subreq) /* * lets retry with the old nt hash. */ - state->try_previous_nt_hash = false; - state->used_nt_hash = state->previous_nt_hash; + state->used_nt_hash = state->nt_hashes[state->idx_nt_hashes]; state->current_flags = state->context->client.proposed_flags; netlogon_creds_cli_auth_challenge_start(req); return; @@ -1331,43 +1338,52 @@ static void netlogon_creds_cli_auth_srvauth_done(struct tevent_req *subreq) tevent_req_done(req); } -NTSTATUS netlogon_creds_cli_auth_recv(struct tevent_req *req) +NTSTATUS netlogon_creds_cli_auth_recv(struct tevent_req *req, + uint8_t *idx_nt_hashes) { + struct netlogon_creds_cli_auth_state *state = + tevent_req_data(req, + struct netlogon_creds_cli_auth_state); NTSTATUS status; + *idx_nt_hashes = 0; + if (tevent_req_is_nterror(req, &status)) { tevent_req_received(req); return status; } + *idx_nt_hashes = state->idx_nt_hashes; tevent_req_received(req); return NT_STATUS_OK; } NTSTATUS netlogon_creds_cli_auth(struct netlogon_creds_cli_context *context, struct dcerpc_binding_handle *b, - struct samr_Password current_nt_hash, - const struct samr_Password *previous_nt_hash) + uint8_t num_nt_hashes, + const struct samr_Password * const *nt_hashes, + uint8_t *idx_nt_hashes) { TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev; struct tevent_req *req; NTSTATUS status = NT_STATUS_NO_MEMORY; + *idx_nt_hashes = 0; + ev = samba_tevent_context_init(frame); if (ev == NULL) { goto fail; } req = netlogon_creds_cli_auth_send(frame, ev, context, b, - current_nt_hash, - previous_nt_hash); + num_nt_hashes, nt_hashes); if (req == NULL) { goto fail; } if (!tevent_req_poll_ntstatus(req, ev, &status)) { goto fail; } - status = netlogon_creds_cli_auth_recv(req); + status = netlogon_creds_cli_auth_recv(req, idx_nt_hashes); fail: TALLOC_FREE(frame); return status; diff --git a/libcli/auth/netlogon_creds_cli.h b/libcli/auth/netlogon_creds_cli.h index 7c737dd920a..dc274203d7d 100644 --- a/libcli/auth/netlogon_creds_cli.h +++ b/libcli/auth/netlogon_creds_cli.h @@ -84,13 +84,15 @@ struct tevent_req *netlogon_creds_cli_auth_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct netlogon_creds_cli_context *context, struct dcerpc_binding_handle *b, - struct samr_Password current_nt_hash, - const struct samr_Password *previous_nt_hash); -NTSTATUS netlogon_creds_cli_auth_recv(struct tevent_req *req); + uint8_t num_nt_hashes, + const struct samr_Password * const *nt_hashes); +NTSTATUS netlogon_creds_cli_auth_recv(struct tevent_req *req, + uint8_t *idx_nt_hashes); NTSTATUS netlogon_creds_cli_auth(struct netlogon_creds_cli_context *context, struct dcerpc_binding_handle *b, - struct samr_Password current_nt_hash, - const struct samr_Password *previous_nt_hash); + uint8_t num_nt_hashes, + const struct samr_Password * const *nt_hashes, + uint8_t *idx_nt_hashes); struct tevent_req *netlogon_creds_cli_check_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, |