1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-27 14:04:05 +03:00

r625: - handle passwords longer than length 14 (thanks to abartlet for pointing out the bug)

- delete unicodePwd if not storing a plaintext password
(This used to be commit 6c3f22a685c55f183f4e0e4303e3d9990f4b39b5)
This commit is contained in:
Andrew Tridgell 2004-05-10 12:05:54 +00:00 committed by Gerald (Jerry) Carter
parent 7dc054acaf
commit 5afbecdc2e
2 changed files with 82 additions and 44 deletions

View File

@ -488,7 +488,7 @@ static NTSTATUS samr_CreateDomainGroup(struct dcesrv_call_state *dce_call, TALLO
ret = samdb_copy_template(d_state->sam_ctx, mem_ctx, &msg,
"(&(name=TemplateGroup)(objectclass=groupTemplate))");
if (ret != 0) {
DEBUG(1,("Failed to load TemplateUser from samdb\n"));
DEBUG(1,("Failed to load TemplateGroup from samdb\n"));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@ -1771,9 +1771,12 @@ static NTSTATUS samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX
return status;
}
/* mark all the message elements as LDB_FLAG_MOD_REPLACE */
/* mark all the message elements as LDB_FLAG_MOD_REPLACE,
unless they are already marked with some other flag */
for (i=0;i<mod.num_elements;i++) {
mod.elements[i].flags = LDB_FLAG_MOD_REPLACE;
if (mod.elements[i].flags == 0) {
mod.elements[i].flags = LDB_FLAG_MOD_REPLACE;
}
}
/* modify the samdb record */

View File

@ -499,7 +499,8 @@ int samdb_copy_template(void *ctx, TALLOC_CTX *mem_ctx,
}
for (j=0;j<el->num_values;j++) {
if (strcasecmp(el->name, "objectClass") == 0 &&
(strcasecmp((char *)el->values[j].data, "userTemplate") == 0 ||
(strcasecmp((char *)el->values[j].data, "Template") == 0 ||
strcasecmp((char *)el->values[j].data, "userTemplate") == 0 ||
strcasecmp((char *)el->values[j].data, "groupTemplate") == 0)) {
continue;
}
@ -626,6 +627,21 @@ int samdb_msg_add_string(void *ctx, TALLOC_CTX *mem_ctx, struct ldb_message *msg
return ldb_msg_add_string(sam_ctx->ldb, msg, a, s);
}
/*
add a delete element operation to a message
*/
int samdb_msg_add_delete(void *ctx, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
const char *attr_name)
{
struct samdb_context *sam_ctx = ctx;
char *a = talloc_strdup(mem_ctx, attr_name);
if (a == NULL) {
return -1;
}
ldb_set_alloc(sam_ctx->ldb, samdb_alloc, mem_ctx);
return ldb_msg_add_empty(sam_ctx->ldb, msg, a, LDB_FLAG_MOD_DELETE);
}
/*
add a uint_t element to a message
*/
@ -815,6 +831,7 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx,
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);
@ -873,14 +890,17 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx,
}
/* compute the new nt and lm hashes */
E_deshash(new_pass, lmNewHash.hash);
lm_hash_ok = E_deshash(new_pass, lmNewHash.hash);
E_md4hash(new_pass, ntNewHash.hash);
/* check the immediately past password */
if (pwdHistoryLength > 0 &&
(memcmp(lmNewHash.hash, lmPwdHash.hash, 16) == 0 ||
memcmp(ntNewHash.hash, ntPwdHash.hash, 16) == 0)) {
return NT_STATUS_PASSWORD_RESTRICTION;
if (pwdHistoryLength > 0) {
if (lm_hash_ok && memcmp(lmNewHash.hash, lmPwdHash.hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
if (memcmp(ntNewHash.hash, ntPwdHash.hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
}
/* check the password history */
@ -888,14 +908,18 @@ NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx,
ntPwdHistory_len = MIN(ntPwdHistory_len, pwdHistoryLength);
if (pwdHistoryLength > 0) {
if (strcmp(unicodePwd, new_pass) == 0 ||
memcmp(lmNewHash.hash, lmPwdHash.hash, 16) == 0 ||
memcmp(ntNewHash.hash, ntPwdHash.hash, 16) == 0) {
if (unicodePwd && strcmp(unicodePwd, new_pass) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
if (lm_hash_ok && memcmp(lmNewHash.hash, lmPwdHash.hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
if (memcmp(ntNewHash.hash, ntPwdHash.hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
}
for (i=0;i<lmPwdHistory_len;i++) {
for (i=0;lm_hash_ok && i<lmPwdHistory_len;i++) {
if (memcmp(lmNewHash.hash, lmPwdHistory[i].hash, 16) == 0) {
return NT_STATUS_PASSWORD_RESTRICTION;
}
@ -909,46 +933,57 @@ NTSTATUS samdb_set_password(void *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 */
CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "lmPwdHash", lmNewHash));
if (lm_hash_ok) {
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) &&
(userAccountControl & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
CHECK_RET(samdb_msg_add_string(ctx, mem_ctx, mod,
"unicodePwd", new_pass));
}
if (pwdHistoryLength > 0) {
new_lmPwdHistory = talloc_array_p(mem_ctx, struct samr_Hash,
pwdHistoryLength);
if (!new_lmPwdHistory) {
return NT_STATUS_NO_MEMORY;
}
new_ntPwdHistory = talloc_array_p(mem_ctx, struct samr_Hash,
pwdHistoryLength);
if (!new_ntPwdHistory) {
return NT_STATUS_NO_MEMORY;
}
for (i=0;i<MIN(pwdHistoryLength-1, lmPwdHistory_len);i++) {
new_lmPwdHistory[i+1] = lmPwdHistory[i];
}
for (i=0;i<MIN(pwdHistoryLength-1, ntPwdHistory_len);i++) {
new_ntPwdHistory[i+1] = ntPwdHistory[i];
}
new_lmPwdHistory[0] = lmNewHash;
new_ntPwdHistory[0] = ntNewHash;
CHECK_RET(samdb_msg_add_hashes(ctx, mem_ctx, mod,
"lmPwdHistory",
new_lmPwdHistory,
MIN(pwdHistoryLength, lmPwdHistory_len+1)));
CHECK_RET(samdb_msg_add_hashes(ctx, mem_ctx, mod,
"ntPwdHistory",
new_ntPwdHistory,
MIN(pwdHistoryLength, ntPwdHistory_len+1)));
} else {
CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "unicodePwd"));
}
CHECK_RET(samdb_msg_add_double(ctx, mem_ctx, mod, "pwdLastSet", now_double));
if (pwdHistoryLength == 0) {
CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "lmPwdHistory"));
CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "ntPwdHistory"));
return NT_STATUS_OK;
}
/* store the password history */
new_lmPwdHistory = talloc_array_p(mem_ctx, struct samr_Hash,
pwdHistoryLength);
if (!new_lmPwdHistory) {
return NT_STATUS_NO_MEMORY;
}
new_ntPwdHistory = talloc_array_p(mem_ctx, struct samr_Hash,
pwdHistoryLength);
if (!new_ntPwdHistory) {
return NT_STATUS_NO_MEMORY;
}
for (i=0;i<MIN(pwdHistoryLength-1, lmPwdHistory_len);i++) {
new_lmPwdHistory[i+1] = lmPwdHistory[i];
}
for (i=0;i<MIN(pwdHistoryLength-1, ntPwdHistory_len);i++) {
new_ntPwdHistory[i+1] = ntPwdHistory[i];
}
new_lmPwdHistory[0] = lmNewHash;
new_ntPwdHistory[0] = ntNewHash;
CHECK_RET(samdb_msg_add_hashes(ctx, mem_ctx, mod,
"lmPwdHistory",
new_lmPwdHistory,
MIN(pwdHistoryLength, lmPwdHistory_len+1)));
CHECK_RET(samdb_msg_add_hashes(ctx, mem_ctx, mod,
"ntPwdHistory",
new_ntPwdHistory,
MIN(pwdHistoryLength, ntPwdHistory_len+1)));
return NT_STATUS_OK;
}