diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-02-09 09:04:42 +0100 |
---|---|---|
committer | Günther Deschner <gd@samba.org> | 2015-03-12 17:13:42 +0100 |
commit | 016c4ce84f2a34abb705b85d0abd1e17aa1325db (patch) | |
tree | fac04261a071885c93400a9c16f317496a335363 /auth | |
parent | 3abccced8cf057ce0768a5acf7e828db3823fae2 (diff) | |
download | samba-016c4ce84f2a34abb705b85d0abd1e17aa1325db.tar.gz |
auth/credentials: add cli_credentials_[g|s]et_old_nt_hash()
The machine and trust accounts it's important to retry
netr_Authenticate3() with the previous (old) nt_hash.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
Diffstat (limited to 'auth')
-rw-r--r-- | auth/credentials/credentials.c | 42 | ||||
-rw-r--r-- | auth/credentials/credentials.h | 4 | ||||
-rw-r--r-- | auth/credentials/credentials_internal.h | 1 | ||||
-rw-r--r-- | auth/credentials/credentials_ntlm.c | 17 |
4 files changed, 64 insertions, 0 deletions
diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index a9e4fc864d4..42aa2a3c51e 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -70,6 +70,7 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) cred->bind_dn = NULL; cred->nt_hash = NULL; + cred->old_nt_hash = NULL; cred->lm_response.data = NULL; cred->lm_response.length = 0; @@ -481,6 +482,7 @@ _PUBLIC_ bool cli_credentials_set_old_password(struct cli_credentials *cred, /* Don't print the actual password in talloc memory dumps */ talloc_set_name_const(cred->old_password, "password set via cli_credentials_set_old_password"); } + cred->old_nt_hash = NULL; return true; } @@ -525,6 +527,46 @@ _PUBLIC_ struct samr_Password *cli_credentials_get_nt_hash(struct cli_credential } /** + * Obtain the old password, in the form MD4(unicode(password)) for this credentials context. + * + * Sometimes we only have this much of the password, while the rest of + * the time this call avoids calling E_md4hash themselves. + * + * @param cred credentials context + * @retval If set, the cleartext password, otherwise NULL + */ +_PUBLIC_ struct samr_Password *cli_credentials_get_old_nt_hash(struct cli_credentials *cred, + TALLOC_CTX *mem_ctx) +{ + const char *old_password = NULL; + + if (cred->old_nt_hash != NULL) { + struct samr_Password *nt_hash = talloc(mem_ctx, struct samr_Password); + if (!nt_hash) { + return NULL; + } + + *nt_hash = *cred->old_nt_hash; + + return nt_hash; + } + + old_password = cli_credentials_get_old_password(cred); + if (old_password) { + struct samr_Password *nt_hash = talloc(mem_ctx, struct samr_Password); + if (!nt_hash) { + return NULL; + } + + E_md4hash(old_password, nt_hash->hash); + + return nt_hash; + } + + return NULL; +} + +/** * Obtain the 'short' or 'NetBIOS' domain for this credentials context. * @param cred credentials context * @retval The domain set on this context. diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 814f01648b0..d875fb57572 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -146,6 +146,8 @@ struct cli_credentials *cli_credentials_init_anon(TALLOC_CTX *mem_ctx); void cli_credentials_parse_string(struct cli_credentials *credentials, const char *data, enum credentials_obtained obtained); struct samr_Password *cli_credentials_get_nt_hash(struct cli_credentials *cred, TALLOC_CTX *mem_ctx); +struct samr_Password *cli_credentials_get_old_nt_hash(struct cli_credentials *cred, + TALLOC_CTX *mem_ctx); bool cli_credentials_set_realm(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained); @@ -197,6 +199,8 @@ bool cli_credentials_set_utf16_password(struct cli_credentials *cred, bool cli_credentials_set_nt_hash(struct cli_credentials *cred, const struct samr_Password *nt_hash, enum credentials_obtained obtained); +bool cli_credentials_set_old_nt_hash(struct cli_credentials *cred, + const struct samr_Password *nt_hash); bool cli_credentials_set_ntlm_response(struct cli_credentials *cred, const DATA_BLOB *lm_response, const DATA_BLOB *nt_response, diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h index d05d1532cb0..aa01ccc1c49 100644 --- a/auth/credentials/credentials_internal.h +++ b/auth/credentials/credentials_internal.h @@ -60,6 +60,7 @@ struct cli_credentials { /* Allows authentication from a keytab or similar */ struct samr_Password *nt_hash; + struct samr_Password *old_nt_hash; /* Allows NTLM pass-though authentication */ DATA_BLOB lm_response; diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index f339c9b6dc2..327cf1396f6 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -289,6 +289,23 @@ _PUBLIC_ bool cli_credentials_set_nt_hash(struct cli_credentials *cred, return false; } +_PUBLIC_ bool cli_credentials_set_old_nt_hash(struct cli_credentials *cred, + const struct samr_Password *nt_hash) +{ + cli_credentials_set_old_password(cred, NULL, CRED_SPECIFIED); + if (nt_hash) { + cred->old_nt_hash = talloc(cred, struct samr_Password); + if (cred->old_nt_hash == NULL) { + return false; + } + *cred->old_nt_hash = *nt_hash; + } else { + cred->old_nt_hash = NULL; + } + + return true; +} + _PUBLIC_ bool cli_credentials_set_ntlm_response(struct cli_credentials *cred, const DATA_BLOB *lm_response, const DATA_BLOB *nt_response, |