From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/rpc_client/cli_login.c | 275 ++-- source3/rpc_client/cli_lsarpc.c | 1058 +++------------ source3/rpc_client/cli_netlogon.c | 758 ++++++----- source3/rpc_client/cli_pipe.c | 1439 +++++++++++--------- source3/rpc_client/cli_reg.c | 1233 ++++++++--------- source3/rpc_client/cli_samr.c | 2640 +++++++----------------------------- source3/rpc_client/cli_srvsvc.c | 594 +++----- source3/rpc_client/cli_wkssvc.c | 72 +- source3/rpc_client/ntclienttrust.c | 10 +- 9 files changed, 2800 insertions(+), 5279 deletions(-) (limited to 'source3/rpc_client') diff --git a/source3/rpc_client/cli_login.c b/source3/rpc_client/cli_login.c index 9b26ca60f4..5fe392f214 100644 --- a/source3/rpc_client/cli_login.c +++ b/source3/rpc_client/cli_login.c @@ -4,6 +4,7 @@ NT Domain Authentication SMB / MSRPC client Copyright (C) Andrew Tridgell 1994-1997 Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + Copyright (C) Jeremy Allison 1999. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,85 +25,76 @@ #include "nterr.h" extern int DEBUGLEVEL; +extern fstring global_myworkgroup; +extern pstring global_myname; /**************************************************************************** Initialize domain session credentials. ****************************************************************************/ -uint32 cli_nt_setup_creds( const char* srv_name, const char* myhostname, - const char* trust_acct, - unsigned char trust_pwd[16], - uint16 sec_chan) +BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16]) { - DOM_CHAL clnt_chal; - DOM_CHAL srv_chal; - uint32 ret; - UTIME zerotime; - uint8 sess_key[16]; - DOM_CRED clnt_cred; - - /******************* Request Challenge ********************/ - - generate_random_buffer( clnt_chal.data, 8, False); - - /* 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; - } - - /**************** Long-term Session key **************/ - - /* calculate the session key */ - cred_session_key(&clnt_chal, &srv_chal, (char *)trust_pwd, sess_key); - bzero(sess_key+8, 8); - - /******************* Authenticate 2 ********************/ - - /* calculate auth-2 credentials */ - zerotime.time = 0; - cred_create(sess_key, &clnt_chal, zerotime, &clnt_cred.challenge); - - if (!cli_con_set_creds(srv_name, sess_key, &clnt_cred)) - { - return NT_STATUS_ACCESS_DENIED | 0xC0000000; - } - - /* - * Send client auth-2 challenge. - * Receive an auth-2 challenge response and check it. - */ - - ret = cli_net_auth2(srv_name, trust_acct, myhostname, - sec_chan, 0x000001ff, &srv_chal); - if (ret != 0x0) - { - DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed. status: %x\n", ret)); - } - - return ret; + DOM_CHAL clnt_chal; + DOM_CHAL srv_chal; + + UTIME zerotime; + + /******************* Request Challenge ********************/ + + generate_random_buffer( clnt_chal.data, 8, False); + + /* send a client challenge; receive a server challenge */ + if (!cli_net_req_chal(cli, &clnt_chal, &srv_chal)) + { + DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); + return False; + } + + /**************** Long-term Session key **************/ + + /* calculate the session key */ + cred_session_key(&clnt_chal, &srv_chal, (char *)mach_pwd, cli->sess_key); + memset((char *)cli->sess_key+8, '\0', 8); + + /******************* Authenticate 2 ********************/ + + /* calculate auth-2 credentials */ + zerotime.time = 0; + cred_create(cli->sess_key, &clnt_chal, zerotime, &(cli->clnt_cred.challenge)); + + /* + * Send client auth-2 challenge. + * Receive an auth-2 challenge response and check it. + */ + + if (!cli_net_auth2(cli, SEC_CHAN_WKSTA, 0x000001ff, &srv_chal)) + { + DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed\n")); + return False; + } + + return True; } /**************************************************************************** Set machine password. ****************************************************************************/ -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_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd) { + 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); + dump_data(6, (char *)new_hashof_mach_pwd, 16); #endif + /* Process the new password. */ + cred_hash3( processed_new_pwd, new_hashof_mach_pwd, cli->sess_key, 1); + /* send client srv_pwset challenge */ - return cli_net_srv_pwset(srv_name, myhostname, trust_acct, - new_hashof_trust_pwd, sec_chan); + return cli_net_srv_pwset(cli, processed_new_pwd); } /**************************************************************************** @@ -111,59 +103,51 @@ 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(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_interactive(struct cli_state *cli, char *domain, char *username, + uint32 smb_userid_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; - uint8 sess_key[16]; + uchar lm_owf_user_pwd[16]; + uchar nt_owf_user_pwd[16]; + BOOL ret; - 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, (char *)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, (char *)nt_owf_user_pwd, 16); #endif - if (!cli_get_sesskey_srv(srv_name, sess_key)) - { - DEBUG(1,("could not obtain session key for %s\n", srv_name)); - return False; - } + DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__)); - /* 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, myhostname, - (char *)sess_key, - lm_owf_user_pwd, nt_owf_user_pwd); + /* Create the structure needed for SAM logon. */ + init_id_info1(&ctr->auth.id1, domain, 0, + smb_userid_low, 0, + username, cli->clnt_name_slash, + (char *)cli->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(srv_name, myhostname, ctr, user_info3); + /* Send client sam-logon request - update credentials on success. */ + ret = cli_net_sam_logon(cli, 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; } /**************************************************************************** @@ -172,98 +156,33 @@ NT login - network. password equivalents over the network. JRA. ****************************************************************************/ -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_login_network(struct cli_state *cli, char *domain, char *username, + uint32 smb_userid_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) { - 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; - } + DEBUG(5,("cli_nt_login_network: %d\n", __LINE__)); - /* 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, 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(srv_name, myhostname, ctr, user_info3); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("cli sess key:")); - dump_data(100, sess_key, 8); - DEBUG(100,("enc user sess key:")); - dump_data(100, user_info3->user_sess_key, 16); -#endif + /* indicate a "network" login */ + ctr->switch_value = NET_LOGON_TYPE; - SamOEMhash(user_info3->user_sess_key, sess_key, False); + /* Create the structure needed for SAM logon. */ + init_id_info2(&ctr->auth.id2, domain, 0, + smb_userid_low, 0, + username, cli->clnt_name_slash, + (uchar *)lm_chal, (uchar *)lm_chal_resp, (uchar *)nt_chal_resp); -#ifdef DEBUG_PASSWORD - DEBUG(100,("dec user sess key:")); - dump_data(100, user_info3->user_sess_key, 16); -#endif - return ret; + /* Send client sam-logon request - update credentials on success. */ + return cli_net_sam_logon(cli, ctr, user_info3); } /**************************************************************************** NT Logoff. ****************************************************************************/ -BOOL cli_nt_logoff(const char* srv_name, const char* myhostname, - NET_ID_INFO_CTR *ctr) +BOOL cli_nt_logoff(struct cli_state *cli, 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(srv_name, myhostname, ctr); + return cli_net_sam_logoff(cli, 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 b039bde159..cfd562785b 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -6,6 +6,7 @@ * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. + * Copyright (C) Jeremy Allison 1999. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,732 +32,180 @@ extern int DEBUGLEVEL; -/**************************************************************************** - obtain the sid from the PDC. do some verification along the way... -****************************************************************************/ -BOOL get_domain_sids(const char *domain, DOM_SID *sid3, DOM_SID *sid5) -{ - POLICY_HND pol; - fstring srv_name; - struct cli_connection *con = NULL; - BOOL res = True; - BOOL res1 = True; - fstring dom3; - fstring dom5; - extern struct ntuser_creds *usr_creds; - struct ntuser_creds usr; - - usr_creds = &usr; - ZERO_STRUCT(usr); - pwd_set_nullpwd(&usr.pwd); - - if (sid3 == NULL && sid5 == NULL) - { - /* don't waste my time... */ - return False; - } - - if (!get_any_dc_name(domain, srv_name)) - { - return False; - } - - /* - * Ok - we have an anonymous connection to the IPC$ share. - * Now start the NT Domain stuff :-). - */ - - fstrcpy(dom3, ""); - fstrcpy(dom5, ""); - if (sid3 != NULL) - { - ZERO_STRUCTP(sid3); - } - if (sid5 != NULL) - { - ZERO_STRUCTP(sid5); - } - - /* lookup domain controller; receive a policy handle */ - res = res ? lsa_open_policy(srv_name, &pol, False) : False; - - if (sid3 != NULL) - { - /* send client info query, level 3. receive domain name and sid */ - res1 = res ? lsa_query_info_pol(&pol, 3, dom3, sid3) : False; - } - - if (sid5 != NULL) - { - /* send client info query, level 5. receive domain name and sid */ - res1 = res1 ? lsa_query_info_pol(&pol, 5, dom5, sid5) : False; - } - - /* close policy handle */ - res = res ? lsa_close(&pol) : False; - - /* close the session */ - cli_connection_unlink(con); - - if (res1) - { - pstring sid; - DEBUG(2,("LSA Query Info Policy\n")); - if (sid3 != NULL) - { - sid_to_string(sid, sid3); - DEBUG(2,("Domain Member - Domain: %s SID: %s\n", dom3, sid)); - } - if (sid5 != NULL) - { - sid_to_string(sid, sid5); - DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", dom5, sid)); - } - } - else - { - DEBUG(1,("lsa query info failed\n")); - } - - return res; -} - -#if 0 -/**************************************************************************** - obtain a sid and domain name from a Domain Controller. -****************************************************************************/ -BOOL get_trust_sid_and_domain(const char* myname, char *server, - DOM_SID *sid, - char *domain, size_t len) -{ - POLICY_HND pol; - fstring srv_name; - struct cli_connection *con = NULL; - BOOL res = True; - BOOL res1 = True; - DOM_SID sid3; - DOM_SID sid5; - fstring dom3; - fstring dom5; - - extern struct ntuser_creds *usr_creds; - struct ntuser_creds usr; - - usr_creds = &usr; - ZERO_STRUCT(usr); - pwd_set_nullpwd(&usr.pwd); - - if (!cli_connection_init_list(server, PIPE_LSARPC, &con)) - { - DEBUG(0,("get_trust_sid: unable to initialise client connection.\n")); - return False; - } - - fstrcpy(dom3, ""); - fstrcpy(dom5, ""); - ZERO_STRUCT(sid3); - ZERO_STRUCT(sid5); - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, myname); - strupper(srv_name); - - /* lookup domain controller; receive a policy handle */ - res = res ? lsa_open_policy(srv_name, &pol, False) : False; - - /* send client info query, level 3. receive domain name and sid */ - res1 = res ? lsa_query_info_pol(&pol, 3, dom3, &sid3) : False; - - /* send client info query, level 5. receive domain name and sid */ - res1 = res1 ? lsa_query_info_pol(&pol, 5, dom5, &sid5) : False; - - /* close policy handle */ - res = res ? lsa_close(&pol) : False; - - /* close the session */ - cli_connection_unlink(con); - - if (res1) - { - pstring sid_str; - DEBUG(2,("LSA Query Info Policy\n")); - sid_to_string(sid_str, &sid3); - DEBUG(2,("Domain Member - Domain: %s SID: %s\n", - dom3, sid_str)); - sid_to_string(sid_str, &sid5); - DEBUG(2,("Domain Controller - Domain: %s SID: %s\n", - dom5, sid_str)); - - if (dom5[0] != 0 && sid_equal(&sid3, &sid5)) - { - safe_strcpy(domain, dom5, len); - sid_copy(sid, &sid5); - } - else - { - DEBUG(2,("Server %s is not a PDC\n", server)); - return False; - } - - } - else - { - DEBUG(1,("lsa query info failed\n")); - } - - return res1; -} -#endif /**************************************************************************** do a LSA Open Policy ****************************************************************************/ -BOOL lsa_open_policy(const char *server_name, POLICY_HND *hnd, + +BOOL do_lsa_open_policy(struct cli_state *cli, + char *server_name, POLICY_HND *hnd, BOOL sec_qos) { prs_struct rbuf; prs_struct buf; LSA_Q_OPEN_POL q_o; LSA_SEC_QOS qos; - BOOL valid_pol = False; - struct cli_connection *con = NULL; + LSA_R_OPEN_POL r_o; - if (!cli_connection_init(server_name, PIPE_LSARPC, &con)) - { + if (hnd == NULL) return False; - } - if (hnd == NULL) return False; - - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL ); /* create and send a MSRPC command with api LSA_OPENPOLICY */ DEBUG(4,("LSA Open Policy\n")); /* store the parameters */ - if (sec_qos) - { - make_lsa_sec_qos(&qos, 2, 1, 0, 0x20000000); - make_q_open_pol(&q_o, 0x5c, 0, 0x02000000, &qos); - } - else - { - make_q_open_pol(&q_o, 0x5c, 0, 0x1, NULL); + if (sec_qos) { + init_lsa_sec_qos(&qos, 2, 1, 0, 0x20000000); + init_q_open_pol(&q_o, 0x5c, 0, 0, &qos); + } else { + init_q_open_pol(&q_o, 0x5c, 0, 0x1, NULL); } /* turn parameters into data stream */ - lsa_io_q_open_pol("", &q_o, &buf, 0); - - /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, LSA_OPENPOLICY, &buf, &rbuf)) - { - LSA_R_OPEN_POL r_o; - BOOL p; - - lsa_io_r_open_pol("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("LSA_OPENPOLICY: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - /* ok, at last: we're happy. return the policy handle */ - memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); - - valid_pol = register_policy_hnd(hnd) && - set_policy_con(hnd, con, - cli_connection_unlink); - } - } - - prs_mem_free(&rbuf); - prs_mem_free(&buf ); - - return valid_pol; -} - -/**************************************************************************** -do a LSA Open Policy2 -****************************************************************************/ -BOOL lsa_open_policy2( const char *server_name, POLICY_HND *hnd, - BOOL sec_qos) -{ - prs_struct rbuf; - prs_struct buf; - LSA_Q_OPEN_POL2 q_o; - LSA_SEC_QOS qos; - BOOL valid_pol = False; - - struct cli_connection *con = NULL; - - if (!cli_connection_init(server_name, PIPE_LSARPC, &con)) - { + if(!lsa_io_q_open_pol("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); return False; } - if (hnd == NULL) 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 LSA_OPENPOLICY2 */ - - DEBUG(4,("LSA Open Policy2\n")); - - /* store the parameters */ - if (sec_qos) - { - make_lsa_sec_qos(&qos, 2, 1, 0, 0x02000000); - make_q_open_pol2(&q_o, server_name, 0, 0x02000000, &qos); - } - else - { - make_q_open_pol2(&q_o, server_name, 0, 0x02000000, NULL); - } - - /* turn parameters into data stream */ - lsa_io_q_open_pol2("", &q_o, &buf, 0); - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, LSA_OPENPOLICY2, &buf, &rbuf)) - { - LSA_R_OPEN_POL2 r_o; - BOOL p; - - lsa_io_r_open_pol2("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("LSA_OPENPOLICY2: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - /* ok, at last: we're happy. return the policy handle */ - memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); - valid_pol = register_policy_hnd(hnd) && - set_policy_con(hnd, con, - cli_connection_unlink); - } - } - - prs_mem_free(&rbuf); - prs_mem_free(&buf ); - - return valid_pol; -} - -/**************************************************************************** -do a LSA Open Secret -****************************************************************************/ -BOOL lsa_open_secret( const POLICY_HND *hnd, - const char *secret_name, - uint32 des_access, - POLICY_HND *hnd_secret) -{ - prs_struct rbuf; - prs_struct buf; - LSA_Q_OPEN_SECRET q_o; - BOOL valid_pol = False; - - if (hnd == NULL) 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 LSA_OPENSECRET */ - - DEBUG(4,("LSA Open Secret\n")); - - make_q_open_secret(&q_o, hnd, secret_name, des_access); - - /* turn parameters into data stream */ - lsa_io_q_open_secret("", &q_o, &buf, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, LSA_OPENSECRET, &buf, &rbuf)) - { - LSA_R_OPEN_SECRET r_o; - BOOL p; - - lsa_io_r_open_secret("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("LSA_OPENSECRET: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - /* ok, at last: we're happy. return the policy handle */ - memcpy(hnd_secret, r_o.pol.data, sizeof(hnd_secret->data)); - valid_pol = True; - } + if (!rpc_api_pipe_req(cli, LSA_OPENPOLICY, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; } - prs_mem_free(&rbuf); - prs_mem_free(&buf ); - - return valid_pol; -} - -/**************************************************************************** -do a LSA Query Secret -****************************************************************************/ -BOOL lsa_query_secret(POLICY_HND *hnd, STRING2 *secret, - NTTIME *last_update) -{ - prs_struct rbuf; - prs_struct buf; - LSA_Q_QUERY_SECRET q_q; - BOOL valid_info = False; - - if (hnd == NULL) return False; - - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_mem_free(&buf); - /* create and send a MSRPC command with api LSA_QUERYSECRET */ - - DEBUG(4,("LSA Query Secret\n")); - - make_q_query_secret(&q_q, hnd); - - /* turn parameters into data stream */ - lsa_io_q_query_secret("", &q_q, &buf, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, LSA_QUERYSECRET, &buf, &rbuf)) - { - LSA_R_QUERY_SECRET r_q; - BOOL p; - - lsa_io_r_query_secret("", &r_q, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_q.status != 0) - { - /* report error code */ - DEBUG(0,("LSA_QUERYSECRET: %s\n", get_nt_error_msg(r_q.status))); - p = False; - } - - if (p && (r_q.info.ptr_value != 0) && - (r_q.info.value.ptr_secret != 0) && - (r_q.info.ptr_update != 0)) - { - uchar sess_key[16]; - 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_sesskey(hnd, sess_key)) - { - return False; - } -#ifdef DEBUG_PASSWORD - dump_data(100, sess_key, 16); -#endif - valid_info = nt_decrypt_string2(secret, &enc_secret, - sess_key); - } + if(!lsa_io_r_open_pol("", &r_o, &rbuf, 0)) { + DEBUG(0,("do_lsa_open_policy: Failed to unmarshall LSA_R_OPEN_POL\n")); + prs_mem_free(&rbuf); + return False; } - prs_mem_free(&rbuf); - prs_mem_free(&buf ); - - return valid_info; -} - - -/**************************************************************************** -do a LSA Lookup Names -****************************************************************************/ -BOOL lsa_lookup_names( POLICY_HND *hnd, - int num_names, - char **names, - DOM_SID **sids, - uint8 **types, - int *num_sids) -{ - prs_struct rbuf; - prs_struct buf; - LSA_Q_LOOKUP_NAMES q_l; - BOOL valid_response = False; - - if (hnd == NULL || num_sids == 0 || sids == NULL) 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 LSA_LOOKUP_NAMES */ - - DEBUG(4,("LSA Lookup NAMEs\n")); - - /* store the parameters */ - make_q_lookup_names(&q_l, hnd, num_names, names); - - /* turn parameters into data stream */ - lsa_io_q_lookup_names("", &q_l, &buf, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, LSA_LOOKUPNAMES, &buf, &rbuf)) - { - LSA_R_LOOKUP_NAMES r_l; - DOM_R_REF ref; - DOM_RID2 t_rids[MAX_LOOKUP_SIDS]; - BOOL p; - - ZERO_STRUCT(ref); - ZERO_STRUCT(t_rids); - - r_l.dom_ref = &ref; - r_l.dom_rid = t_rids; - - lsa_io_r_lookup_names("", &r_l, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_l.status != 0) - { - /* report error code */ - DEBUG(1,("LSA_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_l.status))); - p = False; - } - - if (p) - { - if (r_l.ptr_dom_ref != 0 && r_l.ptr_entries != 0) - { - valid_response = True; - } - } - - if (num_sids != NULL && valid_response) - { - (*num_sids) = r_l.num_entries; - } - if (valid_response) - { - uint32 i; - for (i = 0; i < r_l.num_entries; i++) - { - if (t_rids[i].rid_idx >= ref.num_ref_doms_1 && - t_rids[i].rid_idx != 0xffffffff) - { - DEBUG(0,("LSA_LOOKUP_NAMES: domain index %d out of bounds\n", - t_rids[i].rid_idx)); - valid_response = False; - break; - } - } - } - - if (types != NULL && valid_response && r_l.num_entries != 0) - { - (*types) = (uint8*)malloc((*num_sids) * sizeof(uint8)); - } - - if (sids != NULL && valid_response && r_l.num_entries != 0) - { - (*sids) = (DOM_SID*)malloc((*num_sids) * sizeof(DOM_SID)); - } - - if (sids != NULL && (*sids) != NULL) - { - int i; - /* take each name, construct a SID */ - for (i = 0; i < (*num_sids); i++) - { - uint32 dom_idx = t_rids[i].rid_idx; - uint32 dom_rid = t_rids[i].rid; - DOM_SID *sid = &(*sids)[i]; - if (dom_idx != 0xffffffff) - { - sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid); - if (dom_rid != 0xffffffff) - { - sid_append_rid(sid, dom_rid); - } - if (types != NULL && (*types) != NULL) - { - (*types)[i] = t_rids[i].type; - } - } - else - { - ZERO_STRUCTP(sid); - if (types != NULL && (*types) != NULL) - { - (*types)[i] = SID_NAME_UNKNOWN; - } - } - } - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("LSA_OPENPOLICY: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; + } else { + /* ok, at last: we're happy. return the policy handle */ + memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); } prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_response; + return True; } /**************************************************************************** do a LSA Lookup SIDs ****************************************************************************/ -BOOL lsa_lookup_sids(POLICY_HND *hnd, + +BOOL do_lsa_lookup_sids(struct cli_state *cli, + POLICY_HND *hnd, int num_sids, DOM_SID **sids, char ***names, - uint8 **types, int *num_names) { prs_struct rbuf; prs_struct buf; LSA_Q_LOOKUP_SIDS q_l; + LSA_R_LOOKUP_SIDS r_l; + DOM_R_REF ref; + LSA_TRANS_NAME_ENUM t_names; + int i; BOOL valid_response = False; - ZERO_STRUCT(q_l); - - if (hnd == NULL || num_sids == 0 || sids == NULL) return False; - - if (num_names != NULL) - { - *num_names = 0; - } - if (types != NULL) - { - *types = NULL; - } - if (names != NULL) - { - *names = NULL; - } + if (hnd == NULL || num_sids == 0 || sids == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL ); /* create and send a MSRPC command with api LSA_LOOKUP_SIDS */ DEBUG(4,("LSA Lookup SIDs\n")); /* store the parameters */ - make_q_lookup_sids(&q_l, hnd, num_sids, sids, 1); + init_q_lookup_sids(&q_l, hnd, num_sids, sids, 1); /* turn parameters into data stream */ - lsa_io_q_lookup_sids("", &q_l, &buf, 0); + if(!lsa_io_q_lookup_sids("", &q_l, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, LSA_LOOKUPSIDS, &buf, &rbuf)) - { - LSA_R_LOOKUP_SIDS r_l; - DOM_R_REF ref; - LSA_TRANS_NAME_ENUM t_names; - BOOL p; - - r_l.dom_ref = &ref; - r_l.names = &t_names; - - lsa_io_r_lookup_sids("", &r_l, &rbuf, 0); - p = rbuf.offset != 0; + if (!rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } + + prs_mem_free(&buf); + + r_l.dom_ref = &ref; + r_l.names = &t_names; + + if(!lsa_io_r_lookup_sids("", &r_l, &rbuf, 0)) { + DEBUG(0,("do_lsa_lookup_sids: Failed to unmarshall LSA_R_LOOKUP_SIDS\n")); + prs_mem_free(&rbuf); + return False; + } + - if (p && r_l.status != 0 && - r_l.status != 0x107 && - r_l.status != (0xC0000000 | NT_STATUS_NONE_MAPPED)) - { - /* report error code */ - DEBUG(1,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status))); - p = False; - } + if (r_l.status != 0) { + /* report error code */ + DEBUG(0,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status))); + } else { + if (t_names.ptr_trans_names != 0) + valid_response = True; + } - if (p) - { - if (t_names.ptr_trans_names != 0 && r_l.ptr_dom_ref != 0) - { - valid_response = True; - } - } + if(!valid_response) { + prs_mem_free(&rbuf); + return False; + } - if (num_names != NULL && valid_response) - { - (*num_names) = t_names.num_entries; - } - if (valid_response) - { - uint32 i; - for (i = 0; i < t_names.num_entries; i++) - { - if (t_names.name[i].domain_idx >= ref.num_ref_doms_1) - { - DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n")); - valid_response = False; - break; - } - } - } + if (num_names != NULL) + (*num_names) = t_names.num_entries; - if (types != NULL && valid_response && (*num_names) != 0) - { - (*types) = (uint8*)malloc((*num_names) * sizeof(uint8)); + for (i = 0; i < t_names.num_entries; i++) { + if (t_names.name[i].domain_idx >= ref.num_ref_doms_1) { + DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n")); + prs_mem_free(&rbuf); + return False; } + } - if (names != NULL && valid_response && (*num_names) != 0) - { - (*names) = (char**)malloc((*num_names) * sizeof(char*)); - } + if (names != NULL && t_names.num_entries != 0) + (*names) = (char**)malloc((*num_names) * sizeof(char*)); + + if (names != NULL && (*names) != NULL) { + /* take each name, construct a \DOMAIN\name string */ + for (i = 0; i < (*num_names); i++) { + fstring name; + fstring dom_name; + fstring full_name; + uint32 dom_idx = t_names.name[i].domain_idx; + fstrcpy(dom_name, dos_unistr2(ref.ref_dom[dom_idx].uni_dom_name.buffer)); + fstrcpy(name, dos_unistr2(t_names.uni_name[i].buffer)); + + slprintf(full_name, sizeof(full_name)-1, "\\%s\\%s", + dom_name, name); - if (names != NULL && (*names) != NULL) - { - int i; - /* take each name, construct a \DOMAIN\name string */ - for (i = 0; i < (*num_names); i++) - { - fstring name; - fstring dom_name; - fstring full_name; - uint32 dom_idx = t_names.name[i].domain_idx; - - if (dom_idx != 0xffffffff) - { - unistr2_to_ascii(dom_name, &ref.ref_dom[dom_idx].uni_dom_name, sizeof(dom_name)-1); - unistr2_to_ascii(name, &t_names.uni_name[i], sizeof(name)-1); - - memset(full_name, 0, sizeof(full_name)); - - slprintf(full_name, sizeof(full_name)-1, "%s\\%s", - dom_name, name); - - (*names)[i] = strdup(full_name); - if (types != NULL && (*types) != NULL) - { - (*types)[i] = t_names.name[i].sid_name_use; - } - } - else - { - (*names)[i] = NULL; - if (types != NULL && (*types) != NULL) - { - (*types)[i] = SID_NAME_UNKNOWN; - } - } - } + (*names)[i] = strdup(full_name); } } prs_mem_free(&rbuf); - prs_mem_free(&buf ); return valid_response; } @@ -764,254 +213,169 @@ BOOL lsa_lookup_sids(POLICY_HND *hnd, /**************************************************************************** do a LSA Query Info Policy ****************************************************************************/ -BOOL lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class, +BOOL do_lsa_query_info_pol(struct cli_state *cli, + POLICY_HND *hnd, uint16 info_class, fstring domain_name, DOM_SID *domain_sid) { prs_struct rbuf; prs_struct buf; LSA_Q_QUERY_INFO q_q; - BOOL valid_response = False; + LSA_R_QUERY_INFO r_q; + fstring sid_str; ZERO_STRUCTP(domain_sid); domain_name[0] = 0; - if (hnd == NULL || domain_name == NULL || domain_sid == NULL) return False; + if (hnd == NULL || domain_name == NULL || domain_sid == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL ); /* create and send a MSRPC command with api LSA_QUERYINFOPOLICY */ DEBUG(4,("LSA Query Info Policy\n")); /* store the parameters */ - make_q_query(&q_q, hnd, info_class); + init_q_query(&q_q, hnd, info_class); /* turn parameters into data stream */ - lsa_io_q_query("", &q_q, &buf, 0); + if(!lsa_io_q_query("", &q_q, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, LSA_QUERYINFOPOLICY, &buf, &rbuf)) - { - LSA_R_QUERY_INFO r_q; - BOOL p; - - lsa_io_r_query("", &r_q, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_q.status != 0) - { - /* report error code */ - DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status))); - p = False; - } - - if (p && r_q.info_class != q_q.info_class) - { - /* report different info classes */ - DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n", - q_q.info_class, r_q.info_class)); - p = False; - } - - if (p) - { - fstring sid_str; - /* ok, at last: we're happy. */ - switch (r_q.info_class) - { - case 3: - { - if (r_q.dom.id3.buffer_dom_name != 0) - { - unistr2_to_ascii(domain_name, &r_q.dom.id3.uni_domain_name, sizeof(fstring)-1); - } - if (r_q.dom.id3.buffer_dom_sid != 0) - { - *domain_sid = r_q.dom.id3.dom_sid.sid; - } - - valid_response = True; - break; - } - case 5: - { - if (r_q.dom.id5.buffer_dom_name != 0) - { - unistr2_to_ascii(domain_name, &r_q.dom.id5.uni_domain_name, sizeof(fstring)-1); - } - if (r_q.dom.id5.buffer_dom_sid != 0) - { - *domain_sid = r_q.dom.id5.dom_sid.sid; - } - - valid_response = True; - break; - } - default: - { - DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n")); - domain_name[0] = 0; - - break; - } - } - - sid_to_string(sid_str, domain_sid); - DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s domain sid:%s\n", - r_q.info_class, domain_name, sid_str)); - } + if (!rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; } - prs_mem_free(&rbuf); - prs_mem_free(&buf ); - - return valid_response; -} - -/**************************************************************************** -do a LSA Enumerate Trusted Domain -****************************************************************************/ -BOOL lsa_enum_trust_dom(POLICY_HND *hnd, uint32 *enum_ctx, - uint32 *num_doms, char ***names, - DOM_SID ***sids) -{ - prs_struct rbuf; - prs_struct buf; - LSA_Q_ENUM_TRUST_DOM q_q; - BOOL valid_response = False; - - if (hnd == NULL || num_doms == NULL || names == NULL) 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 LSA_ENUMTRUSTDOM */ - - DEBUG(4,("LSA Enum Trusted Domains\n")); - - /* store the parameters */ - make_q_enum_trust_dom(&q_q, hnd, *enum_ctx, 0xffffffff); - - /* turn parameters into data stream */ - lsa_io_q_enum_trust_dom("", &q_q, &buf, 0); + prs_mem_free(&buf); - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, LSA_ENUMTRUSTDOM, &buf, &rbuf)) - { - LSA_R_ENUM_TRUST_DOM r_q; - BOOL p; + if(!lsa_io_r_query("", &r_q, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - lsa_io_r_enum_trust_dom("", &r_q, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_q.status != 0) - { - /* report error code */ - DEBUG(0,("LSA_ENUMTRUSTDOM: %s\n", get_nt_error_msg(r_q.status))); - p = r_q.status == 0x8000001a; - } + if (r_q.status != 0) { + /* report error code */ + DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status))); + prs_mem_free(&rbuf); + return False; + } - if (p) - { - uint32 i; - uint32 num_sids = 0; - valid_response = True; + if (r_q.info_class != q_q.info_class) { + /* report different info classes */ + DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n", + q_q.info_class, r_q.info_class)); + prs_mem_free(&rbuf); + return False; + } - for (i = 0; i < r_q.num_domains; i++) - { - fstring tmp; - unistr2_to_ascii(tmp, &r_q.uni_domain_name[i], - sizeof(tmp)-1); - add_chars_to_array(num_doms, names, tmp); - add_sid_to_array(&num_sids, sids, - &r_q.domain_sid[i].sid); - } - - if (r_q.status == 0x0) - { - *enum_ctx = r_q.enum_context; - } - else - { - *enum_ctx = 0; - } - } + /* ok, at last: we're happy. */ + switch (r_q.info_class) { + case 3: + if (r_q.dom.id3.buffer_dom_name != 0) { + char *dom_name = dos_unistrn2(r_q.dom.id3.uni_domain_name.buffer, + r_q.dom.id3.uni_domain_name.uni_str_len); + fstrcpy(domain_name, dom_name); + } + if (r_q.dom.id3.buffer_dom_sid != 0) + *domain_sid = r_q.dom.id3.dom_sid.sid; + break; + case 5: + if (r_q.dom.id5.buffer_dom_name != 0) { + char *dom_name = dos_unistrn2(r_q.dom.id5.uni_domain_name.buffer, + r_q.dom.id5.uni_domain_name.uni_str_len); + fstrcpy(domain_name, dom_name); + } + if (r_q.dom.id5.buffer_dom_sid != 0) + *domain_sid = r_q.dom.id5.dom_sid.sid; + break; + default: + DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n")); + domain_name[0] = 0; + + prs_mem_free(&rbuf); + return False; } + + sid_to_string(sid_str, domain_sid); + DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s domain sid:%s\n", + r_q.info_class, domain_name, sid_str)); prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_response; + return True; } /**************************************************************************** do a LSA Close ****************************************************************************/ -BOOL lsa_close(POLICY_HND *hnd) + +BOOL do_lsa_close(struct cli_state *cli, POLICY_HND *hnd) { prs_struct rbuf; prs_struct buf; LSA_Q_CLOSE q_c; - BOOL valid_close = False; + LSA_R_CLOSE r_c; + int i; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; /* create and send a MSRPC command with api LSA_OPENPOLICY */ - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL ); DEBUG(4,("LSA Close\n")); /* store the parameters */ - make_lsa_q_close(&q_c, hnd); + init_lsa_q_close(&q_c, hnd); /* turn parameters into data stream */ - lsa_io_q_close("", &q_c, &buf, 0); + if(!lsa_io_q_close("", &q_c, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, LSA_CLOSE, &buf, &rbuf)) - { - LSA_R_CLOSE r_c; - BOOL p; - - lsa_io_r_close("", &r_c, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_c.status != 0) - { - /* report error code */ - DEBUG(0,("LSA_CLOSE: %s\n", get_nt_error_msg(r_c.status))); - p = False; - } + if (!rpc_api_pipe_req(cli, LSA_CLOSE, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } + + prs_mem_free(&buf); + + if(!lsa_io_r_close("", &r_c, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } + + if (r_c.status != 0) { + /* report error code */ + DEBUG(0,("LSA_CLOSE: %s\n", get_nt_error_msg(r_c.status))); + prs_mem_free(&rbuf); + return False; + } - if (p) - { - /* check that the returned policy handle is all zeros */ - uint32 i; - valid_close = True; - - for (i = 0; i < sizeof(r_c.pol.data); i++) - { - if (r_c.pol.data[i] != 0) - { - valid_close = False; - break; - } - } - if (!valid_close) - { - DEBUG(0,("LSA_CLOSE: non-zero handle returned\n")); - } + /* check that the returned policy handle is all zeros */ + + for (i = 0; i < sizeof(r_c.pol.data); i++) { + if (r_c.pol.data[i] != 0) { + DEBUG(0,("LSA_CLOSE: non-zero handle returned\n")); + prs_mem_free(&rbuf); + return False; } } prs_mem_free(&rbuf); - prs_mem_free(&buf ); - close_policy_hnd(hnd); - - return valid_close; + return True; } - diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 147578f448..8202960089 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -30,12 +30,15 @@ #include "includes.h" extern int DEBUGLEVEL; +extern pstring scope; +extern pstring global_myname; +extern fstring global_myworkgroup; /**************************************************************************** Generate the next creds to use. ****************************************************************************/ -void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) +static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) { /* * Create the new client credentials. @@ -51,58 +54,61 @@ 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(const char* srv_name, uint32 status_level) +BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level) { - prs_struct rbuf; - prs_struct buf; - NET_Q_LOGON_CTRL2 q_l; - BOOL ok = False; - - struct cli_connection *con = NULL; - - if (!cli_connection_init(srv_name, PIPE_NETLOGON, &con)) - { - return False; - } - - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); + prs_struct rbuf; + prs_struct buf; + NET_Q_LOGON_CTRL2 q_l; + BOOL ok = False; - /* create and send a MSRPC command with api NET_LOGON_CTRL2 */ + prs_init(&buf , 1024, 4, False); + prs_init(&rbuf, 0, 4, True ); - DEBUG(4,("net_logon_ctrl2 status level:%x\n", status_level)); + /* create and send a MSRPC command with api NET_LOGON_CTRL2 */ - /* store the parameters */ - make_q_logon_ctrl2(&q_l, srv_name, 0, 0, status_level); + DEBUG(4,("do_net_logon_ctrl2 from %s status level:%x\n", + global_myname, status_level)); - /* turn parameters into data stream */ - net_io_q_logon_ctrl2("", &q_l, &buf, 0); + /* store the parameters */ + init_q_logon_ctrl2(&q_l, cli->srv_name_slash, status_level); - /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, NET_LOGON_CTRL2, &buf, &rbuf)) - { - NET_R_LOGON_CTRL2 r_l; + /* turn parameters into data stream */ + if(!net_io_q_logon_ctrl2("", &q_l, &buf, 0)) { + DEBUG(0,("cli_net_logon_ctrl2: Error : failed to marshall NET_Q_LOGON_CTRL2 struct.\n")); + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - net_io_r_logon_ctrl2("", &r_l, &rbuf, 0); - ok = (rbuf.offset != 0); + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &buf, &rbuf)) + { + NET_R_LOGON_CTRL2 r_l; - 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; - } - } + /* + * Unmarshall the return buffer. + */ + ok = net_io_r_logon_ctrl2("", &r_l, &rbuf, 0); + + if (ok && r_l.status != 0) + { + /* report error code */ + DEBUG(0,("do_net_logon_ctrl2: Error %s\n", get_nt_error_msg(r_l.status))); + cli->nt_error = r_l.status; + ok = False; + } + } - prs_mem_free(&rbuf); - prs_mem_free(&buf ); + prs_mem_free(&buf); + prs_mem_free(&rbuf); - cli_connection_unlink(con); - return ok; + return ok; } +#endif /**************************************************************************** LSA Authenticate 2 @@ -112,114 +118,90 @@ Ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ -uint32 cli_net_auth2(const char *srv_name, - const char *trust_acct, - const char *acct_name, - uint16 sec_chan, - uint32 neg_flags, DOM_CHAL *srv_chal) +BOOL cli_net_auth2(struct cli_state *cli, 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 neg: %x\n", - srv_name, trust_acct, sec_chan, acct_name, - neg_flags)); - - cli_con_get_cli_cred(con, &clnt_cred); - - /* store the parameters */ - make_q_auth_2(&q_a, srv_name, trust_acct, sec_chan, acct_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_con_pipe_req(con, NET_AUTH2, &buf, &rbuf)) - { - NET_R_AUTH_2 r_a; - - net_io_r_auth_2("", &r_a, &rbuf, 0); - status = (rbuf.offset == 0) ? 0xC0000000 | NT_STATUS_INVALID_PARAMETER : 0; - - if (status == 0x0 && r_a.status != 0) - { - /* report error code */ - DEBUG(5,("cli_net_auth2: Error %s\n", - get_nt_error_msg(r_a.status))); - status = r_a.status; - } - - if (status == 0x0) - { - /* - * Check the returned value using the initial - * server received challenge. - */ - UTIME zerotime; - - zerotime.time = 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 trust account password ?).\n", srv_name)); - status = NT_STATUS_NETWORK_CREDENTIAL_CONFLICT | 0xC0000000; - } - } + prs_struct rbuf; + prs_struct buf; + NET_Q_AUTH_2 q_a; + BOOL ok = False; + + prs_init(&buf , 1024, 4, False); + prs_init(&rbuf, 0, 4, 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, global_myname, + credstr(cli->clnt_cred.challenge.data), neg_flags)); + + /* store the parameters */ + init_q_auth_2(&q_a, cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, + &cli->clnt_cred.challenge, neg_flags); + + /* turn parameters into data stream */ + if(!net_io_q_auth_2("", &q_a, &buf, 0)) { + DEBUG(0,("cli_net_auth2: Error : failed to marshall NET_Q_AUTH_2 struct.\n")); + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, NET_AUTH2, &buf, &rbuf)) + { + NET_R_AUTH_2 r_a; + + ok = net_io_r_auth_2("", &r_a, &rbuf, 0); + + if (ok && r_a.status != 0) + { + /* report error code */ + DEBUG(0,("cli_net_auth2: Error %s\n", get_nt_error_msg(r_a.status))); + cli->nt_error = r_a.status; + ok = False; + } + + if (ok) + { + /* + * Check the returned value using the initial + * server received challenge. + */ + UTIME zerotime; + + zerotime.time = 0; + if(cred_assert( &r_a.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) { + /* + * Server replied with bad credential. Fail. + */ + DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ +password ?).\n", cli->desthost )); + ok = False; + } + } #if 0 - /* - * Try commenting this out to see if this makes the connect - * work for a NT 3.51 PDC. JRA. - */ - - if (ok && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags) - { - /* report different neg_flags */ - DEBUG(5,("cli_net_auth2: error neg_flags (q,r) differ - (%x,%x)\n", - q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags)); - ok = False; - } -#endif + /* + * Try commenting this out to see if this makes the connect + * work for a NT 3.51 PDC. JRA. + */ - } - else - { - DEBUG(5,("rpc_con_pipe_req FAILED\n")); - status = 0xC0000000 | NT_STATUS_ACCESS_DENIED; - } + if (ok && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags) + { + /* report different neg_flags */ + DEBUG(0,("cli_net_auth2: error neg_flags (q,r) differ - (%x,%x)\n", + q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags)); + ok = False; + } +#endif - DEBUG(5,("cli_net_auth2 status: %x\n", status)); + } - prs_mem_free(&rbuf); - prs_mem_free(&buf ); + prs_mem_free(&buf); + prs_mem_free(&rbuf); - return status; + return ok; } /**************************************************************************** @@ -227,152 +209,127 @@ LSA Request Challenge. Sends our challenge to server, then gets server response. These are used to generate the credentials. ****************************************************************************/ -uint32 cli_net_req_chal( const char *srv_name, const char* myhostname, - DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal) +BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal) { prs_struct rbuf; prs_struct buf; 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; + BOOL valid_chal = False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); + prs_init(&buf , 1024, 4, False); + prs_init(&rbuf, 0, 4, True ); /* 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", - srv_name, myhostname, credstr(clnt_chal->data))); + cli->desthost, global_myname, credstr(clnt_chal->data))); /* store the parameters */ - make_q_req_chal(&q_c, srv_name, myhostname, clnt_chal); + init_q_req_chal(&q_c, cli->srv_name_slash, global_myname, clnt_chal); /* turn parameters into data stream */ - net_io_q_req_chal("", &q_c, &buf, 0); + if(!net_io_q_req_chal("", &q_c, &buf, 0)) { + DEBUG(0,("cli_net_req_chal: Error : failed to marshall NET_Q_REQ_CHAL struct.\n")); + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, NET_REQCHAL, &buf, &rbuf)) + if (rpc_api_pipe_req(cli, NET_REQCHAL, &buf, &rbuf)) { NET_R_REQ_CHAL r_c; + BOOL ok; - net_io_r_req_chal("", &r_c, &rbuf, 0); - status = (rbuf.offset == 0) ? 0xC0000000 | NT_STATUS_INVALID_PARAMETER : 0; + ok = net_io_r_req_chal("", &r_c, &rbuf, 0); - if (status == 0x0 && r_c.status != 0) + if (ok && r_c.status != 0) { /* report error code */ - DEBUG(5,("cli_net_req_chal: Error %s\n", get_nt_error_msg(r_c.status))); - status = r_c.status; + DEBUG(0,("cli_net_req_chal: Error %s\n", get_nt_error_msg(r_c.status))); + cli->nt_error = r_c.status; + ok = False; } - if (status == 0x0) + if (ok) { /* ok, at last: we're happy. return the challenge */ memcpy(srv_chal, r_c.srv_chal.data, sizeof(srv_chal->data)); + valid_chal = True; } } - else - { - DEBUG(5,("rpc_con_pipe_req FAILED\n")); - status = 0xC0000000 | NT_STATUS_ACCESS_DENIED; - } + prs_mem_free(&buf); prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return status; + return valid_chal; } /*************************************************************************** LSA Server Password Set. ****************************************************************************/ -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_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]) { 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; - - 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); + uint16 sec_chan_type = 2; - cli_con_gen_next_creds( con, &new_clnt_cred); + gen_next_creds( cli, &new_clnt_cred); - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True ); + prs_init(&buf , 1024, 4, False); + prs_init(&rbuf, 0, 4, True ); /* 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", - srv_name, trust_acct, sec_chan_type, myhostname, + cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname, credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time)); /* store the parameters */ - make_q_srv_pwset(&q_s, srv_name, trust_acct, sec_chan_type, - myhostname, &new_clnt_cred, (char *)processed_new_pwd); + init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->mach_acct, sec_chan_type, + global_myname, &new_clnt_cred, (char *)hashed_mach_pwd); /* turn parameters into data stream */ - net_io_q_srv_pwset("", &q_s, &buf, 0); + if(!net_io_q_srv_pwset("", &q_s, &buf, 0)) { + DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n")); + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, NET_SRVPWSET, &buf, &rbuf)) + if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf)) { NET_R_SRV_PWSET r_s; - net_io_r_srv_pwset("", &r_s, &rbuf, 0); - ok = (rbuf.offset != 0); + ok = net_io_r_srv_pwset("", &r_s, &rbuf, 0); if (ok && r_s.status != 0) { /* report error code */ - DEBUG(5,("cli_net_srv_pwset: %s\n", get_nt_error_msg(r_s.status))); + DEBUG(0,("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 && !cli_con_deal_with_creds(con, &(r_s.srv_cred))) + if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred))) { /* * Server replied with bad credential. Fail. */ - DEBUG(5,("cli_net_srv_pwset: server %s replied with bad credential \ -(bad trust account password ?).\n", srv_name)); + DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \ +password ?).\n", cli->desthost )); ok = False; } } + prs_mem_free(&buf); prs_mem_free(&rbuf); - prs_mem_free(&buf ); return ok; } @@ -381,9 +338,8 @@ BOOL cli_net_srv_pwset(const char* srv_name, LSA SAM Logon - interactive or network. ****************************************************************************/ -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_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, + NET_USER_INFO_3 *user_info3) { DOM_CRED new_clnt_cred; DOM_CRED dummy_rtn_creds; @@ -393,75 +349,73 @@ BOOL cli_net_sam_logon(const char* srv_name, const char* myhostname, NET_Q_SAM_LOGON q_s; BOOL ok = False; - struct cli_connection *con = NULL; - - if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con)) - { - return False; - } + gen_next_creds( cli, &new_clnt_cred); - 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 ); + prs_init(&buf , 1024, 4, False); + prs_init(&rbuf, 0, 4, True ); /* create and send a MSRPC command with api NET_SAMLOGON */ - DEBUG(4,("cli_net_sam_logon: srv:%s mc:%s ll: %d\n", - srv_name, myhostname, + 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, 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), srv_name, myhostname, + q_s.validation_level = validation_level; + init_sam_info(&q_s.sam_id, cli->srv_name_slash, global_myname, &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr); - q_s.validation_level = validation_level; - /* turn parameters into data stream */ - net_io_q_sam_logon("", &q_s, &buf, 0); + if(!net_io_q_sam_logon("", &q_s, &buf, 0)) { + DEBUG(0,("cli_net_sam_logon: Error : failed to marshall NET_Q_SAM_LOGON struct.\n")); + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, NET_SAMLOGON, &buf, &rbuf)) + if (rpc_api_pipe_req(cli, NET_SAMLOGON, &buf, &rbuf)) { NET_R_SAM_LOGON r_s; r_s.user = user_info3; - net_io_r_sam_logon("", &r_s, &rbuf, 0); - ok = (rbuf.offset != 0); + ok = net_io_r_sam_logon("", &r_s, &rbuf, 0); if (ok && r_s.status != 0) { /* report error code */ - DEBUG(5,("cli_net_sam_logon: %s\n", get_nt_error_msg(r_s.status))); + DEBUG(0,("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 && !cli_con_deal_with_creds(con, &(r_s.srv_creds))) + if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds))) { /* * Server replied with bad credential. Fail. */ - DEBUG(5,("cli_net_sam_logon: server %s replied with bad credential \ -(bad trust account password ?).\n", srv_name)); + DEBUG(0,("cli_net_sam_logon: server %s replied with bad credential (bad machine \ +password ?).\n", cli->desthost )); ok = False; } if (ok && r_s.switch_value != 3) { /* report different switch_value */ - DEBUG(5,("cli_net_sam_logon: switch_value of 3 expected %x\n", + DEBUG(0,("cli_net_sam_logon: switch_value of 3 expected %x\n", r_s.switch_value)); ok = False; } } + prs_mem_free(&buf); prs_mem_free(&rbuf); - prs_mem_free(&buf ); return ok; } @@ -475,8 +429,7 @@ 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(const char* srv_name, const char* myhostname, - NET_ID_INFO_CTR *ctr) +BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr) { DOM_CRED new_clnt_cred; DOM_CRED dummy_rtn_creds; @@ -485,147 +438,266 @@ BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname, NET_Q_SAM_LOGOFF q_s; BOOL ok = False; - struct cli_connection *con = NULL; - - if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con)) - { - return False; - } + gen_next_creds( cli, &new_clnt_cred); - 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 ); + prs_init(&buf , 1024, 4, False); + prs_init(&rbuf, 0, 4, True ); /* 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", - srv_name, myhostname, + cli->srv_name_slash, global_myname, 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), srv_name, myhostname, + init_sam_info(&q_s.sam_id, cli->srv_name_slash, global_myname, &new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr); /* turn parameters into data stream */ - net_io_q_sam_logoff("", &q_s, &buf, 0); + if(!net_io_q_sam_logoff("", &q_s, &buf, 0)) { + DEBUG(0,("cli_net_sam_logoff: Error : failed to marshall NET_Q_SAM_LOGOFF struct.\n")); + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, NET_SAMLOGOFF, &buf, &rbuf)) + if (rpc_api_pipe_req(cli, NET_SAMLOGOFF, &buf, &rbuf)) { NET_R_SAM_LOGOFF r_s; - net_io_r_sam_logoff("", &r_s, &rbuf, 0); - ok = (rbuf.offset != 0); + ok = net_io_r_sam_logoff("", &r_s, &rbuf, 0); if (ok && r_s.status != 0) { /* report error code */ - DEBUG(5,("cli_net_sam_logoff: %s\n", get_nt_error_msg(r_s.status))); + DEBUG(0,("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 && !cli_con_deal_with_creds(con, &(r_s.srv_creds))) + if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds))) { /* * Server replied with bad credential. Fail. */ - DEBUG(5,("cli_net_sam_logoff: server %s replied with bad credential \ -(bad trust account password ?).\n", srv_name )); + DEBUG(0,("cli_net_sam_logoff: server %s replied with bad credential (bad machine \ +password ?).\n", cli->desthost )); ok = False; } } + prs_mem_free(&buf); prs_mem_free(&rbuf); - prs_mem_free(&buf ); return ok; } -/*************************************************************************** -Synchronise SAM Database (requires SEC_CHAN_BDC). -****************************************************************************/ -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) +/********************************************************* + Change the domain password on the PDC. +**********************************************************/ + +static BOOL modify_trust_password( char *domain, char *remote_machine, + unsigned char orig_trust_passwd_hash[16], + unsigned char new_trust_passwd_hash[16]) { - NET_Q_SAM_SYNC q_s; - prs_struct rbuf; - prs_struct buf; - DOM_CRED new_clnt_cred; - BOOL ok = False; - uint8 sess_key[16]; - - 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, 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_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("", 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))); - ok = False; - } - - /* Update the credentials. */ - 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 trust account password ?).\n", srv_name)); - ok = False; - } - - if (ok) - { - *num_deltas = r_s.num_deltas2; - - if (r_s.status == STATUS_MORE_ENTRIES) - { - DEBUG(5, ("(More entries)\n")); - } - } - } - - prs_mem_free(&rbuf); - prs_mem_free(&buf ); - - return ok; + struct cli_state cli; + + ZERO_STRUCT(cli); + if(cli_initialise(&cli) == False) { + 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; + } + + if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) { + DEBUG(0,("modify_trust_password: unable to connect to SMB server on \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + return False; + } + + if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) { + DEBUG(0,("modify_trust_password: machine %s rejected the NetBIOS \ +session request. Error was %s\n", remote_machine, cli_errstr(&cli) )); + return False; + } + + cli.protocol = PROTOCOL_NT1; + + if (!cli_negprot(&cli)) { + DEBUG(0,("modify_trust_password: machine %s rejected the negotiate protocol. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + 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; + } + + /* + * Do an anonymous session setup. + */ + + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + DEBUG(0,("modify_trust_password: machine %s rejected the session setup. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + cli_shutdown(&cli); + return False; + } + + if (!(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; + } + + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + DEBUG(0,("modify_trust_password: machine %s rejected the tconX on the IPC$ share. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + 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) == False) { + DEBUG(0,("modify_trust_password: unable to open the domain client session to \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); + cli_nt_session_close(&cli); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + + if(cli_nt_setup_creds(&cli, orig_trust_passwd_hash) == False) { + DEBUG(0,("modify_trust_password: unable to setup the PDC credentials to machine \ +%s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); + cli_nt_session_close(&cli); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + + if( cli_nt_srv_pwset( &cli,new_trust_passwd_hash ) == False) { + DEBUG(0,("modify_trust_password: unable to change password for machine %s in domain \ +%s to Domain controller %s. Error was %s.\n", global_myname, domain, remote_machine, + cli_errstr(&cli))); + cli_close(&cli, cli.nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + + cli_nt_session_close(&cli); + cli_ulogoff(&cli); + cli_shutdown(&cli); + + return True; +} + +/************************************************************************ + Change the trust account password for a domain. + The user of this function must have locked the trust password file for + update. +************************************************************************/ + +BOOL change_trust_account_password( char *domain, char *remote_machine_list) +{ + fstring remote_machine; + 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 \ +account password for domain %s.\n", domain)); + return False; + } + + /* + * Create the new (random) password. + */ + generate_random_buffer( new_trust_passwd_hash, 16, True); + + while(remote_machine_list && + next_token(&remote_machine_list, remote_machine, + LIST_SEP, sizeof(remote_machine))) { + strupper(remote_machine); + if(strequal(remote_machine, "*")) { + + /* + * We have been asked to dynamcially determine the IP addresses of the PDC. + */ + + struct in_addr *ip_list = NULL; + int count = 0; + int i; + + if(!get_dc_list(domain, &ip_list, &count)) + continue; + + /* + * Try and connect to the PDC/BDC list in turn as an IP + * address used as a string. + */ + + for(i = 0; i < count; i++) { + fstring dc_name; + if(!lookup_pdc_name(global_myname, domain, &ip_list[i], dc_name)) + continue; + if((res = modify_trust_password( domain, dc_name, + old_trust_passwd_hash, new_trust_passwd_hash))) + break; + } + + if(ip_list != NULL) + free((char *)ip_list); + + } else { + res = modify_trust_password( domain, remote_machine, + old_trust_passwd_hash, new_trust_passwd_hash); + } + + if(res) { + DEBUG(0,("%s : change_trust_account_password: Changed password for \ +domain %s.\n", timestring(False), domain)); + /* + * Return the result of trying to write the new password + * back into the trust account file. + */ + 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(False), domain)); + return False; } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a8debd87fd..8711ab116e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -6,6 +6,7 @@ * Copyright (C) Andrew Tridgell 1992-1998, * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1998. + * Copyright (C) Jeremy Allison 1999. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,196 +32,253 @@ extern int DEBUGLEVEL; extern struct pipe_id_info pipe_names[]; +extern fstring global_myworkgroup; extern pstring global_myname; /******************************************************************** - rpc pipe call id + Rpc pipe call id. ********************************************************************/ + static uint32 get_rpc_call_id(void) { - static uint32 call_id = 0; - return ++call_id; + static uint32 call_id = 0; + return ++call_id; } /******************************************************************* - uses SMBreadX to get rest of rpc data + Use SMBreadX to get rest of one fragment's worth of rpc data. ********************************************************************/ -static BOOL rpc_read(struct cli_state *cli, uint16 fnum, - prs_struct *rdata, uint32 data_to_read, - uint32 rdata_offset, BOOL one_only) +static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 *rdata_offset) { - size_t size = cli->max_recv_frag; - int file_offset = 0; + size_t size = (size_t)cli->max_recv_frag; + int stream_offset = 0; int num_read; - char *data; - uint32 new_data_size = rdata_offset + data_to_read; - uint8 cls; - uint32 type; + char *pdata; + uint32 err; + int extra_data_size = ((int)*rdata_offset) + ((int)data_to_read) - (int)prs_data_size(rdata); - DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n", - data_to_read, rdata_offset, file_offset)); + DEBUG(5,("rpc_read: data_to_read: %u rdata offset: %u extra_data_size: %d\n", + (int)data_to_read, (unsigned int)*rdata_offset, extra_data_size)); - if (new_data_size > rdata->data->data_size) - { - mem_grow_data(&rdata->data, True, new_data_size, True); - DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used)); + /* + * Grow the buffer if needed to accommodate the data to be read. + */ + + if (extra_data_size > 0) { + if(!prs_force_grow(rdata, (uint32)extra_data_size)) { + DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", extra_data_size )); + return False; + } + DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", extra_data_size, prs_data_size(rdata) )); } - data = rdata->data->data + rdata_offset; + pdata = prs_data_p(rdata) + *rdata_offset; do /* read data using SMBreadX */ { - if (size > data_to_read) - { - size = data_to_read; - } + if (size > (size_t)data_to_read) + size = (size_t)data_to_read; - num_read = cli_read(cli, fnum, data, file_offset, size); + num_read = (int)cli_read(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size); - DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n", - file_offset, num_read, data_to_read)); + DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", + num_read, stream_offset, data_to_read)); - data_to_read -= num_read; - file_offset += num_read; - data += num_read; - - if (cli_error(cli, &cls, &type)) - { - if (cls != ERRDOS || type != ERRmoredata) - { - return False; - } + if (cli_error(cli, NULL, &err, NULL)) { + DEBUG(0,("rpc_read: Error %u in cli_read\n", (unsigned int)err )); + return False; } - } while (!one_only && num_read > 0 && data_to_read > 0); + data_to_read -= num_read; + stream_offset += num_read; + pdata += num_read; - rdata->data->offset.end = new_data_size; + } while (num_read > 0 && data_to_read > 0); + /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ - DEBUG(5,("rpc_read: offset end: 0x%x. data left to read:0x%x\n", - rdata->data->offset.end, data_to_read)); + /* + * Update the current offset into rdata by the amount read. + */ + *rdata_offset += stream_offset; return True; } /**************************************************************************** - checks the header + Checks the header. ****************************************************************************/ + static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, - BOOL *first, BOOL *last, int *len) + BOOL *first, BOOL *last, uint32 *len) { - DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used)); + DEBUG(5,("rpc_check_hdr: rdata->data_size = %u\n", (uint32)prs_data_size(rdata) )); - smb_io_rpc_hdr ("rpc_hdr ", rhdr , rdata, 0); - - if (!rdata->offset || rdata->offset != 0x10) - { - DEBUG(0,("cli_pipe: error in rpc header\n")); + if(!smb_io_rpc_hdr("rpc_hdr ", rhdr, rdata, 0)) { + DEBUG(0,("rpc_check_hdr: Failed to unmarshall RPC_HDR.\n")); return False; } - DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n", - rdata->data->data_used)); + if (prs_offset(rdata) != RPC_HEADER_LEN) { + DEBUG(0,("rpc_check_hdr: offset was %x, should be %x.\n", prs_offset(rdata), RPC_HEADER_LEN)); + return False; + } - (*first ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_FIRST); - (*last ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST ); - (*len ) = rhdr->frag_len - rdata->data->data_used; + (*first) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_FIRST); + (*last) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST ); + (*len) = (uint32)rhdr->frag_len - prs_data_size(rdata); - return rhdr->pkt_type != RPC_FAULT; + return (rhdr->pkt_type != RPC_FAULT); } -static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, int len) +static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, uint32 len) { unsigned char *hash = cli->ntlmssp_hash; - unsigned char index_i = hash[256]; - unsigned char index_j = hash[257]; - int ind; + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + int ind; - for( ind = 0; ind < len; ind++) - { - unsigned char tc; - unsigned char t; + for( ind = 0; ind < len; ind++) { + unsigned char tc; + unsigned char t; - index_i++; - index_j += hash[index_i]; + index_i++; + index_j += hash[index_i]; - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; - t = hash[index_i] + hash[index_j]; - data[ind] = data[ind] ^ hash[t]; - } + t = hash[index_i] + hash[index_j]; + data[ind] = data[ind] ^ hash[t]; + } - hash[256] = index_i; - hash[257] = index_j; + hash[256] = index_i; + hash[257] = index_j; } /**************************************************************************** - decrypt data on an rpc pipe + Verify data on an rpc pipe. + The VERIFY & SEAL code is only executed on packets that look like this : + + Request/Response PDU's look like the following... + + |<------------------PDU len----------------------------------------------->| + |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->| + + +------------+-----------------+-------------+---------------+-------------+ + | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA | + +------------+-----------------+-------------+---------------+-------------+ + + Never on bind requests/responses. ****************************************************************************/ -static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, - int len, int auth_len) +static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int auth_len) { - RPC_AUTH_NTLMSSP_CHK chk; - uint32 crc32; - int data_len = len - 0x18 - auth_len - 8; - char *reply_data = mem_data(&rdata->data, 0x18); + /* + * The following is that length of the data we must sign or seal. + * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN + * preceeding the auth_data. + */ + + int data_len = len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len; + + /* + * The start of the data to sign/seal is just after the RPC headers. + */ + char *reply_data = prs_data_p(rdata) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; BOOL auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN); - BOOL auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL); + BOOL auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL); DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n", len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal))); - if (reply_data == NULL) return False; + /* + * Unseal any sealed data in the PDU, not including the + * 8 byte auth_header or the auth_data. + */ - if (auth_seal) - { - DEBUG(10,("rpc_auth_pipe: seal\n")); + if (auth_seal) { + DEBUG(10,("rpc_auth_pipe: unseal\n")); dump_data(100, reply_data, data_len); NTLMSSPcalc_ap(cli, (uchar*)reply_data, data_len); dump_data(100, reply_data, data_len); } - if (auth_verify || auth_seal) - { - RPC_HDR_AUTH rhdr_auth; + if (auth_verify || auth_seal) { + RPC_HDR_AUTH rhdr_auth; prs_struct auth_req; - char *data = mem_data(&rdata->data, len - auth_len - 8); - prs_init(&auth_req , 0x08, 4, 0, True); - memcpy(auth_req.data->data, data, 8); - smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0); - prs_mem_free(&auth_req); - - if (!rpc_hdr_auth_chk(&rhdr_auth)) - { + char data[RPC_HDR_AUTH_LEN]; + /* + * We set dp to be the end of the packet, minus the auth_len + * and the length of the header that preceeds the auth_data. + */ + char *dp = prs_data_p(rdata) + len - auth_len - RPC_HDR_AUTH_LEN; + + if(dp - prs_data_p(rdata) > prs_data_size(rdata)) { + DEBUG(0,("rpc_auth_pipe: auth data > data size !\n")); + return False; + } + + memcpy(data, dp, sizeof(data)); + + prs_init(&auth_req , 0, 4, UNMARSHALL); + prs_give_memory(&auth_req, data, RPC_HDR_AUTH_LEN, False); + + /* + * Unmarshall the 8 byte auth_header that comes before the + * auth data. + */ + + if(!smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0)) { + DEBUG(0,("rpc_auth_pipe: unmarshalling RPC_HDR_AUTH failed.\n")); + return False; + } + + if (!rpc_hdr_auth_chk(&rhdr_auth)) { + DEBUG(0,("rpc_auth_pipe: rpc_hdr_auth_chk failed.\n")); return False; } } - if (auth_verify) - { + /* + * Now unseal and check the auth verifier in the auth_data at + * then end of the packet. The 4 bytes skipped in the unseal + * seem to be a buffer pointer preceeding the sealed data. + */ + + if (auth_verify) { + RPC_AUTH_NTLMSSP_CHK chk; + uint32 crc32; prs_struct auth_verf; - char *data = mem_data(&rdata->data, len - auth_len); - if (data == NULL) return False; + char data[RPC_AUTH_NTLMSSP_CHK_LEN]; + char *dp = prs_data_p(rdata) + len - auth_len; + + if(dp - prs_data_p(rdata) > prs_data_size(rdata)) { + DEBUG(0,("rpc_auth_pipe: auth data > data size !\n")); + return False; + } DEBUG(10,("rpc_auth_pipe: verify\n")); + dump_data(100, dp, auth_len); + NTLMSSPcalc_ap(cli, (uchar*)(dp+4), auth_len - 4); + + memcpy(data, dp, RPC_AUTH_NTLMSSP_CHK_LEN); dump_data(100, data, auth_len); - NTLMSSPcalc_ap(cli, (uchar*)(data+4), auth_len - 4); - prs_init(&auth_verf, 0x08, 4, 0, True); - memcpy(auth_verf.data->data, data, 16); - smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0); - dump_data(100, data, auth_len); - prs_mem_free(&auth_verf); - } - if (auth_verify) - { - crc32 = crc32_calc_buffer(data_len, reply_data); - if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num)) - { + prs_init(&auth_verf, 0, 4, UNMARSHALL); + prs_give_memory(&auth_verf, data, RPC_AUTH_NTLMSSP_CHK_LEN, False); + + if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0)) { + DEBUG(0,("rpc_auth_pipe: unmarshalling RPC_AUTH_NTLMSSP_CHK failed.\n")); + return False; + } + + crc32 = crc32_calc_buffer(reply_data, data_len); + + if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num)) { + DEBUG(0,("rpc_auth_pipe: rpc_auth_ntlmssp_chk failed.\n")); return False; } cli->ntlmssp_seq_num++; @@ -230,204 +288,215 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, /**************************************************************************** - send data on an rpc pipe, which *must* be in one fragment. + Send data on an rpc pipe, which *must* be in one fragment. receive response data from an rpc pipe, which may be large... - read the first fragment: unfortunately have to use SMBtrans for the first + Read the first fragment: unfortunately have to use SMBtrans for the first bit, then SMBreadX for subsequent bits. - if first fragment received also wasn't the last fragment, continue + If first fragment received also wasn't the last fragment, continue getting fragments until we _do_ receive the last fragment. - [note: from a data abstraction viewpoint, this function is marginally - complicated by the return side of cli_api_pipe getting in the way - (i.e, the SMB header stuff). the proper way to do this is to split - cli_api_pipe down into receive / transmit. oh, and split cli_readx - down. in other words, state-based (kernel) techniques...] + Request/Response PDU's look like the following... + + |<------------------PDU len----------------------------------------------->| + |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->| + + +------------+-----------------+-------------+---------------+-------------+ + | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA | + +------------+-----------------+-------------+---------------+-------------+ + + Where the presence of the AUTH_HDR and AUTH are dependent on the + signing & sealing being neogitated. ****************************************************************************/ -static BOOL rpc_api_pipe(struct cli_state *cli, uint16 fnum, - BOOL bind_rq, uint16 cmd, - prs_struct *param , prs_struct *data, - prs_struct *rparam, prs_struct *rdata) +static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, prs_struct *rdata) { - int len; - - uint16 setup[2]; /* only need 2 uint16 setup parameters */ - uint8 cls; - uint32 type; + uint32 len; + char *rparam = NULL; + uint32 rparam_len = 0; + uint16 setup[2]; + uint32 err; BOOL first = True; BOOL last = True; - BOOL used_smb_trans = False; - RPC_HDR rhdr; + RPC_HDR rhdr; + char *pdata = data ? prs_data_p(data) : NULL; + uint32 data_len = data ? prs_offset(data) : 0; + char *prdata = NULL; + uint32 rdata_len = 0; + uint32 current_offset = 0; - /* - * Setup the pointers from the incoming. - */ - char *pparams = param ? param->data->data : NULL; - int params_len = param ? param->data->data_used : 0; - char *pdata = data ? data->data->data : NULL; - int data_len = data ? data->data->data_used : 0; - - /* - * Setup the pointers to the outgoing. - */ - char **pp_ret_params = rparam ? &rparam->data->data : NULL; - uint32 *p_ret_params_len = rparam ? &rparam->data->data_used : NULL; - - char **pp_ret_data = rdata ? &rdata->data->data : NULL; - uint32 *p_ret_data_len = rdata ? &rdata->data->data_used : NULL; - - /* create setup parameters. */ + /* + * Create setup parameters - must be in native byte order. + */ setup[0] = cmd; - setup[1] = fnum; /* pipe file handle. got this from an SMBOpenX. */ + setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */ - if (data_len > 2048 && !bind_rq) - { - ssize_t written; - - DEBUG(5,("rpc_api_pipe: cli_write %d\n", data_len)); + DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd, (int)cli->nt_pipe_fnum)); - written = cli_write(cli, fnum, 0x0008, pdata, 0, data_len); + /* send the data: receive a response. */ + if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, + setup, 2, 0, /* Setup, length, max */ + NULL, 0, 0, /* Params, length, max */ + pdata, data_len, data_len, /* data, length, max */ + &rparam, &rparam_len, /* return params, len */ + &prdata, &rdata_len)) /* return data, len */ + { + DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli))); + return False; + } - if (written != data_len) - - { - fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)-1); - DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", errstr)); - return False; - } + /* + * Throw away returned params - we know we won't use them. + */ - DEBUG(5,("rpc_api_pipe: rpc_read after write\n")); - - first = False; - last = False; + if(rparam) { + free(rparam); + rparam = NULL; } - else - { - DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, fnum)); - used_smb_trans = True; - - /* send the data: receive a response. */ - if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, - setup, 2, 0, /* Setup, length, max */ - pparams, params_len, 0, /* Params, length, max */ - pdata, data_len, 2048, /* data, length, max */ - pp_ret_params, p_ret_params_len, /* return params, len */ - pp_ret_data, p_ret_data_len)) /* return data, len */ - { - fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)-1); - DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", errstr)); - return False; - } - if (rdata->data->data == NULL) return False; + if (prdata == NULL) { + DEBUG(0,("rpc_api_pipe: cmd %x on pipe %x failed to return data.\n", + (int)cmd, (int)cli->nt_pipe_fnum)); + return False; + } - /**** parse the header: check it's a response record */ + /* + * Give this memory as dynamically allocated to the return parse struct. + */ - rdata->data->offset.start = 0; - rdata->data->offset.end = rdata->data->data_used; - rdata->offset = 0; + prs_give_memory(rdata, prdata, rdata_len, True); + current_offset = rdata_len; - /* cli_api_pipe does an ordinary Realloc - we have no margins now. */ - rdata->data->margin = 0; - if (rparam) rparam->data->margin = 0; + if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) { + prs_mem_free(rdata); + return False; + } - if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) - { - return False; + if (rhdr.pkt_type == RPC_BINDACK) { + if (!last && !first) { + DEBUG(5,("rpc_api_pipe: bug in server (AS/U?), setting fragment first/last ON.\n")); + first = True; + last = True; } + } - if (rhdr.pkt_type == RPC_BINDACK) - { - if (!last && !first) - { - DEBUG(5,("rpc_api_pipe: bug in AS/U, setting fragment first/last ON\n")); - first = True; - last = True; - } + if (rhdr.pkt_type == RPC_RESPONSE) { + RPC_HDR_RESP rhdr_resp; + if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0)) { + DEBUG(5,("rpc_api_pipe: failed to unmarshal RPC_HDR_RESP.\n")); + prs_mem_free(rdata); + return False; } + } - if (rhdr.pkt_type == RPC_RESPONSE) - { - RPC_HDR_RESP rhdr_resp; - smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0); + DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n", + (unsigned int)len, (unsigned int)rdata_len )); + + /* check if data to be sent back was too large for one SMB. */ + /* err status is only informational: the _real_ check is on the length */ + if (len > 0) { + /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */ + /* + * Read the rest of the first response PDU. + */ + if (!rpc_read(cli, rdata, len, ¤t_offset)) { + prs_mem_free(rdata); + return False; } + } - DEBUG(5,("rpc_api_pipe: len left: %d smbtrans read: %d\n", - len, rdata->data->data_used)); - - /* check if data to be sent back was too large for one SMB. */ - /* err status is only informational: the _real_ check is on the length */ - if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */ - { - if (!rpc_read(cli, fnum, rdata, len, rdata->data->data_used, False)) - { - return False; - } - } + /* + * Now we have a complete PDU, check the auth struct if any was sent. + */ - if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) - { + if (rhdr.auth_len != 0) { + if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) return False; - } - - /* only one rpc fragment, and it has been read */ - if (first && last) - { - DEBUG(6,("rpc_api_pipe: fragment first and last both set\n")); - return True; - } + /* + * Drop the auth footers from the current offset. + * We need this if there are more fragments. + * The auth footers consist of the auth_data and the + * preceeding 8 byte auth_header. + */ + current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN); + } + + /* + * Only one rpc fragment, and it has been read. + */ + if (first && last) { + DEBUG(6,("rpc_api_pipe: fragment first and last both set\n")); + return True; } - while (!last) /* read more fragments until we get the last one */ - { + /* + * Read more fragments until we get the last one. + */ + + while (!last) { RPC_HDR_RESP rhdr_resp; int num_read; + char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN]; prs_struct hps; - prs_init(&hps, 0x18, 4, 0, True); - - num_read = cli_read(cli, fnum, hps.data->data, 0, 0x18); - DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); + /* + * First read the header of the next PDU. + */ - if (num_read != 0x18) return False; + prs_init(&hps, 0, 4, UNMARSHALL); + prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); - if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len)) - { + num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); + if (cli_error(cli, NULL, &err, NULL)) { + DEBUG(0,("rpc_api_pipe: cli_read error : %d\n", err )); return False; } - smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0); - - prs_mem_free(&hps); + DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); - if (cli_error(cli, &cls, &type)) - { - if (cls != ERRDOS || type != ERRmoredata) - { - return False; - } + if (num_read != RPC_HEADER_LEN+RPC_HDR_RESP_LEN) { + DEBUG(0,("rpc_api_pipe: Error : requested %d bytes, got %d.\n", + RPC_HEADER_LEN+RPC_HDR_RESP_LEN, num_read )); + return False; } - if (first && used_smb_trans) - { - DEBUG(0,("rpc_api_pipe: wierd rpc header received\n")); + if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len)) + return False; + + if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0)) { + DEBUG(0,("rpc_api_pipe: Error in unmarshalling RPC_HDR_RESP.\n")); return False; } - if (!rpc_read(cli, fnum, rdata, len, rdata->data->data_used, False)) - { + if (first) { + DEBUG(0,("rpc_api_pipe: secondary PDU rpc header has 'first' set !\n")); return False; } - if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) - { + /* + * Now read the rest of the PDU. + */ + + if (!rpc_read(cli, rdata, len, ¤t_offset)) return False; + + /* + * Verify any authentication footer. + */ + + if (rhdr.auth_len != 0 ) { + if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) + return False; + /* + * Drop the auth footers from the current offset. + * The auth footers consist of the auth_data and the + * preceeding 8 byte auth_header. + * We need this if there are more fragments. + */ + current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN); } } @@ -442,283 +511,362 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 fnum, - caller is expected to free the header data structure once used. ********************************************************************/ -static BOOL create_rpc_bind_req(prs_struct *rhdr, - prs_struct *rhdr_rb, - prs_struct *rhdr_auth, - prs_struct *auth_req, - prs_struct *auth_ntlm, - uint32 rpc_call_id, + +static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name, char *domain, uint32 neg_flags) { - RPC_HDR_RB hdr_rb; - RPC_HDR hdr; - RPC_HDR_AUTH hdr_auth; - RPC_AUTH_NTLMSSP_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; + RPC_HDR hdr; + RPC_HDR_RB hdr_rb; + char buffer[4096]; + prs_struct auth_info; + int auth_len = 0; - /* create the bind request RPC_HDR_RB */ - make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0, - 0x1, 0x0, 0x1, abstract, transfer); + prs_init(&auth_info, 0, 4, MARSHALL); - /* stream the bind request data */ - smb_io_rpc_hdr_rb("", &hdr_rb, rhdr_rb, 0); - mem_realloc_data(rhdr_rb->data, rhdr_rb->offset); + if (do_auth) { + RPC_HDR_AUTH hdr_auth; + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; - if (auth_req != NULL && rhdr_auth != NULL && auth_ntlm != NULL) - { - make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00, 1); - smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rhdr_auth, 0); - mem_realloc_data(rhdr_auth->data, rhdr_auth->offset); + /* + * Create the auth structs we will marshall. + */ + + init_rpc_hdr_auth(&hdr_auth, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, 0x00, 1); + init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_NEGOTIATE); + init_rpc_auth_ntlmssp_neg(&ntlmssp_neg, neg_flags, my_name, domain); + + /* + * Use the 4k buffer to store the auth info. + */ + + prs_give_memory( &auth_info, buffer, sizeof(buffer), False); - make_rpc_auth_ntlmssp_verifier(&auth_verifier, - "NTLMSSP", NTLMSSP_NEGOTIATE); + /* + * Now marshall the data into the temporary parse_struct. + */ - smb_io_rpc_auth_ntlmssp_verifier("auth_verifier", &auth_verifier, auth_req, 0); - mem_realloc_data(auth_req->data, auth_req->offset); + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) { + DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_AUTH.\n")); + return False; + } + + if(!smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_info, 0)) { + DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_AUTH_VERIFIER.\n")); + return False; + } - make_rpc_auth_ntlmssp_neg(&ntlmssp_neg, - neg_flags, my_name, domain); + if(!smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, &auth_info, 0)) { + DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_AUTH_NTLMSSP_NEG.\n")); + return False; + } - smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, auth_req, 0); - mem_realloc_data(auth_req->data, auth_req->offset); + /* Auth len in the rpc header doesn't include auth_header. */ + auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN; } /* create the request RPC_HDR */ - make_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id, - (auth_req != NULL ? auth_req ->offset : 0) + - (auth_ntlm != NULL ? auth_ntlm->offset : 0) + - (rhdr_auth != NULL ? rhdr_auth->offset : 0) + - rhdr_rb->offset + 0x10, - (auth_req != NULL ? auth_req ->offset : 0) + - (auth_ntlm != NULL ? auth_ntlm->offset : 0)); - - smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0); - mem_realloc_data(rhdr->data, rhdr->offset); + init_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id, + RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info), + auth_len); - if (rhdr->data == NULL || rhdr_rb->data == NULL) return False; + if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) { + DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n")); + return False; + } - /***/ - /*** link rpc header, bind acknowledgment and authentication responses ***/ - /***/ + /* create the bind request RPC_HDR_RB */ + init_rpc_hdr_rb(&hdr_rb, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, 0x0, + 0x1, 0x0, 0x1, abstract, transfer); - if (auth_req != NULL) - { - prs_link(NULL , rhdr , rhdr_rb ); - prs_link(rhdr , rhdr_rb , rhdr_auth); - prs_link(rhdr_rb , rhdr_auth , auth_req ); - prs_link(rhdr_auth, auth_req , auth_ntlm); - prs_link(auth_req , auth_ntlm , NULL ); + /* Marshall the bind request data */ + if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) { + DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_RB.\n")); + return False; } - else - { - prs_link(NULL, rhdr , rhdr_rb); - prs_link(rhdr, rhdr_rb, NULL ); + + /* + * Grow the outgoing buffer to store any auth info. + */ + + if(hdr.auth_len != 0) { + if(!prs_append_prs_data( rpc_out, &auth_info)) { + DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n")); + return False; + } } return True; } /******************************************************************* - creates a DCE/RPC bind authentication response - - - initialises the parse structure. - - dynamically allocates the header data structure - - caller is expected to free the header data structure once used. - + Creates a DCE/RPC bind authentication response. + This is the packet that is sent back to the server once we + have received a BIND-ACK, to finish the third leg of + the authentication handshake. ********************************************************************/ -BOOL create_rpc_bind_resp(struct pwd_info *pwd, + +static BOOL create_rpc_bind_resp(struct pwd_info *pwd, char *domain, char *user_name, char *my_name, uint32 ntlmssp_cli_flgs, uint32 rpc_call_id, - prs_struct *rhdr, - prs_struct *rhdr_autha, - prs_struct *auth_resp) + prs_struct *rpc_out) { - RPC_HDR hdr; - RPC_HDR_AUTHA hdr_autha; - RPC_AUTH_NTLMSSP_VERIFIER auth_verifier; + unsigned char lm_owf[24]; + unsigned char nt_owf[24]; + RPC_HDR hdr; + RPC_HDR_AUTHA hdr_autha; + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; + char buffer[4096]; + prs_struct auth_info; - make_rpc_hdr_autha(&hdr_autha, 0x1630, 0x1630, 0x0a, 0x06, 0x00); - smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rhdr_autha, 0); - mem_realloc_data(rhdr_autha->data, rhdr_autha->offset); + /* + * Marshall the variable length data into a temporary parse + * struct, pointing into a 4k local buffer. + */ + prs_init(&auth_info, 0, 4, MARSHALL); - make_rpc_auth_ntlmssp_verifier(&auth_verifier, - "NTLMSSP", NTLMSSP_AUTH); + /* + * Use the 4k buffer to store the auth info. + */ - smb_io_rpc_auth_ntlmssp_verifier("auth_verifier", &auth_verifier, auth_resp, 0); - mem_realloc_data(auth_resp->data, auth_resp->offset); + prs_give_memory( &auth_info, buffer, sizeof(buffer), False); - create_ntlmssp_resp(pwd, domain, user_name, my_name, ntlmssp_cli_flgs, - auth_resp); + /* + * Create the variable length auth_data. + */ - /* create the request RPC_HDR */ - make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id, - auth_resp->offset + rhdr_autha->offset + 0x10, - auth_resp->offset); + init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH); + + pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf); + + init_rpc_auth_ntlmssp_resp(&ntlmssp_resp, + lm_owf, nt_owf, + domain, user_name, my_name, + ntlmssp_cli_flgs); + + /* + * Marshall the variable length auth_data into a temp parse_struct. + */ + + if(!smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_info, 0)) { + DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_AUTH_VERIFIER.\n")); + return False; + } + + if(!smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, &auth_info, 0)) { + DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_AUTH_NTLMSSP_RESP.\n")); + return False; + } + + /* Create the request RPC_HDR */ + init_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id, + RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN + prs_offset(&auth_info), + prs_offset(&auth_info) ); + + /* Marshall it. */ + if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) { + DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR.\n")); + return False; + } - smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0); - mem_realloc_data(rhdr->data, rhdr->offset); + /* Create the request RPC_HDR_AUTHA */ + init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, + NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, 0x00); - if (rhdr->data == NULL || rhdr_autha->data == NULL) return False; + if(!smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rpc_out, 0)) { + DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR_AUTHA.\n")); + return False; + } - /***/ - /*** link rpc header and authentication responses ***/ - /***/ + /* + * Append the auth data to the outgoing buffer. + */ - prs_link(NULL , rhdr , rhdr_autha); - prs_link(rhdr , rhdr_autha , auth_resp ); - prs_link(rhdr_autha, auth_resp , NULL ); + if(!prs_append_prs_data(rpc_out, &auth_info)) { + DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n")); + return False; + } return True; } /******************************************************************* - creates a DCE/RPC bind request - - - initialises the parse structure. - - dynamically allocates the header data structure - - caller is expected to free the header data structure once used. - + Creates a DCE/RPC request. ********************************************************************/ -static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len, - int auth_len) +static BOOL create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, int auth_len) { uint32 alloc_hint; - RPC_HDR_REQ hdr_req; RPC_HDR hdr; + RPC_HDR_REQ hdr_req; - DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n", - op_num, data_len)); + DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n", op_num, data_len)); /* create the rpc header RPC_HDR */ - make_rpc_hdr(&hdr , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST, + init_rpc_hdr(&hdr, RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST, get_rpc_call_id(), data_len, auth_len); + /* + * The alloc hint should be the amount of data, not including + * RPC headers & footers. + */ + if (auth_len != 0) - { - alloc_hint = data_len - 0x18 - auth_len - 16; - } + alloc_hint = data_len - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len; else - { - alloc_hint = data_len - 0x18; - } + alloc_hint = data_len - RPC_HEADER_LEN; DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n", data_len, auth_len, alloc_hint)); - /* create the rpc request RPC_HDR_REQ */ - make_rpc_hdr_req(&hdr_req, alloc_hint, op_num); + /* Create the rpc request RPC_HDR_REQ */ + init_rpc_hdr_req(&hdr_req, alloc_hint, op_num); /* stream-time... */ - smb_io_rpc_hdr ("hdr ", &hdr , rhdr, 0); - smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0); + if(!smb_io_rpc_hdr("hdr ", &hdr, rpc_out, 0)) + return False; - if (rhdr->data == NULL || rhdr->offset != 0x18) return False; + if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, rpc_out, 0)) + return False; - rhdr->data->offset.start = 0; - rhdr->data->offset.end = rhdr->offset; + if (prs_offset(rpc_out) != RPC_HEADER_LEN + RPC_HDR_REQ_LEN) + return False; return True; } /**************************************************************************** - send a request on an rpc pipe. + Send a request on an rpc pipe. ****************************************************************************/ -BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 fnum, uint8 op_num, + +BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, prs_struct *data, prs_struct *rdata) { - /* fudge this, at the moment: create the header; memcpy the data. oops. */ - prs_struct dataa; - prs_struct rparam; - prs_struct hdr; - prs_struct hdr_auth; - prs_struct auth_verf; - int data_len; - int auth_len; + prs_struct outgoing_packet; + uint32 data_len; + uint32 auth_len; BOOL ret; BOOL auth_verify; BOOL auth_seal; uint32 crc32 = 0; + char *pdata_out = NULL; auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN); auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL); - /* happen to know that NTLMSSP authentication verifier is 16 bytes */ - auth_len = (auth_verify ? 16 : 0); - data_len = data->offset + auth_len + (auth_verify ? 8 : 0) + 0x18; - data->data->offset.end = data->offset; + /* + * The auth_len doesn't include the RPC_HDR_AUTH_LEN. + */ - prs_init(&hdr , data_len, 4, SAFETY_MARGIN, False); - prs_init(&hdr_auth , 8 , 4, SAFETY_MARGIN, False); - prs_init(&auth_verf, auth_len, 4, SAFETY_MARGIN, False); - prs_init(&rparam , 0 , 4, 0 , True ); + auth_len = (auth_verify ? RPC_AUTH_NTLMSSP_CHK_LEN : 0); - create_rpc_request(&hdr, op_num, data_len, auth_len); + /* + * PDU len is header, plus request header, plus data, plus + * auth_header_len (if present), plus auth_len (if present). + * NB. The auth stuff should be aligned on an 8 byte boundary + * to be totally DCE/RPC spec complient. For now we cheat and + * hope that the data structs defined are a multiple of 8 bytes. + */ - if (auth_seal) - { - crc32 = crc32_calc_buffer(data->offset, mem_data(&data->data, 0)); - NTLMSSPcalc_ap(cli, (uchar*)mem_data(&data->data, 0), data->offset); + if((prs_offset(data) % 8) != 0) { + DEBUG(5,("rpc_api_pipe_req: Outgoing data not a multiple of 8 bytes....\n")); } - if (auth_seal || auth_verify) - { - RPC_HDR_AUTH rhdr_auth; + data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(data) + + (auth_verify ? RPC_HDR_AUTH_LEN : 0) + auth_len; - make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0)); - smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0); + /* + * Malloc a parse struct to hold it (and enough for alignments). + */ + + if(!prs_init(&outgoing_packet, data_len + 8, 4, MARSHALL)) { + DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len )); + return False; } - if (auth_verify) - { - RPC_AUTH_NTLMSSP_CHK chk; + pdata_out = prs_data_p(&outgoing_packet); + + /* + * Write out the RPC header and the request header. + */ + + if(!create_rpc_request(&outgoing_packet, op_num, data_len, auth_len)) { + DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n")); + prs_mem_free(&outgoing_packet); + return False; + } + + /* + * Seal the outgoing data if requested. + */ - make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, cli->ntlmssp_seq_num++); - smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0); - NTLMSSPcalc_ap(cli, (uchar*)mem_data(&auth_verf.data, 4), 12); + if (auth_seal) { + crc32 = crc32_calc_buffer(prs_data_p(data), prs_offset(data)); + NTLMSSPcalc_ap(cli, (unsigned char*)prs_data_p(data), prs_offset(data)); } - if (auth_seal || auth_verify) - { - prs_link(NULL , &hdr , data ); - prs_link(&hdr , data , &hdr_auth ); - prs_link(data , &hdr_auth , &auth_verf); - prs_link(&hdr_auth, &auth_verf, NULL ); + /* + * Now copy the data into the outgoing packet. + */ + + if(!prs_append_prs_data( &outgoing_packet, data)) { + DEBUG(0,("rpc_api_pipe_req: Failed to append data to outgoing packet.\n")); + prs_mem_free(&outgoing_packet); + return False; } - else - { - prs_link(NULL, &hdr, data); - prs_link(&hdr, data, NULL); + + /* + * Add a trailing auth_verifier if needed. + */ + + if (auth_seal || auth_verify) { + RPC_HDR_AUTH hdr_auth; + + init_rpc_hdr_auth(&hdr_auth, NTLMSSP_AUTH_TYPE, + NTLMSSP_AUTH_LEVEL, 0x08, (auth_verify ? 1 : 0)); + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &outgoing_packet, 0)) { + DEBUG(0,("rpc_api_pipe_req: Failed to marshal RPC_HDR_AUTH.\n")); + prs_mem_free(&outgoing_packet); + return False; + } } - DEBUG(100,("data_len: %x data_calc_len: %x\n", - data_len, mem_buf_len(data->data))); + /* + * Finally the auth data itself. + */ + + if (auth_verify) { + RPC_AUTH_NTLMSSP_CHK chk; + uint32 current_offset = prs_offset(&outgoing_packet); + + init_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, cli->ntlmssp_seq_num++); + if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &outgoing_packet, 0)) { + DEBUG(0,("rpc_api_pipe_req: Failed to marshal RPC_AUTH_NTLMSSP_CHK.\n")); + prs_mem_free(&outgoing_packet); + return False; + } + NTLMSSPcalc_ap(cli, (unsigned char*)&pdata_out[current_offset+4], RPC_AUTH_NTLMSSP_CHK_LEN - 4); + } - /* this is a hack due to limitations in rpc_api_pipe */ - prs_init(&dataa, data_len, 4, 0x0, False); - mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data)); + DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, prs_offset(&outgoing_packet))); - ret = rpc_api_pipe(cli, fnum, False, 0x0026, NULL, &dataa, &rparam, rdata); + ret = rpc_api_pipe(cli, 0x0026, &outgoing_packet, rdata); - prs_mem_free(&hdr_auth ); - prs_mem_free(&auth_verf); - prs_mem_free(&rparam ); - prs_mem_free(&hdr ); - prs_mem_free(&dataa ); + prs_mem_free(&outgoing_packet); return ret; } /**************************************************************************** -do an rpc bind + Set the handle state. ****************************************************************************/ -static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum, - const char *pipe_name, uint16 device_state) +static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state) { BOOL state_set = False; char param[2]; @@ -727,17 +875,18 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum, char *rdata = NULL; uint32 rparam_len, rdata_len; - if (pipe_name == NULL) return False; + if (pipe_name == NULL) + return False; DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", - fnum, pipe_name, device_state)); + cli->nt_pipe_fnum, pipe_name, device_state)); /* create parameters: device state */ SSVAL(param, 0, device_state); /* create setup parameters. */ setup[0] = 0x0001; - setup[1] = fnum; /* pipe file handle. got this from an SMBOpenX. */ + setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ /* send the data on \PIPE\ */ if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, @@ -751,8 +900,10 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum, state_set = True; } - if (rparam) free(rparam); - if (rdata ) free(rdata ); + if (rparam) + free(rparam); + if (rdata) + free(rdata ); return state_set; } @@ -761,27 +912,22 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum, check the rpc bind acknowledge response ****************************************************************************/ -static BOOL valid_pipe_name(const char *pipe_name, - RPC_IFACE *abstract, RPC_IFACE *transfer) +static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer) { int pipe_idx = 0; - while (pipe_names[pipe_idx].client_pipe != NULL) - { - if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) - { - DEBUG(5,("Bind Abstract Syntax:\n")); + while (pipe_names[pipe_idx].client_pipe != NULL) { + if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) { + DEBUG(5,("Bind Abstract Syntax: ")); dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), sizeof(pipe_names[pipe_idx].abstr_syntax)); - DEBUG(5,("Bind Transfer Syntax:\n")); + DEBUG(5,("Bind Transfer Syntax: ")); dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax), sizeof(pipe_names[pipe_idx].trans_syntax)); /* copy the required syntaxes out so we can do the right bind */ - memcpy(transfer, &(pipe_names[pipe_idx].trans_syntax), - sizeof(pipe_names[pipe_idx].trans_syntax)); - memcpy(abstract, &(pipe_names[pipe_idx].abstr_syntax), - sizeof(pipe_names[pipe_idx].abstr_syntax)); + *transfer = pipe_names[pipe_idx].trans_syntax; + *abstract = pipe_names[pipe_idx].abstr_syntax; return True; } @@ -796,56 +942,44 @@ static BOOL valid_pipe_name(const char *pipe_name, check the rpc bind acknowledge response ****************************************************************************/ -static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name, - RPC_IFACE *transfer) +static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer) { int i = 0; - while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0) - { + while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0) { DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n", pipe_names[i].client_pipe , pipe_names[i].server_pipe )); - if ((strequal(pipe_name, pipe_names[i].client_pipe ))) - { - if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe )) - { + if ((strequal(pipe_name, pipe_names[i].client_pipe ))) { + if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe )) { DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", pipe_names[i].server_pipe )); break; - } - else - { + } else { DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n", pipe_names[i].server_pipe , hdr_ba->addr.str)); break; } - } - else - { + } else { i++; } } - if (pipe_names[i].server_pipe == NULL) - { + if (pipe_names[i].server_pipe == NULL) { DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str)); return False; } /* check the transfer syntax */ - if (!((hdr_ba->transfer.version == transfer->version) && - (memcmp(hdr_ba->transfer.data, transfer->data, - sizeof(transfer->version)) ==0))) - { + if ((hdr_ba->transfer.version != transfer->version) || + (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) { DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n")); return False; } /* lkclXXXX only accept one result: check the result(s) */ - if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) - { + if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) { DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n", hdr_ba->res.num_results, hdr_ba->res.reason)); } @@ -855,196 +989,169 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name, } /**************************************************************************** -do an rpc bind + Create and send the third packet in an RPC auth. ****************************************************************************/ -static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 fnum, - const char *pipe_name, - RPC_IFACE *abstract, RPC_IFACE *transfer, - char *my_name) +static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 rpc_call_id) { - prs_struct hdr; - prs_struct hdr_rb; - prs_struct hdr_auth; - prs_struct auth_req; - prs_struct auth_ntlm; - prs_struct data; - prs_struct rdata; - prs_struct rparam; + RPC_HDR_AUTH rhdr_auth; + RPC_AUTH_VERIFIER rhdr_verf; + RPC_AUTH_NTLMSSP_CHAL rhdr_chal; + char buffer[MAX_PDU_FRAG_LEN]; + prs_struct rpc_out; + ssize_t ret; + + unsigned char p24[24]; + unsigned char lm_owf[24]; + unsigned char lm_hash[16]; + + if(!smb_io_rpc_hdr_auth("", &rhdr_auth, rdata, 0)) { + DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_HDR_AUTH.\n")); + return False; + } + if(!smb_io_rpc_auth_verifier("", &rhdr_verf, rdata, 0)) { + DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_AUTH_VERIFIER.\n")); + return False; + } + if(!smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, rdata, 0)) { + DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_AUTH_NTLMSSP_CHAL.\n")); + return False; + } - BOOL valid_ack = False; - BOOL ntlmssp_auth = cli->ntlmssp_cli_flgs != 0; - uint32 rpc_call_id; + cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags; + + pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge); + + prs_init(&rpc_out, 0, 4, MARSHALL); + + prs_give_memory( &rpc_out, buffer, sizeof(buffer), False); + + create_rpc_bind_resp(&cli->pwd, cli->domain, + cli->user_name, global_myname, + cli->ntlmssp_cli_flgs, rpc_call_id, + &rpc_out); + + pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL); + pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL); + + NTLMSSPOWFencrypt(lm_hash, lm_owf, p24); - if (pipe_name == NULL || abstract == NULL || transfer == NULL) { + unsigned char j = 0; + int ind; + unsigned char k2[8]; + + memcpy(k2, p24, 5); + k2[5] = 0xe5; + k2[6] = 0x38; + k2[7] = 0xb0; + + for (ind = 0; ind < 256; ind++) + cli->ntlmssp_hash[ind] = (unsigned char)ind; + + for( ind = 0; ind < 256; ind++) { + unsigned char tc; + + j += (cli->ntlmssp_hash[ind] + k2[ind%8]); + + tc = cli->ntlmssp_hash[ind]; + cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j]; + cli->ntlmssp_hash[j] = tc; + } + + cli->ntlmssp_hash[256] = 0; + cli->ntlmssp_hash[257] = 0; + } + + memset((char *)lm_hash, '\0', sizeof(lm_hash)); + + if ((ret = cli_write(cli, cli->nt_pipe_fnum, 0x8, prs_data_p(&rpc_out), + 0, (size_t)prs_offset(&rpc_out))) != (ssize_t)prs_offset(&rpc_out)) { + DEBUG(0,("rpc_send_auth_reply: cli_write failed. Return was %d\n", (int)ret)); return False; } - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name)); + cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags; + return True; +} + +/**************************************************************************** + Do an rpc bind. +****************************************************************************/ + +static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) +{ + RPC_IFACE abstract; + RPC_IFACE transfer; + prs_struct rpc_out; + prs_struct rdata; + BOOL do_auth = (cli->ntlmssp_cli_flgs != 0); + uint32 rpc_call_id; + char buffer[MAX_PDU_FRAG_LEN]; - if (!valid_pipe_name(pipe_name, abstract, transfer)) return False; + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name)); - prs_init(&hdr , 0x10 , 4, 0x0 , False); - prs_init(&hdr_rb , 1024 , 4, SAFETY_MARGIN, False); - prs_init(&hdr_auth , (ntlmssp_auth ? 8 : 0), 4, SAFETY_MARGIN, False); - prs_init(&auth_req , (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False); - prs_init(&auth_ntlm, (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False); + if (!valid_pipe_name(pipe_name, &abstract, &transfer)) + return False; - prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True); - prs_init(&rparam , 0 , 4, SAFETY_MARGIN, True); + prs_init(&rpc_out, 0, 4, MARSHALL); - rpc_call_id = get_rpc_call_id(); - create_rpc_bind_req(&hdr, &hdr_rb, - ntlmssp_auth ? &hdr_auth : NULL, - ntlmssp_auth ? &auth_req : NULL, - ntlmssp_auth ? &auth_ntlm : NULL, - rpc_call_id, - abstract, transfer, - global_myname, cli->usr.domain, cli->usr.ntlmssp_flags); + /* + * Use the MAX_PDU_FRAG_LEN buffer to store the bind request. + */ - /* this is a hack due to limitations in rpc_api_pipe */ - prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False); - mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data)); + prs_give_memory( &rpc_out, buffer, sizeof(buffer), False); - cli->max_recv_frag = 0x1000; + rpc_call_id = get_rpc_call_id(); - /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, fnum, True, 0x0026, NULL, &data, &rparam, &rdata)) - { - RPC_HDR_BA hdr_ba; - RPC_HDR_AUTH rhdr_auth; - RPC_AUTH_NTLMSSP_VERIFIER rhdr_verf; - RPC_AUTH_NTLMSSP_CHAL rhdr_chal; + /* Marshall the outgoing data. */ + create_rpc_bind_req(&rpc_out, do_auth, rpc_call_id, + &abstract, &transfer, + global_myname, cli->domain, cli->ntlmssp_cli_flgs); - DEBUG(5, ("rpc_api_pipe: return OK\n")); + /* Initialize the incoming data struct. */ + prs_init(&rdata, 0, 4, UNMARSHALL); - smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0); + /* send data on \PIPE\. receive a response */ + if (rpc_api_pipe(cli, 0x0026, &rpc_out, &rdata)) { + RPC_HDR_BA hdr_ba; - if (rdata.offset != 0) - { - valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer); - } + DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n")); - if (valid_ack) - { - cli->max_xmit_frag = hdr_ba.bba.max_tsize; - cli->max_recv_frag = hdr_ba.bba.max_rsize; + if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0)) { + DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n")); + prs_mem_free(&rdata); + return False; } - if (valid_ack && ntlmssp_auth) - { - smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0); - if (rdata.offset == 0) valid_ack = False; + if(!check_bind_response(&hdr_ba, pipe_name, &transfer)) { + DEBUG(0,("rpc_pipe_bind: check_bind_response failed.\n")); + prs_mem_free(&rdata); + return False; } - if (valid_ack && ntlmssp_auth) - { - smb_io_rpc_auth_ntlmssp_verifier("", &rhdr_verf, &rdata, 0); - if (rdata.offset == 0) valid_ack = False; - } - if (valid_ack && ntlmssp_auth) - { - smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, &rdata, 0); - if (rdata.offset == 0) valid_ack = False; - } - if (valid_ack && ntlmssp_auth) - { - unsigned char p24[24]; - unsigned char lm_owf[24]; - unsigned char lm_hash[16]; - - prs_struct hdra; - prs_struct hdr_autha; - prs_struct auth_resp; - prs_struct dataa; - - cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags; - - prs_init(&hdra , 0x10, 4, 0x0 , False); - prs_init(&hdr_autha, 1024, 4, SAFETY_MARGIN, False); - prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False); - - pwd_make_lm_nt_owf(&cli->usr.pwd, rhdr_chal.challenge); - - create_rpc_bind_resp(&cli->usr.pwd, cli->usr.domain, - cli->usr.user_name, global_myname, - cli->ntlmssp_cli_flgs, - rpc_call_id, - &hdra, &hdr_autha, &auth_resp); - - pwd_get_lm_nt_owf(&cli->usr.pwd, lm_owf, NULL, NULL, NULL); - pwd_get_lm_nt_16(&cli->usr.pwd, lm_hash, NULL); - NTLMSSPOWFencrypt(lm_hash, lm_owf, p24); - { - unsigned char j = 0; - int ind; - unsigned char k2[8]; - - memcpy(k2, p24, 5); - k2[5] = 0xe5; - k2[6] = 0x38; - k2[7] = 0xb0; - - for (ind = 0; ind < 256; ind++) - { - cli->ntlmssp_hash[ind] = (unsigned char)ind; - } - - for( ind = 0; ind < 256; ind++) - { - unsigned char tc; - - j += (cli->ntlmssp_hash[ind] + k2[ind%8]); - - tc = cli->ntlmssp_hash[ind]; - cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j]; - cli->ntlmssp_hash[j] = tc; - } - - cli->ntlmssp_hash[256] = 0; - cli->ntlmssp_hash[257] = 0; - } -/* NTLMSSPhash(cli->ntlmssp_hash, p24); */ - bzero(lm_hash, sizeof(lm_hash)); - - /* this is a hack due to limitations in rpc_api_pipe */ - prs_init(&dataa, mem_buf_len(hdra.data), 4, 0x0, False); - mem_buf_copy(dataa.data->data, hdra.data, 0, mem_buf_len(hdra.data)); - - if (cli_write(cli, fnum, 0x0008, - dataa.data->data, 0, - dataa.data->data_used) < 0) - { - valid_ack = False; - } + cli->max_xmit_frag = hdr_ba.bba.max_tsize; + cli->max_recv_frag = hdr_ba.bba.max_rsize; - if (valid_ack) - { - cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags; - } + /* + * If we're doing NTLMSSP auth we need to send a reply to + * the bind-ack to complete the 3-way challenge response + * handshake. + */ - prs_mem_free(&hdra); - prs_mem_free(&dataa); - prs_mem_free(&hdr_autha); - prs_mem_free(&auth_resp); + if (do_auth && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) { + DEBUG(0,("rpc_pipe_bind: rpc_send_auth_reply failed.\n")); + prs_mem_free(&rdata); + return False; } } - prs_mem_free(&data ); - prs_mem_free(&hdr ); - prs_mem_free(&hdr_rb ); - prs_mem_free(&hdr_auth ); - prs_mem_free(&auth_req ); - prs_mem_free(&auth_ntlm); - prs_mem_free(&rdata ); - prs_mem_free(&rparam ); - - return valid_ack; + prs_mem_free(&rdata); + return True; } /**************************************************************************** - set ntlmssp negotiation flags + Set ntlmssp negotiation flags. ****************************************************************************/ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) @@ -1054,68 +1161,45 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) /**************************************************************************** - open a session + Open a session. ****************************************************************************/ -BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name, - uint16* fnum) +BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) { - RPC_IFACE abstract; - RPC_IFACE transfer; + int fnum; - /******************* open the pipe *****************/ - if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS)) - { - int f; - f = cli_nt_create(cli, &(pipe_name[5])); - if (f == -1) - { - fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)-1); + if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS)) { + if ((fnum = cli_nt_create(cli, &(pipe_name[5]))) == -1) { DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n", - &(pipe_name[5]), cli->desthost, errstr)); + &(pipe_name[5]), cli->desthost, cli_errstr(cli))); return False; } - *fnum = (uint16)f; - } - else - { - int f; - f = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE); - if (f == -1) - { - fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)-1); + + cli->nt_pipe_fnum = (uint16)fnum; + } else { + if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) { DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n", - pipe_name, cli->desthost, errstr)); + pipe_name, cli->desthost, cli_errstr(cli))); return False; } - *fnum = (uint16)f; + + cli->nt_pipe_fnum = (uint16)fnum; /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, *fnum, pipe_name, 0x4300)) - { - fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)-1); + if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) { DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", - errstr)); - cli_close(cli, *fnum); + cli_errstr(cli))); + cli_close(cli, cli->nt_pipe_fnum); return False; } - } /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, *fnum, pipe_name, - &abstract, &transfer, - global_myname)) - { - fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)-1); + if (!rpc_pipe_bind(cli, pipe_name, global_myname)) { DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", - errstr)); - cli_close(cli, *fnum); + cli_errstr(cli))); + cli_close(cli, cli->nt_pipe_fnum); return False; } @@ -1123,6 +1207,18 @@ 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; } @@ -1130,10 +1226,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name, close the session ****************************************************************************/ -void cli_nt_session_close(struct cli_state *cli, uint16 fnum) +void cli_nt_session_close(struct cli_state *cli) { - if (fnum != 0xffff) - { - cli_close(cli, fnum); - } + cli_close(cli, cli->nt_pipe_fnum); } diff --git a/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c index 4f1c28a701..b5e9cbb2ac 100644 --- a/source3/rpc_client/cli_reg.c +++ b/source3/rpc_client/cli_reg.c @@ -6,6 +6,7 @@ * Copyright (C) Andrew Tridgell 1992-1998, * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1997-1998. + * Copyright (C) Jeremy Allison 1999. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,80 +35,38 @@ extern int DEBUGLEVEL; /**************************************************************************** do a REG Open Policy ****************************************************************************/ -BOOL reg_connect( const char* srv_name, - const char *full_keyname, - char *key_name, +BOOL do_reg_connect(struct cli_state *cli, char *full_keyname, char *key_name, POLICY_HND *reg_hnd) { BOOL res = True; uint32 reg_type = 0; - struct cli_connection *con = NULL; - - if (!cli_connection_init(srv_name, PIPE_WINREG, &con)) - { + if (full_keyname == NULL) return False; - } ZERO_STRUCTP(reg_hnd); - if (full_keyname == NULL) - { - return False; - } - /* * open registry receive a policy handle */ - if (!reg_split_key(full_keyname, ®_type, key_name)) - { - DEBUG(0,("reg_connect: unrecognised key name %s\n", - full_keyname)); + if (!reg_split_key(full_keyname, ®_type, key_name)) { + DEBUG(0,("do_reg_connect: unrecognised key name %s\n", full_keyname)); return False; } - switch (reg_type) - { - case HKEY_CLASSES_ROOT: - { - res = res ? reg_open_hkcr(con, - 0x5428, 0x02000000, - reg_hnd) : False; - break; - } + switch (reg_type) { + case HKEY_LOCAL_MACHINE: + res = res ? do_reg_open_hklm(cli, 0x84E0, 0x02000000, reg_hnd) : False; + break; - case HKEY_LOCAL_MACHINE: - { - res = res ? reg_open_hklm(con, - 0x84E0, 0x02000000, - reg_hnd) : False; - break; - } - - case HKEY_USERS: - { - res = res ? reg_open_hku(con, - 0x84E0, 0x02000000, - reg_hnd) : False; - break; - } - default: - { - DEBUG(0,("reg_connect: unrecognised hive key\n")); - return False; - } - } + case HKEY_USERS: + res = res ? do_reg_open_hku(cli, 0x84E0, 0x02000000, reg_hnd) : False; + break; - if (res) - { - if (!register_policy_hnd(reg_hnd) || - !set_policy_con(reg_hnd, con, - cli_connection_unlink)) - { - cli_connection_unlink(con); - return False; - } + default: + DEBUG(0,("do_reg_connect: unrecognised hive key\n")); + return False; } return res; @@ -116,175 +75,123 @@ BOOL reg_connect( const char* srv_name, /**************************************************************************** do a REG Open Policy ****************************************************************************/ -BOOL reg_open_hkcr( struct cli_connection *con, - uint16 unknown_0, uint32 level, - POLICY_HND *hnd) -{ - prs_struct rbuf; - prs_struct buf; - REG_Q_OPEN_HKCR q_o; - BOOL valid_pol = False; - - if (hnd == NULL) 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 REG_OPEN_HKCR */ - - DEBUG(4,("REG Open HKCR\n")); - - make_reg_q_open_hkcr(&q_o, unknown_0, level); - - /* turn parameters into data stream */ - reg_io_q_open_hkcr("", &q_o, &buf, 0); - - /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, REG_OPEN_HKCR, &buf, &rbuf)) - { - REG_R_OPEN_HKCR r_o; - BOOL p; - - ZERO_STRUCT(r_o); - - reg_io_r_open_hkcr("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_OPEN_HKCR: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - /* ok, at last: we're happy. return the policy handle */ - memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); - valid_pol = True; - } - } - - prs_mem_free(&rbuf); - prs_mem_free(&buf ); - - return valid_pol; -} - -/**************************************************************************** -do a REG Open Policy -****************************************************************************/ -BOOL reg_open_hklm( struct cli_connection *con, - uint16 unknown_0, uint32 level, +BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level, POLICY_HND *hnd) { prs_struct rbuf; prs_struct buf; REG_Q_OPEN_HKLM q_o; - BOOL valid_pol = False; + REG_R_OPEN_HKLM r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_OPEN_HKLM */ DEBUG(4,("REG Open HKLM\n")); - make_reg_q_open_hklm(&q_o, unknown_0, level); + init_reg_q_open_hklm(&q_o, unknown_0, level); /* turn parameters into data stream */ - reg_io_q_open_hklm("", &q_o, &buf, 0); + if(!reg_io_q_open_hklm("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, REG_OPEN_HKLM, &buf, &rbuf)) - { - REG_R_OPEN_HKLM r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, REG_OPEN_HKLM, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_open_hklm("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_OPEN_HKLM: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_open_hklm("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - /* ok, at last: we're happy. return the policy handle */ - memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); - valid_pol = True; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_OPEN_HKLM: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } + /* ok, at last: we're happy. return the policy handle */ + memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); + prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_pol; + return True; } /**************************************************************************** do a REG Open HKU ****************************************************************************/ -BOOL reg_open_hku( struct cli_connection *con, - uint16 unknown_0, uint32 level, +BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level, POLICY_HND *hnd) { prs_struct rbuf; prs_struct buf; REG_Q_OPEN_HKU q_o; - BOOL valid_pol = False; + REG_R_OPEN_HKU r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_OPEN_HKU */ DEBUG(4,("REG Open HKU\n")); - make_reg_q_open_hku(&q_o, unknown_0, level); + init_reg_q_open_hku(&q_o, unknown_0, level); /* turn parameters into data stream */ - reg_io_q_open_hku("", &q_o, &buf, 0); + if(!reg_io_q_open_hku("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, REG_OPEN_HKU, &buf, &rbuf)) - { - REG_R_OPEN_HKU r_o; - BOOL p; + if (rpc_api_pipe_req(cli, REG_OPEN_HKU, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_open_hku("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_open_hku("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - /* ok, at last: we're happy. return the policy handle */ - memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); - valid_pol = True; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } + /* ok, at last: we're happy. return the policy handle */ + memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); + prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_pol; + return True; } /**************************************************************************** @@ -292,62 +199,65 @@ do a REG Unknown 0xB command. sent after a create key or create value. this might be some sort of "sync" or "refresh" command, sent after modification of the registry... ****************************************************************************/ -BOOL reg_flush_key( POLICY_HND *hnd) +BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd) { prs_struct rbuf; prs_struct buf; REG_Q_FLUSH_KEY q_o; - BOOL valid_query = False; + REG_R_FLUSH_KEY r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_FLUSH_KEY */ DEBUG(4,("REG Unknown 0xB\n")); - make_reg_q_flush_key(&q_o, hnd); + init_reg_q_flush_key(&q_o, hnd); /* turn parameters into data stream */ - reg_io_q_flush_key("", &q_o, &buf, 0); + if(!reg_io_q_flush_key("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_FLUSH_KEY, &buf, &rbuf)) - { - REG_R_FLUSH_KEY r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, REG_FLUSH_KEY, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_flush_key("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_flush_key("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_query = True; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_query; + return True; } /**************************************************************************** do a REG Query Key ****************************************************************************/ -BOOL reg_query_key( POLICY_HND *hnd, - char *key_class, uint32 *class_len, +BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd, + char *class, uint32 *class_len, uint32 *num_subkeys, uint32 *max_subkeylen, uint32 *max_subkeysize, uint32 *num_values, uint32 *max_valnamelen, uint32 *max_valbufsize, @@ -356,409 +266,427 @@ BOOL reg_query_key( POLICY_HND *hnd, prs_struct rbuf; prs_struct buf; REG_Q_QUERY_KEY q_o; - BOOL valid_query = False; + REG_R_QUERY_KEY r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_QUERY_KEY */ DEBUG(4,("REG Query Key\n")); - make_reg_q_query_key(&q_o, hnd, *class_len); + init_reg_q_query_key(&q_o, hnd, *class_len); /* turn parameters into data stream */ - reg_io_q_query_key("", &q_o, &buf, 0); + if(!reg_io_q_query_key("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_QUERY_KEY, &buf, &rbuf)) - { - REG_R_QUERY_KEY r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, REG_QUERY_KEY, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_query_key("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_query_key("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_query = True; - - *class_len = r_o.hdr_class.uni_max_len; - unistr2_to_ascii(key_class, &r_o.uni_class, sizeof(fstring)-1); - *num_subkeys = r_o.num_subkeys ; - *max_subkeylen = r_o.max_subkeylen ; - *max_subkeysize = r_o.max_subkeysize; - *num_values = r_o.num_values ; - *max_valnamelen = r_o.max_valnamelen; - *max_valbufsize = r_o.max_valbufsize; - *sec_desc = r_o.sec_desc ; - *mod_time = r_o.mod_time ; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } + *class_len = r_o.hdr_class.uni_max_len; + fstrcpy(class, dos_unistr2_to_str(&r_o.uni_class)); + *num_subkeys = r_o.num_subkeys ; + *max_subkeylen = r_o.max_subkeylen ; + *max_subkeysize = r_o.max_subkeysize; + *num_values = r_o.num_values ; + *max_valnamelen = r_o.max_valnamelen; + *max_valbufsize = r_o.max_valbufsize; + *sec_desc = r_o.sec_desc ; + *mod_time = r_o.mod_time ; + prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_query; + return True; } /**************************************************************************** do a REG Unknown 1A ****************************************************************************/ -BOOL reg_unknown_1a( POLICY_HND *hnd, uint32 *unk) +BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk) { prs_struct rbuf; prs_struct buf; REG_Q_UNK_1A q_o; - BOOL valid_query = False; + REG_R_UNK_1A r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_UNKNOWN_1A */ DEBUG(4,("REG Unknown 1a\n")); - make_reg_q_unk_1a(&q_o, hnd); + init_reg_q_unk_1a(&q_o, hnd); /* turn parameters into data stream */ - reg_io_q_unk_1a("", &q_o, &buf, 0); + if(!reg_io_q_unk_1a("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_UNK_1A, &buf, &rbuf)) - { - REG_R_UNK_1A r_o; - BOOL p; + if (rpc_api_pipe_req(cli, REG_UNK_1A, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_unk_1a("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_unk_1a("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_query = True; - (*unk) = r_o.unknown; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } + (*unk) = r_o.unknown; + prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_query; + return True; } /**************************************************************************** do a REG Query Info ****************************************************************************/ -BOOL reg_query_info( POLICY_HND *hnd, - const char* val_name, - uint32 *type, BUFFER2 *buffer) +BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd, + char *type, uint32 *unk_0, uint32 *unk_1) { prs_struct rbuf; prs_struct buf; REG_Q_INFO q_o; - BOOL valid_query = False; + REG_R_INFO r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_INFO */ DEBUG(4,("REG Query Info\n")); - make_reg_q_info(&q_o, hnd, val_name, 4, 0); + init_reg_q_info(&q_o, hnd, "ProductType", time(NULL), 4, 1); /* turn parameters into data stream */ - reg_io_q_info("", &q_o, &buf, 0); + if(!reg_io_q_info("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_INFO, &buf, &rbuf)) - { - REG_R_INFO r_o; - BOOL p; - - ZERO_STRUCT(r_o); + if (!rpc_api_pipe_req(cli, REG_INFO, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - r_o.type = type; - r_o.uni_type = buffer; + prs_mem_free(&buf); - reg_io_r_info("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_info("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_query = True; - } + if ( r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } + fstrcpy(type, dos_buffer2_to_str(&r_o.uni_type)); + (*unk_0) = r_o.unknown_0; + (*unk_1) = r_o.unknown_1; + prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_query; + return True; } /**************************************************************************** do a REG Set Key Security ****************************************************************************/ -BOOL reg_set_key_sec( POLICY_HND *hnd, - uint32 sec_info, - uint32 sec_buf_size, SEC_DESC *sec_buf) +BOOL do_reg_set_key_sec(struct cli_state *cli, POLICY_HND *hnd, SEC_DESC_BUF *sec_desc_buf) { prs_struct rbuf; prs_struct buf; REG_Q_SET_KEY_SEC q_o; - BOOL valid_query = False; + REG_R_SET_KEY_SEC r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_SET_KEY_SEC */ DEBUG(4,("REG Set Key security.\n")); - make_reg_q_set_key_sec(&q_o, hnd, sec_info, sec_buf_size, sec_buf); + init_reg_q_set_key_sec(&q_o, hnd, sec_desc_buf); /* turn parameters into data stream */ - reg_io_q_set_key_sec("", &q_o, &buf, 0); + if(!reg_io_q_set_key_sec("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_SET_KEY_SEC, &buf, &rbuf)) - { - REG_R_SET_KEY_SEC r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, REG_SET_KEY_SEC, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_set_key_sec("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - valid_query = True; - } + if(!reg_io_r_set_key_sec("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } + + if (r_o.status != 0) { + prs_mem_free(&rbuf); + return False; } prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_query; + return True; } - /**************************************************************************** do a REG Query Key Security ****************************************************************************/ -BOOL reg_get_key_sec( POLICY_HND *hnd, - uint32 sec_info, - uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf) + +BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, uint32 *sec_buf_size, SEC_DESC_BUF **ppsec_desc_buf) { prs_struct rbuf; prs_struct buf; REG_Q_GET_KEY_SEC q_o; - BOOL valid_query = False; + REG_R_GET_KEY_SEC r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_GET_KEY_SEC */ DEBUG(4,("REG query key security. buf_size: %d\n", *sec_buf_size)); - make_reg_q_get_key_sec(&q_o, hnd, sec_info, *sec_buf_size, sec_buf); + init_reg_q_get_key_sec(&q_o, hnd, *sec_buf_size, NULL); /* turn parameters into data stream */ - reg_io_q_get_key_sec("", &q_o, &buf, 0); + if(!reg_io_q_get_key_sec("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_GET_KEY_SEC, &buf, &rbuf)) - { - REG_R_GET_KEY_SEC r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, REG_GET_KEY_SEC, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - r_o.data = sec_buf; - if (*sec_buf_size != 0) - { - sec_buf->sec = (SEC_DESC*)malloc(*sec_buf_size); - } - reg_io_r_get_key_sec("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_o.status == 0x0000007a) - { - /* - * get the maximum buffer size: it was too small - */ - (*sec_buf_size) = r_o.hdr_sec.buf_max_len; - DEBUG(5,("sec_buf_size too small. use %d\n", *sec_buf_size)); - valid_query = True; - } - else if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - else - { - valid_query = True; - (*sec_buf_size) = r_o.data->len; - } + ZERO_STRUCT(r_o); + + if(!reg_io_r_get_key_sec("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } + + if (r_o.status == 0x0000007a) { + /* + * get the maximum buffer size: it was too small + */ + (*sec_buf_size) = r_o.hdr_sec.buf_max_len; + DEBUG(5,("sec_buf_size too small. use %d\n", *sec_buf_size)); + } else if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; + } else { + (*sec_buf_size) = r_o.data->len; + *ppsec_desc_buf = r_o.data; } prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_query; + return True; } /**************************************************************************** do a REG Delete Value ****************************************************************************/ -BOOL reg_delete_val( POLICY_HND *hnd, char *val_name) +BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name) { prs_struct rbuf; prs_struct buf; REG_Q_DELETE_VALUE q_o; - BOOL valid_delete = False; + REG_R_DELETE_VALUE r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_DELETE_VALUE */ DEBUG(4,("REG Delete Value: %s\n", val_name)); - make_reg_q_delete_val(&q_o, hnd, val_name); + init_reg_q_delete_val(&q_o, hnd, val_name); /* turn parameters into data stream */ - reg_io_q_delete_val("", &q_o, &buf, 0); + if(!reg_io_q_delete_val("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_DELETE_VALUE, &buf, &rbuf)) - { - REG_R_DELETE_VALUE r_o; - BOOL p; + if (rpc_api_pipe_req(cli, REG_DELETE_VALUE, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_delete_val("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_delete_val("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_delete = True; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_delete; + return True; } /**************************************************************************** do a REG Delete Key ****************************************************************************/ -BOOL reg_delete_key( POLICY_HND *hnd, char *key_name) +BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name) { prs_struct rbuf; prs_struct buf; REG_Q_DELETE_KEY q_o; - BOOL valid_delete = False; + REG_R_DELETE_KEY r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_DELETE_KEY */ DEBUG(4,("REG Delete Key: %s\n", key_name)); - make_reg_q_delete_key(&q_o, hnd, key_name); + init_reg_q_delete_key(&q_o, hnd, key_name); /* turn parameters into data stream */ - reg_io_q_delete_key("", &q_o, &buf, 0); + if(!reg_io_q_delete_key("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_DELETE_KEY, &buf, &rbuf)) - { - REG_R_DELETE_KEY r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, REG_DELETE_KEY, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_delete_key("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_delete_key("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_delete = True; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_delete; + return True; } /**************************************************************************** do a REG Create Key ****************************************************************************/ -BOOL reg_create_key( POLICY_HND *hnd, +BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name, char *key_class, SEC_ACCESS *sam_access, POLICY_HND *key) @@ -766,73 +694,84 @@ BOOL reg_create_key( POLICY_HND *hnd, prs_struct rbuf; prs_struct buf; REG_Q_CREATE_KEY q_o; - BOOL valid_create = False; - SEC_DESC sec; - SEC_DESC_BUF sec_buf; - int sec_len; + REG_R_CREATE_KEY r_o; + SEC_DESC *sec = NULL; + SEC_DESC_BUF *sec_buf = NULL; + size_t sec_len; - ZERO_STRUCT(sec); - ZERO_STRUCT(sec_buf); ZERO_STRUCT(q_o); - if (hnd == NULL) return False; - - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + if (hnd == NULL) + return False; /* create and send a MSRPC command with api REG_CREATE_KEY */ DEBUG(4,("REG Create Key: %s %s 0x%08x\n", key_name, key_class, sam_access != NULL ? sam_access->mask : 0)); - sec_len = make_sec_desc(&sec, 1, SEC_DESC_SELF_RELATIVE, - NULL, NULL, NULL, NULL); + if((sec = make_sec_desc( 1, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, NULL, &sec_len)) == NULL) { + DEBUG(0,("make_sec_desc : malloc fail.\n")); + return False; + } + + DEBUG(10,("make_sec_desc: len = %d\n", (int)sec_len)); + + if((sec_buf = make_sec_desc_buf( (int)sec_len, sec)) == NULL) { + DEBUG(0,("make_sec_desc : malloc fail (1)\n")); + free_sec_desc(&sec); + return False; + } + free_sec_desc(&sec); - DEBUG(10,("make_sec_desc: len = %d\n", sec_len)); + prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); - make_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access, - &sec_buf, sec_len, &sec); + init_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access, sec_buf); /* turn parameters into data stream */ - reg_io_q_create_key("", &q_o, &buf, 0); + if(!reg_io_q_create_key("", &q_o, &buf, 0)) { + free_sec_desc_buf(&sec_buf); + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_CREATE_KEY, &buf, &rbuf)) - { - REG_R_CREATE_KEY r_o; - BOOL p; + if (rpc_api_pipe_req(cli, REG_CREATE_KEY, &buf, &rbuf)) { + free_sec_desc_buf(&sec_buf); + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + free_sec_desc_buf(&sec_buf); + prs_mem_free(&buf); - reg_io_r_create_key("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_create_key("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_create = True; - memcpy(key, r_o.key_pol.data, sizeof(key->data)); - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } - free_sec_desc(&sec); + memcpy(key, r_o.key_pol.data, sizeof(key->data)); prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_create; + return True; } /**************************************************************************** do a REG Enum Key ****************************************************************************/ -BOOL reg_enum_key( POLICY_HND *hnd, +BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd, int key_index, char *key_name, uint32 *unk_1, uint32 *unk_2, time_t *mod_time) @@ -840,116 +779,122 @@ BOOL reg_enum_key( POLICY_HND *hnd, prs_struct rbuf; prs_struct buf; REG_Q_ENUM_KEY q_o; - BOOL valid_query = False; + REG_R_ENUM_KEY r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_ENUM_KEY */ DEBUG(4,("REG Enum Key\n")); - make_reg_q_enum_key(&q_o, hnd, key_index); + init_reg_q_enum_key(&q_o, hnd, key_index); /* turn parameters into data stream */ - reg_io_q_enum_key("", &q_o, &buf, 0); + if(!reg_io_q_enum_key("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_ENUM_KEY, &buf, &rbuf)) - { - REG_R_ENUM_KEY r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, REG_ENUM_KEY, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_enum_key("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_enum_key("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_query = True; - (*unk_1) = r_o.unknown_1; - (*unk_2) = r_o.unknown_2; - unistr_to_ascii(key_name, r_o.key_name.str.buffer, - sizeof(fstring)-1); - (*mod_time) = nt_time_to_unix(&r_o.time); - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } + (*unk_1) = r_o.unknown_1; + (*unk_2) = r_o.unknown_2; + fstrcpy(key_name, dos_unistr2(r_o.key_name.str.buffer)); + (*mod_time) = nt_time_to_unix(&r_o.time); + prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_query; + return True; } /**************************************************************************** do a REG Create Value ****************************************************************************/ -BOOL reg_create_val( POLICY_HND *hnd, +BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name, uint32 type, BUFFER3 *data) { prs_struct rbuf; prs_struct buf; REG_Q_CREATE_VALUE q_o; - BOOL valid_create = False; + REG_R_CREATE_VALUE r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_CREATE_VALUE */ DEBUG(4,("REG Create Value: %s\n", val_name)); - make_reg_q_create_val(&q_o, hnd, val_name, type, data); + init_reg_q_create_val(&q_o, hnd, val_name, type, data); /* turn parameters into data stream */ - reg_io_q_create_val("", &q_o, &buf, 0); + if(!reg_io_q_create_val("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_CREATE_VALUE, &buf, &rbuf)) - { - REG_R_CREATE_VALUE r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, REG_CREATE_VALUE, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - ZERO_STRUCT(r_o); + prs_mem_free(&buf); - reg_io_r_create_val("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + ZERO_STRUCT(r_o); - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!reg_io_r_create_val("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_create = True; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_create; + return True; } /**************************************************************************** do a REG Enum Value ****************************************************************************/ -BOOL reg_enum_val( POLICY_HND *hnd, +BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd, int val_index, int max_valnamelen, int max_valbufsize, fstring val_name, uint32 *val_type, BUFFER2 *value) @@ -957,253 +902,185 @@ BOOL reg_enum_val( POLICY_HND *hnd, prs_struct rbuf; prs_struct buf; REG_Q_ENUM_VALUE q_o; - BOOL valid_query = False; + REG_R_ENUM_VALUE r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_ENUM_VALUE */ DEBUG(4,("REG Enum Value\n")); - make_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize); + init_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize); /* turn parameters into data stream */ - reg_io_q_enum_val("", &q_o, &buf, 0); + if(!reg_io_q_enum_val("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_ENUM_VALUE, &buf, &rbuf)) - { - REG_R_ENUM_VALUE r_o; - BOOL p; - - ZERO_STRUCT(r_o); - r_o.buf_value = value; - - reg_io_r_enum_val("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if (!rpc_api_pipe_req(cli, REG_ENUM_VALUE, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - if (p) - { - valid_query = True; - (*val_type) = r_o.type; - unistr2_to_ascii(val_name, &r_o.uni_name, sizeof(fstring)-1); - } + prs_mem_free(&buf); + + ZERO_STRUCT(r_o); + r_o.buf_value = value; + + if(!reg_io_r_enum_val("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } + + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } + (*val_type) = r_o.type; + fstrcpy(val_name, dos_unistr2_to_str(&r_o.uni_name)); + prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_query; + return True; } /**************************************************************************** do a REG Open Key ****************************************************************************/ -BOOL reg_open_entry( POLICY_HND *hnd, +BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd, char *key_name, uint32 unk_0, POLICY_HND *key_hnd) { prs_struct rbuf; prs_struct buf; REG_Q_OPEN_ENTRY q_o; - BOOL valid_pol = False; + REG_R_OPEN_ENTRY r_o; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api REG_OPEN_ENTRY */ DEBUG(4,("REG Open Entry\n")); - make_reg_q_open_entry(&q_o, hnd, key_name, unk_0); + init_reg_q_open_entry(&q_o, hnd, key_name, unk_0); /* turn parameters into data stream */ - reg_io_q_open_entry("", &q_o, &buf, 0); + if(!reg_io_q_open_entry("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_OPEN_ENTRY, &buf, &rbuf)) - { - REG_R_OPEN_ENTRY r_o; - BOOL p; - - ZERO_STRUCT(r_o); - - reg_io_r_open_entry("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + if (!rpc_api_pipe_req(cli, REG_OPEN_ENTRY, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + prs_mem_free(&buf); - if (p) - { - struct cli_connection *con = NULL; + ZERO_STRUCT(r_o); - if (!cli_connection_get(hnd, &con)) - { - return False; - } + if(!reg_io_r_open_entry("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } - memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data)); - valid_pol = cli_pol_link(key_hnd, hnd); - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; } + memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data)); + prs_mem_free(&rbuf); - prs_mem_free(&buf ); - return valid_pol; + return True; } /**************************************************************************** do a REG Close ****************************************************************************/ -BOOL reg_close( POLICY_HND *hnd) +BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd) { prs_struct rbuf; prs_struct buf; REG_Q_CLOSE q_c; - BOOL valid_close = False; + REG_R_CLOSE r_c; + int i; - if (hnd == NULL) return False; + if (hnd == NULL) + return False; /* create and send a MSRPC command with api REG_CLOSE */ - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL); DEBUG(4,("REG Close\n")); /* store the parameters */ - make_reg_q_close(&q_c, hnd); + init_reg_q_close(&q_c, hnd); /* turn parameters into data stream */ - reg_io_q_close("", &q_c, &buf, 0); + if(!reg_io_q_close("", &q_c, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, REG_CLOSE, &buf, &rbuf)) - { - REG_R_CLOSE r_c; - BOOL p; - - ZERO_STRUCT(r_c); - - reg_io_r_close("", &r_c, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_c.status != 0) - { - /* report error code */ - DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status))); - p = False; - } - - if (p) - { - /* check that the returned policy handle is all zeros */ - uint32 i; - valid_close = True; - - for (i = 0; i < sizeof(r_c.pol.data); i++) - { - if (r_c.pol.data[i] != 0) - { - valid_close = False; - break; - } - } - if (!valid_close) - { - DEBUG(0,("REG_CLOSE: non-zero handle returned\n")); - } - } + if (!rpc_api_pipe_req(cli, REG_CLOSE, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; } - prs_mem_free(&rbuf); - prs_mem_free(&buf ); - - close_policy_hnd(hnd); - - return valid_close; -} - -/**************************************************************************** -do a REG Shutdown Server -****************************************************************************/ -BOOL reg_shutdown(const char *srv_name, - const char *msg, uint32 timeout, uint16 flags) -{ - prs_struct rbuf; - prs_struct buf; - REG_Q_SHUTDOWN q_o; - BOOL valid_shutdown = False; + prs_mem_free(&buf); - struct cli_connection *con = NULL; + ZERO_STRUCT(r_c); - if (!cli_connection_init(srv_name, PIPE_LSARPC, &con)) - { + if(!reg_io_r_close("", &r_c, &rbuf, 0)) { + prs_mem_free(&rbuf); return False; } - if (msg == NULL) 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 REG_SHUTDOWN */ - - DEBUG(4,("REG Shutdown: (timeout: %d secs) %s\n", timeout, msg)); - - make_reg_q_shutdown(&q_o, msg, timeout, flags); - - /* turn parameters into data stream */ - reg_io_q_shutdown("", &q_o, &buf, 0); - - /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, REG_SHUTDOWN, &buf, &rbuf)) - { - REG_R_SHUTDOWN r_o; - BOOL p; - - ZERO_STRUCT(r_o); - - reg_io_r_shutdown("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; + if (r_c.status != 0) { + /* report error code */ + DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status))); + prs_mem_free(&rbuf); + return False; + } - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("REG_SHUTDOWN: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + /* check that the returned policy handle is all zeros */ - if (p) - { - valid_shutdown = True; + for (i = 0; i < sizeof(r_c.pol.data); i++) { + if (r_c.pol.data[i] != 0) { + prs_mem_free(&rbuf); + DEBUG(0,("REG_CLOSE: non-zero handle returned\n")); + return False; } - } + } prs_mem_free(&rbuf); - prs_mem_free(&buf ); - - cli_connection_unlink(con); - return valid_shutdown; + return True; } - - diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 9a68016c66..8fccf6c796 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -4,6 +4,7 @@ NT Domain Authentication SMB / MSRPC client Copyright (C) Andrew Tridgell 1994-1997 Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + Copyright (C) Jeremy Allison 1999. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,2409 +33,792 @@ extern int DEBUGLEVEL; /**************************************************************************** -do a SAMR change user password command -****************************************************************************/ -BOOL samr_chgpasswd_user( struct cli_connection *con, - char *srv_name, char *user_name, - char nt_newpass[516], uchar nt_oldhash[16], - char lm_newpass[516], uchar lm_oldhash[16]) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_CHGPASSWD_USER q_e; - BOOL valid_pwc = False; - - /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Change User Password. server:%s username:%s\n", - srv_name, user_name)); - - make_samr_q_chgpasswd_user(&q_e, srv_name, user_name, - nt_newpass, nt_oldhash, - lm_newpass, lm_oldhash); - - /* turn parameters into data stream */ - samr_io_q_chgpasswd_user("", &q_e, &data, 0); - - dbgflush(); - - /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SAMR_CHGPASSWD_USER, &data, &rdata)) - { - SAMR_R_CHGPASSWD_USER r_e; - BOOL p; - - samr_io_r_chgpasswd_user("", &r_e, &rdata, 0); - - p = rdata.offset != 0; - if (p && r_e.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status))); - p = False; - } - - if (p) - { - valid_pwc = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pwc; -} - - -/**************************************************************************** -do a SAMR unknown 0x38 command -****************************************************************************/ -BOOL samr_unknown_38(struct cli_connection *con, char *srv_name) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_UNKNOWN_38 q_e; - BOOL valid_un8 = False; - - /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name)); - - make_samr_q_unknown_38(&q_e, srv_name); - - /* turn parameters into data stream */ - samr_io_q_unknown_38("", &q_e, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SAMR_GET_DOM_PWINFO, &data, &rdata)) - { - SAMR_R_UNKNOWN_38 r_e; - BOOL p; - - samr_io_r_unknown_38("", &r_e, &rdata, 0); - - p = rdata.offset != 0; -#if 0 - if (p && r_e.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status))); - p = False; - } -#endif - if (p) - { - valid_un8 = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_un8; -} - -/**************************************************************************** -do a SAMR unknown 0x8 command -****************************************************************************/ -BOOL samr_query_dom_info( POLICY_HND *domain_pol, uint16 switch_value, - SAM_UNK_CTR *ctr) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_QUERY_DOMAIN_INFO q_e; - BOOL valid_un8 = False; - - DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value)); - - if (domain_pol == NULL) return False; - - /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_query_dom_info(&q_e, domain_pol, switch_value); - - /* turn parameters into data stream */ - samr_io_q_query_dom_info("", &q_e, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(domain_pol, SAMR_QUERY_DOMAIN_INFO, &data, &rdata)) - { - SAMR_R_QUERY_DOMAIN_INFO r_e; - BOOL p; - - r_e.ctr = ctr; - samr_io_r_query_dom_info("", &r_e, &rdata, 0); - - p = rdata.offset != 0; - if (p && r_e.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status))); - p = False; - } - - if (p) - { - valid_un8 = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_un8; -} - -/**************************************************************************** -do a SAMR enumerate Domains -****************************************************************************/ -uint32 samr_enum_domains( POLICY_HND *pol, - uint32 *start_idx, uint32 size, - struct acct_info **sam, - uint32 *num_sam_domains) -{ - uint32 status = 0x0; - prs_struct data; - prs_struct rdata; - - SAMR_Q_ENUM_DOMAINS q_e; - - DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size)); - - if (pol == NULL || num_sam_domains == NULL || sam == NULL) - { - return NT_STATUS_INVALID_PARAMETER | 0xC0000000; - } - - /* create and send a MSRPC command with api SAMR_ENUM_DOMAINS */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_enum_domains(&q_e, pol, *start_idx, size); - - /* turn parameters into data stream */ - samr_io_q_enum_domains("", &q_e, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOMAINS, &data, &rdata)) - { - SAMR_R_ENUM_DOMAINS r_e; - BOOL p; - - samr_io_r_enum_domains("", &r_e, &rdata, 0); - - status = r_e.status; - p = rdata.offset != 0; - if (p && r_e.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_ENUM_DOMAINS: %s\n", get_nt_error_msg(r_e.status))); - p = (r_e.status == STATUS_MORE_ENTRIES); - } - - if (p) - { - uint32 i = (*num_sam_domains); - uint32 j = 0; - uint32 name_idx = 0; - - (*num_sam_domains) += r_e.num_entries2; - (*sam) = (struct acct_info*) Realloc((*sam), - sizeof(struct acct_info) * (*num_sam_domains)); - - if ((*sam) == NULL) - { - (*num_sam_domains) = 0; - i = 0; - } - - for (j = 0; i < (*num_sam_domains) && j < r_e.num_entries2; j++, i++) - { - (*sam)[i].rid = r_e.sam[j].rid; - (*sam)[i].acct_name[0] = 0; - (*sam)[i].acct_desc[0] = 0; - if (r_e.sam[j].hdr_name.buffer) - { - unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_dom_name[name_idx], sizeof((*sam)[i].acct_name)-1); - name_idx++; - } - DEBUG(5,("samr_enum_domains: idx: %4d rid: %8x acct: %s\n", - i, (*sam)[i].rid, (*sam)[i].acct_name)); - } - (*start_idx) = r_e.next_idx; - } - else if (status == 0x0) - { - status = NT_STATUS_INVALID_PARAMETER | 0xC0000000; - } - - if (r_e.sam != NULL) - { - free(r_e.sam); - } - if (r_e.uni_dom_name != NULL) - { - free(r_e.uni_dom_name); - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return status; -} - -/**************************************************************************** -do a SAMR enumerate groups -****************************************************************************/ -uint32 samr_enum_dom_groups( POLICY_HND *pol, - uint32 *start_idx, uint32 size, - struct acct_info **sam, - uint32 *num_sam_groups) -{ - uint32 status = 0x0; - prs_struct data; - prs_struct rdata; - - SAMR_Q_ENUM_DOM_GROUPS q_e; - - DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size)); - - if (pol == NULL || num_sam_groups == NULL) - { - return NT_STATUS_INVALID_PARAMETER | 0xC0000000; - } - - /* create and send a MSRPC command with api SAMR_ENUM_DOM_GROUPS */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_enum_dom_groups(&q_e, pol, *start_idx, size); - - /* turn parameters into data stream */ - samr_io_q_enum_dom_groups("", &q_e, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_GROUPS, &data, &rdata)) - { - SAMR_R_ENUM_DOM_GROUPS r_e; - BOOL p; - - samr_io_r_enum_dom_groups("", &r_e, &rdata, 0); - - status = r_e.status; - p = rdata.offset != 0; - if (p && r_e.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_ENUM_DOM_GROUPS: %s\n", get_nt_error_msg(r_e.status))); - p = (r_e.status == STATUS_MORE_ENTRIES); - } - - if (p) - { - uint32 i = (*num_sam_groups); - uint32 j = 0; - uint32 name_idx = 0; - - (*num_sam_groups) += r_e.num_entries2; - (*sam) = (struct acct_info*) Realloc((*sam), - sizeof(struct acct_info) * (*num_sam_groups)); - - if ((*sam) == NULL) - { - (*num_sam_groups) = 0; - i = 0; - } - - for (j = 0; i < (*num_sam_groups) && j < r_e.num_entries2; j++, i++) - { - (*sam)[i].rid = r_e.sam[j].rid; - (*sam)[i].acct_name[0] = 0; - (*sam)[i].acct_desc[0] = 0; - if (r_e.sam[j].hdr_name.buffer) - { - unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_grp_name[name_idx], sizeof((*sam)[i].acct_name)-1); - name_idx++; - } - DEBUG(5,("samr_enum_dom_groups: idx: %4d rid: %8x acct: %s\n", - i, (*sam)[i].rid, (*sam)[i].acct_name)); - } - (*start_idx) = r_e.next_idx; - } - else if (status == 0x0) - { - status = NT_STATUS_INVALID_PARAMETER | 0xC0000000; - } - - if (r_e.sam != NULL) - { - free(r_e.sam); - } - if (r_e.uni_grp_name != NULL) - { - free(r_e.uni_grp_name); - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return status; -} - -/**************************************************************************** -do a SAMR enumerate aliases -****************************************************************************/ -uint32 samr_enum_dom_aliases( POLICY_HND *pol, - uint32 *start_idx, uint32 size, - struct acct_info **sam, - uint32 *num_sam_aliases) -{ - uint32 status = 0x0; - prs_struct data; - prs_struct rdata; - - SAMR_Q_ENUM_DOM_ALIASES q_e; - - DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size)); - - if (pol == NULL || num_sam_aliases == NULL) - { - return NT_STATUS_INVALID_PARAMETER | 0xC0000000; - } - - /* create and send a MSRPC command with api SAMR_ENUM_DOM_ALIASES */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_enum_dom_aliases(&q_e, pol, *start_idx, size); - - /* turn parameters into data stream */ - samr_io_q_enum_dom_aliases("", &q_e, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_ALIASES, &data, &rdata)) - { - SAMR_R_ENUM_DOM_ALIASES r_e; - BOOL p; - - samr_io_r_enum_dom_aliases("", &r_e, &rdata, 0); - - p = rdata.offset != 0; - if (p && r_e.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_ENUM_DOM_ALIASES: %s\n", get_nt_error_msg(r_e.status))); - p = (r_e.status == STATUS_MORE_ENTRIES); - } - - if (p) - { - uint32 i = (*num_sam_aliases); - uint32 j = 0; - uint32 name_idx = 0; - - (*num_sam_aliases) += r_e.num_entries2; - (*sam) = (struct acct_info*) Realloc((*sam), - sizeof(struct acct_info) * (*num_sam_aliases)); - - if ((*sam) == NULL) - { - (*num_sam_aliases) = 0; - i = 0; - } - - for (j = 0; i < (*num_sam_aliases) && j < r_e.num_entries2; j++, i++) - { - (*sam)[i].rid = r_e.sam[j].rid; - (*sam)[i].acct_name[0] = 0; - (*sam)[i].acct_desc[0] = 0; - if (r_e.sam[j].hdr_name.buffer) - { - unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_grp_name[name_idx], sizeof((*sam)[i].acct_name)-1); - name_idx++; - } - DEBUG(5,("samr_enum_dom_aliases: idx: %4d rid: %8x acct: %s\n", - i, (*sam)[i].rid, (*sam)[i].acct_name)); - } - (*start_idx) = r_e.next_idx; - } - else if (status == 0x0) - { - status = NT_STATUS_INVALID_PARAMETER | 0xC0000000; - } - - if (r_e.sam != NULL) - { - free(r_e.sam); - } - if (r_e.uni_grp_name != NULL) - { - free(r_e.uni_grp_name); - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return status; -} - -/**************************************************************************** -do a SAMR enumerate users -****************************************************************************/ -uint32 samr_enum_dom_users( POLICY_HND *pol, uint32 *start_idx, - uint16 acb_mask, uint16 unk_1, uint32 size, - struct acct_info **sam, - uint32 *num_sam_users) -{ - uint32 status = 0x0; - prs_struct data; - prs_struct rdata; - - SAMR_Q_ENUM_DOM_USERS q_e; - - DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size)); - - if (pol == NULL || num_sam_users == NULL) - { - return NT_STATUS_INVALID_PARAMETER | 0xC0000000; - } - - /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_enum_dom_users(&q_e, pol, *start_idx, - acb_mask, unk_1, size); - - /* turn parameters into data stream */ - samr_io_q_enum_dom_users("", &q_e, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_USERS, &data, &rdata)) - { - SAMR_R_ENUM_DOM_USERS r_e; - BOOL p; - - samr_io_r_enum_dom_users("", &r_e, &rdata, 0); - - status = r_e.status; - p = rdata.offset != 0; - - if (p && r_e.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status))); - p = (r_e.status == STATUS_MORE_ENTRIES); - } - - if (p) - { - uint32 i = (*num_sam_users); - uint32 j = 0; - uint32 name_idx = 0; - - (*num_sam_users) += r_e.num_entries2; - (*sam) = (struct acct_info*) Realloc((*sam), - sizeof(struct acct_info) * (*num_sam_users)); - - if ((*sam) == NULL) - { - (*num_sam_users) = 0; - i = 0; - } - - for (j = 0; i < (*num_sam_users) && j < r_e.num_entries2; j++, i++) - { - (*sam)[i].rid = r_e.sam[j].rid; - (*sam)[i].acct_name[0] = 0; - (*sam)[i].acct_desc[0] = 0; - if (r_e.sam[j].hdr_name.buffer) - { - unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_acct_name[name_idx], sizeof((*sam)[i].acct_name)-1); - name_idx++; - } - DEBUG(5,("samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n", - i, (*sam)[i].rid, (*sam)[i].acct_name)); - } - (*start_idx) = r_e.next_idx; - } - else if (status == 0x0) - { - status = NT_STATUS_INVALID_PARAMETER | 0xC0000000; - } - - if (r_e.sam != NULL) - { - free(r_e.sam); - } - if (r_e.uni_acct_name != NULL) - { - free(r_e.uni_acct_name); - } - } - else - { - status = NT_STATUS_ACCESS_DENIED | 0xC0000000; - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return status; -} - -/**************************************************************************** -do a SAMR Connect -****************************************************************************/ -BOOL samr_connect( const char *srv_name, uint32 unknown_0, - POLICY_HND *connect_pol) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_CONNECT q_o; - BOOL valid_pol = False; - - struct cli_connection *con = NULL; - - if (!cli_connection_init(srv_name, PIPE_SAMR, &con)) - { - return False; - } - - DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n", - srv_name, unknown_0)); - - if (srv_name == NULL || connect_pol == NULL) return False; - - /* create and send a MSRPC command with api SAMR_CONNECT */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_connect(&q_o, srv_name, unknown_0); - - /* turn parameters into data stream */ - samr_io_q_connect("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SAMR_CONNECT, &data, &rdata)) - { - SAMR_R_CONNECT r_o; - BOOL p; - - samr_io_r_connect("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol)); - valid_pol = register_policy_hnd(connect_pol) && - set_policy_con(connect_pol, con, - cli_connection_unlink); - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Open User -****************************************************************************/ -BOOL samr_open_user( const POLICY_HND *pol, - uint32 unk_0, uint32 rid, - POLICY_HND *user_pol) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_OPEN_USER q_o; - BOOL valid_pol = False; - - DEBUG(4,("SAMR Open User. unk_0: %08x RID:%x\n", - unk_0, rid)); - - if (pol == NULL || user_pol == NULL) return False; - - /* create and send a MSRPC command with api SAMR_OPEN_USER */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_open_user(&q_o, pol, unk_0, rid); - - /* turn parameters into data stream */ - samr_io_q_open_user("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_OPEN_USER, &data, &rdata)) - { - SAMR_R_OPEN_USER r_o; - BOOL p; - - samr_io_r_open_user("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol)); - valid_pol = cli_pol_link(user_pol, pol); - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Open Alias -****************************************************************************/ -BOOL samr_open_alias( const POLICY_HND *domain_pol, - uint32 flags, uint32 rid, - POLICY_HND *alias_pol) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_OPEN_ALIAS q_o; - BOOL valid_pol = False; - - DEBUG(4,("SAMR Open Alias. RID:%x\n", rid)); - - if (alias_pol == NULL || domain_pol == NULL) return False; - - /* create and send a MSRPC command with api SAMR_OPEN_ALIAS */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_open_alias(&q_o, domain_pol, flags, rid); - - /* turn parameters into data stream */ - samr_io_q_open_alias("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(domain_pol, SAMR_OPEN_ALIAS, &data, &rdata)) - { - SAMR_R_OPEN_ALIAS r_o; - BOOL p; - - samr_io_r_open_alias("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_OPEN_ALIAS: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - memcpy(alias_pol, &r_o.pol, sizeof(r_o.pol)); - valid_pol = cli_pol_link(alias_pol, domain_pol); - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Delete Alias Member -****************************************************************************/ -BOOL samr_del_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_DEL_ALIASMEM q_o; - BOOL valid_pol = False; - - if (alias_pol == NULL || sid == NULL) return False; - - /* create and send a MSRPC command with api SAMR_DEL_ALIASMEM */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Delete Alias Member.\n")); - - /* store the parameters */ - make_samr_q_del_aliasmem(&q_o, alias_pol, sid); - - /* turn parameters into data stream */ - samr_io_q_del_aliasmem("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(alias_pol, SAMR_DEL_ALIASMEM, &data, &rdata)) - { - SAMR_R_DEL_ALIASMEM r_o; - BOOL p; - - samr_io_r_del_aliasmem("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_DEL_ALIASMEM: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_pol = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Add Alias Member -****************************************************************************/ -BOOL samr_add_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_ADD_ALIASMEM q_o; - BOOL valid_pol = False; - - if (alias_pol == NULL || sid == NULL) return False; - - /* create and send a MSRPC command with api SAMR_ADD_ALIASMEM */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Add Alias Member.\n")); - - /* store the parameters */ - make_samr_q_add_aliasmem(&q_o, alias_pol, sid); - - /* turn parameters into data stream */ - samr_io_q_add_aliasmem("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(alias_pol, SAMR_ADD_ALIASMEM, &data, &rdata)) - { - SAMR_R_ADD_ALIASMEM r_o; - BOOL p; - - samr_io_r_add_aliasmem("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_ADD_ALIASMEM: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_pol = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Delete Domain Alias -****************************************************************************/ -BOOL samr_delete_dom_alias( POLICY_HND *alias_pol) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_DELETE_DOM_ALIAS q_o; - BOOL valid_pol = False; - - if (alias_pol == NULL) return False; - - /* delete and send a MSRPC command with api SAMR_DELETE_DOM_ALIAS */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Delete Domain Alias.\n")); - - /* store the parameters */ - make_samr_q_delete_dom_alias(&q_o, alias_pol); - - /* turn parameters into data stream */ - samr_io_q_delete_dom_alias("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(alias_pol, SAMR_DELETE_DOM_ALIAS, &data, &rdata)) - { - SAMR_R_DELETE_DOM_ALIAS r_o; - BOOL p; - - samr_io_r_delete_dom_alias("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_DELETE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_pol = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Create Domain User -****************************************************************************/ -uint32 samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name, - uint32 unk_0, uint32 unk_1, - POLICY_HND *user_pol, uint32 *rid) -{ - prs_struct data; - prs_struct rdata; - uint32 status = NT_STATUS_INVALID_PARAMETER | 0xC0000000; - - SAMR_Q_CREATE_USER q_o; - - if (user_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False; - - /* create and send a MSRPC command with api SAMR_CREATE_USER */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Create Domain User. Name:%s\n", acct_name)); - - /* store the parameters */ - make_samr_q_create_user(&q_o, domain_pol, acct_name, unk_0, unk_1); - - /* turn parameters into data stream */ - samr_io_q_create_user("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_USER, &data, &rdata)) - { - SAMR_R_CREATE_USER r_o; - BOOL p; - - samr_io_r_create_user("", &r_o, &rdata, 0); - p = rdata.offset != 0; - status = r_o.status; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_CREATE_USER: %s\n", get_nt_error_msg(r_o.status))); - p = r_o.status != NT_STATUS_USER_EXISTS; - } - - if (p) - { - memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol)); - *rid = r_o.user_rid; - if (!cli_pol_link(user_pol, domain_pol)) - { - status = NT_STATUS_INVALID_HANDLE | 0xC0000000; - } - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return status; -} - -/**************************************************************************** -do a SAMR Create Domain Alias -****************************************************************************/ -BOOL samr_create_dom_alias( POLICY_HND *domain_pol, const char *acct_name, - POLICY_HND *alias_pol, uint32 *rid) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_CREATE_DOM_ALIAS q_o; - BOOL valid_pol = False; - - if (alias_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False; - - /* create and send a MSRPC command with api SAMR_CREATE_DOM_ALIAS */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Create Domain Alias. Name:%s\n", acct_name)); - - /* store the parameters */ - make_samr_q_create_dom_alias(&q_o, domain_pol, acct_name); - - /* turn parameters into data stream */ - samr_io_q_create_dom_alias("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_ALIAS, &data, &rdata)) - { - SAMR_R_CREATE_DOM_ALIAS r_o; - BOOL p; - - samr_io_r_create_dom_alias("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_CREATE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - memcpy(alias_pol, &r_o.alias_pol, sizeof(r_o.alias_pol)); - *rid = r_o.rid; - valid_pol = cli_pol_link(alias_pol, domain_pol); - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Get Alias Info -****************************************************************************/ -BOOL samr_query_aliasinfo( POLICY_HND *alias_pol, uint16 switch_value, - ALIAS_INFO_CTR *ctr) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_QUERY_ALIASINFO q_o; - BOOL valid_pol = False; - - if (alias_pol == NULL || ctr == NULL) return False; - - /* create and send a MSRPC command with api SAMR_GET_ALIASINFO */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Get Alias Info\n")); - - /* store the parameters */ - make_samr_q_query_aliasinfo(&q_o, alias_pol, switch_value); - - /* turn parameters into data stream */ - samr_io_q_query_aliasinfo("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASINFO, &data, &rdata)) - { - SAMR_R_QUERY_ALIASINFO r_o; - BOOL p; - - /* get alias info */ - r_o.ctr = ctr; - - samr_io_r_query_aliasinfo("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_ALIASINFO: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_pol = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Set Alias Info -****************************************************************************/ -BOOL samr_set_aliasinfo( POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_SET_ALIASINFO q_o; - BOOL valid_pol = False; - - if (alias_pol == NULL || ctr == NULL) return False; - - /* create and send a MSRPC command with api SAMR_SET_ALIASINFO */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Set Alias Info\n")); - - /* store the parameters */ - make_samr_q_set_aliasinfo(&q_o, alias_pol, ctr); - - /* turn parameters into data stream */ - samr_io_q_set_aliasinfo("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(alias_pol, SAMR_SET_ALIASINFO, &data, &rdata)) - { - SAMR_R_SET_ALIASINFO r_o; - BOOL p; - - samr_io_r_set_aliasinfo("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_SET_ALIASINFO: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_pol = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Open Group -****************************************************************************/ -BOOL samr_open_group( const POLICY_HND *domain_pol, - uint32 flags, uint32 rid, - POLICY_HND *group_pol) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_OPEN_GROUP q_o; - BOOL valid_pol = False; - - DEBUG(4,("SAMR Open Group. RID:%x\n", rid)); - - if (group_pol == NULL || domain_pol == NULL) return False; - - /* create and send a MSRPC command with api SAMR_OPEN_GROUP */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_open_group(&q_o, domain_pol, flags, rid); - - /* turn parameters into data stream */ - samr_io_q_open_group("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(domain_pol, SAMR_OPEN_GROUP, &data, &rdata)) - { - SAMR_R_OPEN_GROUP r_o; - BOOL p; - - samr_io_r_open_group("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_OPEN_GROUP: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - memcpy(group_pol, &r_o.pol, sizeof(r_o.pol)); - valid_pol = cli_pol_link(group_pol, domain_pol); - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Delete Group Member -****************************************************************************/ -BOOL samr_del_groupmem( POLICY_HND *group_pol, uint32 rid) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_DEL_GROUPMEM q_o; - BOOL valid_pol = False; - - if (group_pol == NULL) return False; - - /* create and send a MSRPC command with api SAMR_DEL_GROUPMEM */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Delete Group Member.\n")); - - /* store the parameters */ - make_samr_q_del_groupmem(&q_o, group_pol, rid); - - /* turn parameters into data stream */ - samr_io_q_del_groupmem("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(group_pol, SAMR_DEL_GROUPMEM, &data, &rdata)) - { - SAMR_R_DEL_GROUPMEM r_o; - BOOL p; - - samr_io_r_del_groupmem("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_DEL_GROUPMEM: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_pol = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Add Group Member -****************************************************************************/ -BOOL samr_add_groupmem( POLICY_HND *group_pol, uint32 rid) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_ADD_GROUPMEM q_o; - BOOL valid_pol = False; - - if (group_pol == NULL) return False; - - /* create and send a MSRPC command with api SAMR_ADD_GROUPMEM */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Add Group Member.\n")); - - /* store the parameters */ - make_samr_q_add_groupmem(&q_o, group_pol, rid); - - /* turn parameters into data stream */ - samr_io_q_add_groupmem("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(group_pol, SAMR_ADD_GROUPMEM, &data, &rdata)) - { - SAMR_R_ADD_GROUPMEM r_o; - BOOL p; - - samr_io_r_add_groupmem("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_ADD_GROUPMEM: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_pol = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Delete Domain Group -****************************************************************************/ -BOOL samr_delete_dom_group( POLICY_HND *group_pol) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_DELETE_DOM_GROUP q_o; - BOOL valid_pol = False; - - if (group_pol == NULL) return False; - - /* delete and send a MSRPC command with api SAMR_DELETE_DOM_GROUP */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Delete Domain Group.\n")); - - /* store the parameters */ - make_samr_q_delete_dom_group(&q_o, group_pol); - - /* turn parameters into data stream */ - samr_io_q_delete_dom_group("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(group_pol, SAMR_DELETE_DOM_GROUP, &data, &rdata)) - { - SAMR_R_DELETE_DOM_GROUP r_o; - BOOL p; - - samr_io_r_delete_dom_group("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_DELETE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_pol = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Create Domain Group -****************************************************************************/ -BOOL samr_create_dom_group( POLICY_HND *domain_pol, const char *acct_name, - POLICY_HND *group_pol, uint32 *rid) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_CREATE_DOM_GROUP q_o; - BOOL valid_pol = False; - - if (group_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False; - - /* create and send a MSRPC command with api SAMR_CREATE_DOM_GROUP */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Create Domain Group. Name:%s\n", acct_name)); - - /* store the parameters */ - make_samr_q_create_dom_group(&q_o, domain_pol, acct_name); - - /* turn parameters into data stream */ - samr_io_q_create_dom_group("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_GROUP, &data, &rdata)) - { - SAMR_R_CREATE_DOM_GROUP r_o; - BOOL p; - - samr_io_r_create_dom_group("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_CREATE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - memcpy(group_pol, &r_o.pol, sizeof(r_o.pol)); - *rid = r_o.rid; - valid_pol = cli_pol_link(group_pol, domain_pol); - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Set Group Info +do a SAMR query user groups ****************************************************************************/ -BOOL samr_set_groupinfo( POLICY_HND *group_pol, GROUP_INFO_CTR *ctr) +BOOL get_samr_query_usergroups(struct cli_state *cli, + POLICY_HND *pol_open_domain, uint32 user_rid, + uint32 *num_groups, DOM_GID *gid) { - prs_struct data; - prs_struct rdata; - - SAMR_Q_SET_GROUPINFO q_o; - BOOL valid_pol = False; - - if (group_pol == NULL || ctr == NULL) return False; - - /* create and send a MSRPC command with api SAMR_SET_GROUPINFO */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Set Group Info\n")); - - /* store the parameters */ - make_samr_q_set_groupinfo(&q_o, group_pol, ctr); - - /* turn parameters into data stream */ - samr_io_q_set_groupinfo("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(group_pol, SAMR_SET_GROUPINFO, &data, &rdata)) - { - SAMR_R_SET_GROUPINFO r_o; - BOOL p; - - samr_io_r_set_groupinfo("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_SET_GROUPINFO: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_pol = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; -} - -/**************************************************************************** -do a SAMR Open Domain -****************************************************************************/ -BOOL samr_open_domain( const POLICY_HND *connect_pol, - uint32 ace_perms, - const DOM_SID *sid, - POLICY_HND *domain_pol) -{ - pstring sid_str; - prs_struct data; - prs_struct rdata; - - SAMR_Q_OPEN_DOMAIN q_o; - BOOL valid_pol = False; + POLICY_HND pol_open_user; + if (pol_open_domain == NULL || num_groups == NULL || gid == NULL) + return False; - if (DEBUGLEVEL >= 4) + /* send open domain (on user sid) */ + if (!do_samr_open_user(cli, + pol_open_domain, + 0x02011b, user_rid, + &pol_open_user)) { - sid_to_string(sid_str, sid); - DEBUG(4,("SAMR Open Domain. SID:%s Permissions:%x\n", - sid_str, ace_perms)); + return False; } - if (connect_pol == NULL || sid == NULL || domain_pol == NULL) return False; - - /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* store the parameters */ - make_samr_q_open_domain(&q_o, connect_pol, ace_perms, sid); - - /* turn parameters into data stream */ - samr_io_q_open_domain("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(connect_pol, SAMR_OPEN_DOMAIN, &data, &rdata)) + /* send user groups query */ + if (!do_samr_query_usergroups(cli, + &pol_open_user, + num_groups, gid)) { - SAMR_R_OPEN_DOMAIN r_o; - BOOL p; - - samr_io_r_open_domain("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol)); - valid_pol = cli_pol_link(domain_pol, connect_pol); - } + DEBUG(5,("do_samr_query_usergroups: error in query user groups\n")); } - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_pol; + return do_samr_close(cli, &pol_open_user); } /**************************************************************************** -do a SAMR Query Lookup Domain +do a SAMR query user info ****************************************************************************/ -BOOL samr_query_lookup_domain( POLICY_HND *pol, const char *dom_name, - DOM_SID *dom_sid) +BOOL get_samr_query_userinfo(struct cli_state *cli, + POLICY_HND *pol_open_domain, + uint32 info_level, + uint32 user_rid, SAM_USER_INFO_21 *usr) { - prs_struct data; - prs_struct rdata; - - SAMR_Q_LOOKUP_DOMAIN q_o; - BOOL valid_query = False; - - if (pol == NULL || dom_name == NULL || dom_sid == NULL) return False; - - /* create and send a MSRPC command with api SAMR_LOOKUP_DOMAIN */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Query Lookup Domain.\n")); - - /* store the parameters */ - make_samr_q_lookup_domain(&q_o, pol, dom_name); + POLICY_HND pol_open_user; + if (pol_open_domain == NULL || usr == NULL) + return False; - /* turn parameters into data stream */ - samr_io_q_lookup_domain("", &q_o, &data, 0); + memset((char *)usr, '\0', sizeof(*usr)); - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_DOMAIN, &data, &rdata)) + /* send open domain (on user sid) */ + if (!do_samr_open_user(cli, + pol_open_domain, + 0x02011b, user_rid, + &pol_open_user)) { - SAMR_R_LOOKUP_DOMAIN r_o; - BOOL p; - - samr_io_r_lookup_domain("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_LOOKUP_DOMAIN: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p && r_o.ptr_sid != 0) - { - sid_copy(dom_sid, &r_o.dom_sid.sid); - valid_query = True; - } + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_query; -} - -/**************************************************************************** -do a SAMR Query Lookup Names -****************************************************************************/ -BOOL samr_query_lookup_names( POLICY_HND *pol, uint32 flags, - uint32 num_names, char **names, - uint32 *num_rids, - uint32 rid[MAX_LOOKUP_SIDS], - uint32 type[MAX_LOOKUP_SIDS]) -{ - prs_struct data; - prs_struct rdata; - - SAMR_Q_LOOKUP_NAMES q_o; - BOOL valid_query = False; - - if (pol == NULL || flags == 0 || num_names == 0 || names == NULL || - num_rids == NULL || rid == NULL || type == NULL ) return False; - - /* create and send a MSRPC command with api SAMR_LOOKUP_NAMES */ - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - DEBUG(4,("SAMR Query Lookup NAMES.\n")); - - /* store the parameters */ - make_samr_q_lookup_names(&q_o, pol, flags, num_names, names); - - /* turn parameters into data stream */ - samr_io_q_lookup_names("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_NAMES, &data, &rdata)) + /* send user info query */ + if (!do_samr_query_userinfo(cli, + &pol_open_user, + info_level, (void*)usr)) { - SAMR_R_LOOKUP_NAMES r_o; - BOOL p; - - samr_io_r_lookup_names("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_o.status))); - p = r_o.status == 0x107; - } - - if (p) - { - if (r_o.ptr_rids != 0 && r_o.ptr_types != 0 && - r_o.num_types1 == r_o.num_rids1) - { - uint32 i; - - valid_query = True; - *num_rids = r_o.num_rids1; - - for (i = 0; i < r_o.num_rids1; i++) - { - rid[i] = r_o.rid[i]; - } - for (i = 0; i < r_o.num_types1; i++) - { - type[i] = r_o.type[i]; - } - } - else if (r_o.ptr_rids == 0 && r_o.ptr_types == 0) - { - valid_query = True; - *num_rids = 0; - } - else - { - p = False; - } - } + DEBUG(5,("do_samr_query_userinfo: error in query user info, level 0x%x\n", + info_level)); } - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - return valid_query; + return do_samr_close(cli, &pol_open_user); } /**************************************************************************** -do a SAMR Query Lookup RIDS +do a SAMR change user password command ****************************************************************************/ -BOOL samr_query_lookup_rids( const POLICY_HND *pol, uint32 flags, - uint32 num_rids, uint32 *rids, - uint32 *num_names, - char ***names, - uint32 **type) +BOOL do_samr_chgpasswd_user(struct cli_state *cli, + char *srv_name, char *user_name, + char nt_newpass[516], uchar nt_oldhash[16], + char lm_newpass[516], uchar lm_oldhash[16]) { prs_struct data; prs_struct rdata; + SAMR_Q_CHGPASSWD_USER q_e; + SAMR_R_CHGPASSWD_USER r_e; - SAMR_Q_LOOKUP_RIDS q_o; - BOOL valid_query = False; - - if (pol == NULL || flags == 0 || num_rids == 0 || rids == NULL || - num_names == NULL || names == NULL || type == NULL ) return False; - - /* create and send a MSRPC command with api SAMR_LOOKUP_RIDS */ + /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */ - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - DEBUG(4,("SAMR Query Lookup RIDs.\n")); + DEBUG(4,("SAMR Change User Password. server:%s username:%s\n", + srv_name, user_name)); - /* store the parameters */ - make_samr_q_lookup_rids(&q_o, pol, flags, num_rids, rids); + init_samr_q_chgpasswd_user(&q_e, srv_name, user_name, + nt_newpass, nt_oldhash, + lm_newpass, lm_oldhash); /* turn parameters into data stream */ - samr_io_q_lookup_rids("", &q_o, &data, 0); + if(!samr_io_q_chgpasswd_user("", &q_e, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_LOOKUP_RIDS, &data, &rdata)) - { - SAMR_R_LOOKUP_RIDS r_o; - BOOL p; - ZERO_STRUCT(r_o); + if (!rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - samr_io_r_lookup_rids("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_LOOKUP_RIDS: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + prs_mem_free(&data); - if (p) - { - if (r_o.ptr_names != 0 && r_o.ptr_types != 0 && - r_o.num_types1 == r_o.num_names1) - { - uint32 i; - valid_query = True; - - (*num_names) = 0; - (*names) = NULL; - - for (i = 0; i < r_o.num_names1; i++) - { - fstring tmp; - unistr2_to_ascii(tmp, &r_o.uni_name[i], sizeof(tmp)-1); - add_chars_to_array(num_names, names, tmp); - } - - if ((*num_names) != 0) - { - (*type) = (uint32*)malloc((*num_names) * sizeof(**type)); - } - - for (i = 0; (*type) != NULL && i < r_o.num_types1; i++) - { - (*type)[i] = r_o.type[i]; - } - } - else if (r_o.ptr_names == 0 && r_o.ptr_types == 0) - { - valid_query = True; - *num_names = 0; - *names = NULL; - *type = NULL; - } - else - { - p = False; - } - } + if(!samr_io_r_chgpasswd_user("", &r_e, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } - samr_free_r_lookup_rids(&r_o); + if (r_e.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status))); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + prs_mem_free(&rdata); - return valid_query; + return True; } /**************************************************************************** -do a SAMR Query Alias Members +do a SAMR unknown 0x38 command ****************************************************************************/ -BOOL samr_query_aliasmem( const POLICY_HND *alias_pol, - uint32 *num_mem, DOM_SID2 *sid) +BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name) { prs_struct data; prs_struct rdata; - SAMR_Q_QUERY_ALIASMEM q_o; - BOOL valid_query = False; - - DEBUG(4,("SAMR Query Alias Members.\n")); + SAMR_Q_UNKNOWN_38 q_e; + SAMR_R_UNKNOWN_38 r_e; - if (alias_pol == NULL || sid == NULL || num_mem == NULL) return False; + /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */ - /* create and send a MSRPC command with api SAMR_QUERY_ALIASMEM */ + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name)); - /* store the parameters */ - make_samr_q_query_aliasmem(&q_o, alias_pol); + init_samr_q_unknown_38(&q_e, srv_name); /* turn parameters into data stream */ - samr_io_q_query_aliasmem("", &q_o, &data, 0); + if(!samr_io_q_unknown_38("", &q_e, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASMEM, &data, &rdata)) - { - SAMR_R_QUERY_ALIASMEM r_o; - BOOL p; - - /* get user info */ - r_o.sid = sid; + if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_38, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - samr_io_r_query_aliasmem("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_ALIASMEM: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + prs_mem_free(&data); - if (p && r_o.ptr != 0) - { - valid_query = True; - *num_mem = r_o.num_sids; - } + if(!samr_io_r_unknown_38("", &r_e, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } + if (r_e.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status))); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + prs_mem_free(&rdata); - return valid_query; + return True; } /**************************************************************************** -do a SAMR Query User Aliases +do a SAMR unknown 0x8 command ****************************************************************************/ -BOOL samr_query_useraliases( const POLICY_HND *pol, - uint32 *ptr_sid, DOM_SID2 *sid, - uint32 *num_aliases, uint32 **rid) +BOOL do_samr_query_dom_info(struct cli_state *cli, + POLICY_HND *domain_pol, uint16 switch_value) { prs_struct data; prs_struct rdata; + SAMR_Q_QUERY_DOMAIN_INFO q_e; + SAMR_R_QUERY_DOMAIN_INFO r_e; - SAMR_Q_QUERY_USERALIASES q_o; - BOOL valid_query = False; - ZERO_STRUCT(q_o); - - DEBUG(4,("SAMR Query User Aliases.\n")); + if (domain_pol == NULL) + return False; - if (pol == NULL || sid == NULL || rid == NULL || num_aliases == 0) return False; + /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */ - /* create and send a MSRPC command with api SAMR_QUERY_USERALIASES */ + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value)); /* store the parameters */ - make_samr_q_query_useraliases(&q_o, pol, ptr_sid, sid); + init_samr_q_query_dom_info(&q_e, domain_pol, switch_value); /* turn parameters into data stream */ - samr_io_q_query_useraliases("", &q_o, &data, 0); + if(!samr_io_q_query_dom_info("", &q_e, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERALIASES, &data, &rdata)) - { - SAMR_R_QUERY_USERALIASES r_o; - BOOL p; - - r_o.rid = NULL; + if (!rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - samr_io_r_query_useraliases("", &r_o, &rdata, 0); - *rid = r_o.rid; - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_USERALIASES: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + prs_mem_free(&data); - if (p && r_o.ptr != 0) - { - valid_query = True; - *num_aliases = r_o.num_entries; - } + if(!samr_io_r_query_dom_info("", &r_e, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } + if (r_e.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status))); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + prs_mem_free(&rdata); - return valid_query; + return True; } /**************************************************************************** -do a SAMR Query Group Members +do a SAMR enumerate users ****************************************************************************/ -BOOL samr_query_groupmem( POLICY_HND *group_pol, - uint32 *num_mem, uint32 **rid, uint32 **attr) +BOOL do_samr_enum_dom_users(struct cli_state *cli, + POLICY_HND *pol, uint16 num_entries, uint16 unk_0, + uint16 acb_mask, uint16 unk_1, uint32 size, + struct acct_info **sam, + int *num_sam_users) { prs_struct data; prs_struct rdata; + SAMR_Q_ENUM_DOM_USERS q_e; + SAMR_R_ENUM_DOM_USERS r_e; + int i; + int name_idx = 0; - SAMR_Q_QUERY_GROUPMEM q_o; - BOOL valid_query = False; - - DEBUG(4,("SAMR Query Group Members.\n")); + if (pol == NULL || num_sam_users == NULL) + return False; - if (group_pol == NULL || rid == NULL || attr == NULL || num_mem == NULL) return False; + /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */ - /* create and send a MSRPC command with api SAMR_QUERY_GROUPMEM */ + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size)); /* store the parameters */ - make_samr_q_query_groupmem(&q_o, group_pol); + init_samr_q_enum_dom_users(&q_e, pol, + num_entries, unk_0, + acb_mask, unk_1, size); /* turn parameters into data stream */ - samr_io_q_query_groupmem("", &q_o, &data, 0); + if(!samr_io_q_enum_dom_users("", &q_e, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(group_pol, SAMR_QUERY_GROUPMEM, &data, &rdata)) - { - SAMR_R_QUERY_GROUPMEM r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - r_o.rid = NULL; - r_o.attr = NULL; + prs_mem_free(&data); - samr_io_r_query_groupmem("", &r_o, &rdata, 0); - *rid = r_o.rid ; - *attr = r_o.attr; - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_GROUPMEM: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!samr_io_r_enum_dom_users("", &r_e, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } + + if (r_e.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status))); + prs_mem_free(&rdata); + return False; + } + + *num_sam_users = r_e.num_entries2; + if (*num_sam_users > MAX_SAM_ENTRIES) { + *num_sam_users = MAX_SAM_ENTRIES; + DEBUG(2,("do_samr_enum_dom_users: sam user entries limited to %d\n", + *num_sam_users)); + } + + *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_users)); + + if ((*sam) == NULL) + *num_sam_users = 0; - if (p && r_o.ptr != 0 && - r_o.ptr_rids != 0 && r_o.ptr_attrs != 0 && - r_o.num_rids == r_o.num_attrs) - { - valid_query = True; - *num_mem = r_o.num_rids; + for (i = 0; i < *num_sam_users; i++) { + (*sam)[i].smb_userid = r_e.sam[i].rid; + if (r_e.sam[i].hdr_name.buffer) { + char *acct_name = dos_unistrn2(r_e.uni_acct_name[name_idx].buffer, + r_e.uni_acct_name[name_idx].uni_str_len); + fstrcpy((*sam)[i].acct_name, acct_name); + name_idx++; + } else { + memset((char *)(*sam)[i].acct_name, '\0', sizeof((*sam)[i].acct_name)); } + DEBUG(5,("do_samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n", + i, (*sam)[i].smb_userid, (*sam)[i].acct_name)); } - prs_mem_free(&data ); prs_mem_free(&rdata ); - return valid_query; + return True; } /**************************************************************************** -do a SAMR Query User Groups +do a SAMR Connect ****************************************************************************/ -BOOL samr_query_usergroups( POLICY_HND *pol, uint32 *num_groups, - DOM_GID **gid) +BOOL do_samr_connect(struct cli_state *cli, + char *srv_name, uint32 unknown_0, + POLICY_HND *connect_pol) { prs_struct data; prs_struct rdata; + SAMR_Q_CONNECT q_o; + SAMR_R_CONNECT r_o; - SAMR_Q_QUERY_USERGROUPS q_o; - BOOL valid_query = False; - - DEBUG(4,("SAMR Query User Groups.\n")); + if (srv_name == NULL || connect_pol == NULL) + return False; - if (pol == NULL || gid == NULL || num_groups == 0) return False; + /* create and send a MSRPC command with api SAMR_CONNECT */ - /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */ + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n", + srv_name, unknown_0)); /* store the parameters */ - make_samr_q_query_usergroups(&q_o, pol); + init_samr_q_connect(&q_o, srv_name, unknown_0); /* turn parameters into data stream */ - samr_io_q_query_usergroups("", &q_o, &data, 0); + if(!samr_io_q_connect("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERGROUPS, &data, &rdata)) - { - SAMR_R_QUERY_USERGROUPS r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, SAMR_CONNECT, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - /* get user info */ - r_o.gid = NULL; + prs_mem_free(&data); - samr_io_r_query_usergroups("", &r_o, &rdata, 0); - *gid = r_o.gid; - p = rdata.offset != 0; + if(!samr_io_r_connect("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p && r_o.ptr_0 != 0) - { - valid_query = True; - *num_groups = r_o.num_entries; - } - + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol)); - return valid_query; + prs_mem_free(&rdata); + + return True; } /**************************************************************************** -do a SAMR Query Group Info +do a SAMR Open User ****************************************************************************/ -BOOL samr_query_groupinfo( POLICY_HND *pol, - uint16 switch_value, GROUP_INFO_CTR* ctr) +BOOL do_samr_open_user(struct cli_state *cli, + POLICY_HND *pol, uint32 unk_0, uint32 rid, + POLICY_HND *user_pol) { prs_struct data; prs_struct rdata; + SAMR_Q_OPEN_USER q_o; + SAMR_R_OPEN_USER r_o; - SAMR_Q_QUERY_GROUPINFO q_o; - BOOL valid_query = False; - - DEBUG(4,("SAMR Query Group Info. level: %d\n", switch_value)); + if (pol == NULL || user_pol == NULL) + return False; - if (pol == NULL || ctr == NULL || switch_value == 0) return False; + /* create and send a MSRPC command with api SAMR_OPEN_USER */ - /* create and send a MSRPC command with api SAMR_QUERY_GROUPINFO */ + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + DEBUG(4,("SAMR Open User. unk_0: %08x RID:%x\n", + unk_0, rid)); /* store the parameters */ - make_samr_q_query_groupinfo(&q_o, pol, switch_value); + init_samr_q_open_user(&q_o, pol, unk_0, rid); /* turn parameters into data stream */ - samr_io_q_query_groupinfo("", &q_o, &data, 0); + if(!samr_io_q_open_user("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_QUERY_GROUPINFO, &data, &rdata)) - { - SAMR_R_QUERY_GROUPINFO r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, SAMR_OPEN_USER, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - /* get group info */ - r_o.ctr = ctr; + prs_mem_free(&data); - samr_io_r_query_groupinfo("", &r_o, &rdata, 0); - p = rdata.offset != 0; + if(!samr_io_r_open_user("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_GROUPINFO: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p && r_o.ctr->switch_value1 != switch_value) - { - DEBUG(4,("SAMR_R_QUERY_GROUPINFO: received incorrect level %d\n", - r_o.ctr->switch_value1)); - } - - if (p && r_o.ptr != 0) - { - valid_query = True; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol)); + + prs_mem_free(&rdata); - return valid_query; + return True; } /**************************************************************************** -do a SAMR Set User Info +do a SAMR Open Domain ****************************************************************************/ -BOOL samr_set_userinfo2( POLICY_HND *pol, uint16 switch_value, - void* usr) +BOOL do_samr_open_domain(struct cli_state *cli, + POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid, + POLICY_HND *domain_pol) { prs_struct data; prs_struct rdata; + pstring sid_str; + SAMR_Q_OPEN_DOMAIN q_o; + SAMR_R_OPEN_DOMAIN r_o; - SAMR_Q_SET_USERINFO2 q_o; - BOOL valid_query = False; - - DEBUG(4,("SAMR Set User Info 2. level: %d\n", switch_value)); + if (connect_pol == NULL || sid == NULL || domain_pol == NULL) + return False; - if (pol == NULL || usr == NULL || switch_value == 0) return False; + /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */ - /* create and send a MSRPC command with api SAMR_SET_USERINFO2 */ + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + sid_to_string(sid_str, sid); + DEBUG(4,("SAMR Open Domain. SID:%s RID:%x\n", sid_str, rid)); /* store the parameters */ - make_samr_q_set_userinfo2(&q_o, pol, switch_value, usr); + init_samr_q_open_domain(&q_o, connect_pol, rid, sid); /* turn parameters into data stream */ - samr_io_q_set_userinfo2("", &q_o, &data, 0); + if(!samr_io_q_open_domain("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO2, &data, &rdata)) - { - SAMR_R_SET_USERINFO2 r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - samr_io_r_set_userinfo2("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_USERINFO2: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + prs_mem_free(&data); - if (p) - { - valid_query = True; - } + if(!samr_io_r_open_domain("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; + } + + memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol)); - return valid_query; + prs_mem_free(&rdata); + + return True; } /**************************************************************************** -do a SAMR Set User Info +do a SAMR Query Unknown 12 ****************************************************************************/ -BOOL samr_set_userinfo( POLICY_HND *pol, uint16 switch_value, void* usr) +BOOL do_samr_query_unknown_12(struct cli_state *cli, + POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids, + uint32 *num_aliases, + fstring als_names [MAX_LOOKUP_SIDS], + uint32 num_als_users[MAX_LOOKUP_SIDS]) { prs_struct data; prs_struct rdata; + SAMR_Q_UNKNOWN_12 q_o; + SAMR_R_UNKNOWN_12 r_o; - SAMR_Q_SET_USERINFO q_o; - BOOL valid_query = False; - - DEBUG(4,("SAMR Set User Info. level: %d\n", switch_value)); + if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL || + num_aliases == NULL || als_names == NULL || num_als_users == NULL ) + return False; - if (pol == NULL || usr == NULL || switch_value == 0) return False; + /* create and send a MSRPC command with api SAMR_UNKNOWN_12 */ - /* create and send a MSRPC command with api SAMR_SET_USERINFO */ + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + DEBUG(4,("SAMR Query Unknown 12.\n")); /* store the parameters */ - make_samr_q_set_userinfo(&q_o, pol, switch_value, usr); + init_samr_q_unknown_12(&q_o, pol, rid, num_gids, gids); /* turn parameters into data stream */ - samr_io_q_set_userinfo("", &q_o, &data, 0); + if(!samr_io_q_unknown_12("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO, &data, &rdata)) - { - SAMR_R_SET_USERINFO r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_12, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } + + prs_mem_free(&data); - samr_io_r_set_userinfo("", &r_o, &rdata, 0); - p = rdata.offset != 0; + if(!samr_io_r_unknown_12("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_UNKNOWN_12: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; + } + + if (r_o.ptr_aliases != 0 && r_o.ptr_als_usrs != 0 && + r_o.num_als_usrs1 == r_o.num_aliases1) { + int i; - if (p) - { - valid_query = True; + *num_aliases = r_o.num_aliases1; + + for (i = 0; i < r_o.num_aliases1; i++) { + fstrcpy(als_names[i], dos_unistrn2(r_o.uni_als_name[i].buffer, + r_o.uni_als_name[i].uni_str_len)); + } + for (i = 0; i < r_o.num_als_usrs1; i++) { + num_als_users[i] = r_o.num_als_usrs[i]; } + } else if (r_o.ptr_aliases == 0 && r_o.ptr_als_usrs == 0) { + *num_aliases = 0; + } else { + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + prs_mem_free(&rdata); - return valid_query; + return True; } /**************************************************************************** -do a SAMR Query User Info +do a SAMR Query User Groups ****************************************************************************/ -BOOL samr_query_userinfo( POLICY_HND *pol, uint16 switch_value, void* usr) +BOOL do_samr_query_usergroups(struct cli_state *cli, + POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid) { prs_struct data; prs_struct rdata; + SAMR_Q_QUERY_USERGROUPS q_o; + SAMR_R_QUERY_USERGROUPS r_o; - SAMR_Q_QUERY_USERINFO q_o; - BOOL valid_query = False; - - DEBUG(4,("SAMR Query User Info. level: %d\n", switch_value)); + if (pol == NULL || gid == NULL || num_groups == 0) + return False; - if (pol == NULL || usr == NULL || switch_value == 0) return False; + /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */ - /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */ + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + DEBUG(4,("SAMR Query User Groups.\n")); /* store the parameters */ - make_samr_q_query_userinfo(&q_o, pol, switch_value); + init_samr_q_query_usergroups(&q_o, pol); /* turn parameters into data stream */ - samr_io_q_query_userinfo("", &q_o, &data, 0); + if(!samr_io_q_query_usergroups("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol, SAMR_QUERY_USERINFO, &data, &rdata)) - { - SAMR_R_QUERY_USERINFO r_o; - BOOL p; - - /* get user info */ - r_o.info.id = usr; + if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - samr_io_r_query_userinfo("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + prs_mem_free(&data); - if (p && r_o.switch_value != switch_value) - { - DEBUG(4,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n", - r_o.switch_value)); - } + /* get user info */ + r_o.gid = gid; - if (p && r_o.ptr != 0) - { - valid_query = True; - } + if(!samr_io_r_query_usergroups("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } + + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + *num_groups = r_o.num_entries; + + prs_mem_free(&rdata); - return valid_query; + return True; } /**************************************************************************** -do a SAMR Close +do a SAMR Query User Info ****************************************************************************/ -BOOL samr_close( POLICY_HND *hnd) +BOOL do_samr_query_userinfo(struct cli_state *cli, + POLICY_HND *pol, uint16 switch_value, void* usr) { prs_struct data; prs_struct rdata; + SAMR_Q_QUERY_USERINFO q_o; + SAMR_R_QUERY_USERINFO r_o; - SAMR_Q_CLOSE_HND q_c; - BOOL valid_close = False; - - DEBUG(4,("SAMR Close\n")); + if (pol == NULL || usr == NULL || switch_value == 0) + return False; - if (hnd == NULL) return False; + /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */ - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); - /* create and send a MSRPC command with api SAMR_CLOSE_HND */ + DEBUG(4,("SAMR Query User Info. level: %d\n", switch_value)); /* store the parameters */ - make_samr_q_close_hnd(&q_c, hnd); + init_samr_q_query_userinfo(&q_o, pol, switch_value); /* turn parameters into data stream */ - samr_io_q_close_hnd("", &q_c, &data, 0); + if(!samr_io_q_query_userinfo("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(hnd, SAMR_CLOSE_HND, &data, &rdata)) - { - SAMR_R_CLOSE_HND r_c; - BOOL p; + if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - samr_io_r_close_hnd("", &r_c, &rdata, 0); - p = rdata.offset != 0; + prs_mem_free(&data); - if (p && r_c.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status))); - p = False; - } + /* get user info */ + r_o.info.id = usr; - if (p) - { - /* check that the returned policy handle is all zeros */ - uint32 i; - valid_close = True; - - for (i = 0; i < sizeof(r_c.pol.data); i++) - { - if (r_c.pol.data[i] != 0) - { - valid_close = False; - break; - } - } - if (!valid_close) - { - DEBUG(4,("SAMR_CLOSE_HND: non-zero handle returned\n")); - } - } + if(!samr_io_r_query_userinfo("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } + + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + if (r_o.switch_value != switch_value) { + DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n", + r_o.switch_value)); + prs_mem_free(&rdata); + return False; + } - close_policy_hnd(hnd); + if (r_o.ptr == 0) { + prs_mem_free(&rdata); + return False; + } - return valid_close; + prs_mem_free(&rdata); + + return True; } /**************************************************************************** -do a SAMR query display info +do a SAMR Close ****************************************************************************/ -BOOL samr_query_dispinfo( POLICY_HND *pol_domain, uint16 level, - uint32 *num_entries, - SAM_DISPINFO_CTR *ctr) +BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd) { prs_struct data; prs_struct rdata; + SAMR_Q_CLOSE_HND q_c; + SAMR_R_CLOSE_HND r_c; + int i; - SAMR_Q_QUERY_DISPINFO q_o; - BOOL valid_query = False; - - DEBUG(4,("SAMR Query Display Info. level: %d\n", level)); - - if (pol_domain == NULL || num_entries == NULL || ctr == NULL || - level == 0) - { + if (hnd == NULL) return False; - } - /* create and send a MSRPC command with api SAMR_QUERY_DISPINFO */ + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); + + /* create and send a MSRPC command with api SAMR_CLOSE_HND */ - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + DEBUG(4,("SAMR Close\n")); /* store the parameters */ - make_samr_q_query_dispinfo(&q_o, pol_domain, level, 0, 0xffffffff); + init_samr_q_close_hnd(&q_c, hnd); /* turn parameters into data stream */ - samr_io_q_query_dispinfo("", &q_o, &data, 0); + if(!samr_io_q_close_hnd("", &q_c, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_hnd_pipe_req(pol_domain, SAMR_QUERY_DISPINFO, &data, &rdata)) - { - SAMR_R_QUERY_DISPINFO r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - /* get user info */ - r_o.ctr = ctr; + prs_mem_free(&data); - samr_io_r_query_dispinfo("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(4,("SAMR_R_QUERY_DISPINFO: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } + if(!samr_io_r_close_hnd("", &r_c, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } - if (p && r_o.switch_level != level) - { - DEBUG(4,("SAMR_R_QUERY_DISPINFO: received incorrect level %d\n", - r_o.switch_level)); - } + if (r_c.status != 0) { + /* report error code */ + DEBUG(0,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status))); + prs_mem_free(&rdata); + return False; + } - if (p && r_o.ptr_entries != 0) - { - valid_query = True; - (*num_entries) = r_o.num_entries; + /* check that the returned policy handle is all zeros */ + + for (i = 0; i < sizeof(r_c.pol.data); i++) { + if (r_c.pol.data[i] != 0) { + DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n")); + prs_mem_free(&rdata); + return False; } - } + } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + prs_mem_free(&rdata); - return valid_query; + return True; } - diff --git a/source3/rpc_client/cli_srvsvc.c b/source3/rpc_client/cli_srvsvc.c index 4180141cba..b883cc1942 100644 --- a/source3/rpc_client/cli_srvsvc.c +++ b/source3/rpc_client/cli_srvsvc.c @@ -6,6 +6,7 @@ * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. + * Copyright (C) Jeremy Allison 1999. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,95 +32,11 @@ extern int DEBUGLEVEL; -/**************************************************************************** -do a server net tprt enum -****************************************************************************/ -BOOL srv_net_srv_tprt_enum( - const char *srv_name, - uint32 switch_value, SRV_TPRT_INFO_CTR *ctr, - uint32 preferred_len, - ENUM_HND *hnd) -{ - prs_struct data; - prs_struct rdata; - SRV_Q_NET_TPRT_ENUM q_o; - BOOL valid_enum = False; - struct cli_connection *con = NULL; - - if (ctr == NULL || preferred_len == 0) return False; - - if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con)) - { - return False; - } - - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* create and send a MSRPC command with api SRV_NETTPRTENUM */ - - DEBUG(4,("SRV Net Server Transport Enum, level %d, enum:%8x\n", - switch_value, get_enum_hnd(hnd))); - - ctr->switch_value = switch_value; - ctr->ptr_tprt_ctr = 1; - ctr->tprt.info0.num_entries_read = 0; - ctr->tprt.info0.ptr_tprt_info = 1; - - /* store the parameters */ - make_srv_q_net_tprt_enum(&q_o, srv_name, - switch_value, ctr, - preferred_len, - hnd); - - /* turn parameters into data stream */ - srv_io_q_net_tprt_enum("", &q_o, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SRV_NETTRANSPORTENUM, &data, &rdata)) - { - SRV_R_NET_TPRT_ENUM r_o; - BOOL p; - - r_o.ctr = ctr; - - srv_io_r_net_tprt_enum("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status))); - p = 0; - } - - if (p && r_o.ctr->switch_value != switch_value) - { - /* different switch levels. oops. */ - DEBUG(0,("SRV_R_NET_SRV_TPRT_ENUM: info class %d does not match request %d\n", - r_o.ctr->switch_value, switch_value)); - p = 0; - } - - if (p) - { - /* ok, at last: we're happy. */ - valid_enum = True; - } - } - - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - cli_connection_unlink(con); - - return valid_enum; -} - /**************************************************************************** do a server net conn enum ****************************************************************************/ -BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name, +BOOL do_srv_net_srv_conn_enum(struct cli_state *cli, + char *server_name, char *qual_name, uint32 switch_value, SRV_CONN_INFO_CTR *ctr, uint32 preferred_len, ENUM_HND *hnd) @@ -127,23 +44,18 @@ BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name, prs_struct data; prs_struct rdata; SRV_Q_NET_CONN_ENUM q_o; - BOOL valid_enum = False; - struct cli_connection *con = NULL; - - if (ctr == NULL || preferred_len == 0) return False; + SRV_R_NET_CONN_ENUM r_o; - if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con)) - { + if (server_name == NULL || ctr == NULL || preferred_len == 0) return False; - } - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api SRV_NETCONNENUM */ - DEBUG(4,("SRV Net Server Connection Enum %s), level %d, enum:%8x\n", - qual_name, switch_value, get_enum_hnd(hnd))); + DEBUG(4,("SRV Net Server Connection Enum(%s, %s), level %d, enum:%8x\n", + server_name, qual_name, switch_value, get_enum_hnd(hnd))); ctr->switch_value = switch_value; ctr->ptr_conn_ctr = 1; @@ -151,59 +63,60 @@ BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name, ctr->conn.info0.ptr_conn_info = 1; /* store the parameters */ - make_srv_q_net_conn_enum(&q_o, srv_name, qual_name, + init_srv_q_net_conn_enum(&q_o, server_name, qual_name, switch_value, ctr, preferred_len, hnd); /* turn parameters into data stream */ - srv_io_q_net_conn_enum("", &q_o, &data, 0); + if(!srv_io_q_net_conn_enum("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SRV_NETCONNENUM, &data, &rdata)) - { - SRV_R_NET_CONN_ENUM r_o; - BOOL p; + if(!rpc_api_pipe_req(cli, SRV_NETCONNENUM, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - r_o.ctr = ctr; + prs_mem_free(&data); - srv_io_r_net_conn_enum("", &r_o, &rdata, 0); - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status))); - p = 0; - } - - if (p && r_o.ctr->switch_value != switch_value) - { - /* different switch levels. oops. */ - DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: info class %d does not match request %d\n", - r_o.ctr->switch_value, switch_value)); - p = 0; - } - - if (p) - { - /* ok, at last: we're happy. */ - valid_enum = True; - } + r_o.ctr = ctr; + + if(!srv_io_r_net_conn_enum("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - cli_connection_unlink(con); + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; + } - return valid_enum; + if (r_o.ctr->switch_value != switch_value) { + /* different switch levels. oops. */ + DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: info class %d does not match request %d\n", + r_o.ctr->switch_value, switch_value)); + prs_mem_free(&rdata); + return False; + } + + prs_mem_free(&rdata); + + return True; } /**************************************************************************** do a server net sess enum ****************************************************************************/ -BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name, + +BOOL do_srv_net_srv_sess_enum(struct cli_state *cli, + char *server_name, char *qual_name, uint32 switch_value, SRV_SESS_INFO_CTR *ctr, uint32 preferred_len, ENUM_HND *hnd) @@ -211,23 +124,18 @@ BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name, prs_struct data; prs_struct rdata; SRV_Q_NET_SESS_ENUM q_o; - BOOL valid_enum = False; - struct cli_connection *con = NULL; - - if (ctr == NULL || preferred_len == 0) return False; + SRV_R_NET_SESS_ENUM r_o; - if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con)) - { + if (server_name == NULL || ctr == NULL || preferred_len == 0) return False; - } - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api SRV_NETSESSENUM */ - DEBUG(4,("SRV Net Session Enum, level %d, enum:%8x\n", - switch_value, get_enum_hnd(hnd))); + DEBUG(4,("SRV Net Session Enum (%s), level %d, enum:%8x\n", + server_name, switch_value, get_enum_hnd(hnd))); ctr->switch_value = switch_value; ctr->ptr_sess_ctr = 1; @@ -235,145 +143,130 @@ BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name, ctr->sess.info0.ptr_sess_info = 1; /* store the parameters */ - make_srv_q_net_sess_enum(&q_o, srv_name, qual_name, user_name, + init_srv_q_net_sess_enum(&q_o, server_name, qual_name, switch_value, ctr, preferred_len, hnd); /* turn parameters into data stream */ - srv_io_q_net_sess_enum("", &q_o, &data, 0); + if(!srv_io_q_net_sess_enum("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SRV_NETSESSENUM, &data, &rdata)) - { - SRV_R_NET_SESS_ENUM r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, SRV_NETSESSENUM, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } + + prs_mem_free(&data); - r_o.ctr = ctr; + r_o.ctr = ctr; - srv_io_r_net_sess_enum("", &r_o, &rdata, 0); - p = rdata.offset != 0; + if(!srv_io_r_net_sess_enum("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: %s\n", get_nt_error_msg(r_o.status))); - p = 0; - } - - if (p && r_o.ctr->switch_value != switch_value) - { - /* different switch levels. oops. */ - DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: info class %d does not match request %d\n", - r_o.ctr->switch_value, switch_value)); - p = 0; - } - - if (p) - { - /* ok, at last: we're happy. */ - valid_enum = True; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - cli_connection_unlink(con); + if (r_o.ctr->switch_value != switch_value) { + /* different switch levels. oops. */ + DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: info class %d does not match request %d\n", + r_o.ctr->switch_value, switch_value)); + prs_mem_free(&rdata); + return False; + } - return valid_enum; + prs_mem_free(&rdata); + + return True; } /**************************************************************************** do a server net share enum ****************************************************************************/ -BOOL srv_net_srv_share_enum( char *srv_name, - uint32 switch_value, SRV_SHARE_INFO_CTR *ctr, - uint32 preferred_len, - ENUM_HND *hnd) +BOOL do_srv_net_srv_share_enum(struct cli_state *cli, + char *server_name, + uint32 switch_value, SRV_R_NET_SHARE_ENUM *r_o, + uint32 preferred_len, ENUM_HND *hnd) { prs_struct data; prs_struct rdata; SRV_Q_NET_SHARE_ENUM q_o; - BOOL valid_enum = False; - struct cli_connection *con = NULL; - - if (ctr == NULL || preferred_len == 0) return False; - if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con)) - { + if (server_name == NULL || preferred_len == 0) return False; - } - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api SRV_NETSHAREENUM */ - DEBUG(4,("SRV Get Share Info, level %d, enum:%8x\n", - switch_value, get_enum_hnd(hnd))); + DEBUG(4,("SRV Get Share Info (%s), level %d, enum:%8x\n", + server_name, switch_value, get_enum_hnd(hnd))); - q_o.share_level = switch_value; - - ctr->switch_value = switch_value; - ctr->ptr_share_ctr = 1; - ctr->share.info1.num_entries_read = 0; - ctr->share.info1.ptr_share_info = 1; - /* store the parameters */ - make_srv_q_net_share_enum(&q_o, srv_name, - switch_value, ctr, - preferred_len, - hnd); + init_srv_q_net_share_enum(&q_o, server_name, switch_value, + preferred_len, hnd); /* turn parameters into data stream */ - srv_io_q_net_share_enum("", &q_o, &data, 0); + if(!srv_io_q_net_share_enum("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SRV_NETSHAREENUM, &data, &rdata)) - { - SRV_R_NET_SHARE_ENUM r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, SRV_NETSHAREENUM, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - r_o.ctr = ctr; + prs_mem_free(&data); - srv_io_r_net_share_enum("", &r_o, &rdata, 0); - p = rdata.offset != 0; + if(!srv_io_r_net_share_enum("", r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status))); - p = 0; - } - - if (p && r_o.ctr->switch_value != switch_value) - { - /* different switch levels. oops. */ - DEBUG(0,("SRV_R_NET_SRV_SHARE_ENUM: info class %d does not match request %d\n", - r_o.ctr->switch_value, switch_value)); - p = 0; - } - - if (p) - { - /* ok, at last: we're happy. */ - valid_enum = True; - } + if (r_o->status != 0) { + /* report error code */ + DEBUG(0,("SRV_R_NET_SHARE_ENUM: %s\n", get_nt_error_msg(r_o->status))); + prs_mem_free(&rdata); + free_srv_r_net_share_enum(r_o); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - cli_connection_unlink(con); + if (r_o->ctr.switch_value != switch_value) { + /* different switch levels. oops. */ + DEBUG(0,("SRV_R_NET_SHARE_ENUM: info class %d does not match request %d\n", + r_o->ctr.switch_value, switch_value)); + prs_mem_free(&rdata); + free_srv_r_net_share_enum(r_o); + return False; + } - return valid_enum; + prs_mem_free(&rdata); + + return True; } /**************************************************************************** do a server net file enum ****************************************************************************/ -BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id, + +BOOL do_srv_net_srv_file_enum(struct cli_state *cli, + char *server_name, char *qual_name, uint32 switch_value, SRV_FILE_INFO_CTR *ctr, uint32 preferred_len, ENUM_HND *hnd) @@ -381,23 +274,18 @@ BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id, prs_struct data; prs_struct rdata; SRV_Q_NET_FILE_ENUM q_o; - BOOL valid_enum = False; - struct cli_connection *con = NULL; + SRV_R_NET_FILE_ENUM r_o; - if (ctr == NULL || preferred_len == 0) return False; - - if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con)) - { + if (server_name == NULL || ctr == NULL || preferred_len == 0) return False; - } - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api SRV_NETFILEENUM */ - DEBUG(4,("SRV Get File Info level %d, enum:%8x\n", - switch_value, get_enum_hnd(hnd))); + DEBUG(4,("SRV Get File Info (%s), level %d, enum:%8x\n", + server_name, switch_value, get_enum_hnd(hnd))); q_o.file_level = switch_value; @@ -407,189 +295,117 @@ BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id, ctr->file.info3.ptr_file_info = 1; /* store the parameters */ - make_srv_q_net_file_enum(&q_o, srv_name, qual_name, file_id, + init_srv_q_net_file_enum(&q_o, server_name, qual_name, switch_value, ctr, preferred_len, hnd); /* turn parameters into data stream */ - srv_io_q_net_file_enum("", &q_o, &data, 0); + if(!srv_io_q_net_file_enum("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SRV_NETFILEENUM, &data, &rdata)) - { - SRV_R_NET_FILE_ENUM r_o; - BOOL p; + if (!rpc_api_pipe_req(cli, SRV_NETFILEENUM, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } - r_o.ctr = ctr; + prs_mem_free(&data); - srv_io_r_net_file_enum("", &r_o, &rdata, 0); - p = rdata.offset != 0; + r_o.ctr = ctr; + + if(!srv_io_r_net_file_enum("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); + return False; + } - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status))); - p = 0; - } - - if (p && r_o.ctr->switch_value != switch_value) - { - /* different switch levels. oops. */ - DEBUG(0,("SRV_R_NET_SRV_FILE_ENUM: info class %d does not match request %d\n", - r_o.ctr->switch_value, switch_value)); - p = 0; - } - - if (p) - { - /* ok, at last: we're happy. */ - valid_enum = True; - } + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SRV_R_NET_FILE_ENUM: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - cli_connection_unlink(con); + if (r_o.ctr->switch_value != switch_value) { + /* different switch levels. oops. */ + DEBUG(0,("SRV_R_NET_FILE_ENUM: info class %d does not match request %d\n", + r_o.ctr->switch_value, switch_value)); + prs_mem_free(&rdata); + return False; + } - return valid_enum; + prs_mem_free(&rdata); + + return True; } /**************************************************************************** do a server get info ****************************************************************************/ -BOOL srv_net_srv_get_info( char *srv_name, uint32 switch_value, - SRV_INFO_CTR *ctr) +BOOL do_srv_net_srv_get_info(struct cli_state *cli, + char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr) { prs_struct data; prs_struct rdata; SRV_Q_NET_SRV_GET_INFO q_o; - BOOL valid_info = False; - struct cli_connection *con = NULL; - - if (switch_value == 0 || ctr == NULL) return False; + SRV_R_NET_SRV_GET_INFO r_o; - if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con)) - { + if (server_name == NULL || switch_value == 0 || ctr == NULL) return False; - } - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rdata, 0, 4, UNMARSHALL); /* create and send a MSRPC command with api SRV_NET_SRV_GET_INFO */ - DEBUG(4,("SRV Get Server Info level %d\n", switch_value)); + DEBUG(4,("SRV Get Server Info (%s), level %d\n", server_name, switch_value)); /* store the parameters */ - make_srv_q_net_srv_get_info(&q_o, srv_name, switch_value); + init_srv_q_net_srv_get_info(&q_o, server_name, switch_value); /* turn parameters into data stream */ - srv_io_q_net_srv_get_info("", &q_o, &data, 0); + if(!srv_io_q_net_srv_get_info("", &q_o, &data, 0)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SRV_NET_SRV_GET_INFO, &data, &rdata)) - { - SRV_R_NET_SRV_GET_INFO r_o; - BOOL p; - - r_o.ctr = ctr; - - srv_io_r_net_srv_get_info("", &r_o, &rdata, 0); - p = rdata.offset != 0; - p = rdata.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status))); - p = 0; - } - - if (p && r_o.ctr->switch_value != q_o.switch_value) - { - /* different switch levels. oops. */ - DEBUG(0,("SRV_R_NET_SRV_GET_INFO: info class %d does not match request %d\n", - r_o.ctr->switch_value, q_o.switch_value)); - p = 0; - } - - if (p) - { - /* ok, at last: we're happy. */ - valid_info = True; - } + if (!rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &data, &rdata)) { + prs_mem_free(&data); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); - - cli_connection_unlink(con); + prs_mem_free(&data); - return valid_info; -} + r_o.ctr = ctr; -/**************************************************************************** -get server time -****************************************************************************/ -BOOL srv_net_remote_tod( char *srv_name, TIME_OF_DAY_INFO *tod) -{ - prs_struct data; - prs_struct rdata; - SRV_Q_NET_REMOTE_TOD q_t; - BOOL valid_info = False; - struct cli_connection *con = NULL; - - if (tod == NULL) return False; - - if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con)) - { + if(!srv_io_r_net_srv_get_info("", &r_o, &rdata, 0)) { + prs_mem_free(&rdata); return False; } - prs_init(&data , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); - - /* create and send a MSRPC command with api SRV_NET_REMOTE_TOD */ - - DEBUG(4,("SRV Remote TOD (%s)\n", srv_name)); - - /* store the parameters */ - make_srv_q_net_remote_tod(&q_t, srv_name); - - /* turn parameters into data stream */ - srv_io_q_net_remote_tod("", &q_t, &data, 0); - - /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, SRV_NET_REMOTE_TOD, &data, &rdata)) - { - SRV_R_NET_REMOTE_TOD r_t; - BOOL p; - - r_t.tod = tod; + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rdata); + return False; + } - srv_io_r_net_remote_tod("", &r_t, &rdata, 0); - p = rdata.offset != 0; - p = rdata.offset != 0; - - if (p && r_t.status != 0) - { - /* report error code */ - DEBUG(0,("SRV_R_NET_REMOTE_TOD: %s\n", get_nt_error_msg(r_t.status))); - p = False; - } - - if (p) - { - valid_info = True; - } + if (r_o.ctr->switch_value != q_o.switch_value) { + /* different switch levels. oops. */ + DEBUG(0,("SRV_R_NET_SRV_GET_INFO: info class %d does not match request %d\n", + r_o.ctr->switch_value, q_o.switch_value)); + prs_mem_free(&rdata); + return False; } - prs_mem_free(&data ); - prs_mem_free(&rdata ); + prs_mem_free(&rdata); - cli_connection_unlink(con); - - return valid_info; + return True; } diff --git a/source3/rpc_client/cli_wkssvc.c b/source3/rpc_client/cli_wkssvc.c index 99141bae6c..ae0d5d8231 100644 --- a/source3/rpc_client/cli_wkssvc.c +++ b/source3/rpc_client/cli_wkssvc.c @@ -6,6 +6,7 @@ * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Paul Ashton 1997. + * Copyright (C) Jeremy Allison 1999. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,64 +35,59 @@ extern int DEBUGLEVEL; /**************************************************************************** do a WKS Open Policy ****************************************************************************/ -BOOL wks_query_info( char *srv_name, uint32 switch_value, +BOOL do_wks_query_info(struct cli_state *cli, + char *server_name, uint32 switch_value, WKS_INFO_100 *wks100) { prs_struct rbuf; prs_struct buf; WKS_Q_QUERY_INFO q_o; - BOOL valid_info = False; - struct cli_connection *con = NULL; + WKS_R_QUERY_INFO r_o; - if (wks100 == NULL) return False; - - if (!cli_connection_init(srv_name, PIPE_WKSSVC, &con)) - { + if (server_name == 0 || wks100 == NULL) return False; - } - prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); - prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rbuf, 0, 4, UNMARSHALL ); /* create and send a MSRPC command with api WKS_QUERY_INFO */ DEBUG(4,("WKS Query Info\n")); /* store the parameters */ - make_wks_q_query_info(&q_o, srv_name, switch_value); + init_wks_q_query_info(&q_o, server_name, switch_value); /* turn parameters into data stream */ - wks_io_q_query_info("", &q_o, &buf, 0); + if(!wks_io_q_query_info("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; + } /* send the data on \PIPE\ */ - if (rpc_con_pipe_req(con, WKS_QUERY_INFO, &buf, &rbuf)) - { - WKS_R_QUERY_INFO r_o; - BOOL p; - - r_o.wks100 = wks100; - - wks_io_r_query_info("", &r_o, &rbuf, 0); - p = rbuf.offset != 0; - - if (p && r_o.status != 0) - { - /* report error code */ - DEBUG(0,("WKS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status))); - p = False; - } - - if (p) - { - valid_info = True; - } + if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return False; } - prs_mem_free(&rbuf); - prs_mem_free(&buf ); + prs_mem_free(&buf); - cli_connection_unlink(con); + r_o.wks100 = wks100; - return valid_info; -} + if(!wks_io_r_query_info("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return False; + } + + if (r_o.status != 0) { + /* report error code */ + DEBUG(0,("WKS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return False; + } + prs_mem_free(&rbuf); + + return True; +} diff --git a/source3/rpc_client/ntclienttrust.c b/source3/rpc_client/ntclienttrust.c index 0486017181..8ef193fa89 100644 --- a/source3/rpc_client/ntclienttrust.c +++ b/source3/rpc_client/ntclienttrust.c @@ -34,7 +34,7 @@ extern int DEBUGLEVEL; check workstation trust account status ************************************************************************/ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host, - char *myhostname, char *domain, fstring mach_acct, + char *hostname, char *domain, fstring mach_acct, fstring new_mach_pwd) { pstring tmp; @@ -53,7 +53,7 @@ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host, char *change_mach_pwd; /* initial machine password */ - fstrcpy(mach_pwd, myhostname); + fstrcpy(mach_pwd, hostname); strlower(mach_pwd); slprintf(tmp, sizeof(tmp) - 1,"Enter Workstation Trust Account password for [%s].\nDefault is [%s].\nPassword:", @@ -91,9 +91,9 @@ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host, DEBUG(1,("server connect for cli_trust\n")); - if (!server_connect_init(&cli_trust, myhostname, dest_ip, dest_host)) + if (!server_connect_init(&cli_trust, hostname, dest_ip, dest_host)) { - cli_error(&cli_trust, &err_cls, &err_num); + cli_error(&cli_trust, &err_cls, &err_num, NULL); DEBUG(1,("server_connect_init failed (%s)\n", cli_errstr(&cli_trust))); cli_shutdown(&cli_trust); @@ -141,7 +141,7 @@ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host, return False; } - cli_error(&cli_trust, &err_cls, &err_num); + cli_error(&cli_trust, &err_cls, &err_num, NULL); if (err_num == (0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)) { -- cgit