summaryrefslogtreecommitdiff
path: root/source3/passdb/pdb_get_set.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb/pdb_get_set.c')
-rw-r--r--source3/passdb/pdb_get_set.c141
1 files changed, 78 insertions, 63 deletions
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
index 30775e49fe..d7fc02f807 100644
--- a/source3/passdb/pdb_get_set.c
+++ b/source3/passdb/pdb_get_set.c
@@ -239,8 +239,7 @@ const DOM_SID *pdb_get_group_sid(struct samu *sampass)
/* Just set it to the 'Domain Users' RID of 512 which will
always resolve to a name */
- sid_copy( gsid, get_global_sam_sid() );
- sid_append_rid( gsid, DOMAIN_GROUP_RID_USERS );
+ sid_compose(gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS);
sampass->group_sid = gsid;
@@ -552,8 +551,8 @@ bool pdb_set_group_sid(struct samu *sampass, const DOM_SID *g_sid, enum pdb_valu
if ( sid_to_gid( g_sid, &gid ) ) {
sid_copy(sampass->group_sid, g_sid);
} else {
- sid_copy( sampass->group_sid, get_global_sam_sid() );
- sid_append_rid( sampass->group_sid, DOMAIN_GROUP_RID_USERS );
+ sid_compose(sampass->group_sid, get_global_sam_sid(),
+ DOMAIN_GROUP_RID_USERS);
}
DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
@@ -876,6 +875,7 @@ bool pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], e
bool pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
{
if (historyLen && pwd){
+ data_blob_free(&(sampass->nt_pw_his));
sampass->nt_pw_his = data_blob_talloc(sampass,
pwd, historyLen*PW_HISTORY_ENTRY_LEN);
if (!sampass->nt_pw_his.length) {
@@ -980,6 +980,9 @@ 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;
+ uint32 current_history_len;
if (!plaintext)
return False;
@@ -1009,68 +1012,80 @@ 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, &current_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);
-
- /* 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 {
- 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);
+ if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) {
+ /*
+ * No password history for non-user accounts
+ */
+ return true;
+ }
+
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
+
+ if (pwHistLen == 0) {
+ /* Set the history length to zero. */
+ pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
+ return true;
+ }
+
+ /*
+ * 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, &current_history_len);
+
+ if ((current_history_len != 0) && (pwhistory == NULL)) {
+ DEBUG(1, ("pdb_set_plaintext_passwd: pwhistory == NULL!\n"));
+ return false;
+ }
+
+ if (current_history_len < pwHistLen) {
+ /*
+ * Ensure we have space for the needed history. This
+ * also takes care of an account which did not have
+ * any history at all so far, i.e. pwhistory==NULL
+ */
+ uchar *new_history = talloc_zero_array(
+ sampass, uchar,
+ pwHistLen*PW_HISTORY_ENTRY_LEN);
+
+ if (!new_history) {
+ return False;
}
+
+ memcpy(new_history, pwhistory,
+ current_history_len*PW_HISTORY_ENTRY_LEN);
+
+ pwhistory = new_history;
}
+ /*
+ * 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 );
+ }
+
+ /*
+ * Fill the salt area with 0-s: this indicates that
+ * a plain nt hash is stored in the has area.
+ * The old format was to store a 16 byte salt and
+ * then an md5hash of the nt_hash concatenated with
+ * the salt.
+ */
+ memset(pwhistory, 0, PW_HISTORY_SALT_LEN);
+
+ /*
+ * Store the plain nt hash in the second 16 bytes.
+ * The old format was to store the md5 hash of
+ * the salt+newpw.
+ */
+ memcpy(&pwhistory[PW_HISTORY_SALT_LEN], new_nt_p16, SALTED_MD5_HASH_LEN);
+
+ pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
+
return True;
}