summaryrefslogtreecommitdiff
path: root/source4/lib/credentials.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-06-17 13:12:13 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:18:23 -0500
commit5b19286df08d6cf10654d6e20c323ba44f7d2054 (patch)
tree922bdf3301089611449f501e83e3489881427021 /source4/lib/credentials.c
parenta4bb5ae30c1abcf385f02493e778755b09710d95 (diff)
downloadsamba-5b19286df08d6cf10654d6e20c323ba44f7d2054.tar.gz
samba-5b19286df08d6cf10654d6e20c323ba44f7d2054.tar.bz2
samba-5b19286df08d6cf10654d6e20c323ba44f7d2054.zip
r7690: Move the NT hash generation into the credentials system, rather than
in all the callers. This also allows us to be more flexible in the type of password we store. Andrew Bartlett (This used to be commit 00b8588c68526e1d86fda0bd81c0b86f690b62c3)
Diffstat (limited to 'source4/lib/credentials.c')
-rw-r--r--source4/lib/credentials.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/source4/lib/credentials.c b/source4/lib/credentials.c
index 1dbb536f9e..aaaa2cf05d 100644
--- a/source4/lib/credentials.c
+++ b/source4/lib/credentials.c
@@ -24,6 +24,7 @@
#include "system/filesys.h"
#include "include/secrets.h"
#include "lib/ldb/include/ldb.h"
+#include "librpc/gen_ndr/ndr_samr.h" /* for struct samrPassword */
/**
* Create a new credentials structure
@@ -101,6 +102,46 @@ BOOL cli_credentials_set_password(struct cli_credentials *cred, const char *val,
if (obtained >= cred->password_obtained) {
cred->password = talloc_strdup(cred, val);
cred->password_obtained = obtained;
+
+ cred->nt_hash = NULL;
+ return True;
+ }
+
+ return False;
+}
+
+/**
+ * Obtain the password for this credentials context.
+ * @param cred credentials context
+ * @retval If set, the cleartext password, otherwise NULL
+ */
+const struct samr_Password *cli_credentials_get_nt_hash(struct cli_credentials *cred,
+ TALLOC_CTX *mem_ctx)
+{
+ const char *password = cli_credentials_get_password(cred);
+
+ if (password) {
+ struct samr_Password *nt_hash = talloc(mem_ctx, struct samr_Password);
+ if (!nt_hash) {
+ return NULL;
+ }
+
+ E_md4hash(password, nt_hash->hash);
+
+ return nt_hash;
+ } else {
+ return cred->nt_hash;
+ }
+}
+
+BOOL cli_credentials_set_nt_hash(struct cli_credentials *cred,
+ const struct samr_Password *nt_hash,
+ enum credentials_obtained obtained)
+{
+ if (obtained >= cred->password_obtained) {
+ cli_credentials_set_password(cred, NULL, obtained);
+ cred->nt_hash = talloc(cred, struct samr_Password);
+ *cred->nt_hash = *nt_hash;
return True;
}
@@ -462,6 +503,7 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
"flatname",
"realm",
"secureChannelType",
+ "ntPwdHash",
NULL
};
@@ -500,14 +542,9 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
}
password = ldb_msg_find_string(msgs[0], "secret", NULL);
- if (!password) {
- DEBUG(1, ("Could not find 'secret' in join record to domain: %s\n",
- cli_credentials_get_domain(cred)));
- talloc_free(mem_ctx);
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
+
machine_account = ldb_msg_find_string(msgs[0], "samAccountName", NULL);
+
if (!machine_account) {
DEBUG(1, ("Could not find 'samAccountName' in join record to domain: %s\n",
cli_credentials_get_domain(cred)));
@@ -516,14 +553,32 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
}
sct = ldb_msg_find_int(msgs[0], "secureChannelType", 0);
- if (sct) {
- cli_credentials_set_secure_channel_type(cred, sct);
- } else {
+ if (!sct) {
DEBUG(1, ("Domain join for acocunt %s did not have a secureChannelType set!\n",
machine_account));
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
+ if (!password) {
+ const struct ldb_val *nt_password_hash = ldb_msg_find_ldb_val(msgs[0], "ntPwdHash");
+ struct samr_Password hash;
+ ZERO_STRUCT(hash);
+ if (nt_password_hash) {
+ memcpy(hash.hash, nt_password_hash->data,
+ MIN(nt_password_hash->length, sizeof(hash.hash)));
+
+ cli_credentials_set_nt_hash(cred, &hash, CRED_SPECIFIED);
+ } else {
+
+ DEBUG(1, ("Could not find 'secret' in join record to domain: %s\n",
+ cli_credentials_get_domain(cred)));
+ talloc_free(mem_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+ }
+
+ cli_credentials_set_secure_channel_type(cred, sct);
+
domain = ldb_msg_find_string(msgs[0], "flatname", NULL);
if (domain) {
cli_credentials_set_domain(cred, domain, CRED_SPECIFIED);
@@ -535,7 +590,10 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
}
cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
- cli_credentials_set_password(cred, password, CRED_SPECIFIED);
+ if (password) {
+ cli_credentials_set_password(cred, password, CRED_SPECIFIED);
+ }
+
talloc_free(mem_ctx);
return NT_STATUS_OK;