diff options
-rw-r--r-- | source3/passdb/pdb_get_set.c | 139 |
1 files changed, 83 insertions, 56 deletions
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index da65440b06..4c240763dc 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -981,6 +981,8 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext) { uchar new_lanman_p16[LM_HASH_LEN]; uchar new_nt_p16[NT_HASH_LEN]; + uchar *pwhistory; + uint32 pwHistLen; if (!plaintext) return False; @@ -1010,68 +1012,93 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext) if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED)) return False; - /* Store the password history. */ - if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) { - uchar *pwhistory; - uint32 pwHistLen; - pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); - if (pwHistLen != 0){ - uint32 current_history_len; - /* We need to make sure we don't have a race condition here - the - account policy history length can change between when the pw_history - was first loaded into the struct samu struct and now.... JRA. */ - pwhistory = (uchar *)pdb_get_pw_history(sampass, ¤t_history_len); - - if (current_history_len != pwHistLen) { - /* After closing and reopening struct samu the history - values will sync up. We can't do this here. */ - - /* current_history_len > pwHistLen is not a problem - we - have more history than we need. */ - - if (current_history_len < pwHistLen) { - /* Ensure we have space for the needed history. */ - uchar *new_history = (uchar *)TALLOC(sampass, - pwHistLen*PW_HISTORY_ENTRY_LEN); - if (!new_history) { - return False; - } - - /* And copy it into the new buffer. */ - if (current_history_len) { - memcpy(new_history, pwhistory, - current_history_len*PW_HISTORY_ENTRY_LEN); - } - /* Clearing out any extra space. */ - memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN], - '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN); - /* Finally replace it. */ - pwhistory = new_history; - } - } - if (pwhistory && pwHistLen){ - /* Make room for the new password in the history list. */ - if (pwHistLen > 1) { - memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], - pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN ); - } - /* Create the new salt as the first part of the history entry. */ - generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN); + if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) { + /* + * No password history for non-user accounts + */ + return true; + } - /* Generate the md5 hash of the salt+new password as the second - part of the history entry. */ + pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); + if (pwHistLen != 0){ + uint32 current_history_len; + /* + * We need to make sure we don't have a race condition + * here - the account policy history length can change + * between when the pw_history was first loaded into + * the struct samu struct and now.... JRA. + */ + pwhistory = (uchar *)pdb_get_pw_history(sampass, + ¤t_history_len); + + if (current_history_len != pwHistLen) { + /* + * After closing and reopening struct samu the history + * values will sync up. We can't do this here. + */ + + /* + * current_history_len > pwHistLen is not a + * problem - we have more history than we + * need. + */ + + if (current_history_len < pwHistLen) { + /* + * Ensure we have space for the needed history. + */ + uchar *new_history = (uchar *)TALLOC( + sampass, + pwHistLen*PW_HISTORY_ENTRY_LEN); + if (!new_history) { + return False; + } - E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]); - pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED); - } else { - DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n")); + /* And copy it into the new buffer. */ + if (current_history_len) { + memcpy(new_history, pwhistory, + current_history_len*PW_HISTORY_ENTRY_LEN); + } + /* Clearing out any extra space. */ + memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN], + '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN); + /* Finally replace it. */ + pwhistory = new_history; + } + } + if (pwhistory && pwHistLen){ + /* + * Make room for the new password in the + * history list. + */ + if (pwHistLen > 1) { + memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], + pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN ); } + /* + * Create the new salt as the first part of + * the history entry. + */ + generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN); + + /* + * Generate the md5 hash of the salt+new + * password as the second part of the history + * entry. + */ + + E_md5hash(pwhistory, new_nt_p16, + &pwhistory[PW_HISTORY_SALT_LEN]); + pdb_set_pw_history(sampass, pwhistory, pwHistLen, + PDB_CHANGED); } else { - /* Set the history length to zero. */ - pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED); + DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: " + "pwhistory was NULL!\n")); } + } else { + /* Set the history length to zero. */ + pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED); } - return True; } |