From: Volker Lendecke Date: Wed, 9 Apr 2003 15:54:17 +0000 (+0000) Subject: This is the netlogon schannel client code. Try a X-Git-Tag: release-3-0alpha24~469 X-Git-Url: http://git.samba.org/samba.git/?p=tprouty%2Fsamba.git;a=commitdiff_plain;h=eaef0d8aeff1aa5a067679be3f17e08d7434e1e8 This is the netlogon schannel client code. Try a rpcclient -S pdc -U% -c "samlogon user password" and it should work with the schannel. Needs testing against platforms different from NT4SP6. Volker --- diff --git a/source/include/client.h b/source/include/client.h index 0ea793de68..d75effd7d0 100644 --- a/source/include/client.h +++ b/source/include/client.h @@ -132,6 +132,12 @@ struct cli_state { */ uint16 nt_pipe_fnum; /* Pipe handle. */ + + uint16 saved_netlogon_pipe_fnum; /* The "first" pipe to get + the session key for the + schannel. */ + struct netsec_auth_struct auth_info; + unsigned char sess_key[16]; /* Current session key. */ unsigned char ntlmssp_hash[258]; /* ntlmssp data. */ uint32 ntlmssp_cli_flgs; /* ntlmssp client flags */ diff --git a/source/include/smb.h b/source/include/smb.h index edd25fb44e..5baec705f5 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -187,6 +187,8 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN]; #define PIPE_SPOOLSS "\\PIPE\\spoolss" #define PIPE_NETDFS "\\PIPE\\netdfs" +#define PIPE_NETLOGON_PLAIN "\\NETLOGON" + #define PI_LSARPC 0 #define PI_LSARPC_DS 1 #define PI_SAMR 2 diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index d969193089..81b3bbcab5 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -275,6 +275,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->inbuf, 0, cli->bufsize); cli->nt_pipe_fnum = 0; + cli->saved_netlogon_pipe_fnum = 0; cli->initialised = 1; cli->allocated = alloced_cli; diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 807f8607f1..0c07f575c1 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -230,6 +230,7 @@ typedef struct BOOL bDomainLogons; BOOL bEncryptPasswords; BOOL bUpdateEncrypt; + int clientSchannel; int serverSchannel; BOOL bStripDot; BOOL bNullPasswords; @@ -736,6 +737,7 @@ static struct parm_struct parm_table[] = { {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER}, {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER}, + {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC}, {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC}, {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, @@ -1333,6 +1335,7 @@ static void init_globals(void) Globals.paranoid_server_security = True; Globals.bEncryptPasswords = True; Globals.bUpdateEncrypt = False; + Globals.clientSchannel = Auto; Globals.serverSchannel = Auto; Globals.bReadRaw = True; Globals.bWriteRaw = True; @@ -1662,6 +1665,7 @@ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions) FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot) FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords) FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt) +FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel) FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel) FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly) FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs) diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c index bbbf194fbd..c4a9b37127 100644 --- a/source/rpc_client/cli_pipe.c +++ b/source/rpc_client/cli_pipe.c @@ -191,6 +191,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int BOOL auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); BOOL auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0); + BOOL auth_schannel = (cli->saved_netlogon_pipe_fnum != 0); DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n", len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal))); @@ -293,6 +294,48 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int } cli->ntlmssp_seq_num++; } + + if (auth_schannel) { + RPC_AUTH_NETSEC_CHK chk; + char data[RPC_AUTH_NETSEC_CHK_LEN]; + char *dp = prs_data_p(rdata) + len - auth_len; + prs_struct auth_verf; + + if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + DEBUG(0,("rpc_auth_pipe: wrong auth len %d\n", auth_len)); + return False; + } + + 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 netsec\n")); + dump_data(100, dp, auth_len); + + memcpy(data, dp, sizeof(data)); + dump_data(100, data, sizeof(data)); + + prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL); + + /* The endinness must be preserved. JRA. */ + prs_set_endian_data( &auth_verf, rdata->bigendian_data); + + prs_give_memory(&auth_verf, data, RPC_AUTH_NETSEC_CHK_LEN, False); + + if (!smb_io_rpc_auth_netsec_chk("auth_sign", &chk, &auth_verf, 0)) { + DEBUG(0, ("rpc_auth_pipe: unmarshalling " + "RPC_AUTH_NETSECK_CHK failed\n")); + return False; + } + + if (!netsec_decode(&cli->auth_info, &chk, reply_data, data_len)) { + DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n")); + return False; + } + cli->auth_info.seq_num++; + } return True; } @@ -542,7 +585,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd ********************************************************************/ -static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_call_id, +static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netsec, uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, const char *my_name, const char *domain, uint32 neg_flags) { @@ -596,6 +639,43 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_ca auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN; } + if (do_netsec) { + RPC_HDR_AUTH hdr_auth; + RPC_AUTH_NETSEC_NEG netsec_neg; + + /* + * Create the auth structs we will marshall. + */ + + init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, + 0x00, 1); + init_rpc_auth_netsec_neg(&netsec_neg, my_name, domain); + + /* + * Use the 4k buffer to store the auth info. + */ + + prs_give_memory( &auth_info, buffer, sizeof(buffer), False); + + /* + * Now marshall the data into the temporary parse_struct. + */ + + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) { + DEBUG(0,("Failed to marshall RPC_HDR_AUTH.\n")); + return False; + } + + if(!smb_io_rpc_auth_netsec_neg("netsec_neg", + &netsec_neg, &auth_info, 0)) { + DEBUG(0,("Failed to marshall RPC_AUTH_NETSEC_NEG.\n")); + return False; + } + + /* 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 */ init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id, RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info), @@ -747,9 +827,9 @@ static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len */ if (auth_len != 0) - alloc_hint = data_left - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len; + alloc_hint = data_len - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len; else - alloc_hint = data_left - RPC_HEADER_LEN; + 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)); @@ -771,10 +851,10 @@ static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len } /******************************************************************* - Puts an auth header into an rpc request. + Puts an NTLMSSP auth header into an rpc request. ********************************************************************/ -static BOOL create_auth_hdr(prs_struct *outgoing_packet, BOOL auth_verify) +static BOOL create_ntlmssp_auth_hdr(prs_struct *outgoing_packet, BOOL auth_verify) { RPC_HDR_AUTH hdr_auth; @@ -789,6 +869,24 @@ static BOOL create_auth_hdr(prs_struct *outgoing_packet, BOOL auth_verify) return True; } +/******************************************************************* + Puts a NETLOGON schannel auth header into an rpc request. + ********************************************************************/ + +static BOOL create_netsec_auth_hdr(prs_struct *outgoing_packet, int padding) +{ + RPC_HDR_AUTH hdr_auth; + + init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, + NETSEC_AUTH_LEVEL, padding, 1); + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, + outgoing_packet, 0)) { + DEBUG(0,("create_auth_hdr:Failed to marshal RPC_HDR_AUTH.\n")); + return False; + } + return True; +} + /******************************************************************* Puts auth data into an rpc request. ********************************************************************/ @@ -825,19 +923,26 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, { uint32 auth_len, max_data, data_left, data_sent; BOOL ret = False; - BOOL auth_verify, auth_seal; + BOOL auth_verify, auth_seal, auth_schannel; fstring dump_name; auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0); + auth_schannel = (cli->saved_netlogon_pipe_fnum != 0); + + auth_len = 0; - auth_len = (auth_verify ? RPC_AUTH_NTLMSSP_CHK_LEN : 0); + if (auth_verify) + auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; + + if (auth_schannel) + auth_len = RPC_AUTH_NETSEC_CHK_LEN; /* * calc how much actual data we can send in a PDU fragment */ max_data = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - - (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len; + (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len - 8; for (data_left = prs_offset(data), data_sent = 0; data_left > 0;) { prs_struct outgoing_packet; @@ -845,13 +950,28 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, uint8 flags = 0; uint32 crc32 = 0; uint32 callid = 0; + uint32 auth_padding = 0; + RPC_AUTH_NETSEC_CHK verf; /* * how much will we send this time */ send_size = MIN(data_left, max_data); + + /* + * NT expects the data that is sealed to be 8-byte + * aligned. The padding must be encrypted as well and + * taken into account when generating the + * authentication verifier. The amount of padding must + * be stored in the auth header. + */ + + if (auth_schannel) + auth_padding = 8 - (send_size & 7); + data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + send_size + - (auth_verify ? RPC_HDR_AUTH_LEN : 0) + auth_len; + ((auth_verify|auth_schannel) ? RPC_HDR_AUTH_LEN : 0) + + auth_len + auth_padding; /* * Malloc parse struct to hold it (and enough for alignments). @@ -891,18 +1011,65 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, /* * Now copy the data into the outgoing packet. */ - if(!prs_append_some_prs_data(&outgoing_packet, data, - data_sent, send_size)) { - DEBUG(0,("rpc_api_pipe_req: Failed to append data to outgoing packet.\n")); - prs_mem_free(&outgoing_packet); - return False; + + if (auth_schannel) { + static const uchar netsec_sig[8] = NETSEC_SIGNATURE; + static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 }; + uchar sign[8]; + BOOL ret; + int i; + prs_struct netsec_blob; + + memset(sign, 0, sizeof(sign)); + sign[4] = 0x80; + + if (!prs_init(&netsec_blob, send_size+auth_padding, + cli->mem_ctx, MARSHALL)) { + DEBUG(0,("Could not malloc %u bytes", + send_size+auth_padding)); + prs_mem_free(&outgoing_packet); + return False; + } + + if(!prs_append_some_prs_data(&netsec_blob, data, + data_sent, send_size)) { + DEBUG(0,("Failed to append data to netsec blob\n")); + prs_mem_free(&outgoing_packet); + return False; + } + + netsec_blob.align = 8; + + if (!prs_align(&netsec_blob)) { + DEBUG(0,("Could not align netsec blob\n")); + prs_mem_free(&outgoing_packet); + return False; + } + + init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, + sign, nullbytes); + + netsec_encode(&(cli->auth_info), &verf, + prs_data_p(&netsec_blob), + prs_data_size(&netsec_blob)); + + prs_append_prs_data(&outgoing_packet, &netsec_blob); + prs_mem_free(&netsec_blob); + } else { + if(!prs_append_some_prs_data(&outgoing_packet, data, + data_sent, send_size)) { + DEBUG(0,("rpc_api_pipe_req: Failed to append " + "data to outgoing packet.\n")); + prs_mem_free(&outgoing_packet); + return False; + } } /* * Add a trailing auth_verifier if needed. */ if (auth_seal || auth_verify) { - if(!create_auth_hdr(&outgoing_packet, auth_verify)) { + if(!create_ntlmssp_auth_hdr(&outgoing_packet, auth_verify)) { prs_mem_free(&outgoing_packet); return False; } @@ -918,6 +1085,21 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, } } + if (auth_schannel) { + + if (!create_netsec_auth_hdr(&outgoing_packet, + auth_padding)) { + prs_mem_free(&outgoing_packet); + return False; + } + + if (!smb_io_rpc_auth_netsec_chk("", &verf, + &outgoing_packet, 0)) { + prs_mem_free(&outgoing_packet); + return False; + } + } + DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, prs_offset(&outgoing_packet))); @@ -1191,7 +1373,8 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 Do an rpc bind. ****************************************************************************/ -BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name) +static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name, + BOOL do_netsec) { RPC_IFACE abstract; RPC_IFACE transfer; @@ -1220,7 +1403,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name) rpc_call_id = get_rpc_call_id(); /* Marshall the outgoing data. */ - create_rpc_bind_req(&rpc_out, do_auth, rpc_call_id, + create_rpc_bind_req(&rpc_out, do_auth, do_netsec, rpc_call_id, &abstract, &transfer, global_myname(), cli->domain, cli->ntlmssp_cli_flgs); @@ -1310,7 +1493,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, pipe_idx, global_myname())) { + if (!rpc_pipe_bind(cli, pipe_idx, global_myname(), False)) { DEBUG(2,("cli_nt_session_open: rpc bind to %s failed\n", get_pipe_name_from_index(pipe_idx))); cli_close(cli, cli->nt_pipe_fnum); @@ -1340,6 +1523,106 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) } +/**************************************************************************** + Open a session to the NETLOGON pipe using schannel. + ****************************************************************************/ + +BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, + int sec_chan) +{ + NTSTATUS result; + uint32 neg_flags = 0x000001ff; + int fnum; + + if (lp_client_schannel() != False) + neg_flags |= NETLOGON_NEG_SCHANNEL; + + + if (!cli_nt_session_open(cli, PI_NETLOGON)) { + return False; + } + + if (!secrets_init()) { + DEBUG(3,("Failed to init secrets.tdb\n")); + return False; + } + + result = cli_nt_setup_creds(cli, sec_chan, trust_password, + &neg_flags, 2); + + if (!NT_STATUS_IS_OK(result)) { + cli_nt_session_close(cli); + return False; + } + + if ((lp_client_schannel() == True) && + ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { + + DEBUG(3, ("Server did not offer schannel\n")); + cli_nt_session_close(cli); + return False; + } + + if ((lp_client_schannel() == False) || + ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { + return True; + } + + /* Server offered schannel, so try it. */ + + cli->auth_info.seq_num = 0; + memcpy(cli->auth_info.sess_key, cli->sess_key, + sizeof(cli->auth_info.sess_key)); + + cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum; + + if (cli->capabilities & CAP_NT_SMBS) { + + /* If we open \\PIPE\NETLOGON here, NT4SP6 + gives us an ACCESS_DENIED. Do I have to + understand this? + */ + if ((fnum = cli_nt_create(cli, PIPE_NETLOGON_PLAIN, + DESIRED_ACCESS_PIPE)) == -1) { + DEBUG(0,("cli_nt_create failed to %s machine %s. " + "Error was %s\n", + PIPE_NETLOGON, cli->desthost, + cli_errstr(cli))); + return False; + } + + cli->nt_pipe_fnum = (uint16)fnum; + } else { + if ((fnum = cli_open(cli, PIPE_NETLOGON, + O_CREAT|O_RDWR, DENY_NONE)) == -1) { + DEBUG(0,("cli_open failed on pipe %s to machine %s. " + "Error was %s\n", + PIPE_NETLOGON, cli->desthost, + cli_errstr(cli))); + return False; + } + + cli->nt_pipe_fnum = (uint16)fnum; + + /**************** Set Named Pipe State ***************/ + if (!rpc_pipe_set_hnd_state(cli, PIPE_NETLOGON, 0x4300)) { + DEBUG(0,("Pipe hnd state failed. Error was %s\n", + cli_errstr(cli))); + cli_close(cli, cli->nt_pipe_fnum); + return False; + } + } + + if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname(), True)) { + DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON)); + cli_close(cli, cli->nt_pipe_fnum); + return False; + } + + return True; +} + + const char *cli_pipe_get_name(struct cli_state *cli) { return cli->pipe_name; @@ -1352,6 +1635,10 @@ close the session void cli_nt_session_close(struct cli_state *cli) { + if (cli->saved_netlogon_pipe_fnum != 0) { + cli_close(cli, cli->saved_netlogon_pipe_fnum); + cli->saved_netlogon_pipe_fnum = 0; + } cli_close(cli, cli->nt_pipe_fnum); cli->nt_pipe_fnum = 0; } diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c index 700ce8cfd6..656082e05a 100644 --- a/source/rpc_parse/parse_rpc.c +++ b/source/rpc_parse/parse_rpc.c @@ -1128,6 +1128,18 @@ BOOL smb_io_rpc_auth_ntlmssp_chk(const char *desc, RPC_AUTH_NTLMSSP_CHK *chk, pr return True; } +/******************************************************************* +creates an RPC_AUTH_NETSEC_NEG structure. +********************************************************************/ +void init_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg, + const char *domain, const char *myname) +{ + neg->unknown1 = 0; + neg->unknown2 = 0x13; + fstrcpy(neg->domain, domain); + fstrcpy(neg->myname, myname); +} + /******************************************************************* Reads or writes an RPC_AUTH_NETSEC_NEG structure. ********************************************************************/ @@ -1148,11 +1160,11 @@ BOOL smb_io_rpc_auth_netsec_neg(const char *desc, RPC_AUTH_NETSEC_NEG *neg, return False; if(!prs_uint32("unknown2", ps, depth, &neg->unknown2)) return False; - if(!prs_string("domain ", ps, depth, neg->domain, - strlen(&ps->data_p[ps->data_offset]), sizeof(neg->domain))) - return False; if(!prs_string("myname ", ps, depth, neg->myname, - strlen(&ps->data_p[ps->data_offset]), sizeof(neg->myname))) + strlen(neg->myname), sizeof(neg->myname))) + return False; + if(!prs_string("domain ", ps, depth, neg->domain, + strlen(neg->domain), sizeof(neg->domain))) return False; return True; diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c index 1421c4da26..e6ec28beab 100644 --- a/source/rpcclient/cmd_netlogon.c +++ b/source/rpcclient/cmd_netlogon.c @@ -296,25 +296,6 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli, if (argc == 6) sscanf(argv[5], "%i", &auth_level); - /* Authenticate ourselves with the domain controller */ - - if (!secrets_init()) { - fprintf(stderr, "Unable to initialise secrets database\n"); - return result; - } - - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, NULL)) { - fprintf(stderr, "could not fetch trust account password\n"); - goto done; - } - - result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, auth_level); - - if (!NT_STATUS_IS_OK(result)) { - fprintf(stderr, "Error initialising session creds\n"); - goto done; - } - /* Perform the sam logon */ result = cli_netlogon_sam_logon(cli, mem_ctx, username, password, logon_type); diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c index 2338d72f19..0cb4ba98c8 100644 --- a/source/rpcclient/rpcclient.c +++ b/source/rpcclient/rpcclient.c @@ -475,11 +475,28 @@ static NTSTATUS do_cmd(struct cli_state *cli, /* Open pipe */ - if (cmd_entry->pipe_idx != -1) - if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) { - DEBUG(0, ("Could not initialize pipe\n")); + if (cmd_entry->pipe_idx == PI_NETLOGON) { + uchar trust_password[16]; + + if (!secrets_fetch_trust_account_password(lp_workgroup(), + trust_password, + NULL)) { + return NT_STATUS_UNSUCCESSFUL; + } + + if (!cli_nt_open_netlogon(cli, trust_password, + SEC_CHAN_WKSTA)) { + DEBUG(0, ("Could not initialize NETLOGON pipe\n")); return NT_STATUS_UNSUCCESSFUL; } + } else { + if (cmd_entry->pipe_idx != -1) { + if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) { + DEBUG(0, ("Could not initialize pipe\n")); + return NT_STATUS_UNSUCCESSFUL; + } + } + } /* Run command */ diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c index 9367404b35..f811d76f68 100644 --- a/source/utils/net_rpc_samsync.c +++ b/source/utils/net_rpc_samsync.c @@ -209,19 +209,17 @@ int rpc_samdump(int argc, const char **argv) return 1; } - if (!cli_nt_session_open(cli, PI_NETLOGON)) { - DEBUG(0,("Error connecting to NETLOGON pipe\n")); - goto fail; - } + fstrcpy(cli->domain, lp_workgroup()); - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_password, NULL)) { - d_printf("Could not retrieve domain trust secret\n"); + if (!secrets_fetch_trust_account_password(lp_workgroup(), + trust_password, + NULL)) { + DEBUG(0,("Could not fetch trust account password\n")); goto fail; } - - result = cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_password, &neg_flags, 2); - if (!NT_STATUS_IS_OK(result)) { - d_printf("Failed to setup BDC creds\n"); + + if (!cli_nt_open_netlogon(cli, trust_password, SEC_CHAN_BDC)) { + DEBUG(0,("Error connecting to NETLOGON pipe\n")); goto fail; }