From 5bc05dd07c20c6b1f6d537c478d6b33bfae71ce7 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 15 Mar 2000 02:08:59 +0000 Subject: 1) SAM_USER_INFO_12 what i thought was acb_info isn't. this may be responsible for some of the password set failure problems: treating the wrong field as an acb_info would result in rejection of password sets. 2) in attempting to track down server-password-set problems i noticed that the "security = domain" mode sets the password incorrectly. --- source/include/proto.h | 1 + source/include/rpc_parse_proto.h | 1 - source/include/rpc_samr.h | 3 +- source/include/winbindd_proto.h | 1 - source/lsarpcd/lsarpcd.c | 17 +++-- source/netlogond/srv_netlogon_nt.c | 41 ---------- source/rpc_client/msrpc_lsarpc.c | 31 +++++--- source/rpc_parse/parse_samr.c | 11 +-- source/rpcclient/cmd_netlogon.c | 148 ++++++++++++++++++++++++++++--------- source/rpcclient/cmd_samr.c | 3 +- source/samrd/srv_samr_passdb.c | 3 +- 11 files changed, 156 insertions(+), 104 deletions(-) diff --git a/source/include/proto.h b/source/include/proto.h index 148532a218f..53eab2ab515 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -2583,6 +2583,7 @@ void cmd_lsa_query_secret(struct client_info *info, int argc, char *argv[]); /*The following definitions come from rpcclient/cmd_netlogon.c */ +void cmd_netlogon_pwset(struct client_info *info, int argc, char *argv[]); void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]); void cmd_netlogon_domain_test(struct client_info *info, int argc, char *argv[]); diff --git a/source/include/rpc_parse_proto.h b/source/include/rpc_parse_proto.h index 39de05474d1..1e4080bf322 100644 --- a/source/include/rpc_parse_proto.h +++ b/source/include/rpc_parse_proto.h @@ -717,7 +717,6 @@ BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO * q_u, BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO * q_u, prs_struct * ps, int depth); BOOL make_sam_user_info12(SAM_USER_INFO_12 * usr, - uint16 acb_info, const uint8 lm_pwd[16], const uint8 nt_pwd[16]); BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 * u, prs_struct * ps, int depth); diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h index 68e0e85e462..724ff27a6e7 100644 --- a/source/include/rpc_samr.h +++ b/source/include/rpc_samr.h @@ -286,7 +286,8 @@ typedef struct sam_user_info_12 uint8 lm_pwd[16]; /* lm user passwords */ uint8 nt_pwd[16]; /* nt user passwords */ - uint16 acb_info; /* account control bits */ + uint8 lm_pwd_active; + uint8 nt_pwd_active; } SAM_USER_INFO_12; diff --git a/source/include/winbindd_proto.h b/source/include/winbindd_proto.h index 6407a73c4d3..caff219d189 100644 --- a/source/include/winbindd_proto.h +++ b/source/include/winbindd_proto.h @@ -2451,7 +2451,6 @@ BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO * q_u, BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO * q_u, prs_struct * ps, int depth); BOOL make_sam_user_info12(SAM_USER_INFO_12 * usr, - uint16 acb_info, const uint8 lm_pwd[16], const uint8 nt_pwd[16]); BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 * u, prs_struct * ps, int depth); diff --git a/source/lsarpcd/lsarpcd.c b/source/lsarpcd/lsarpcd.c index e53bc9ff8be..db543f550dc 100644 --- a/source/lsarpcd/lsarpcd.c +++ b/source/lsarpcd/lsarpcd.c @@ -148,23 +148,26 @@ static void update_trust_account(void) if (trust_pwd_needs_changing) { + unsigned char trust_passwd[16]; unsigned char trust_passwd_hash[16]; fstring srv_name; BOOL res2; res2 = get_any_dc_name(global_myworkgroup, srv_name); - generate_random_buffer(trust_passwd_hash, 16, True); - secret_store_data(&secret, trust_passwd_hash, 16); + generate_random_buffer(trust_passwd, 16, True); + secret_store_data(&secret, trust_passwd, 16); - res2 = - res2 ? nt_encrypt_string2(&encsec, &secret, - user_sess_key) : False; + res2 = res2 ? secret_to_nt_owf(trust_passwd_hash, &secret) : + False; + + res2 = res2 ? nt_encrypt_string2(&encsec, &secret, + user_sess_key) : False; if (!strequal("\\\\.", srv_name)) { - res2 = - res2 ? + + res2 = res2 ? modify_trust_password(global_myworkgroup, srv_name, old_trust, trust_passwd_hash, diff --git a/source/netlogond/srv_netlogon_nt.c b/source/netlogond/srv_netlogon_nt.c index aaeff700380..1264a1d2f95 100644 --- a/source/netlogond/srv_netlogon_nt.c +++ b/source/netlogond/srv_netlogon_nt.c @@ -711,7 +711,6 @@ uint32 _net_srv_pwset(const DOM_CLNT_INFO * clnt_id, struct dcinfo dc; const UNISTR2 *uni_samusr; SAM_USERINFO_CTR ctr; - uint16 acb_info; ZERO_STRUCT(dc); @@ -751,46 +750,6 @@ uint32 _net_srv_pwset(const DOM_CLNT_INFO * clnt_id, return status_pwd; } - acb_info = ctr.info.id12->acb_info; - - if (IS_BITS_SET_SOME - (acb_info, ACB_NORMAL | ACB_DISABLED | ACB_PWNOTREQ)) - { - return NT_STATUS_ACCESS_DENIED; - } - - switch (clnt_id->login.sec_chan) - { - case SEC_CHAN_DOMAIN: - { - if (!IS_BITS_SET_ALL(acb_info, ACB_DOMTRUST)) - { - return NT_STATUS_ACCESS_DENIED; - } - break; - } - case SEC_CHAN_BDC: - { - if (!IS_BITS_SET_ALL(acb_info, ACB_SVRTRUST)) - { - return NT_STATUS_ACCESS_DENIED; - } - break; - } - case SEC_CHAN_WKSTA: - { - if (!IS_BITS_SET_ALL(acb_info, ACB_WSTRUST)) - { - return NT_STATUS_ACCESS_DENIED; - } - break; - } - default: - { - return NT_STATUS_ACCESS_DENIED; - } - } - /* Some debug output, needed an iterater variable */ { int i; diff --git a/source/rpc_client/msrpc_lsarpc.c b/source/rpc_client/msrpc_lsarpc.c index 2ee84569ed8..38cdd219add 100644 --- a/source/rpc_client/msrpc_lsarpc.c +++ b/source/rpc_client/msrpc_lsarpc.c @@ -339,23 +339,14 @@ BOOL secret_get_data(const STRING2 *secret, uchar *data, uint32 *len) /**************************************************************************** obtains a trust account password ****************************************************************************/ -BOOL msrpc_lsa_query_trust_passwd(const char *srv_name, - const char *secret_name, - uchar trust_passwd[16], - NTTIME * last_update) +BOOL secret_to_nt_owf(uchar trust_passwd[16], const STRING2 *secret) { - STRING2 secret; UNISTR2 uni_pwd; uint32 len; pstring data; int i; - if (!msrpc_lsa_query_secret(srv_name, secret_name, &secret, - last_update)) - { - return False; - } - if (!secret_get_data(&secret, data, &len)) + if (!secret_get_data(secret, data, &len)) { return False; } @@ -369,3 +360,21 @@ BOOL msrpc_lsa_query_trust_passwd(const char *srv_name, return True; } + +/**************************************************************************** +obtains a trust account password +****************************************************************************/ +BOOL msrpc_lsa_query_trust_passwd(const char *srv_name, + const char *secret_name, + uchar trust_passwd[16], + NTTIME * last_update) +{ + STRING2 secret; + + if (!msrpc_lsa_query_secret(srv_name, secret_name, &secret, + last_update)) + { + return False; + } + return secret_to_nt_owf(trust_passwd, &secret); +} diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c index f4687c8c333..c3a6456fee1 100644 --- a/source/rpc_parse/parse_samr.c +++ b/source/rpc_parse/parse_samr.c @@ -4944,7 +4944,6 @@ static BOOL sam_io_logon_hrs(char *desc, LOGON_HRS * hrs, prs_struct * ps, makes a SAM_USER_INFO_12 structure. ********************************************************************/ BOOL make_sam_user_info12(SAM_USER_INFO_12 * usr, - uint16 acb_info, const uint8 lm_pwd[16], const uint8 nt_pwd[16]) { if (usr == NULL) @@ -4952,24 +4951,26 @@ BOOL make_sam_user_info12(SAM_USER_INFO_12 * usr, DEBUG(5, ("make_sam_user_info12\n")); - usr->acb_info = acb_info; - if (lm_pwd == NULL) { bzero(usr->lm_pwd, sizeof(usr->lm_pwd)); + usr->lm_pwd_active = 0; } else { memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd)); + usr->lm_pwd_active = 1; } if (nt_pwd == NULL) { bzero(usr->nt_pwd, sizeof(usr->nt_pwd)); + usr->nt_pwd_active = 0; } else { memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd)); + usr->nt_pwd_active = 1; } return True; @@ -4994,7 +4995,8 @@ BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 * u, prs_struct * ps, prs_uint8s(False, "lm_pwd", ps, depth, u->lm_pwd, sizeof(u->lm_pwd)); prs_uint8s(False, "nt_pwd", ps, depth, u->nt_pwd, sizeof(u->nt_pwd)); - prs_uint16("acb_info", ps, depth, &u->acb_info); + prs_uint8("lm_pwd_active", ps, depth, &u->lm_pwd_active); + prs_uint8("nt_pwd_active", ps, depth, &u->nt_pwd_active); prs_align(ps); return True; @@ -5868,7 +5870,6 @@ uint32 make_samr_userinfo_ctr_usr21(SAM_USERINFO_CTR * ctr, return NT_STATUS_NO_MEMORY; } make_sam_user_info12(ctr->info.id12, - usr->acb_info, usr->lm_pwd, usr->nt_pwd); break; } diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c index 7a3972bbab5..49eaa7509db 100644 --- a/source/rpcclient/cmd_netlogon.c +++ b/source/rpcclient/cmd_netlogon.c @@ -43,13 +43,29 @@ experimental nt login trust account change. ****************************************************************************/ void cmd_netlogon_pwset(struct client_info *info, int argc, char *argv[]) { - BOOL res = True; - char *nt_password; - uchar trust_passwd[16]; - uchar nt_pw[16]; - uchar lm_pw[16]; - fstring trust_acct; fstring domain; + fstring acct_name; + fstring name; + fstring sid; + DOM_SID sid1; + uint32 user_rid; + int opt; + char *password = NULL; + pstring upwb; + int plen = 0; + int len = 0; + UNISTR2 upw; + uchar ntpw[16]; + STRING2 secret; + + BOOL res = True; + POLICY_HND lsa_pol; + + POLICY_HND pol_sec; + BOOL res1; + uint32 res2; + + uchar old_trust_passwd[16]; char *p; uint16 validation_level; @@ -86,50 +102,114 @@ void cmd_netlogon_pwset(struct client_info *info, int argc, char *argv[]) argc--; argv++; - if (domain[0] == 0) { report(out_hnd, "no domain specified.\n"); } - nt_owf_genW(nt_password, nt_pw, lm_pw); - DEBUG(5, ("do_nt_login_test: username %s from: %s\n", nt_user_name, info->myhostname)); - fstrcpy(trust_acct, info->myhostname); - fstrcat(trust_acct, "$"); - res = res ? msrpc_lsa_query_trust_passwd(wks_name, "$MACHINE.ACC", - trust_passwd, NULL) : False; + old_trust_passwd, NULL) : False; - res = res ? cli_nt_setup_creds(srv_name, domain, info->myhostname, - trust_acct, - trust_passwd, - SEC_CHAN_WKSTA, - &validation_level) == 0x0 : False; + safe_strcpy(acct_name, argv[0], sizeof(acct_name)); + len = strlen(acct_name)-1; + if (acct_name[len] == '$') + { + safe_strcpy(name, argv[0], sizeof(name)); + name[len] = 0; + } + /* + * generate new random password. unicode string is stored + * in secret $MACHINE.ACC; nt owf is sent in net_srv_pwset. + */ + + upw.uni_str_len = 0xc; + upw.uni_max_len = 0xc; + password = (char*)upw.buffer; + plen = upw.uni_str_len * 2; + generate_random_buffer(password, plen, True); + + nt_owf_genW(&upw, ntpw); + + /* + * ok. this looks really weird, but if you don't open + * the connection to the workstation first, then the + * set trust account on the SAM database may get the + * local copy-of trust account out-of-sync with the + * remote one, and you're stuffed! + */ + res = lsa_open_policy( wks_name, &lsa_pol, True, 0x02000000); + + if (!res) + { + report(out_hnd, "Connection to %s FAILED\n", wks_name); + report(out_hnd, "(Do a \"use \\\\%s -U localadmin\")\n", + wks_name); - memset(trust_passwd, 0, 16); + return; + } + res1 = lsa_open_secret( &lsa_pol, "$MACHINE.ACC", 0x020003, &pol_sec); - /* do an NT login */ - res = res ? (cli_nt_login_interactive(srv_name, info->myhostname, - domain, nt_user_name, - getuid(), lm_pw, nt_pw, - &info->dom.ctr, - validation_level, - &info->dom.user_info3) == - 0x0) : False; + if (!res1) + { + lsa_close(&lsa_pol); + report(out_hnd, "Open Secret failed\n"); + return; + } + if (!lsa_query_secret(&pol_sec, &secret, NULL) || + !secret_to_nt_owf(&old_trust_passwd, &secret)) + { + lsa_close(&lsa_pol); + lsa_close(&pol_sec); + report(out_hnd, "Query local Trust Account password: Failed\n"); + return; + } + + if (net_srv_pwset(srv_name, &sid1, + acct_name, , password, plen, + &user_rid) != NT_STATUS_NOPROBLEMO) + { + lsa_close(&lsa_pol); + lsa_close(&pol_sec); + report(out_hnd, "Set remote Trust Account password: Failed\n"); + return; + } -#if 0 - /* ok! you're logged in! do anything you like, then... */ + report(out_hnd, "Set remote Trust Account password: OK\n"); + + strupper(domain); + strupper(name); + + /* valid pol_sec on $MACHINE.ACC, set trust passwd */ + secret_store_data(&secret, password, plen); + + res2 = lsa_set_secret(&pol_sec, &secret); + + if (res2 == NT_STATUS_NOPROBLEMO) + { + report(out_hnd, "Set $MACHINE.ACC: OK\n"); + } + else + { + report(out_hnd, "Set $MACHINE.ACC: FAILED\n"); + } + + res1 = res1 ? lsa_close(&pol_sec) : False; + res = res ? lsa_close(&lsa_pol) : False; + + memset(&upw, 0, sizeof(upw)); + memset(ntpw, 0, sizeof(ntpw)); +} + res = res ? cli_nt_setup_creds(srv_name, domain, info->myhostname, + trust_acct, + old_trust_passwd, + SEC_CHAN_WKSTA, + &validation_level) == 0x0 : False; - /* do an NT logout */ - res = - res ? cli_nt_logoff(srv_name, info->myhostname, - &info->dom.ctr) : False; -#endif report(out_hnd, "cmd_nt_login: login (%s) test succeeded: %s\n", nt_user_name, BOOLSTR(res)); diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c index bcbed57b333..41f8717cfcb 100644 --- a/source/rpcclient/cmd_samr.c +++ b/source/rpcclient/cmd_samr.c @@ -2500,7 +2500,8 @@ void cmd_sam_set_userinfo2(struct client_info *info, int argc, char *argv[]) if (usr != NULL) { nt_lm_owf_gen(password, p->nt_pwd, p->lm_pwd); - p->acb_info = 0x101; + p->lm_pwd_active = 1; + p->nt_pwd_active = 1; res1 = set_samr_set_userinfo2( &pol_dom, switch_value, rids[0], usr); } diff --git a/source/samrd/srv_samr_passdb.c b/source/samrd/srv_samr_passdb.c index 7dae052ba8e..c855dba9b07 100644 --- a/source/samrd/srv_samr_passdb.c +++ b/source/samrd/srv_samr_passdb.c @@ -1709,8 +1709,7 @@ static BOOL get_user_info_12(SAM_USER_INFO_12 *id12, uint32 user_rid) return False; } - make_sam_user_info12(id12, sam_pass->acct_ctrl, - sam_pass->smb_passwd, + make_sam_user_info12(id12, sam_pass->smb_passwd, sam_pass->smb_nt_passwd); return True; -- cgit