summaryrefslogtreecommitdiff
path: root/source4/dsdb/common/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb/common/util.c')
-rw-r--r--source4/dsdb/common/util.c88
1 files changed, 51 insertions, 37 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 5b93efb316..0a87c5ffe1 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -26,6 +26,7 @@
#include "ldb.h"
#include "ldb_errors.h"
#include "../lib/util/util_ldb.h"
+#include "../lib/crypto/crypto.h"
#include "dsdb/samdb/samdb.h"
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_security.h"
@@ -571,7 +572,7 @@ uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
return count;
}
-NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
+NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct ldb_message *msg,
struct samr_Password **lm_pwd, struct samr_Password **nt_pwd)
{
struct samr_Password *lmPwdHash, *ntPwdHash;
@@ -587,14 +588,21 @@ NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
}
}
if (lm_pwd) {
- int num_lm;
- num_lm = samdb_result_hashes(mem_ctx, msg, "dBCSPwd", &lmPwdHash);
- if (num_lm == 0) {
- *lm_pwd = NULL;
- } else if (num_lm > 1) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ /* Ensure that if we have turned off LM
+ * authentication, that we never use the LM hash, even
+ * if we store it */
+ if (lp_lanman_auth(lp_ctx)) {
+ int num_lm;
+ num_lm = samdb_result_hashes(mem_ctx, msg, "dBCSPwd", &lmPwdHash);
+ if (num_lm == 0) {
+ *lm_pwd = NULL;
+ } else if (num_lm > 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ } else {
+ *lm_pwd = &lmPwdHash[0];
+ }
} else {
- *lm_pwd = &lmPwdHash[0];
+ *lm_pwd = NULL;
}
}
return NT_STATUS_OK;
@@ -1531,7 +1539,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
struct ldb_dn *user_dn,
struct ldb_dn *domain_dn,
struct ldb_message *mod,
- const char *new_pass,
+ const DATA_BLOB *new_password,
struct samr_Password *lmNewHash,
struct samr_Password *ntNewHash,
bool user_change,
@@ -1632,40 +1640,47 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
*_dominfo = dominfo;
}
- if (restrictions && new_pass) {
-
+ if (restrictions && new_password) {
+ char *new_pass;
+
/* check the various password restrictions */
- if (restrictions && minPwdLength > strlen_m(new_pass)) {
+ if (restrictions && minPwdLength > utf16_len_n(new_password->data, (new_password->length / 2))) {
if (reject_reason) {
*reject_reason = SAMR_REJECT_TOO_SHORT;
}
return NT_STATUS_PASSWORD_RESTRICTION;
}
+
+ /* Create the NT hash */
+ mdfour(local_ntNewHash.hash, new_password->data, new_password->length);
- /* possibly check password complexity */
- if (restrictions && pwdProperties & DOMAIN_PASSWORD_COMPLEX &&
- !samdb_password_complexity_ok(new_pass)) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_COMPLEXITY;
+ ntNewHash = &local_ntNewHash;
+
+ /* Only check complexity if we can convert it at all. Assuming unconvertable passwords are 'strong' */
+ if (convert_string_talloc(mem_ctx, lp_iconv_convenience(ldb_get_opaque(ctx, "loadparm")),
+ CH_UTF16, CH_UNIX,
+ new_password->data, new_password->length,
+ (void **)&new_pass) != -1) {
+
+
+ /* possibly check password complexity */
+ if (restrictions && pwdProperties & DOMAIN_PASSWORD_COMPLEX &&
+ !samdb_password_complexity_ok(new_pass)) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_COMPLEXITY;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
}
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
-
- /* compute the new nt and lm hashes */
- if (E_deshash(new_pass, local_lmNewHash.hash)) {
- lmNewHash = &local_lmNewHash;
- }
- if (!E_md4hash(new_pass, local_ntNewHash.hash)) {
- /* If we can't convert this password to UCS2, then we should not accept it */
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_OTHER;
+
+ /* compute the new lm hashes (for checking history - case insenitivly!) */
+ if (E_deshash(new_pass, local_lmNewHash.hash)) {
+ lmNewHash = &local_lmNewHash;
}
- return NT_STATUS_PASSWORD_RESTRICTION;
+
}
- ntNewHash = &local_ntNewHash;
}
- if (user_change) {
+ if (restrictions && user_change) {
/* are all password changes disallowed? */
if (pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
if (reject_reason) {
@@ -1731,16 +1746,15 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
#define CHECK_RET(x) do { if (x != 0) return NT_STATUS_NO_MEMORY; } while(0)
/* the password is acceptable. Start forming the new fields */
- if (new_pass) {
- /* if we know the cleartext, then only set it.
+ if (new_password) {
+ /* if we know the cleartext UTF16 password, then set it.
* Modules in ldb will set all the appropriate
* hashes */
- CHECK_RET(samdb_msg_add_string(ctx, mem_ctx, mod,
- "userPassword", new_pass));
+ CHECK_RET(ldb_msg_add_value(mod, "clearTextPassword", new_password, NULL));
} else {
/* We don't have the cleartext, so delete the old one
* and set what we have of the hashes */
- CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "userPassword"));
+ CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "clearTextPassword"));
if (lmNewHash) {
CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "dBCSPwd", lmNewHash));
@@ -1769,7 +1783,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
*/
NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
const struct dom_sid *user_sid,
- const char *new_pass,
+ const DATA_BLOB *new_pass,
struct samr_Password *lmNewHash,
struct samr_Password *ntNewHash,
bool user_change,