summaryrefslogtreecommitdiff
path: root/auth
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-02-09 09:04:42 +0100
committerGünther Deschner <gd@samba.org>2015-03-12 17:13:42 +0100
commit016c4ce84f2a34abb705b85d0abd1e17aa1325db (patch)
treefac04261a071885c93400a9c16f317496a335363 /auth
parent3abccced8cf057ce0768a5acf7e828db3823fae2 (diff)
downloadsamba-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.c42
-rw-r--r--auth/credentials/credentials.h4
-rw-r--r--auth/credentials/credentials_internal.h1
-rw-r--r--auth/credentials/credentials_ntlm.c17
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,