From 79c84bb5487ba9e090acfa83d60066534dc21eb8 Mon Sep 17 00:00:00 2001 From: Alberto Maria Fiaschi Date: Wed, 10 Jun 2015 15:26:58 +0200 Subject: [PATCH] Add --set-nt-hash option to pdbedit to update user password from nt-hash hexstring. Useful to take in sync password from other repository. (Modify MASK_USER_GOOD to include new flag BIT_PWSETNTHASH) pdbedit -vw show also password hashes . Split pdb_set_plaintext_passwd in two function: pdb_set_plaintext_passwd and pdb_update_history. pdb_update_history update password history and is call from pdb_set_plaintext_passwd. Signed-off-by: Alberto Maria Fiaschi --- docs-xml/manpages/pdbedit.8.xml | 20 +++++++++++++-- source3/include/passdb.h | 1 + source3/passdb/pdb_get_set.c | 24 +++++++++++++----- source3/utils/pdbedit.c | 43 ++++++++++++++++++++++++++++++--- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/docs-xml/manpages/pdbedit.8.xml b/docs-xml/manpages/pdbedit.8.xml index 6ed03993d38c..355f0511e716 100644 --- a/docs-xml/manpages/pdbedit.8.xml +++ b/docs-xml/manpages/pdbedit.8.xml @@ -43,6 +43,7 @@ -r -s configfile -S script + --set-nt-hash -t --time-format -u username @@ -99,7 +100,8 @@ samba:45:Test User -v|--verbose This option enables the verbose listing format. It causes pdbedit to list the users in the database, printing - out the account fields in a descriptive format. + out the account fields in a descriptive format. Used together + with -w also shows passwords hashes. Example: pdbedit -L -v @@ -134,7 +136,9 @@ Profile Path: \\BERSERKER\profile out the account fields in a format compatible with the smbpasswd file format. (see the smbpasswd - 5 for details) + 5 for details). + Instead used together with (-v) displays the passwords + hashes in verbose output. Example: pdbedit -L -w @@ -204,6 +208,18 @@ samba:45:0F2B255F7B67A7A9AAD3B435B51404EE: + + --set-nt-hash + This option can be used while modifying + a user account. It will set the user's password using + the nt-hash value given as hexadecimal string. + Useful to synchronize passwords. + + Example: --set-nt-hash 8846F7EAEE8FB117AD06BDD830B7586C + + + + -p|--profile profile This option can be used while adding or diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 893d0d09bf6b..d8f7f1090a5e 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -811,6 +811,7 @@ bool pdb_set_nt_passwd(struct samu *sampass, const uint8_t pwd[NT_HASH_LEN], enu bool pdb_set_lanman_passwd(struct samu *sampass, const uint8_t pwd[LM_HASH_LEN], enum pdb_value_state flag); bool pdb_set_pw_history(struct samu *sampass, const uint8_t *pwd, uint32_t historyLen, enum pdb_value_state flag); bool pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag); +bool pdb_update_history(struct samu *sampass, const uint8_t new_nt[NT_HASH_LEN]); bool pdb_set_bad_password_count(struct samu *sampass, uint16_t bad_password_count, enum pdb_value_state flag); bool pdb_set_logon_count(struct samu *sampass, uint16_t logon_count, enum pdb_value_state flag); bool pdb_set_country_code(struct samu *sampass, uint16_t country_code, diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 9f274594a343..74a71cbf04b3 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -999,10 +999,6 @@ 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_t pwHistLen; - uint32_t current_history_len; - const uint8_t *current_history; if (!plaintext) return False; @@ -1032,6 +1028,21 @@ 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; + + return pdb_update_history(sampass, new_nt_p16); +} + +/********************************************************************* + Update password history after change + ********************************************************************/ + +bool pdb_update_history(struct samu *sampass, const uint8_t new_nt[NT_HASH_LEN]) +{ + uchar *pwhistory; + uint32_t pwHistLen; + uint32_t current_history_len; + const uint8_t *current_history; + if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) { /* * No password history for non-user accounts @@ -1055,7 +1066,7 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext) */ current_history = pdb_get_pw_history(sampass, ¤t_history_len); if ((current_history_len != 0) && (current_history == NULL)) { - DEBUG(1, ("pdb_set_plaintext_passwd: pwhistory == NULL!\n")); + DEBUG(1, ("pdb_update_history: pwhistory == NULL!\n")); return false; } @@ -1096,11 +1107,12 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext) * 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); + memcpy(&pwhistory[PW_HISTORY_SALT_LEN], new_nt, SALTED_MD5_HASH_LEN); pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED); return True; + } /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */ diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 1f44fb0ee4f6..a353bae7c4eb 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -55,9 +55,10 @@ #define BIT_LOGONHOURS 0x10000000 #define BIT_KICKOFFTIME 0x20000000 #define BIT_DESCRIPTION 0x40000000 +#define BIT_PWSETNTHASH 0x80000000 #define MASK_ALWAYS_GOOD 0x0000001F -#define MASK_USER_GOOD 0x60405FE0 +#define MASK_USER_GOOD 0xE0405FE0 static int get_sid_from_cli_string(struct dom_sid *sid, const char *str_sid) { @@ -317,6 +318,12 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst hours = pdb_get_hours(sam_pwent); pdb_sethexhours(temp, hours); printf ("Logon hours : %s\n", temp); + if (smbpwdstyle){ + pdb_sethexpwd(temp, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); + printf ("LM hash : %s\n", temp); + pdb_sethexpwd(temp, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); + printf ("NT hash : %s\n", temp); + } } else if (smbpwdstyle) { char lm_passwd[33]; @@ -499,7 +506,7 @@ static int set_user_info(const char *username, const char *fullname, const char *profile, const char *account_control, const char *user_sid, const char *user_domain, const bool badpw, const bool hours, - const char *kickoff_time) + const char *kickoff_time, const char *str_hex_pwd) { bool updated_autolock = False, updated_badpw = False; struct samu *sam_pwent; @@ -601,9 +608,33 @@ static int set_user_info(const char *username, const char *fullname, pdb_set_kickoff_time(sam_pwent, value, PDB_CHANGED); } + if (str_hex_pwd) { + unsigned char new_nt_p16[NT_HASH_LEN]; + if(strlen(str_hex_pwd) != (NT_HASH_LEN *2)){ + fprintf(stderr, "Invalid hash\n"); + return -1; + } + + pdb_gethexpwd(str_hex_pwd, new_nt_p16); + + if (!pdb_set_nt_passwd (sam_pwent, new_nt_p16 , PDB_CHANGED)) { + fprintf(stderr, "Failed to set password from nt-hash\n"); + return -1; + } + + if (!pdb_set_pass_last_set_time (sam_pwent, time(NULL), PDB_CHANGED)){ + fprintf(stderr, "Failed to set last password set time\n"); + return -1; + } + if (!pdb_update_history(sam_pwent, new_nt_p16)){ + fprintf(stderr, "Failed to update password history\n"); + return -1; + } + } if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) { - print_user_info(username, True, False); + + print_user_info(username, True, (str_hex_pwd != NULL )); } else { fprintf (stderr, "Unable to modify entry!\n"); TALLOC_FREE(sam_pwent); @@ -1021,6 +1052,7 @@ int main(int argc, const char **argv) static int pw_from_stdin = False; struct pdb_methods *bin, *bout; static char *kickoff_time = NULL; + static char *str_hex_pwd = NULL; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; poptContext pc; @@ -1058,6 +1090,7 @@ int main(int argc, const char **argv) {"time-format", 0, POPT_ARG_STRING, &pwd_time_format, 0, "The time format for time parameters", NULL }, {"password-from-stdin", 't', POPT_ARG_NONE, &pw_from_stdin, 0, "get password from standard in", NULL}, {"kickoff-time", 'K', POPT_ARG_STRING, &kickoff_time, 0, "set the kickoff time", NULL}, + {"set-nt-hash", 0, POPT_ARG_STRING, &str_hex_pwd, 0, "set password from nt-hash", NULL}, POPT_COMMON_SAMBA POPT_TABLEEND }; @@ -1118,7 +1151,9 @@ int main(int argc, const char **argv) (badpw_reset ? BIT_BADPWRESET : 0) + (hours_reset ? BIT_LOGONHOURS : 0) + (kickoff_time ? BIT_KICKOFFTIME : 0) + + (str_hex_pwd ? BIT_PWSETNTHASH : 0 ) + (acct_desc ? BIT_DESCRIPTION : 0); + if (setparms & BIT_BACKEND) { /* HACK: set the global passdb backend by overwriting globals. @@ -1315,7 +1350,7 @@ int main(int argc, const char **argv) profile_path, account_control, user_sid, user_domain, badpw_reset, hours_reset, - kickoff_time); + kickoff_time, str_hex_pwd); } } }