summaryrefslogtreecommitdiff
path: root/source4/rpc_server/samr
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2004-05-16 21:30:48 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:53:48 -0500
commit92dd542aa01f2c3b64ca104696c731919f4d7ec7 (patch)
tree1a1e2489c32f2b8c6b4eec31a7f8dc019ebda2ed /source4/rpc_server/samr
parent8b84f643bd50c83230b723eb35b0edafe5670fca (diff)
downloadsamba-92dd542aa01f2c3b64ca104696c731919f4d7ec7.tar.gz
samba-92dd542aa01f2c3b64ca104696c731919f4d7ec7.tar.bz2
samba-92dd542aa01f2c3b64ca104696c731919f4d7ec7.zip
r754: Implement the SetPassword operation on the netlogon pipe.
This involves allowing the password set code in samdb to take an already hashed password, and some fixes to our torture code. Andrew Bartlett (This used to be commit f9f581b5804a20785df06cde157b23c952edc2ce)
Diffstat (limited to 'source4/rpc_server/samr')
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c4
-rw-r--r--source4/rpc_server/samr/samdb.c102
2 files changed, 67 insertions, 39 deletions
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 847b30e71c..62be2cd262 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -1687,7 +1687,9 @@ static NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
so the domain password policy can be used */
return samdb_set_password(a_state->sam_ctx, mem_ctx,
a_state->account_dn, a_state->domain_state->domain_dn,
- msg, new_pass, False /* This is a password set, not change */);
+ msg, new_pass,
+ NULL, NULL,
+ False /* This is a password set, not change */);
}
/*
diff --git a/source4/rpc_server/samr/samdb.c b/source4/rpc_server/samr/samdb.c
index 2489dae684..76de26222d 100644
--- a/source4/rpc_server/samr/samdb.c
+++ b/source4/rpc_server/samr/samdb.c
@@ -840,9 +840,12 @@ static BOOL samdb_password_complexity_ok(const char *pass)
password restrictions
*/
NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx,
- const char *user_dn, const char *domain_dn,
- struct ldb_message *mod, const char *new_pass,
- BOOL user_change)
+ const char *user_dn, const char *domain_dn,
+ struct ldb_message *mod,
+ const char *new_pass,
+ struct samr_Hash *lmNewHash,
+ struct samr_Hash *ntNewHash,
+ BOOL user_change)
{
const char * const user_attrs[] = { "userAccountControl", "lmPwdHistory",
"ntPwdHistory", "unicodePwd",
@@ -857,15 +860,14 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx,
uint_t userAccountControl, badPwdCount;
struct samr_Hash *lmPwdHistory, *ntPwdHistory, lmPwdHash, ntPwdHash;
struct samr_Hash *new_lmPwdHistory, *new_ntPwdHistory;
- struct samr_Hash lmNewHash, ntNewHash;
- uint_t lmPwdHistory_len, ntPwdHistory_len;
+ struct samr_Hash local_lmNewHash, local_ntNewHash;
+ int lmPwdHistory_len, ntPwdHistory_len;
struct ldb_message **res;
int count;
time_t now = time(NULL);
NTTIME now_nt;
double now_double;
int i;
- BOOL lm_hash_ok;
/* we need to know the time to compute password age */
unix_to_nt_time(&now_nt, now);
@@ -897,9 +899,25 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx,
minPwdLength = samdb_result_uint(res[0], "minPwdLength", 0);
minPwdAge = samdb_result_double(res[0], "minPwdAge", 0);
- /* compute the new nt and lm hashes */
- lm_hash_ok = E_deshash(new_pass, lmNewHash.hash);
- E_md4hash(new_pass, ntNewHash.hash);
+ if (new_pass) {
+ /* check the various password restrictions */
+ if (minPwdLength > str_charnum(new_pass)) {
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+
+ /* possibly check password complexity */
+ if (pwdProperties & DOMAIN_PASSWORD_COMPLEX &&
+ !samdb_password_complexity_ok(new_pass)) {
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+
+ /* compute the new nt and lm hashes */
+ if (E_deshash(new_pass, local_lmNewHash.hash)) {
+ lmNewHash = &local_lmNewHash;
+ }
+ E_md4hash(new_pass, local_ntNewHash.hash);
+ ntNewHash = &local_ntNewHash;
+ }
if (user_change) {
/* are all password changes disallowed? */
@@ -919,10 +937,10 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx,
/* check the immediately past password */
if (pwdHistoryLength > 0) {
- if (lm_hash_ok && memcmp(lmNewHash.hash, lmPwdHash.hash, 16) == 0) {
+ if (lmNewHash && memcmp(lmNewHash->hash, lmPwdHash.hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
- if (memcmp(ntNewHash.hash, ntPwdHash.hash, 16) == 0) {
+ if (ntNewHash && memcmp(ntNewHash->hash, ntPwdHash.hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
}
@@ -932,51 +950,45 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx,
ntPwdHistory_len = MIN(ntPwdHistory_len, pwdHistoryLength);
if (pwdHistoryLength > 0) {
- if (unicodePwd && strcmp(unicodePwd, new_pass) == 0) {
+ if (unicodePwd && new_pass && strcmp(unicodePwd, new_pass) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
- if (lm_hash_ok && memcmp(lmNewHash.hash, lmPwdHash.hash, 16) == 0) {
+ if (lmNewHash && memcmp(lmNewHash->hash, lmPwdHash.hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
- if (memcmp(ntNewHash.hash, ntPwdHash.hash, 16) == 0) {
+ if (ntNewHash && memcmp(ntNewHash->hash, ntPwdHash.hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
}
- for (i=0;lm_hash_ok && i<lmPwdHistory_len;i++) {
- if (memcmp(lmNewHash.hash, lmPwdHistory[i].hash, 16) == 0) {
+ for (i=0; lmNewHash && i<lmPwdHistory_len;i++) {
+ if (memcmp(lmNewHash->hash, lmPwdHistory[i].hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
}
- for (i=0;i<ntPwdHistory_len;i++) {
- if (memcmp(ntNewHash.hash, ntPwdHistory[i].hash, 16) == 0) {
+ for (i=0; ntNewHash && i<ntPwdHistory_len;i++) {
+ if (memcmp(ntNewHash->hash, ntPwdHistory[i].hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
}
}
- /* check the various password restrictions */
- if (minPwdLength > str_charnum(new_pass)) {
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
-
- /* possibly check password complexity */
- if (pwdProperties & DOMAIN_PASSWORD_COMPLEX &&
- !samdb_password_complexity_ok(new_pass)) {
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
-
#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 (lm_hash_ok) {
- CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "lmPwdHash", lmNewHash));
+ if (lmNewHash) {
+ CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "lmPwdHash", *lmNewHash));
} else {
CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "lmPwdHash"));
}
- CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "ntPwdHash", ntNewHash));
- if ((pwdProperties & DOMAIN_PASSWORD_STORE_CLEARTEXT) &&
+ if (ntNewHash) {
+ CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "ntPwdHash", *ntNewHash));
+ } else {
+ CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "ntPwdHash"));
+ }
+
+ if (new_pass && (pwdProperties & DOMAIN_PASSWORD_STORE_CLEARTEXT) &&
(userAccountControl & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
CHECK_RET(samdb_msg_add_string(ctx, mem_ctx, mod,
"unicodePwd", new_pass));
@@ -1009,17 +1021,31 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx,
for (i=0;i<MIN(pwdHistoryLength-1, ntPwdHistory_len);i++) {
new_ntPwdHistory[i+1] = ntPwdHistory[i];
}
- new_lmPwdHistory[0] = lmNewHash;
- new_ntPwdHistory[0] = ntNewHash;
+
+ /* Don't store 'long' passwords in the LM history,
+ but make sure to 'expire' one password off the other end */
+ if (lmNewHash) {
+ new_lmPwdHistory[0] = *lmNewHash;
+ } else {
+ ZERO_STRUCT(new_lmPwdHistory[0]);
+ }
+ lmPwdHistory_len = MIN(lmPwdHistory_len + 1, pwdHistoryLength);
+
+ if (ntNewHash) {
+ new_ntPwdHistory[0] = *ntNewHash;
+ } else {
+ ZERO_STRUCT(new_ntPwdHistory[0]);
+ }
+ ntPwdHistory_len = MIN(ntPwdHistory_len + 1, pwdHistoryLength);
CHECK_RET(samdb_msg_add_hashes(ctx, mem_ctx, mod,
"lmPwdHistory",
new_lmPwdHistory,
- MIN(pwdHistoryLength, lmPwdHistory_len+1)));
+ lmPwdHistory_len));
+
CHECK_RET(samdb_msg_add_hashes(ctx, mem_ctx, mod,
"ntPwdHistory",
new_ntPwdHistory,
- MIN(pwdHistoryLength, ntPwdHistory_len+1)));
-
+ ntPwdHistory_len));
return NT_STATUS_OK;
}