From e302cb2b189f679bcf7efe60d5ae9fb4218c1411 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 29 Nov 1999 19:46:57 +0000 Subject: first attempt at getting \PIPE\NETLOGON working. it's pretty horrible. (This used to be commit 44dd3efa6380544e9a515e91960f9271498cefaf) --- source3/include/client.h | 3 - source3/include/proto.h | 110 +++++++----- source3/libsmb/clienttrust.c | 108 ++---------- source3/rpc_client/cli_connect.c | 89 +++++++++- source3/rpc_client/cli_login.c | 227 +++++++++++++++--------- source3/rpc_client/cli_lsarpc.c | 2 +- source3/rpc_client/cli_netlogon.c | 306 ++++++++++++++++++--------------- source3/rpc_client/cli_netlogon_sync.c | 13 +- source3/rpc_client/cli_pipe.c | 12 -- source3/rpc_parse/parse_net.c | 44 ++++- source3/rpc_parse/parse_samr.c | 4 +- source3/rpcclient/cmd_netlogon.c | 63 ++++--- source3/rpcclient/rpcclient.c | 15 +- 13 files changed, 568 insertions(+), 428 deletions(-) (limited to 'source3') diff --git a/source3/include/client.h b/source3/include/client.h index 066c5e73f3..edc20bdde0 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -153,9 +153,6 @@ struct cli_state uint32 ntlmssp_srv_flgs; /* ntlmssp server flags */ uint32 ntlmssp_seq_num; /* ntlmssp sequence number */ DOM_CRED clnt_cred; /* Client credential. */ - fstring mach_acct; /* MYNAME$. */ - fstring srv_name_slash; /* \\remote server. */ - fstring clnt_name_slash; /* \\local client. */ uint16 max_xmit_frag; uint16 max_recv_frag; }; diff --git a/source3/include/proto.h b/source3/include/proto.h index 9e5819cb13..1ffe32f314 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1791,9 +1791,21 @@ BOOL cli_connection_init_list(char* servers, const char* pipe_name, struct cli_connection **con); BOOL cli_connection_init(const char* server_name, const char* pipe_name, struct cli_connection **con); +BOOL cli_connection_getsrv(const char* srv_name, const char* pipe_name, + struct cli_connection **con); BOOL cli_connection_get(const POLICY_HND *pol, struct cli_connection **con); BOOL cli_pol_link(POLICY_HND *to, const POLICY_HND *from); -BOOL cli_get_usr_sesskey(const POLICY_HND *pol, uchar sess_key[16]); +BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16]); +BOOL cli_get_sesskey(const POLICY_HND *pol, uchar sess_key[16]); +BOOL cli_get_sesskey_srv(const char* srv_name, uchar sess_key[16]); +void cli_con_gen_next_creds(struct cli_connection *con, + DOM_CRED *new_clnt_cred); +void cli_con_get_cli_cred(struct cli_connection *con, + DOM_CRED *clnt_cred); +BOOL cli_con_deal_with_creds(struct cli_connection *con, + DOM_CRED *rcv_srv_cred); +BOOL cli_con_set_creds(const char* srv_name, const uchar sess_key[16], + DOM_CRED *cred); BOOL rpc_hnd_pipe_req(const POLICY_HND *hnd, uint8 op_num, prs_struct *data, prs_struct *rdata); BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num, @@ -1810,21 +1822,34 @@ BOOL event_readeventlog(POLICY_HND *hnd, /*The following definitions come from rpc_client/cli_login.c */ -uint32 cli_nt_setup_creds(struct cli_state *cli, uint16 fnum, +uint32 cli_nt_setup_creds( const char* srv_name, const char* myhostname, const char* trust_acct, - const char* srv_name, unsigned char trust_pwd[16], uint16 sec_chan); -BOOL cli_nt_srv_pwset(struct cli_state *cli, uint16 fnum, - unsigned char *new_hashof_trust_pwd, uint16 sec_chan); -BOOL cli_nt_login_interactive(struct cli_state *cli, uint16 fnum, char *domain, char *username, - uint32 luid_low, char *password, - NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3); -BOOL cli_nt_login_network(struct cli_state *cli, uint16 fnum, char *domain, char *username, - uint32 luid_low, char lm_chal[8], char lm_chal_resp[24], - char nt_chal_resp[24], - NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3); -BOOL cli_nt_logoff(struct cli_state *cli, uint16 fnum, NET_ID_INFO_CTR *ctr); +BOOL cli_nt_srv_pwset(const char* srv_name, const char* myhostname, + const char* trust_acct, + unsigned char *new_hashof_trust_pwd, + uint16 sec_chan); +BOOL cli_nt_login_interactive(const char* srv_name, const char* myhostname, + const char *domain, const char *username, + uint32 luid_low, char *password, + NET_ID_INFO_CTR *ctr, + NET_USER_INFO_3 *user_info3); +BOOL cli_nt_login_network(const char* srv_name, const char* myhostname, + const char *domain, const char *username, + uint32 luid_low, char lm_chal[8], + char lm_chal_resp[24], + char nt_chal_resp[24], + NET_ID_INFO_CTR *ctr, + NET_USER_INFO_3 *user_info3); +BOOL cli_nt_logoff(const char* srv_name, const char* myhostname, + NET_ID_INFO_CTR *ctr); +BOOL net_sam_sync(const char* srv_name, const char* myhostname, + const char* trust_acct, + uchar trust_passwd[16], + SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS], + SAM_DELTA_CTR deltas [MAX_SAM_DELTAS], + uint32 *num_deltas); /*The following definitions come from rpc_client/cli_lsarpc.c */ @@ -1864,31 +1889,29 @@ BOOL lsa_close(POLICY_HND *hnd); /*The following definitions come from rpc_client/cli_netlogon.c */ -BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint16 nt_pipe_fnum, uint32 status_level); -uint32 cli_net_auth2(struct cli_state *cli, uint16 nt_pipe_fnum, +void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred); +BOOL cli_net_logon_ctrl2(const char* srv_name, uint32 status_level); +uint32 cli_net_auth2(const char *srv_name, const char *trust_acct, - const char *srv_name, uint16 sec_chan, + uint16 sec_chan, uint32 neg_flags, DOM_CHAL *srv_chal); -uint32 cli_net_req_chal(struct cli_state *cli, uint16 nt_pipe_fnum, - const char *srv_name, +uint32 cli_net_req_chal( const char *srv_name, const char* myhostname, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal); -BOOL cli_net_srv_pwset(struct cli_state *cli, uint16 nt_pipe_fnum, - uint8 hashed_mach_pwd[16], uint16 sec_chan_type); -BOOL cli_net_sam_logon(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_CTR *ctr, - NET_USER_INFO_3 *user_info3); -BOOL cli_net_sam_logoff(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_CTR *ctr); -BOOL cli_net_sam_sync(struct cli_state *cli, uint16 nt_pipe_fnum, - const char* srv_name, +BOOL cli_net_srv_pwset(const char* srv_name, + const char* myhostname, + const char* trust_acct, + uint8 hashed_trust_pwd[16], + uint16 sec_chan_type); +BOOL cli_net_sam_logon(const char* srv_name, const char* myhostname, + NET_ID_INFO_CTR *ctr, + NET_USER_INFO_3 *user_info3); +BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname, + NET_ID_INFO_CTR *ctr); +BOOL cli_net_sam_sync( const char* srv_name, const char* myhostname, uint32 database_id, uint32 *num_deltas, SAM_DELTA_HDR *hdr_deltas, SAM_DELTA_CTR *deltas); -BOOL do_sam_sync(struct cli_state *cli, uchar trust_passwd[16], - const char* acct_name, - const char* srv_name, - SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS], - SAM_DELTA_CTR deltas [MAX_SAM_DELTAS], - uint32 *num_deltas); /*The following definitions come from rpc_client/cli_netlogon_sync.c */ @@ -2482,6 +2505,11 @@ BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_net.c */ +BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, + const char* srv_name, + uint32 function_code, + uint32 query_level, + uint32 switch_value); BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth); BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level, uint32 flags, uint32 pdc_status, uint32 logon_attempts, @@ -2508,23 +2536,27 @@ BOOL make_q_auth_2(NET_Q_AUTH_2 *q_a, DOM_CHAL *clnt_chal, uint32 clnt_flgs); BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth); BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth); -BOOL 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]); +BOOL make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, + const char *logon_srv, const char *acct_name, + uint16 sec_chan, const char *comp_name, + DOM_CRED *cred, char nt_cypher[16]); BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth); BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth); -BOOL make_id_info1(NET_ID_INFO_1 *id, char *domain_name, +BOOL make_id_info1(NET_ID_INFO_1 *id, const char *domain_name, uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high, - char *user_name, char *wksta_name, + const char *user_name, const char *wksta_name, char sess_key[16], unsigned char lm_cypher[16], unsigned char nt_cypher[16]); -BOOL 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, +BOOL make_id_info2(NET_ID_INFO_2 *id, const char *domain_name, + uint32 param_ctrl, + uint32 log_id_low, uint32 log_id_high, + const char *user_name, const char *wksta_name, unsigned char lm_challenge[8], unsigned char lm_chal_resp[24], unsigned char nt_chal_resp[24]); BOOL make_sam_info(DOM_SAM_INFO *sam, - char *logon_srv, char *comp_name, DOM_CRED *clnt_cred, + const char *logon_srv, const char *comp_name, + DOM_CRED *clnt_cred, DOM_CRED *rtn_cred, uint16 logon_level, NET_ID_INFO_CTR *ctr, uint16 validation_level); BOOL make_net_user_info3(NET_USER_INFO_3 *usr, diff --git a/source3/libsmb/clienttrust.c b/source3/libsmb/clienttrust.c index 81855585e6..b223750529 100644 --- a/source3/libsmb/clienttrust.c +++ b/source3/libsmb/clienttrust.c @@ -42,117 +42,33 @@ static BOOL modify_trust_password( char *domain, char *remote_machine, unsigned char new_trust_passwd_hash[16], uint16 sec_chan) { - uint16 nt_pipe_fnum; - struct cli_state cli; struct nmb_name calling, called; + fstring trust_acct; + fstring srv_name; - make_nmb_name(&calling, global_myname , 0x0 , scope); - make_nmb_name(&called , remote_machine, 0x20, scope); - - ZERO_STRUCT(cli); - if(cli_initialise(&cli) == NULL) - { - DEBUG(0,("modify_trust_password: unable to initialize client \ -connection.\n")); - return False; - } - - if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) - { - DEBUG(0,("modify_trust_password: Can't resolve address for \ -%s\n", remote_machine)); - return False; - } - - if (ismyip(cli.dest_ip)) - { - DEBUG(0,("modify_trust_password: Machine %s is one of our \ -addresses. Cannot add to ourselves.\n", remote_machine)); - return False; - } + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, remote_machine); + strupper(srv_name); - cli.protocol = PROTOCOL_NT1; + fstrcpy(trust_acct, global_myname); + fstrcat(trust_acct, "$"); - pwd_set_nullpwd(&cli.usr.pwd); - - if (!cli_establish_connection(&cli, remote_machine, &cli.dest_ip, - &calling, &called, - "IPC$", "IPC", False, True)) - { - fstring errstr; - cli_safe_errstr(&cli, errstr, sizeof(errstr)); - DEBUG(0,("modify_trust_password: machine %s rejected the SMB \ -session. Error was : %s.\n", remote_machine, errstr )); - cli_shutdown(&cli); - return False; - } - - - if (cli.protocol != PROTOCOL_NT1) - { - DEBUG(0,("modify_trust_password: machine %s didn't negotiate \ -NT protocol.\n", remote_machine)); - cli_shutdown(&cli); - return False; - } - - if (!(IS_BITS_SET_ALL(cli.sec_mode, 1))) - { - DEBUG(0,("modify_trust_password: machine %s isn't in user \ -level security mode\n", remote_machine)); - cli_shutdown(&cli); - return False; - } - - /* - * Ok - we have an anonymous connection to the IPC$ share. - * Now start the NT Domain stuff :-). - */ - - if (!cli_nt_session_open(&cli, PIPE_NETLOGON, &nt_pipe_fnum)) - { - fstring errstr; - cli_safe_errstr(&cli, errstr, sizeof(errstr)); - DEBUG(0,("modify_trust_password: unable to open the domain \ -client session to server %s. Error was : %s.\n", remote_machine, errstr )); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return False; - } + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); - if (cli_nt_setup_creds(&cli, nt_pipe_fnum, - cli.mach_acct, global_myname, + if (cli_nt_setup_creds(srv_name, global_myname, trust_acct, orig_trust_passwd_hash, sec_chan) != 0x0) { - fstring errstr; - cli_safe_errstr(&cli, errstr, sizeof(errstr)); - DEBUG(0,("modify_trust_password: unable to setup the PDC \ -credentials to server %s. Error was : %s.\n", remote_machine, errstr )); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); return False; } - if (!cli_nt_srv_pwset( &cli, nt_pipe_fnum, new_trust_passwd_hash, + if (!cli_nt_srv_pwset( srv_name, global_myname, trust_acct, + new_trust_passwd_hash, sec_chan ) ) { - fstring errstr; - cli_safe_errstr(&cli, errstr, sizeof(errstr)); - DEBUG(0,("modify_trust_password: unable to change password for \ -workstation %s in domain %s to Domain controller %s. Error was %s.\n", - global_myname, domain, remote_machine, errstr )); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); return False; } - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return True; } diff --git a/source3/rpc_client/cli_connect.c b/source3/rpc_client/cli_connect.c index 0b5d20d913..bca539c396 100644 --- a/source3/rpc_client/cli_connect.c +++ b/source3/rpc_client/cli_connect.c @@ -189,6 +189,15 @@ BOOL cli_connection_init(const char* server_name, const char* pipe_name, return res; } +/**************************************************************************** +obtain client state +****************************************************************************/ +BOOL cli_connection_getsrv(const char* srv_name, const char* pipe_name, + struct cli_connection **con) +{ + return False; +} + /**************************************************************************** obtain client state ****************************************************************************/ @@ -216,7 +225,18 @@ BOOL cli_pol_link(POLICY_HND *to, const POLICY_HND *from) get a user session key associated with a connection associated with a policy handle. ****************************************************************************/ -BOOL cli_get_usr_sesskey(const POLICY_HND *pol, uchar sess_key[16]) +BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16]) +{ + memcpy(sess_key, con->cli->sess_key, sizeof(con->cli->sess_key)); + + return True; +} + +/**************************************************************************** +get a user session key associated with a connection associated with a +policy handle. +****************************************************************************/ +BOOL cli_get_sesskey(const POLICY_HND *pol, uchar sess_key[16]) { struct cli_connection *con = NULL; @@ -225,7 +245,72 @@ BOOL cli_get_usr_sesskey(const POLICY_HND *pol, uchar sess_key[16]) return False; } - memcpy(sess_key, con->cli->sess_key, sizeof(con->cli->sess_key)); + return cli_get_con_sesskey(con, sess_key); +} + +/**************************************************************************** +get a user session key associated with a connection associated with a +policy handle. +****************************************************************************/ +BOOL cli_get_sesskey_srv(const char* srv_name, uchar sess_key[16]) +{ + struct cli_connection *con = NULL; + + if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con)) + { + return False; + } + + return cli_get_con_sesskey(con, sess_key); +} + +/**************************************************************************** +get a user session key associated with a connection associated with a +policy handle. +****************************************************************************/ +void cli_con_gen_next_creds(struct cli_connection *con, + DOM_CRED *new_clnt_cred) +{ + gen_next_creds(con->cli, new_clnt_cred); +} + +/**************************************************************************** +get a user session key associated with a connection associated with a +policy handle. +****************************************************************************/ +void cli_con_get_cli_cred(struct cli_connection *con, + DOM_CRED *clnt_cred) +{ + memcpy(clnt_cred, &con->cli->clnt_cred, sizeof(*clnt_cred)); +} + +/**************************************************************************** +get a user session key associated with a connection associated with a +policy handle. +****************************************************************************/ +BOOL cli_con_deal_with_creds(struct cli_connection *con, + DOM_CRED *rcv_srv_cred) +{ + return clnt_deal_with_creds(con->cli->sess_key, &con->cli->clnt_cred, + rcv_srv_cred); +} + +/**************************************************************************** +get a user session key associated with a connection associated with a +policy handle. +****************************************************************************/ +BOOL cli_con_set_creds(const char* srv_name, const uchar sess_key[16], + DOM_CRED *cred) +{ + struct cli_connection *con = NULL; + + if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con)) + { + return False; + } + + memcpy(con->cli->sess_key, sess_key, 16); + memcpy(&con->cli->clnt_cred, cred, sizeof(*cred)); return True; } diff --git a/source3/rpc_client/cli_login.c b/source3/rpc_client/cli_login.c index 45345cf4ac..6bb9fed063 100644 --- a/source3/rpc_client/cli_login.c +++ b/source3/rpc_client/cli_login.c @@ -29,76 +29,80 @@ extern int DEBUGLEVEL; Initialize domain session credentials. ****************************************************************************/ -uint32 cli_nt_setup_creds(struct cli_state *cli, uint16 fnum, +uint32 cli_nt_setup_creds( const char* srv_name, const char* myhostname, const char* trust_acct, - const char* srv_name, unsigned char trust_pwd[16], uint16 sec_chan) { - DOM_CHAL clnt_chal; - DOM_CHAL srv_chal; + DOM_CHAL clnt_chal; + DOM_CHAL srv_chal; uint32 ret; - UTIME zerotime; + UTIME zerotime; + uint8 sess_key[16]; + DOM_CRED clnt_cred; - /******************* Request Challenge ********************/ + /******************* Request Challenge ********************/ - generate_random_buffer( clnt_chal.data, 8, False); - - /* send a client challenge; receive a server challenge */ - ret = cli_net_req_chal(cli, fnum, srv_name, &clnt_chal, &srv_chal); - if (ret != 0) - { - DEBUG(1,("cli_nt_setup_creds: request challenge failed\n")); - return ret; - } + generate_random_buffer( clnt_chal.data, 8, False); - /**************** Long-term Session key **************/ + /* send a client challenge; receive a server challenge */ + ret = cli_net_req_chal(srv_name, myhostname, &clnt_chal, &srv_chal); + if (ret != 0) + { + DEBUG(1,("cli_nt_setup_creds: request challenge failed\n")); + return ret; + } - /* calculate the session key */ - cred_session_key(&clnt_chal, &srv_chal, (char *)trust_pwd, cli->sess_key); - bzero(cli->sess_key+8, 8); + /**************** Long-term Session key **************/ - /******************* Authenticate 2 ********************/ + /* calculate the session key */ + cred_session_key(&clnt_chal, &srv_chal, (char *)trust_pwd, sess_key); + bzero(sess_key+8, 8); - /* calculate auth-2 credentials */ - zerotime.time = 0; - cred_create(cli->sess_key, &clnt_chal, zerotime, &(cli->clnt_cred.challenge)); + /******************* Authenticate 2 ********************/ - /* - * Send client auth-2 challenge. - * Receive an auth-2 challenge response and check it. - */ + /* calculate auth-2 credentials */ + zerotime.time = 0; + cred_create(sess_key, &clnt_chal, zerotime, &clnt_cred.challenge); - ret = cli_net_auth2(cli, fnum, trust_acct, srv_name, - sec_chan, 0x000001ff, &srv_chal); - if (ret != 0x0) - { - DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed. status: %x\n", ret)); - } + if (!cli_con_set_creds(srv_name, sess_key, &clnt_cred)) + { + return NT_STATUS_ACCESS_DENIED | 0xC0000000; + } - return ret; + /* + * Send client auth-2 challenge. + * Receive an auth-2 challenge response and check it. + */ + + ret = cli_net_auth2(srv_name, trust_acct, + sec_chan, 0x000001ff, &srv_chal); + if (ret != 0x0) + { + DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed. status: %x\n", ret)); + } + + return ret; } /**************************************************************************** Set machine password. ****************************************************************************/ -BOOL cli_nt_srv_pwset(struct cli_state *cli, uint16 fnum, - unsigned char *new_hashof_trust_pwd, uint16 sec_chan) +BOOL cli_nt_srv_pwset(const char* srv_name, const char* myhostname, + const char* trust_acct, + unsigned char *new_hashof_trust_pwd, + uint16 sec_chan) { - unsigned char processed_new_pwd[16]; - DEBUG(5,("cli_nt_srv_pwset: %d\n", __LINE__)); #ifdef DEBUG_PASSWORD dump_data(6, new_hashof_trust_pwd, 16); #endif - /* Process the new password. */ - cred_hash3( processed_new_pwd, new_hashof_trust_pwd, cli->sess_key, 1); - /* send client srv_pwset challenge */ - return cli_net_srv_pwset(cli, fnum, processed_new_pwd, sec_chan); + return cli_net_srv_pwset(srv_name, myhostname, trust_acct, + new_hashof_trust_pwd, sec_chan); } /**************************************************************************** @@ -107,51 +111,59 @@ NT login - interactive. password equivalents, protected by the session key) is inherently insecure given the current design of the NT Domain system. JRA. ****************************************************************************/ -BOOL cli_nt_login_interactive(struct cli_state *cli, uint16 fnum, char *domain, char *username, - uint32 luid_low, char *password, - NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3) +BOOL cli_nt_login_interactive(const char* srv_name, const char* myhostname, + const char *domain, const char *username, + uint32 luid_low, char *password, + NET_ID_INFO_CTR *ctr, + NET_USER_INFO_3 *user_info3) { - uchar lm_owf_user_pwd[16]; - uchar nt_owf_user_pwd[16]; - BOOL ret; + uchar lm_owf_user_pwd[16]; + uchar nt_owf_user_pwd[16]; + BOOL ret; + uint8 sess_key[16]; - DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__)); + DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__)); - nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); + nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); #ifdef DEBUG_PASSWORD - DEBUG(100,("nt owf of user password: ")); - dump_data(100, lm_owf_user_pwd, 16); + DEBUG(100,("nt owf of user password: ")); + dump_data(100, lm_owf_user_pwd, 16); - DEBUG(100,("nt owf of user password: ")); - dump_data(100, nt_owf_user_pwd, 16); + DEBUG(100,("nt owf of user password: ")); + dump_data(100, nt_owf_user_pwd, 16); #endif - DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__)); + if (!cli_get_sesskey_srv(srv_name, sess_key)) + { + DEBUG(1,("could not obtain session key for %s\n", srv_name)); + return False; + } - /* indicate an "interactive" login */ - ctr->switch_value = INTERACTIVE_LOGON_TYPE; + /* indicate an "interactive" login */ + ctr->switch_value = INTERACTIVE_LOGON_TYPE; - /* Create the structure needed for SAM logon. */ - make_id_info1(&ctr->auth.id1, domain, 0, - luid_low, 0, - username, cli->clnt_name_slash, - (char *)cli->sess_key, lm_owf_user_pwd, nt_owf_user_pwd); + /* Create the structure needed for SAM logon. */ + make_id_info1(&ctr->auth.id1, domain, 0, + luid_low, 0, + username, myhostname, + (char *)sess_key, + lm_owf_user_pwd, nt_owf_user_pwd); - /* Ensure we overwrite all the plaintext password - equivalents. */ - memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd)); - memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd)); + /* Ensure we overwrite all the plaintext password + equivalents. */ + memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd)); + memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd)); - /* Send client sam-logon request - update credentials on success. */ - ret = cli_net_sam_logon(cli, fnum, ctr, user_info3); + /* Send client sam-logon request - update credentials on success. */ + ret = cli_net_sam_logon(srv_name, myhostname, ctr, user_info3); - memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd)); - memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd)); + memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd)); + memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd)); - return ret; + return ret; } /**************************************************************************** @@ -160,38 +172,44 @@ NT login - network. password equivalents over the network. JRA. ****************************************************************************/ -BOOL cli_nt_login_network(struct cli_state *cli, uint16 fnum, char *domain, char *username, - uint32 luid_low, char lm_chal[8], char lm_chal_resp[24], - char nt_chal_resp[24], - NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3) +BOOL cli_nt_login_network(const char* srv_name, const char* myhostname, + const char *domain, const char *username, + uint32 luid_low, char lm_chal[8], + char lm_chal_resp[24], + char nt_chal_resp[24], + NET_ID_INFO_CTR *ctr, + NET_USER_INFO_3 *user_info3) { - uchar key[16]; + uint8 sess_key[16]; BOOL ret; DEBUG(5,("cli_nt_login_network: %d\n", __LINE__)); + if (!cli_get_sesskey_srv(srv_name, sess_key)) + { + DEBUG(1,("could not obtain session key for %s\n", srv_name)); + return False; + } + /* indicate a "network" login */ ctr->switch_value = NET_LOGON_TYPE; /* Create the structure needed for SAM logon. */ make_id_info2(&ctr->auth.id2, domain, 0, luid_low, 0, - username, cli->clnt_name_slash, + username, myhostname, (uchar *)lm_chal, (uchar *)lm_chal_resp, (uchar *)nt_chal_resp); /* Send client sam-logon request - update credentials on success. */ - ret = cli_net_sam_logon(cli, fnum, ctr, user_info3); + ret = cli_net_sam_logon(srv_name, myhostname, ctr, user_info3); #ifdef DEBUG_PASSWORD DEBUG(100,("cli sess key:")); - dump_data(100, cli->sess_key, 8); + dump_data(100, sess_key, 8); DEBUG(100,("enc user sess key:")); dump_data(100, user_info3->user_sess_key, 16); #endif - memset(key, 0, 16); - memcpy(key, (char*)cli->sess_key, 8); - - SamOEMhash(user_info3->user_sess_key, key, False); + SamOEMhash(user_info3->user_sess_key, sess_key, False); #ifdef DEBUG_PASSWORD DEBUG(100,("dec user sess key:")); @@ -203,10 +221,49 @@ BOOL cli_nt_login_network(struct cli_state *cli, uint16 fnum, char *domain, char /**************************************************************************** NT Logoff. ****************************************************************************/ -BOOL cli_nt_logoff(struct cli_state *cli, uint16 fnum, NET_ID_INFO_CTR *ctr) +BOOL cli_nt_logoff(const char* srv_name, const char* myhostname, + NET_ID_INFO_CTR *ctr) { DEBUG(5,("cli_nt_logoff: %d\n", __LINE__)); /* Send client sam-logoff request - update credentials on success. */ - return cli_net_sam_logoff(cli, fnum, ctr); + return cli_net_sam_logoff(srv_name, myhostname, ctr); +} + +/**************************************************************************** +NT SAM database sync +****************************************************************************/ +BOOL net_sam_sync(const char* srv_name, const char* myhostname, + const char* trust_acct, + uchar trust_passwd[16], + SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS], + SAM_DELTA_CTR deltas [MAX_SAM_DELTAS], + uint32 *num_deltas) +{ + BOOL res = True; + + *num_deltas = 0; + + DEBUG(5,("Attempting SAM sync with PDC: %s\n", + srv_name)); + + res = res ? cli_nt_setup_creds( srv_name, myhostname, + trust_acct, + trust_passwd, SEC_CHAN_BDC) == 0x0 : False; + + memset(trust_passwd, 0, 16); + + res = res ? cli_net_sam_sync(srv_name, myhostname, + 0, num_deltas, hdr_deltas, deltas) : False; + + if (!res) + { + DEBUG(5, ("SAM synchronisation FAILED\n")); + return False; + } + + DEBUG(5, ("SAM synchronisation returned %d entries\n", *num_deltas)); + + return True; } + diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index c8240a3299..e9bb175c83 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -465,7 +465,7 @@ BOOL lsa_query_secret(POLICY_HND *hnd, STRING2 *secret, STRING2 enc_secret; memcpy(&enc_secret, &(r_q.info.value.enc_secret), sizeof(STRING2)); memcpy(last_update, &(r_q.info.last_update), sizeof(NTTIME)); - if (!cli_get_usr_sesskey(hnd, sess_key)) + if (!cli_get_sesskey(hnd, sess_key)) { return False; } diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index d6db75f243..1231c706d0 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -30,13 +30,12 @@ #include "includes.h" extern int DEBUGLEVEL; -extern pstring global_myname; /**************************************************************************** Generate the next creds to use. ****************************************************************************/ -static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) +void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) { /* * Create the new client credentials. @@ -52,54 +51,58 @@ static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) } -#if UNUSED_CODE /**************************************************************************** do a LSA Logon Control2 ****************************************************************************/ -BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint16 nt_pipe_fnum, uint32 status_level) +BOOL cli_net_logon_ctrl2(const char* srv_name, uint32 status_level) { - prs_struct rbuf; - prs_struct buf; - NET_Q_LOGON_CTRL2 q_l; - BOOL ok = False; + prs_struct rbuf; + prs_struct buf; + NET_Q_LOGON_CTRL2 q_l; + BOOL ok = False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); + struct cli_connection *con = NULL; - /* create and send a MSRPC command with api NET_LOGON_CTRL2 */ + if (!cli_connection_init(srv_name, PIPE_NETLOGON, &con)) + { + return False; + } - DEBUG(4,("do_net_logon_ctrl2 from %s status level:%x\n", - global_myname, status_level)); + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); - /* store the parameters */ - make_q_logon_ctrl2(&q_l, cli->srv_name_slash, status_level); + /* create and send a MSRPC command with api NET_LOGON_CTRL2 */ - /* turn parameters into data stream */ - net_io_q_logon_ctrl2("", &q_l, &buf, 0); + DEBUG(4,("net_logon_ctrl2 status level:%x\n", status_level)); - /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, nt_pipe_fnum, NET_LOGON_CTRL2, &buf, &rbuf)) - { - NET_R_LOGON_CTRL2 r_l; + /* store the parameters */ + make_q_logon_ctrl2(&q_l, srv_name, 0, 0, status_level); - net_io_r_logon_ctrl2("", &r_l, &rbuf, 0); - ok = (rbuf.offset != 0); - - if (ok && r_l.status != 0) - { - /* report error code */ - DEBUG(5,("do_net_logon_ctrl2: Error %s\n", get_nt_error_msg(r_l.status))); - cli->nt_error = r_l.status; - ok = False; - } - } + /* turn parameters into data stream */ + net_io_q_logon_ctrl2("", &q_l, &buf, 0); - prs_mem_free(&rbuf); - prs_mem_free(&buf ); + /* send the data on \PIPE\ */ + if (rpc_con_pipe_req(con, NET_LOGON_CTRL2, &buf, &rbuf)) + { + NET_R_LOGON_CTRL2 r_l; - return ok; + net_io_r_logon_ctrl2("", &r_l, &rbuf, 0); + ok = (rbuf.offset != 0); + + if (ok && r_l.status != 0) + { + /* report error code */ + DEBUG(5,("net_logon_ctrl2: Error %s\n", get_nt_error_msg(r_l.status))); + ok = False; + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + cli_connection_unlink(con); + return ok; } -#endif /**************************************************************************** LSA Authenticate 2 @@ -109,34 +112,50 @@ Ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ -uint32 cli_net_auth2(struct cli_state *cli, uint16 nt_pipe_fnum, +uint32 cli_net_auth2(const char *srv_name, const char *trust_acct, - const char *srv_name, uint16 sec_chan, + uint16 sec_chan, uint32 neg_flags, DOM_CHAL *srv_chal) { prs_struct rbuf; prs_struct buf; NET_Q_AUTH_2 q_a; uint32 status = 0x0; + uint8 sess_key[16]; + DOM_CRED clnt_cred; + + struct cli_connection *con = NULL; + + if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con)) + { + return False; + } + + if (!cli_get_con_sesskey(con, sess_key)) + { + return False; + } prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); /* create and send a MSRPC command with api NET_AUTH2 */ - DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", - cli->srv_name_slash, cli->mach_acct, sec_chan, srv_name, - credstr(cli->clnt_cred.challenge.data), neg_flags)); + DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s neg: %x\n", + srv_name, trust_acct, sec_chan, srv_name, + neg_flags)); + + cli_con_get_cli_cred(con, &clnt_cred); /* store the parameters */ - make_q_auth_2(&q_a, cli->srv_name_slash, trust_acct, sec_chan, srv_name, - &cli->clnt_cred.challenge, neg_flags); + make_q_auth_2(&q_a, srv_name, trust_acct, sec_chan, srv_name, + &clnt_cred.challenge, neg_flags); /* turn parameters into data stream */ net_io_q_auth_2("", &q_a, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, nt_pipe_fnum, NET_AUTH2, &buf, &rbuf)) + if (rpc_con_pipe_req(con, NET_AUTH2, &buf, &rbuf)) { NET_R_AUTH_2 r_a; @@ -148,7 +167,6 @@ uint32 cli_net_auth2(struct cli_state *cli, uint16 nt_pipe_fnum, /* report error code */ DEBUG(5,("cli_net_auth2: Error %s\n", get_nt_error_msg(r_a.status))); - cli->nt_error = r_a.status; status = r_a.status; } @@ -161,13 +179,14 @@ uint32 cli_net_auth2(struct cli_state *cli, uint16 nt_pipe_fnum, UTIME zerotime; zerotime.time = 0; - if(cred_assert( &r_a.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) + if(cred_assert( &r_a.srv_chal, sess_key, + srv_chal, zerotime) == 0) { /* * Server replied with bad credential. Fail. */ - DEBUG(5,("cli_net_auth2: server %s replied with bad credential (bad machine \ - password ?).\n", cli->desthost )); + DEBUG(5,("cli_net_auth2: server %s replied \ +with bad credential (bad trust account password ?).\n", srv_name)); status = NT_STATUS_NETWORK_CREDENTIAL_CONFLICT | 0xC0000000; } } @@ -190,7 +209,7 @@ uint32 cli_net_auth2(struct cli_state *cli, uint16 nt_pipe_fnum, } else { - DEBUG(5,("rpc_api_pipe_req FAILED\n")); + DEBUG(5,("rpc_con_pipe_req FAILED\n")); status = 0xC0000000 | NT_STATUS_ACCESS_DENIED; } @@ -207,8 +226,7 @@ LSA Request Challenge. Sends our challenge to server, then gets server response. These are used to generate the credentials. ****************************************************************************/ -uint32 cli_net_req_chal(struct cli_state *cli, uint16 nt_pipe_fnum, - const char *srv_name, +uint32 cli_net_req_chal( const char *srv_name, const char* myhostname, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal) { prs_struct rbuf; @@ -216,6 +234,13 @@ uint32 cli_net_req_chal(struct cli_state *cli, uint16 nt_pipe_fnum, NET_Q_REQ_CHAL q_c; uint32 status = 0x0; + struct cli_connection *con = NULL; + + if (!cli_connection_init(srv_name, PIPE_NETLOGON, &con)) + { + return False; + } + if (srv_chal == NULL || clnt_chal == NULL) return 0xC0000000 | NT_STATUS_INVALID_PARAMETER; @@ -225,16 +250,16 @@ uint32 cli_net_req_chal(struct cli_state *cli, uint16 nt_pipe_fnum, /* create and send a MSRPC command with api NET_REQCHAL */ DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", - cli->desthost, srv_name, credstr(clnt_chal->data))); + srv_name, myhostname, credstr(clnt_chal->data))); /* store the parameters */ - make_q_req_chal(&q_c, cli->srv_name_slash, srv_name, clnt_chal); + make_q_req_chal(&q_c, srv_name, myhostname, clnt_chal); /* turn parameters into data stream */ net_io_q_req_chal("", &q_c, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, nt_pipe_fnum, NET_REQCHAL, &buf, &rbuf)) + if (rpc_con_pipe_req(con, NET_REQCHAL, &buf, &rbuf)) { NET_R_REQ_CHAL r_c; @@ -245,7 +270,6 @@ uint32 cli_net_req_chal(struct cli_state *cli, uint16 nt_pipe_fnum, { /* report error code */ DEBUG(5,("cli_net_req_chal: Error %s\n", get_nt_error_msg(r_c.status))); - cli->nt_error = r_c.status; status = r_c.status; } @@ -257,7 +281,7 @@ uint32 cli_net_req_chal(struct cli_state *cli, uint16 nt_pipe_fnum, } else { - DEBUG(5,("rpc_api_pipe_req FAILED\n")); + DEBUG(5,("rpc_con_pipe_req FAILED\n")); status = 0xC0000000 | NT_STATUS_ACCESS_DENIED; } @@ -271,16 +295,37 @@ uint32 cli_net_req_chal(struct cli_state *cli, uint16 nt_pipe_fnum, LSA Server Password Set. ****************************************************************************/ -BOOL cli_net_srv_pwset(struct cli_state *cli, uint16 nt_pipe_fnum, - uint8 hashed_mach_pwd[16], uint16 sec_chan_type) +BOOL cli_net_srv_pwset(const char* srv_name, + const char* myhostname, + const char* trust_acct, + uint8 hashed_trust_pwd[16], + uint16 sec_chan_type) { prs_struct rbuf; prs_struct buf; DOM_CRED new_clnt_cred; NET_Q_SRV_PWSET q_s; BOOL ok = False; + unsigned char processed_new_pwd[16]; + /* Process the new password. */ + + uint8 sess_key[16]; + + struct cli_connection *con = NULL; - gen_next_creds( cli, &new_clnt_cred); + if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con)) + { + return False; + } + + if (!cli_get_con_sesskey(con, sess_key)) + { + return False; + } + + cred_hash3( processed_new_pwd, hashed_trust_pwd, sess_key, 1); + + cli_con_gen_next_creds( con, &new_clnt_cred); prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); @@ -288,18 +333,18 @@ BOOL cli_net_srv_pwset(struct cli_state *cli, uint16 nt_pipe_fnum, /* create and send a MSRPC command with api NET_SRV_PWSET */ DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n", - cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname, + srv_name, trust_acct, sec_chan_type, myhostname, credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time)); /* store the parameters */ - make_q_srv_pwset(&q_s, cli->srv_name_slash, cli->mach_acct, sec_chan_type, - global_myname, &new_clnt_cred, (char *)hashed_mach_pwd); + make_q_srv_pwset(&q_s, srv_name, trust_acct, sec_chan_type, + myhostname, &new_clnt_cred, (char *)processed_new_pwd); /* turn parameters into data stream */ net_io_q_srv_pwset("", &q_s, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, nt_pipe_fnum, NET_SRVPWSET, &buf, &rbuf)) + if (rpc_con_pipe_req(con, NET_SRVPWSET, &buf, &rbuf)) { NET_R_SRV_PWSET r_s; @@ -310,18 +355,17 @@ BOOL cli_net_srv_pwset(struct cli_state *cli, uint16 nt_pipe_fnum, { /* report error code */ DEBUG(5,("cli_net_srv_pwset: %s\n", get_nt_error_msg(r_s.status))); - cli->nt_error = r_s.status; ok = False; } /* Update the credentials. */ - if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred))) + if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_cred))) { /* * Server replied with bad credential. Fail. */ - DEBUG(5,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \ -password ?).\n", cli->desthost )); + DEBUG(5,("cli_net_srv_pwset: server %s replied with bad credential \ +(bad trust account password ?).\n", srv_name)); ok = False; } } @@ -336,8 +380,9 @@ password ?).\n", cli->desthost )); LSA SAM Logon - interactive or network. ****************************************************************************/ -BOOL cli_net_sam_logon(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_CTR *ctr, - NET_USER_INFO_3 *user_info3) +BOOL cli_net_sam_logon(const char* srv_name, const char* myhostname, + NET_ID_INFO_CTR *ctr, + NET_USER_INFO_3 *user_info3) { DOM_CRED new_clnt_cred; DOM_CRED dummy_rtn_creds; @@ -347,30 +392,36 @@ BOOL cli_net_sam_logon(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_C NET_Q_SAM_LOGON q_s; BOOL ok = False; - gen_next_creds( cli, &new_clnt_cred); + struct cli_connection *con = NULL; + + if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con)) + { + return False; + } + + cli_con_gen_next_creds( con, &new_clnt_cred); prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); /* create and send a MSRPC command with api NET_SAMLOGON */ - DEBUG(4,("cli_net_sam_logon: srv:%s mc:%s clnt %s %x ll: %d\n", - cli->srv_name_slash, global_myname, - credstr(new_clnt_cred.challenge.data), cli->clnt_cred.timestamp.time, + DEBUG(4,("cli_net_sam_logon: srv:%s mc:%s ll: %d\n", + srv_name, myhostname, ctr->switch_value)); memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); dummy_rtn_creds.timestamp.time = time(NULL); /* store the parameters */ - make_sam_info(&(q_s.sam_id), cli->srv_name_slash, global_myname, + make_sam_info(&(q_s.sam_id), srv_name, myhostname, &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr, validation_level); /* turn parameters into data stream */ net_io_q_sam_logon("", &q_s, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, nt_pipe_fnum, NET_SAMLOGON, &buf, &rbuf)) + if (rpc_con_pipe_req(con, NET_SAMLOGON, &buf, &rbuf)) { NET_R_SAM_LOGON r_s; @@ -383,18 +434,17 @@ BOOL cli_net_sam_logon(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_C { /* report error code */ DEBUG(5,("cli_net_sam_logon: %s\n", get_nt_error_msg(r_s.status))); - cli->nt_error = r_s.status; ok = False; } /* Update the credentials. */ - if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds))) + if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds))) { /* * Server replied with bad credential. Fail. */ - DEBUG(5,("cli_net_sam_logon: server %s replied with bad credential (bad machine \ -password ?).\n", cli->desthost )); + DEBUG(5,("cli_net_sam_logon: server %s replied with bad credential \ +(bad trust account password ?).\n", srv_name)); ok = False; } @@ -422,7 +472,8 @@ send a different info level. Right now though, I'm not sure what that needs to be (I need to see one on the wire before I can be sure). JRA. ****************************************************************************/ -BOOL cli_net_sam_logoff(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_CTR *ctr) +BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname, + NET_ID_INFO_CTR *ctr) { DOM_CRED new_clnt_cred; DOM_CRED dummy_rtn_creds; @@ -432,7 +483,14 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_ uint16 validation_level = 3; BOOL ok = False; - gen_next_creds( cli, &new_clnt_cred); + struct cli_connection *con = NULL; + + if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con)) + { + return False; + } + + cli_con_gen_next_creds( con, &new_clnt_cred); prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); @@ -440,21 +498,21 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_ /* create and send a MSRPC command with api NET_SAMLOGOFF */ DEBUG(4,("cli_net_sam_logoff: srv:%s mc:%s clnt %s %x ll: %d\n", - cli->srv_name_slash, global_myname, + srv_name, myhostname, credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time, ctr->switch_value)); memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); /* store the parameters */ - make_sam_info(&(q_s.sam_id), cli->srv_name_slash, global_myname, + make_sam_info(&(q_s.sam_id), srv_name, myhostname, &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr, validation_level); /* turn parameters into data stream */ net_io_q_sam_logoff("", &q_s, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, nt_pipe_fnum, NET_SAMLOGOFF, &buf, &rbuf)) + if (rpc_con_pipe_req(con, NET_SAMLOGOFF, &buf, &rbuf)) { NET_R_SAM_LOGOFF r_s; @@ -465,18 +523,17 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, uint16 nt_pipe_fnum, NET_ID_INFO_ { /* report error code */ DEBUG(5,("cli_net_sam_logoff: %s\n", get_nt_error_msg(r_s.status))); - cli->nt_error = r_s.status; ok = False; } /* Update the credentials. */ - if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds))) + if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds))) { /* * Server replied with bad credential. Fail. */ - DEBUG(5,("cli_net_sam_logoff: server %s replied with bad credential (bad machine \ -password ?).\n", cli->desthost )); + DEBUG(5,("cli_net_sam_logoff: server %s replied with bad credential \ +(bad trust account password ?).\n", srv_name )); ok = False; } } @@ -490,8 +547,7 @@ password ?).\n", cli->desthost )); /*************************************************************************** Synchronise SAM Database (requires SEC_CHAN_BDC). ****************************************************************************/ -BOOL cli_net_sam_sync(struct cli_state *cli, uint16 nt_pipe_fnum, - const char* srv_name, +BOOL cli_net_sam_sync( const char* srv_name, const char* myhostname, uint32 database_id, uint32 *num_deltas, SAM_DELTA_HDR *hdr_deltas, @@ -502,43 +558,56 @@ BOOL cli_net_sam_sync(struct cli_state *cli, uint16 nt_pipe_fnum, prs_struct buf; DOM_CRED new_clnt_cred; BOOL ok = False; + uint8 sess_key[16]; - gen_next_creds(cli, &new_clnt_cred); + struct cli_connection *con = NULL; + + if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con)) + { + return False; + } + + if (!cli_get_con_sesskey(con, sess_key)) + { + return False; + } + + cli_con_gen_next_creds(con, &new_clnt_cred); prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); /* create and send a MSRPC command with api NET_SAM_SYNC */ - make_q_sam_sync(&q_s, cli->srv_name_slash, srv_name, + make_q_sam_sync(&q_s, srv_name, myhostname, &new_clnt_cred, database_id); /* turn parameters into data stream */ net_io_q_sam_sync("", &q_s, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, nt_pipe_fnum, NET_SAM_SYNC, &buf, &rbuf)) + if (rpc_con_pipe_req(con, NET_SAM_SYNC, &buf, &rbuf)) { NET_R_SAM_SYNC r_s; r_s.hdr_deltas = hdr_deltas; r_s.deltas = deltas; - net_io_r_sam_sync("", cli->sess_key, &r_s, &rbuf, 0); + net_io_r_sam_sync("", sess_key, &r_s, &rbuf, 0); ok = (rbuf.offset != 0); if (ok && r_s.status != 0 && r_s.status != STATUS_MORE_ENTRIES) { /* report error code */ DEBUG(5,("cli_net_sam_sync: %s\n", get_nt_error_msg(r_s.status))); - cli->nt_error = r_s.status; ok = False; } /* Update the credentials. */ - if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds))) + if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds))) { - DEBUG(5,("cli_net_sam_sync: server %s replied with bad credential (bad machine password ?).\n", cli->desthost)); + DEBUG(5,("cli_net_sam_sync: server %s replied with bad \ +credential (bad trust account password ?).\n", srv_name)); ok = False; } @@ -558,46 +627,3 @@ BOOL cli_net_sam_sync(struct cli_state *cli, uint16 nt_pipe_fnum, return ok; } - - -BOOL do_sam_sync(struct cli_state *cli, uchar trust_passwd[16], - const char* acct_name, - const char* srv_name, - SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS], - SAM_DELTA_CTR deltas [MAX_SAM_DELTAS], - uint32 *num_deltas) -{ - uint16 nt_pipe_fnum; - BOOL res = True; - - *num_deltas = 0; - - DEBUG(5,("Attempting SAM sync with PDC: %s\n", - srv_name)); - - /* open NETLOGON session. negotiate credentials */ - res = res ? cli_nt_session_open(cli, PIPE_NETLOGON, &nt_pipe_fnum) : False; - - res = res ? cli_nt_setup_creds(cli, nt_pipe_fnum, - acct_name, srv_name, - trust_passwd, SEC_CHAN_BDC) == 0x0 : False; - - memset(trust_passwd, 0, 16); - - res = res ? cli_net_sam_sync(cli, nt_pipe_fnum, srv_name, - 0, num_deltas, hdr_deltas, deltas) : False; - - /* close the session */ - cli_nt_session_close(cli, nt_pipe_fnum); - - if (!res) - { - DEBUG(5, ("SAM synchronisation FAILED\n")); - return False; - } - - DEBUG(5, ("SAM synchronisation returned %d entries\n", *num_deltas)); - - return True; -} - diff --git a/source3/rpc_client/cli_netlogon_sync.c b/source3/rpc_client/cli_netlogon_sync.c index 526f366a15..fad802d0c9 100644 --- a/source3/rpc_client/cli_netlogon_sync.c +++ b/source3/rpc_client/cli_netlogon_sync.c @@ -44,23 +44,34 @@ BOOL synchronise_passdb(void) unsigned char smb_passwd[16]; unsigned char smb_nt_passwd[16]; uchar trust_passwd[16]; + fstring trust_acct; + fstring srv_name; char *mode; BOOL success; BOOL ret; int i; + DEBUG(0,("cannot make connection to multi-list of servers yet!\n")); + if (!cli_connect_serverlist(&cli, lp_passwordserver())) { return False; } + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, lp_passwordserver()); /* LKCL XXXX oops! */ + strupper(srv_name); + + fstrcpy(trust_acct, global_myname); + fstrcat(trust_acct, "$"); + if (!trust_get_passwd(trust_passwd, lp_workgroup(), global_myname)) { return False; } - ret = do_sam_sync(&cli, trust_passwd, cli.mach_acct, global_myname, + ret = net_sam_sync(srv_name, global_myname, trust_acct, trust_passwd, hdr_deltas, deltas, &num); if (ret) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8ca5255203..f8216cb1e0 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1125,18 +1125,6 @@ BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name, * Setup the remote server name prefixed by \ and the machine account name. */ - fstrcpy(cli->srv_name_slash, "\\\\"); - fstrcat(cli->srv_name_slash, cli->desthost); - strupper(cli->srv_name_slash); - - fstrcpy(cli->clnt_name_slash, "\\\\"); - fstrcat(cli->clnt_name_slash, global_myname); - strupper(cli->clnt_name_slash); - - fstrcpy(cli->mach_acct, global_myname); - fstrcat(cli->mach_acct, "$"); - strupper(cli->mach_acct); - return True; } diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index c6e366bbbe..cd1476e201 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -163,6 +163,30 @@ static BOOL net_io_netinfo_2(char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, return True; } +/******************************************************************* +makes an NET_Q_LOGON_CTRL2 structure. +********************************************************************/ +BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, + const char* srv_name, + uint32 function_code, + uint32 query_level, + uint32 switch_value) +{ + if (q_l == NULL) return False; + + DEBUG(5,("make_q_logon_ctrl2\n")); + + q_l->ptr = 1; + + make_unistr2(&(q_l->uni_server_name ), srv_name , strlen(srv_name )+1); + + q_l->function_code = function_code; + q_l->query_level = query_level; + q_l->switch_value = switch_value; + + return True; +} + /******************************************************************* reads or writes an NET_Q_LOGON_CTRL2 structure. ********************************************************************/ @@ -552,8 +576,10 @@ BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth) /******************************************************************* reads or writes a structure. ********************************************************************/ -BOOL 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]) +BOOL make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, + const char *logon_srv, const char *acct_name, + uint16 sec_chan, const char *comp_name, + DOM_CRED *cred, char nt_cypher[16]) { if (q_s == NULL || cred == NULL) return False; @@ -634,9 +660,9 @@ static int make_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids) /******************************************************************* makes a NET_ID_INFO_1 structure. ********************************************************************/ -BOOL make_id_info1(NET_ID_INFO_1 *id, char *domain_name, +BOOL make_id_info1(NET_ID_INFO_1 *id, const char *domain_name, uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high, - char *user_name, char *wksta_name, + const char *user_name, const char *wksta_name, char sess_key[16], unsigned char lm_cypher[16], unsigned char nt_cypher[16]) { @@ -753,9 +779,10 @@ checking for a logon as it doesn't export the password hashes to anyone who has compromised the secure channel. JRA. ********************************************************************/ -BOOL 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, +BOOL make_id_info2(NET_ID_INFO_2 *id, const char *domain_name, + uint32 param_ctrl, + uint32 log_id_low, uint32 log_id_high, + const char *user_name, const char *wksta_name, unsigned char lm_challenge[8], unsigned char lm_chal_resp[24], unsigned char nt_chal_resp[24]) @@ -854,7 +881,8 @@ static BOOL net_io_id_info2(char *desc, NET_ID_INFO_2 *id, prs_struct *ps, int makes a DOM_SAM_INFO structure. ********************************************************************/ BOOL make_sam_info(DOM_SAM_INFO *sam, - char *logon_srv, char *comp_name, DOM_CRED *clnt_cred, + const char *logon_srv, const char *comp_name, + DOM_CRED *clnt_cred, DOM_CRED *rtn_cred, uint16 logon_level, NET_ID_INFO_CTR *ctr, uint16 validation_level) { diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 50f85ea5f2..e9d425d869 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -5673,7 +5673,7 @@ BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u, case 0x18: { uchar sess_key[16]; - if (!cli_get_usr_sesskey(hnd, sess_key)) + if (!cli_get_sesskey(hnd, sess_key)) { return False; } @@ -5685,7 +5685,7 @@ BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u, case 0x17: { uchar sess_key[16]; - if (!cli_get_usr_sesskey(hnd, sess_key)) + if (!cli_get_sesskey(hnd, sess_key)) { return False; } diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 67585ffff4..3010ed5297 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -33,11 +33,9 @@ extern int DEBUGLEVEL; #define DEBUG_TESTING -extern struct cli_state *smb_cli; extern struct user_credentials *usr_creds; extern FILE* out_hnd; -extern pstring global_myname; /**************************************************************************** @@ -45,7 +43,6 @@ experimental nt login. ****************************************************************************/ void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]) { - uint16 nt_pipe_fnum; #if 0 extern BOOL global_machine_password_needs_changing; #endif @@ -55,6 +52,12 @@ void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]) BOOL res = True; char *nt_password; unsigned char trust_passwd[16]; + fstring trust_acct; + + fstring srv_name; + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, info->dest_host); + strupper(srv_name); #if 0 /* machine account passwords */ @@ -93,7 +96,11 @@ void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]) nt_password = getpass("Enter NT Login password:"); } - DEBUG(5,("do_nt_login_test: username %s\n", nt_user_name)); + 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 ? trust_get_passwd(trust_passwd, usr_creds->domain, info->myhostname) : False; @@ -103,11 +110,9 @@ void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]) info->myhostname, usr_creds->domain, info->mach_acct, new_mach_pwd) : False; #endif - /* open NETLOGON session. negotiate credentials */ - res = res ? cli_nt_session_open(smb_cli, PIPE_NETLOGON, &nt_pipe_fnum) : False; - res = res ? cli_nt_setup_creds(smb_cli, nt_pipe_fnum, - smb_cli->mach_acct, global_myname, + res = res ? cli_nt_setup_creds(srv_name, info->myhostname, + trust_acct, trust_passwd, SEC_CHAN_WKSTA) == 0x0 : False; #if 0 @@ -116,7 +121,7 @@ void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]) { unsigned char new_trust_passwd[16]; generate_random_buffer(new_trust_passwd, 16, True); - res = res ? cli_nt_srv_pwset(smb_cli, nt_pipe_fnum, new_trust_passwd, SEC_CHAN_WKSTA) : False; + res = res ? cli_nt_srv_pwset(srv_name, info->myhostname, new_trust_passwd, SEC_CHAN_WKSTA) : False; if (res) { @@ -130,7 +135,7 @@ void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]) memset(trust_passwd, 0, 16); /* do an NT login */ - res = res ? cli_nt_login_interactive(smb_cli, nt_pipe_fnum, + res = res ? cli_nt_login_interactive(srv_name, info->myhostname, usr_creds->domain, nt_user_name, getuid(), nt_password, &info->dom.ctr, &info->dom.user_info3) : False; @@ -141,10 +146,7 @@ void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]) /* ok! you're logged in! do anything you like, then... */ /* do an NT logout */ - res = res ? cli_nt_logoff(smb_cli, nt_pipe_fnum, &info->dom.ctr) : False; - - /* close the session */ - cli_nt_session_close(smb_cli, nt_pipe_fnum); + res = res ? cli_nt_logoff(srv_name, info->myhostname, &info->dom.ctr) : False; report(out_hnd,"cmd_nt_login: login (%s) test succeeded: %s\n", nt_user_name, BOOLSTR(res)); @@ -155,13 +157,16 @@ experimental nt login. ****************************************************************************/ void cmd_netlogon_domain_test(struct client_info *info, int argc, char *argv[]) { - uint16 nt_pipe_fnum; - char *nt_trust_dom; BOOL res = True; unsigned char trust_passwd[16]; fstring inter_dom_acct; + fstring srv_name; + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, info->dest_host); + strupper(srv_name); + if (argc < 2) { report(out_hnd,"domtest: must specify domain name\n"); @@ -177,18 +182,12 @@ void cmd_netlogon_domain_test(struct client_info *info, int argc, char *argv[]) res = res ? trust_get_passwd(trust_passwd, usr_creds->domain, nt_trust_dom) : False; - /* open NETLOGON session. negotiate credentials */ - res = res ? cli_nt_session_open(smb_cli, PIPE_NETLOGON, &nt_pipe_fnum) : False; - - res = res ? cli_nt_setup_creds(smb_cli, nt_pipe_fnum, inter_dom_acct, - global_myname, trust_passwd, + res = res ? cli_nt_setup_creds(srv_name, info->myhostname, inter_dom_acct, + trust_passwd, SEC_CHAN_DOMAIN) == 0x0 : False; memset(trust_passwd, 0, 16); - /* close the session */ - cli_nt_session_close(smb_cli, nt_pipe_fnum); - report(out_hnd,"cmd_nt_login: credentials (%s) test succeeded: %s\n", nt_trust_dom, BOOLSTR(res)); } @@ -202,16 +201,24 @@ void cmd_sam_sync(struct client_info *info, int argc, char *argv[]) SAM_DELTA_CTR deltas[MAX_SAM_DELTAS]; uint32 num; uchar trust_passwd[16]; - extern pstring global_myname; + fstring srv_name; + fstring trust_acct; + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, info->dest_host); + strupper(srv_name); + + fstrcpy(trust_acct, info->myhostname); + fstrcat(trust_acct, "$"); - if (!trust_get_passwd(trust_passwd, usr_creds->domain, global_myname)) + if (!trust_get_passwd(trust_passwd, usr_creds->domain, info->myhostname)) { report(out_hnd, "cmd_sam_sync: no trust account password\n"); return; } - if (do_sam_sync(smb_cli, trust_passwd, - smb_cli->mach_acct, global_myname, + if (net_sam_sync(srv_name, info->myhostname, + trust_acct, trust_passwd, hdr_deltas, deltas, &num)) { display_sam_sync(out_hnd, ACTION_HEADER , hdr_deltas, deltas, num); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index aaf872683a..3951b8e564 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -49,9 +49,6 @@ static void cmd_set (struct client_info *info, int argc, char *argv[]); static struct user_credentials usr; -static struct cli_state smbcli; -struct cli_state *smb_cli = &smbcli; - static struct client_info cli_info; static char **cmd_argv = NULL; @@ -788,14 +785,14 @@ static BOOL process( struct client_info *info, char *cmd_str) fflush(out_hnd); #ifdef CLIX - line[0] = wait_keyboard(smb_cli); + line[0] = wait_keyboard(NULL); /* this might not be such a good idea... */ if ( line[0] == EOF) { break; } #else - wait_keyboard(smb_cli); + wait_keyboard(NULL); #endif /* and get a response */ @@ -1185,7 +1182,7 @@ static char *complete_printersenum(char *text, int state) { fstring srv_name; fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, smb_cli->desthost); + fstrcat(srv_name, cli_info.dest_host); strupper(srv_name); free_print1_array(num, ctr); @@ -1193,7 +1190,7 @@ static char *complete_printersenum(char *text, int state) num = 0; /* Iterate all users */ - if (!msrpc_spoolss_enum_printers(smb_cli, srv_name, + if (!msrpc_spoolss_enum_printers(srv_name, 1, &num, (void***)&ctr, NULL)) { @@ -1609,10 +1606,6 @@ static void cmd_set(struct client_info *info, int argc, char *argv[]) load_interfaces(); } - fstrcpy(cli_info.mach_acct, cli_info.myhostname); - strupper(cli_info.mach_acct); - fstrcat(cli_info.mach_acct, "$"); - if (cmd_str != NULL) { process(&cli_info, cmd_str); -- cgit