From c404bb775414139a4b07a73f79cf069a083acb26 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 15 Oct 1998 23:51:07 +0000 Subject: rpcclient interactive login (with trust account changing if you are root) cli_session_setup handles null sessions correctly (This used to be commit 60c0f22a4e84703467006dfe1971384a6294a9aa) --- source3/Makefile.in | 2 +- source3/include/proto.h | 10 ++++++ source3/libsmb/clientgen.c | 18 +++++++--- source3/passdb/smbpass.c | 4 +-- source3/passdb/smbpassfile.c | 36 +++++++++++++++++++ source3/rpc_client/cli_login.c | 6 +--- source3/rpc_client/cli_lsarpc.c | 4 +-- source3/rpc_client/cli_netlogon.c | 11 ++++-- source3/rpc_parse/parse_net.c | 69 +++++++++++++++++++++++++++++++++++ source3/rpcclient/cmd_netlogon.c | 75 +++++++++++++++++++++++++++------------ source3/rpcclient/rpcclient.c | 16 ++++----- source3/smbd/password.c | 25 ++----------- source3/smbd/process.c | 2 +- 13 files changed, 205 insertions(+), 73 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 3906b365b8..35e98e025b 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -192,9 +192,9 @@ RPCCLIENT_OBJ = rpcclient/rpcclient.o \ rpcclient/cmd_wkssvc.o \ rpcclient/cmd_samr.o \ rpcclient/cmd_srvsvc.o \ + rpcclient/cmd_netlogon.o \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) -# rpcclient/cmd_netlogon.o SMBWRAPPER_OBJ = smbwrapper/smbw.o smbwrapper/wrapped.o \ smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index 411f923ba8..09fe5b0873 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1189,6 +1189,7 @@ BOOL trust_password_unlock(void); BOOL trust_password_delete( char *domain, char *name ); BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_time); BOOL set_trust_account_password( unsigned char *md4_new_pwd); +BOOL trust_get_passwd( unsigned char trust_passwd[16], char *myname, char *domain); /*The following definitions come from printing/pcap.c */ @@ -1452,6 +1453,11 @@ void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16]); void net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth); void net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth); +void make_id_info1(NET_ID_INFO_1 *id, char *domain_name, + uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high, + char *user_name, char *wksta_name, + char sess_key[16], + unsigned char lm_cypher[16], unsigned char nt_cypher[16]); void make_id_info2(NET_ID_INFO_2 *id, char *domain_name, uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high, char *user_name, char *wksta_name, @@ -1911,6 +1917,10 @@ BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data); void cmd_lsa_query_info(struct client_info *info); void cmd_lsa_lookup_sids(struct client_info *info); +/*The following definitions come from rpcclient/cmd_netlogon.c */ + +void cmd_netlogon_login_test(struct client_info *info); + /*The following definitions come from rpcclient/cmd_samr.c */ void cmd_sam_ntchange_pwd(struct client_info *info); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 64e67c5522..a6ffb57834 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2494,15 +2494,25 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->pwd.cleartext || cli->pwd.null_pwd) { - /* attempt clear-text session */ - fstring passwd; + int pass_len; - pwd_get_cleartext(&(cli->pwd), passwd); + if (cli->pwd.null_pwd) + { + /* attempt null session */ + passwd[0] = 0; + pass_len = 1; + } + else + { + /* attempt clear-text session */ + pwd_get_cleartext(&(cli->pwd), passwd); + pass_len = strlen(passwd); + } /* attempt clear-text session */ if (!cli_session_setup(cli, cli->user_name, - passwd, strlen(passwd), + passwd, pass_len, NULL, 0, cli->domain)) { diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c index eefc30382b..bde696290d 100644 --- a/source3/passdb/smbpass.c +++ b/source3/passdb/smbpass.c @@ -330,8 +330,8 @@ static struct sam_passwd *getsmbfile21pwent(void *vp) pwfile = getpwnam(pw_buf->smb_name); if (pwfile == NULL) { - DEBUG(0,"getsmbfile21pwent: smbpasswd database is corrupt!\n")); - DEBUG(0,"getsmbfile21pwent: username %s not in unix passwd database!\n", pw_buf->smb_name)); + DEBUG(0,("getsmbfile21pwent: smbpasswd database is corrupt!\n")); + DEBUG(0,("getsmbfile21pwent: username %s not in unix passwd database!\n", pw_buf->smb_name)); return NULL; } diff --git a/source3/passdb/smbpassfile.c b/source3/passdb/smbpassfile.c index 8542ad081d..13a1a9f508 100644 --- a/source3/passdb/smbpassfile.c +++ b/source3/passdb/smbpassfile.c @@ -24,6 +24,8 @@ extern int DEBUGLEVEL; static int gotalarm; int pw_file_lock_depth = 0; +BOOL global_machine_password_needs_changing = False; + /*************************************************************** Signal function to tell us we timed out. ****************************************************************/ @@ -318,3 +320,37 @@ account is now invalid. Please recreate. Error was %s.\n", strerror(errno) )); fflush(mach_passwd_fp); return True; } + +BOOL trust_get_passwd( unsigned char trust_passwd[16], char *myname, char *domain) +{ + time_t lct; + + /* + * Get the machine account password. + */ + if(!trust_password_lock( myname, domain, False)) { + DEBUG(0,("domain_client_validate: unable to open the machine account password file for \ +machine %s in domain %s.\n", myname, domain )); + return False; + } + + if(get_trust_account_password( trust_passwd, &lct) == False) { + DEBUG(0,("domain_client_validate: unable to read the machine account password for \ +machine %s in domain %s.\n", myname, domain )); + trust_password_unlock(); + return False; + } + + trust_password_unlock(); + + /* + * Here we check the last change time to see if the machine + * password needs changing. JRA. + */ + + if(time(NULL) > lct + lp_machine_password_timeout()) + { + global_machine_password_needs_changing = True; + } + return True; +} diff --git a/source3/rpc_client/cli_login.c b/source3/rpc_client/cli_login.c index abe471379b..1b12828550 100644 --- a/source3/rpc_client/cli_login.c +++ b/source3/rpc_client/cli_login.c @@ -83,7 +83,7 @@ BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd) { unsigned char processed_new_pwd[16]; - DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__)); + DEBUG(5,("cli_nt_srv_pwset: %d\n", __LINE__)); #ifdef DEBUG_PASSWORD dump_data(6, new_hashof_mach_pwd, 16); @@ -96,7 +96,6 @@ BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd) return cli_net_srv_pwset(cli, processed_new_pwd); } -#if UNUSED_CODE /**************************************************************************** NT login - interactive. *NEVER* use this code. This method of doing a logon (sending the cleartext @@ -149,7 +148,6 @@ BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *usernam return ret; } -#endif /**************************************************************************** NT login - network. @@ -177,7 +175,6 @@ BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username, return cli_net_sam_logon(cli, ctr, user_info3); } -#if UNUSED_CODE /**************************************************************************** NT Logoff. ****************************************************************************/ @@ -188,4 +185,3 @@ BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr) /* Send client sam-logoff request - update credentials on success. */ return cli_net_sam_logoff(cli, ctr); } -#endif diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index d010ae4e29..c280929417 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -58,11 +58,11 @@ BOOL do_lsa_open_policy(struct cli_state *cli, if (sec_qos) { make_lsa_sec_qos(&qos, 2, 1, 0, 0x20000000); - make_q_open_pol(&q_o, server_name, 0, 0, &qos); + make_q_open_pol(&q_o, 0x5c, 0, 0, &qos); } else { - make_q_open_pol(&q_o, server_name, 0, 0x1, NULL); + make_q_open_pol(&q_o, 0x5c, 0, 0x1, NULL); } /* turn parameters into data stream */ diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 2671bac773..9c81b73692 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -391,7 +391,6 @@ password ?).\n", cli->desthost )); return ok; } -#if UNUSED_CODE /*************************************************************************** LSA SAM Logoff. @@ -465,7 +464,6 @@ password ?).\n", cli->desthost )); return ok; } -#endif /********************************************************* Change the domain password on the PDC. @@ -605,6 +603,7 @@ BOOL change_trust_account_password( char *domain, char *remote_machine_list) unsigned char old_trust_passwd_hash[16]; unsigned char new_trust_passwd_hash[16]; time_t lct; + BOOL res; if(!get_trust_account_password( old_trust_passwd_hash, &lct)) { DEBUG(0,("change_trust_account_password: unable to read the machine \ @@ -629,10 +628,16 @@ domain %s.\n", timestring(), domain)); * Return the result of trying to write the new password * back into the trust account file. */ - return set_trust_account_password(new_trust_passwd_hash); + res = set_trust_account_password(new_trust_passwd_hash); + memset(new_trust_passwd_hash, 0, 16); + memset(old_trust_passwd_hash, 0, 16); + return res; } } + memset(new_trust_passwd_hash, 0, 16); + memset(old_trust_passwd_hash, 0, 16); + DEBUG(0,("%s : change_trust_account_password: Failed to change password for \ domain %s.\n", timestring(), domain)); return False; diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index 12d6aca264..2fc0d12446 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -538,6 +538,75 @@ static int make_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids) return count; } +/******************************************************************* +makes a NET_ID_INFO_1 structure. +********************************************************************/ +void make_id_info1(NET_ID_INFO_1 *id, char *domain_name, + uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high, + char *user_name, char *wksta_name, + char sess_key[16], + unsigned char lm_cypher[16], unsigned char nt_cypher[16]) +{ + int len_domain_name = strlen(domain_name); + int len_user_name = strlen(user_name ); + int len_wksta_name = strlen(wksta_name ); + + unsigned char lm_owf[16]; + unsigned char nt_owf[16]; + + if (id == NULL) return; + + DEBUG(5,("make_id_info1: %d\n", __LINE__)); + + id->ptr_id_info1 = 1; + + make_uni_hdr(&(id->hdr_domain_name), len_domain_name, len_domain_name, 4); + + id->param_ctrl = param_ctrl; + make_logon_id(&(id->logon_id), log_id_low, log_id_high); + + make_uni_hdr(&(id->hdr_user_name ), len_user_name , len_user_name , 4); + make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name , len_wksta_name , 4); + + if (lm_cypher && nt_cypher) + { + unsigned char key[16]; +#ifdef DEBUG_PASSWORD + DEBUG(100,("lm cypher:")); + dump_data(100, lm_cypher, 16); + + DEBUG(100,("nt cypher:")); + dump_data(100, nt_cypher, 16); +#endif + + memset(key, 0, 16); + memcpy(key, sess_key, 16); + + memcpy(lm_cypher, lm_owf, 16); + SamOEMhash(lm_owf, key, False); + memcpy(lm_cypher, lm_owf, 16); + SamOEMhash(nt_owf, key, False); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("encrypt of lm owf password:")); + dump_data(100, lm_owf, 16); + + DEBUG(100,("encrypt of nt owf password:")); + dump_data(100, nt_owf, 16); +#endif + /* set up pointers to cypher blocks */ + lm_cypher = lm_owf; + nt_cypher = nt_owf; + } + + make_owf_info(&(id->lm_owf), lm_cypher); + make_owf_info(&(id->nt_owf), nt_cypher); + + make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name); + make_unistr2(&(id->uni_user_name ), user_name , len_user_name ); + make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name ); +} + /******************************************************************* reads or writes an NET_ID_INFO_1 structure. ********************************************************************/ diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 40bb257072..88510c95e7 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -43,7 +43,13 @@ experimental nt login. ****************************************************************************/ void cmd_netlogon_login_test(struct client_info *info) { + extern BOOL global_machine_password_needs_changing; + + fstring nt_user_name; + fstring password; BOOL res = True; + char *nt_password; + unsigned char trust_passwd[16]; /* machine account passwords */ pstring new_mach_pwd; @@ -51,7 +57,28 @@ void cmd_netlogon_login_test(struct client_info *info) /* initialisation */ new_mach_pwd[0] = 0; - DEBUG(5,("do_nt_login_test: %d\n", __LINE__)); + if (!next_token(NULL, nt_user_name, NULL, sizeof(nt_user_name))) + { + fstrcpy(nt_user_name, smb_cli->user_name); + if (nt_user_name[0] == 0) + { + fprintf(out_hnd,"ntlogin: must specify username with anonymous connection\n"); + return; + } + } + + if (next_token(NULL, password, NULL, sizeof(password))) + { + nt_password = password; + } + else + { + nt_password = getpass("Enter NT Login password:"); + } + + DEBUG(5,("do_nt_login_test: username %s\n", nt_user_name)); + + res = res ? trust_get_passwd(trust_passwd, info->myhostname, smb_cli->domain) : False; #if 0 /* check whether the user wants to change their machine password */ @@ -60,38 +87,40 @@ void cmd_netlogon_login_test(struct client_info *info) info->mach_acct, new_mach_pwd) : False; #endif /* open NETLOGON session. negotiate credentials */ - res = res ? do_nt_session_open(smb_cli, - info->dest_host, info->myhostname, - info->mach_acct, - smb_cli->user_name, smb_cli->domain, - info->dom.sess_key, &info->dom.clnt_cred) : False; + res = res ? cli_nt_session_open(smb_cli, PIPE_NETLOGON, False) : False; + + res = res ? cli_nt_setup_creds(smb_cli, trust_passwd) : False; /* change the machine password? */ - if (new_mach_pwd != NULL && new_mach_pwd[0] != 0) + if (global_machine_password_needs_changing) { - res = res ? do_nt_srv_pwset(smb_cli, info->dom.lsarpc_fnum, - info->dom.sess_key, &info->dom.clnt_cred, &info->dom.rtn_cred, - new_mach_pwd, - info->dest_host, info->mach_acct, info->myhostname) : False; + unsigned char new_trust_passwd[16]; + generate_random_buffer(new_trust_passwd, 16, True); + res = res ? cli_nt_srv_pwset(smb_cli, new_trust_passwd) : False; + + if (res) + { + global_machine_password_needs_changing = !set_trust_account_password(new_trust_passwd); + } + + memset(new_trust_passwd, 0, 16); } - /* create the user-identification info */ - make_nt_login_interactive(&info->dom.ctr, - info->dom.sess_key, - smb_cli->domain, info->myhostname, - getuid(), smb_cli->user_name); + memset(trust_passwd, 0, 16); /* do an NT login */ - res = res ? do_nt_login(smb_cli, info->dom.lsarpc_fnum, - info->dom.sess_key, &info->dom.clnt_cred, &info->dom.rtn_cred, - &info->dom.ctr, info->dest_host, info->myhostname, &info->dom.user_info3) : False; + res = res ? cli_nt_login_interactive(smb_cli, + smb_cli->domain, nt_user_name, + getuid(), nt_password, + &info->dom.ctr, &info->dom.user_info3) : False; + + /*** clear out the password ***/ + memset(password, 0, sizeof(password)); /* ok! you're logged in! do anything you like, then... */ - + /* do an NT logout */ - res = res ? do_nt_logoff(smb_cli, info->dom.lsarpc_fnum, - info->dom.sess_key, &info->dom.clnt_cred, &info->dom.rtn_cred, - &info->dom.ctr, info->dest_host, info->myhostname) : False; + res = res ? cli_nt_logoff(smb_cli, &info->dom.ctr) : False; /* close the session */ cli_nt_session_close(smb_cli); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 7d1df61bb7..ba7f7d0180 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -105,15 +105,13 @@ struct char *description; } commands[] = { -#if 0 - {"ntlogin", cmd_netlogon_login_test, " NT Domain login test"}, -#endif - {"wksinfo", cmd_wks_query_info, "DCE/RPC - Workstation Query Info"}, - {"srvinfo", cmd_srv_query_info, "DCE/RPC - Server Query Info"}, - {"srvsessions",cmd_srv_enum_sess, "DCE/RPC - List sessions on a server"}, - {"srvshares", cmd_srv_enum_shares, "DCE/RPC - List shares on a server"}, - {"srvconnections",cmd_srv_enum_conn, "DCE/RPC - List connections on a server"}, - {"srvfiles", cmd_srv_enum_files, "DCE/RPC - List files on a server"}, + {"ntlogin", cmd_netlogon_login_test, "[username] [password] NT Domain login test"}, + {"wksinfo", cmd_wks_query_info, "Workstation Query Info"}, + {"srvinfo", cmd_srv_query_info, "Server Query Info"}, + {"srvsessions",cmd_srv_enum_sess, "List sessions on a server"}, + {"srvshares", cmd_srv_enum_shares, "List shares on a server"}, + {"srvconnections",cmd_srv_enum_conn, "List connections on a server"}, + {"srvfiles", cmd_srv_enum_files, "List files on a server"}, {"lsaquery", cmd_lsa_query_info, "Query Info Policy (domain member or server)"}, {"lookupsids", cmd_lsa_lookup_sids, "Resolve names from SIDs"}, {"enumusers", cmd_sam_enum_users, "SAM User Database Query (experimental!)"}, diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 761313b688..45d4d72863 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -24,8 +24,6 @@ extern int DEBUGLEVEL; extern int Protocol; -BOOL global_machine_pasword_needs_changing; - /* users from session setup */ static pstring session_users=""; @@ -1136,7 +1134,6 @@ BOOL domain_client_validate( char *user, char *domain, unsigned char local_lm_response[24]; unsigned char local_nt_reponse[24]; unsigned char trust_passwd[16]; - time_t lct; fstring remote_machine; char *p; struct in_addr dest_ip; @@ -1193,29 +1190,11 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password. */ - if(!trust_password_lock( global_myworkgroup, global_myname, False)) { - DEBUG(0,("domain_client_validate: unable to open the machine account password file for \ -machine %s in domain %s.\n", global_myname, global_myworkgroup )); - return False; - } - - if(get_trust_account_password( trust_passwd, &lct) == False) { - DEBUG(0,("domain_client_validate: unable to read the machine account password for \ -machine %s in domain %s.\n", global_myname, global_myworkgroup )); - trust_password_unlock(); + if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname)) + { return False; } - trust_password_unlock(); - - /* - * Here we check the last change time to see if the machine - * password needs changing. JRA. - */ - - if(time(NULL) > lct + lp_machine_password_timeout()) - global_machine_pasword_needs_changing = True; - /* * At this point, smb_apasswd points to the lanman response to * the challenge in local_challenge, and smb_ntpasswd points to diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 6e1bdc941a..9c00d6fc00 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -49,7 +49,7 @@ extern char *InBuffer; extern char *OutBuffer; extern int smb_read_error; extern BOOL reload_after_sighup; -extern BOOL global_machine_pasword_needs_changing; +extern BOOL global_machine_password_needs_changing; extern fstring global_myworkgroup; extern pstring global_myname; extern int max_send; -- cgit