From fdeea341ed1bae670382e45eb731db1b5838ad21 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Mar 1998 21:11:04 +0000 Subject: "For I have laboured mightily on Luke's code, and hath broken all I saw" - the book of Jeremy, chapter 1 :-). So here is the mega-merge of the NTDOM branch server code. It doesn't include the new client side pieces, we'll look at that later. This should give the same functionality, server wise, as the NTDOM branch does, only merged into the main branch. Any fixes to domain controler functionality should be added to the main branch, not the NTDOM branch. This code compiles without warnings on gcc2.8, but will need further testing before we are sure all the working functionality of the NTDOM server branch has been correctly carried over. I hereby declare the server side of the NTDOM branch dead (and all who sail in her :-). Jeremy. (This used to be commit 118ba4d77a33248e762a2cf843fb7cbc906ee6e7) --- source3/rpc_client/cli_pipe.c | 683 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 683 insertions(+) create mode 100644 source3/rpc_client/cli_pipe.c (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c new file mode 100644 index 0000000000..625b774167 --- /dev/null +++ b/source3/rpc_client/cli_pipe.c @@ -0,0 +1,683 @@ + +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-1998, + * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, + * Copyright (C) Paul Ashton 1998. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" + +extern int DEBUGLEVEL; + + +extern struct pipe_id_info pipe_names[]; + +/******************************************************************** + rpc pipe call id + ********************************************************************/ +uint32 get_rpc_call_id(void) +{ + static uint32 call_id = 1; + return ++call_id; +} + +/******************************************************************* + uses SMBreadX to get rest of rpc data + ********************************************************************/ +static BOOL rpc_read(struct cli_state *cli, int t_idx, uint16 fnum, + prs_struct *rdata, uint32 data_to_read) +{ + uint32 data_offset = rdata->data->data_used; + int size = 512; + int num_read; + char *data = rdata->data->data; + uint32 err; + data += rdata->data->data_used; + + if (data_offset + data_to_read > rdata->data->data_size) + { + mem_grow_data(&rdata->data, True, rdata->data->data_used + data_to_read); + DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used)); + } + + do /* read data using SMBreadX */ + { + if (size > data_to_read) size = data_to_read; + + if (data_offset + size > rdata->data->data_size) + { + mem_grow_data(&rdata->data, True, rdata->data->data_used + size); + DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used)); + } + + num_read = cli_readx(cli, t_idx, fnum, data, data_offset, size); + + DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n", + data_offset, num_read, data_to_read)); + + data_to_read -= num_read; + data_offset += num_read; + data += num_read; + + if (cli_error(cli, NULL, &err)) return False; + + } while (num_read > 0 && data_to_read > 0); /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ + + mem_realloc_data(rdata->data, rdata->data->data_used); + rdata->data->offset.end = rdata->data->data_used; + + DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read)); + + return data_to_read == 0; +} + +/**************************************************************************** + checks the header + ****************************************************************************/ +static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, + BOOL *first, BOOL *last, uint32 *len) +{ + RPC_HDR rhdr; + + smb_io_rpc_hdr ("rpc_hdr ", &rhdr , rdata, 0); + + if (!rdata->offset || rdata->offset != 0x10) + { + DEBUG(5,("cli_pipe: error in rpc header\n")); + 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; + (*pkt_type) = rhdr.pkt_type; + + return True; +} + +/**************************************************************************** + 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 + bit, then SMBreadX for subsequent bits. + + 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...] + + ****************************************************************************/ +BOOL rpc_api_pipe(struct cli_state *cli, int t_idx, + uint16 cmd, uint16 fnum, + prs_struct *param , prs_struct *data, + prs_struct *rparam, prs_struct *rdata) +{ + uint32 len; + + uint16 setup[2]; /* only need 2 uint16 setup parameters */ + uint32 err; + uint8 pkt_type = 0xff; + BOOL first = True; + BOOL last = True; + + /* prepare return data and params */ + + /* create setup parameters. */ + setup[0] = cmd; + setup[1] = fnum; /* pipe file handle. got this from an SMBcreateX. */ + + /* send the data: receive a response. */ + if (!cli_api_pipe(cli, t_idx, "\\PIPE\\\0\0\0", 8, + + param != NULL ? param->data->data_used : 0, + data != NULL ? data ->data->data_used : 0, + 2, + + 0, + data != NULL ? 1024 : 0 , + + param != NULL ? param->data->data : NULL, + data != NULL ? data ->data->data : NULL, + setup, + + rparam != NULL ? rparam->data : NULL, + rdata != NULL ? rdata ->data : NULL)) + { + DEBUG(5, ("cli_pipe: return critical error\n")); + return False; + } + + if (cli_error(cli, NULL, &err)) return False; + + if (rdata->data->data == NULL) return False; + + /**** parse the header: check it's a response record */ + + rdata->data->offset.start = 0; + rdata->data->offset.end = rdata->data->data_used; + rdata->offset = 0; + + if (!rpc_check_hdr(rdata, &pkt_type, &first, &last, &len)) return False; + + if (pkt_type == RPC_RESPONSE) + { + RPC_HDR_RR rhdr_rr; + smb_io_rpc_hdr_rr("rpc_hdr_rr", &rhdr_rr, rdata, 0); + } + + if (first && last) + { + DEBUG(6,("rpc_api_pipe: fragment first and last both set\n")); + return True; + } + + /* 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 < rdata->data->data_used) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */ + { + if (!rpc_read(cli, t_idx, fnum, rdata, len)) return False; + } + + /* only one rpc fragment, and it has been read */ + if (first && last) return True; + + while (!last) /* read more fragments until we get the last one */ + { + RPC_HDR rhdr; + RPC_HDR_RR rhdr_rr; + int num_read; + prs_struct hps; + + prs_init(&hps, 0x18, 4, 0, True); + + num_read = cli_readx(cli, t_idx, fnum, hps.data->data, 0, 0x18); + DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); + + if (num_read != 0x18) return False; + + smb_io_rpc_hdr ("rpc_hdr ", &rhdr , &hps, 0); + smb_io_rpc_hdr_rr("rpc_hdr_rr", &rhdr_rr, &hps, 0); + + prs_mem_free(&hps); + + if (cli_error(cli, NULL, &err)) return False; + + first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST); + last = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST ); + + if (first) + { + DEBUG(4,("rpc_api_pipe: wierd rpc header received\n")); + return False; + } + + len = rhdr.frag_len - hps.offset; + if (!rpc_read(cli, t_idx, fnum, rdata, len)) 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. + + ********************************************************************/ +static BOOL create_rpc_bind_req(prs_struct *rhdr, + prs_struct *rhdr_rb, + prs_struct *auth_req, + RPC_IFACE *abstract, RPC_IFACE *transfer, + char *my_name, char *domain) +{ + RPC_HDR_RB hdr_rb; + RPC_HDR hdr; + RPC_AUTH_NTLMSSP_REQ ntlmssp_req; + + /* create the bind request RPC_HDR_RB */ + make_rpc_hdr_rb(&hdr_rb, + 0x1630, 0x1630, 0x0, + 0x1, 0x0, 0x1, + abstract, transfer); + + /* 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 (auth_req != NULL) + { + make_rpc_auth_ntlmssp_req(&ntlmssp_req, + "NTLMSSP", 0x1, + 0x0000b2b3, + my_name, domain); + smb_io_rpc_auth_ntlmssp_req("", &ntlmssp_req, auth_req, 0); + mem_realloc_data(auth_req->data, auth_req->offset); + } + + /* create the request RPC_HDR */ + make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(), + rhdr_rb->offset, + auth_req != NULL ? auth_req->offset : 0); + + smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0); + mem_realloc_data(rhdr->data, rhdr->offset); + + if (rhdr->data == NULL || rhdr_rb->data == NULL) return False; + + /***/ + /*** link rpc header, bind acknowledgment and authentication responses ***/ + /***/ + + rhdr->data->offset.start = 0; + rhdr->data->offset.end = rhdr->offset; + rhdr->data->next = rhdr_rb->data; + + if (auth_req != NULL) + { + rhdr_rb->data->offset.start = rhdr->offset; + rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; + rhdr_rb->data->next = auth_req->data; + + auth_req->data->offset.start = rhdr->offset + rhdr_rb->offset; + auth_req->data->offset.end = rhdr->offset + auth_req->offset + rhdr_rb->offset; + auth_req->data->next = NULL; + } + else + { + rhdr_rb->data->offset.start = rhdr->offset; + rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; + rhdr_rb->data->next = NULL; + } + + 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. + + ********************************************************************/ +static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len) +{ + RPC_HDR_RR hdr_rr; + RPC_HDR hdr; + + 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, + get_rpc_call_id(), data_len + 0x18, 0); + + /* create the rpc request RPC_HDR_RR */ + make_rpc_hdr_rr(&hdr_rr, data_len, op_num); + + /* stream-time... */ + smb_io_rpc_hdr ("hdr" , &hdr , rhdr, 0); + smb_io_rpc_hdr_rr("hdr_rr", &hdr_rr, rhdr, 0); + + if (rhdr->data == NULL || rhdr->offset != 0x18) return False; + + rhdr->data->offset.start = 0; + rhdr->data->offset.end = rhdr->offset; + + return True; +} + + +/**************************************************************************** + send a request on an rpc pipe. + ****************************************************************************/ +BOOL rpc_api_pipe_req(struct cli_state *cli, int t_idx, uint16 fnum, + uint8 op_num, + prs_struct *data, prs_struct *rdata) +{ + /* fudge this, at the moment: create the header; memcpy the data. oops. */ + prs_struct rparam; + prs_struct hdr; + int data_len; + BOOL ret; + + data_len = data->offset + 0x18; + data->data->offset.end = data->offset; + + prs_init(&hdr , data_len, 4, SAFETY_MARGIN, False); + prs_init(&rparam, 0 , 4, 0 , True ); + + create_rpc_request(&hdr, op_num, data_len); + + mem_realloc_data(hdr.data, data_len); + hdr.data->offset.end = data_len; + mem_buf_copy(mem_data(&(hdr.data), 0x18), data->data, 0, data->offset); + + ret = rpc_api_pipe(cli, t_idx, 0x0026, fnum, NULL, &hdr, &rparam, rdata); + + prs_mem_free(&rparam); + prs_mem_free(&hdr); + + return ret; +} + + +/**************************************************************************** +do an rpc bind +****************************************************************************/ +BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, int t_idx, + char *pipe_name, uint16 fnum, uint16 device_state) +{ + prs_struct param; + prs_struct rdata; + prs_struct rparam; + BOOL state_set = False; + uint16 setup[2]; /* only need 2 uint16 setup parameters */ + + if (pipe_name == NULL) return False; + + prs_init(¶m , 2, 4, 0 , False); + prs_init(&rdata , 0, 4, SAFETY_MARGIN, True ); + prs_init(&rparam, 0, 4, SAFETY_MARGIN, True ); + + param.data->offset.start = 0; + param.data->offset.end = 2; + + DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", + fnum, pipe_name, device_state)); + + /* create data parameters: device state */ + SSVAL(param.data->data, 0, device_state); + + /* create setup parameters. */ + setup[0] = 0x0001; + setup[1] = fnum; /* pipe file handle. got this from an SMBcreateX. */ + + /* send the data on \PIPE\ */ + if (cli_api_pipe(cli, t_idx, "\\PIPE\\\0\0\0", 8, + + 2, 0, 2, + + 0, 1024, + + param.data->data, NULL, setup, + + rparam.data, rdata.data)) + { + DEBUG(5, ("Set Handle state: return OK\n")); + state_set = True; + } + + prs_mem_free(¶m ); + prs_mem_free(&rparam); + prs_mem_free(&rdata ); + + return state_set; +} + +/**************************************************************************** + check the rpc bind acknowledge response +****************************************************************************/ +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 (strcmp(pipe_name, pipe_names[pipe_idx].client_pipe ) == 0) + { + DEBUG(5,("Bind Abstract Syntax: ")); + dump_data(5, (uchar*)&(pipe_names[pipe_idx].abstr_syntax), sizeof(pipe_names[pipe_idx].abstr_syntax)); + DEBUG(5,("Bind Transfer Syntax: ")); + dump_data(5, (uchar*)&(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)); + + return True; + } + pipe_idx++; + }; + + DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name)); + return False; +} + +/**************************************************************************** + check the rpc bind acknowledge response +****************************************************************************/ +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)) + { + DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n", + pipe_names[i].client_pipe , pipe_names[i].server_pipe )); + + if ((strcmp(pipe_name, pipe_names[i].client_pipe ) == 0)) + { + if (strcmp(hdr_ba->addr.str, pipe_names[i].server_pipe ) == 0) + { + DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", + pipe_names[i].server_pipe )); + break; + } + else + { + DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n", + pipe_names[i].server_pipe , hdr_ba->addr.str)); + return False; + } + } + else + { + i++; + } + } + + 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))) + { + DEBUG(2,("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) + { + DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n", + hdr_ba->res.num_results, + hdr_ba->res.reason)); + } + + DEBUG(5,("bind_rpc_pipe: accepted!\n")); + return True; +} + +/**************************************************************************** +do an rpc bind +****************************************************************************/ +BOOL rpc_pipe_bind(struct cli_state *cli, int t_idx, char *pipe_name, uint16 fnum, + RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth, + char *my_name, char *domain) +{ + prs_struct hdr; + prs_struct hdr_rb; + prs_struct auth_req; + prs_struct data; + prs_struct rdata; + prs_struct rparam; + + BOOL valid_ack = False; + + if (pipe_name == NULL || abstract == NULL || transfer == NULL) return False; + + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name)); + + if (!valid_pipe_name(pipe_name, abstract, transfer)) return False; + + prs_init(&hdr , 0x10 , 4, 0x0 , False); + prs_init(&hdr_rb , 1024 , 4, SAFETY_MARGIN, False); + prs_init(&auth_req, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False); + + prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True ); + prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True ); + + create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL, + abstract, transfer, + my_name, domain); + + /* 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)); + + /* send data on \PIPE\. receive a response */ + if (rpc_api_pipe(cli, t_idx, 0x0026, fnum, NULL, &data, &rparam, &rdata)) + { + RPC_HDR_BA hdr_ba; + + DEBUG(5, ("rpc_api_pipe: return OK\n")); + + smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0); + + if (rdata.offset != 0) valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer); + } + + prs_mem_free(&data ); + prs_mem_free(&hdr ); + prs_mem_free(&hdr_rb ); + prs_mem_free(&auth_req); + prs_mem_free(&rdata ); + prs_mem_free(&rparam ); + + return valid_ack; +} + +/**************************************************************************** + open a session + ****************************************************************************/ +BOOL do_session_open(struct cli_state *cli, int t_idx, + char *pipe_name, uint16 *fnum) +{ + RPC_IFACE abstract; + RPC_IFACE transfer; + + + /******************* open the pipe *****************/ + if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_RDONLY, DENY_NONE, + NULL, NULL, NULL)) == 0xffff) + { + DEBUG(1,("do_session_open: cli_open failed\n")); + return False; + } + + /**************** Set Named Pipe State ***************/ + if (!rpc_pipe_set_hnd_state(cli, t_idx, pipe_name, (*fnum), 0x4300)) + { + DEBUG(1,("do_session_open: pipe hnd state failed\n")); + return False; + } + + /******************* bind request on pipe *****************/ + if (!rpc_pipe_bind(cli, t_idx, pipe_name, (*fnum), + &abstract, &transfer, + False, NULL, NULL)) + { + DEBUG(1,("do_session_open: rpc bind failed\n")); + return False; + } + + return True; +} + + +/**************************************************************************** + open an encrypted session + ****************************************************************************/ +BOOL do_ntlm_session_open(struct cli_state *cli, int t_idx, + char *pipe_name, uint16 *fnum, + char *my_name, char *domain) +{ + RPC_IFACE abstract; + RPC_IFACE transfer; + + /******************* open the pipe *****************/ + if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_RDONLY, DENY_NONE, + NULL, NULL, NULL)) == 0xffff) + { + DEBUG(1,("do_ntlm_session_open: cli_open failed\n")); + return False; + } + + /**************** Set Named Pipe State ***************/ + if (!rpc_pipe_set_hnd_state(cli, t_idx, pipe_name, (*fnum), 0x4300)) + { + DEBUG(1,("do_ntlm_session_open: pipe hnd state failed\n")); + return False; + } + + /******************* bind request on pipe *****************/ + if (!rpc_pipe_bind(cli, t_idx, pipe_name, (*fnum), + &abstract, &transfer, + True, my_name, domain)) + { + DEBUG(1,("do_ntlm_session_open: rpc bind failed\n")); + return False; + } + + return True; +} + + +/**************************************************************************** +close the session +****************************************************************************/ +void do_session_close(struct cli_state *cli, int t_idx, uint16 fnum) +{ + if (fnum != 0xffff) + { + cli_close(cli, t_idx, fnum, 0); + } +} + -- cgit From 76d3bc36a5ce13d2a7bd08f9c18b2cfd0ab0210f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 21 Apr 1998 02:36:37 +0000 Subject: put server-side long dce/rpc code in main branch. (This used to be commit 2e1a08b28c1c0c9ea988a09067cd149926f25c69) --- source3/rpc_client/cli_pipe.c | 95 ++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 41 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 625b774167..91ba8a263e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -47,18 +47,24 @@ uint32 get_rpc_call_id(void) uses SMBreadX to get rest of rpc data ********************************************************************/ static BOOL rpc_read(struct cli_state *cli, int t_idx, uint16 fnum, - prs_struct *rdata, uint32 data_to_read) + prs_struct *rdata, uint32 data_to_read, uint32 rdata_offset) { - uint32 data_offset = rdata->data->data_used; - int size = 512; + int size = 0x1630; + int file_offset = rdata_offset; int num_read; char *data = rdata->data->data; uint32 err; - data += rdata->data->data_used; + uint32 new_data_size = rdata->data->data_used + data_to_read; + data += rdata_offset; - if (data_offset + data_to_read > rdata->data->data_size) + file_offset -= rdata_offset; + + DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n", + data_to_read, rdata_offset, file_offset)); + + if (new_data_size > rdata->data->data_size) { - mem_grow_data(&rdata->data, True, rdata->data->data_used + data_to_read); + mem_grow_data(&rdata->data, True, new_data_size, True); DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used)); } @@ -66,27 +72,29 @@ static BOOL rpc_read(struct cli_state *cli, int t_idx, uint16 fnum, { if (size > data_to_read) size = data_to_read; - if (data_offset + size > rdata->data->data_size) + new_data_size = rdata->data->data_used + size; + + if (new_data_size > rdata->data->data_size) { - mem_grow_data(&rdata->data, True, rdata->data->data_used + size); + mem_grow_data(&rdata->data, True, new_data_size, True); DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used)); } - num_read = cli_readx(cli, t_idx, fnum, data, data_offset, size); + num_read = cli_readx(cli, t_idx, fnum, data, file_offset + 0x100000, size); DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n", - data_offset, num_read, data_to_read)); + file_offset, num_read, data_to_read)); data_to_read -= num_read; - data_offset += num_read; + file_offset += num_read; data += num_read; if (cli_error(cli, NULL, &err)) return False; } while (num_read > 0 && data_to_read > 0); /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ - mem_realloc_data(rdata->data, rdata->data->data_used); - rdata->data->offset.end = rdata->data->data_used; + mem_realloc_data(rdata->data, file_offset + rdata_offset); + rdata->data->offset.end = file_offset + rdata_offset; DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read)); @@ -97,10 +105,12 @@ static BOOL rpc_read(struct cli_state *cli, int t_idx, uint16 fnum, checks the header ****************************************************************************/ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, - BOOL *first, BOOL *last, uint32 *len) + BOOL *first, BOOL *last, int *len) { RPC_HDR rhdr; + DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used)); + smb_io_rpc_hdr ("rpc_hdr ", &rhdr , rdata, 0); if (!rdata->offset || rdata->offset != 0x10) @@ -109,6 +119,8 @@ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, return False; } + DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n", 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 ) = rhdr.frag_len - rdata->data->data_used; @@ -139,7 +151,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, int t_idx, prs_struct *param , prs_struct *data, prs_struct *rparam, prs_struct *rdata) { - uint32 len; + int len; uint16 setup[2]; /* only need 2 uint16 setup parameters */ uint32 err; @@ -188,30 +200,31 @@ BOOL rpc_api_pipe(struct cli_state *cli, int t_idx, if (pkt_type == RPC_RESPONSE) { - RPC_HDR_RR rhdr_rr; - smb_io_rpc_hdr_rr("rpc_hdr_rr", &rhdr_rr, rdata, 0); + RPC_HDR_RESP rhdr_resp; + smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0); } - if (first && last) - { - DEBUG(6,("rpc_api_pipe: fragment first and last both set\n")); - return True; - } + 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 < rdata->data->data_used) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */ + if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */ { - if (!rpc_read(cli, t_idx, fnum, rdata, len)) return False; + if (!rpc_read(cli, t_idx, fnum, rdata, len, rdata->data->data_used)) return False; } /* only one rpc fragment, and it has been read */ - if (first && last) return True; + 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 */ { - RPC_HDR rhdr; - RPC_HDR_RR rhdr_rr; + RPC_HDR rhdr; + RPC_HDR_RESP rhdr_resp; int num_read; prs_struct hps; @@ -222,8 +235,8 @@ BOOL rpc_api_pipe(struct cli_state *cli, int t_idx, if (num_read != 0x18) return False; - smb_io_rpc_hdr ("rpc_hdr ", &rhdr , &hps, 0); - smb_io_rpc_hdr_rr("rpc_hdr_rr", &rhdr_rr, &hps, 0); + smb_io_rpc_hdr ("rpc_hdr ", &rhdr , &hps, 0); + smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0); prs_mem_free(&hps); @@ -239,7 +252,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, int t_idx, } len = rhdr.frag_len - hps.offset; - if (!rpc_read(cli, t_idx, fnum, rdata, len)) return False; + if (!rpc_read(cli, t_idx, fnum, rdata, len, rdata->data->data_used)) return False; } return True; @@ -332,22 +345,22 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, ********************************************************************/ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len) { - RPC_HDR_RR hdr_rr; - RPC_HDR hdr; + RPC_HDR_REQ hdr_req; + RPC_HDR hdr; DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n", - op_num, data_len)); + op_num, data_len)); /* create the rpc header RPC_HDR */ - make_rpc_hdr (&hdr , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST, - get_rpc_call_id(), data_len + 0x18, 0); + make_rpc_hdr(&hdr , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST, + get_rpc_call_id(), data_len + 0x18, 0); - /* create the rpc request RPC_HDR_RR */ - make_rpc_hdr_rr(&hdr_rr, data_len, op_num); + /* create the rpc request RPC_HDR_REQ */ + make_rpc_hdr_req(&hdr_req, data_len, op_num); /* stream-time... */ - smb_io_rpc_hdr ("hdr" , &hdr , rhdr, 0); - smb_io_rpc_hdr_rr("hdr_rr", &hdr_rr, rhdr, 0); + smb_io_rpc_hdr ("hdr ", &hdr , rhdr, 0); + smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0); if (rhdr->data == NULL || rhdr->offset != 0x18) return False; @@ -605,7 +618,7 @@ BOOL do_session_open(struct cli_state *cli, int t_idx, /******************* open the pipe *****************/ - if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_RDONLY, DENY_NONE, + if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_WRONLY, DENY_NONE, NULL, NULL, NULL)) == 0xffff) { DEBUG(1,("do_session_open: cli_open failed\n")); @@ -643,7 +656,7 @@ BOOL do_ntlm_session_open(struct cli_state *cli, int t_idx, RPC_IFACE transfer; /******************* open the pipe *****************/ - if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_RDONLY, DENY_NONE, + if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_WRONLY, DENY_NONE, NULL, NULL, NULL)) == 0xffff) { DEBUG(1,("do_ntlm_session_open: cli_open failed\n")); -- cgit From d5114f624591c55a75d86a1efec3378fd4c9ef5a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Apr 1998 22:45:53 +0000 Subject: These don't compile yet - but they are the core code in what will be DOMAIN_CLIENT called code. Jeremy. (This used to be commit ad81735fa1ce02937f6aae3d6518c1cd6156b090) --- source3/rpc_client/cli_pipe.c | 964 +++++++++++++++++++++--------------------- 1 file changed, 486 insertions(+), 478 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 91ba8a263e..e4853f8da9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -30,103 +30,109 @@ #include "includes.h" extern int DEBUGLEVEL; - - extern struct pipe_id_info pipe_names[]; /******************************************************************** rpc pipe call id ********************************************************************/ + uint32 get_rpc_call_id(void) { - static uint32 call_id = 1; - return ++call_id; + static uint32 call_id = 1; + return ++call_id; } /******************************************************************* uses SMBreadX to get rest of rpc data ********************************************************************/ -static BOOL rpc_read(struct cli_state *cli, int t_idx, uint16 fnum, - prs_struct *rdata, uint32 data_to_read, uint32 rdata_offset) + +static BOOL rpc_read(struct cli_state *cli, uint16 fnum, + prs_struct *rdata, uint32 data_to_read, + uint32 rdata_offset) { - int size = 0x1630; - int file_offset = rdata_offset; - int num_read; - char *data = rdata->data->data; - uint32 err; - uint32 new_data_size = rdata->data->data_used + data_to_read; - data += rdata_offset; + int size = 0x1630; + int file_offset = rdata_offset; + int num_read; + char *data = rdata->data->data; + uint32 err; + uint32 new_data_size = rdata->data->data_used + data_to_read; + + data += rdata_offset; - file_offset -= rdata_offset; + file_offset -= rdata_offset; - 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: %d data offset: %d file offset: %d\n", + data_to_read, rdata_offset, file_offset)); - 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)); - } + 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)); + } - do /* read data using SMBreadX */ - { - if (size > data_to_read) size = data_to_read; + do /* read data using SMBreadX */ + { + if (size > data_to_read) + size = data_to_read; - new_data_size = rdata->data->data_used + size; + new_data_size = rdata->data->data_used + 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)); - } + 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)); + } - num_read = cli_readx(cli, t_idx, fnum, data, file_offset + 0x100000, size); + num_read = cli_read(cli, fnum, data, file_offset + 0x100000, 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: read offset: %d read: %d to read: %d\n", + file_offset, num_read, data_to_read)); - data_to_read -= num_read; - file_offset += num_read; - data += num_read; + data_to_read -= num_read; + file_offset += num_read; + data += num_read; - if (cli_error(cli, NULL, &err)) return False; + if (cli_error(cli, NULL, &err)) + return False; - } while (num_read > 0 && data_to_read > 0); /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ + } while (num_read > 0 && data_to_read > 0); + /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ - mem_realloc_data(rdata->data, file_offset + rdata_offset); - rdata->data->offset.end = file_offset + rdata_offset; + mem_realloc_data(rdata->data, file_offset + rdata_offset); + rdata->data->offset.end = file_offset + rdata_offset; - DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read)); + DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read)); - return data_to_read == 0; + return data_to_read == 0; } /**************************************************************************** checks the header ****************************************************************************/ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, - BOOL *first, BOOL *last, int *len) + BOOL *first, BOOL *last, int *len) { - RPC_HDR rhdr; + RPC_HDR rhdr; - DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used)); + DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used)); - smb_io_rpc_hdr ("rpc_hdr ", &rhdr , rdata, 0); + smb_io_rpc_hdr ("rpc_hdr ", &rhdr , rdata, 0); - if (!rdata->offset || rdata->offset != 0x10) - { - DEBUG(5,("cli_pipe: error in rpc header\n")); - return False; - } + if (!rdata->offset || rdata->offset != 0x10) + { + DEBUG(5,("cli_pipe: error in rpc header\n")); + return False; + } - DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n", rdata->data->data_used)); + DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n", + 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 ) = rhdr.frag_len - rdata->data->data_used; - (*pkt_type) = rhdr.pkt_type; + (*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; + (*pkt_type) = rhdr.pkt_type; - return True; + return True; } /**************************************************************************** @@ -146,116 +152,119 @@ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, down. in other words, state-based (kernel) techniques...] ****************************************************************************/ -BOOL rpc_api_pipe(struct cli_state *cli, int t_idx, - uint16 cmd, uint16 fnum, - prs_struct *param , prs_struct *data, - prs_struct *rparam, prs_struct *rdata) -{ - int len; - uint16 setup[2]; /* only need 2 uint16 setup parameters */ - uint32 err; - uint8 pkt_type = 0xff; - BOOL first = True; - BOOL last = True; +BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 fnum, + prs_struct *param , prs_struct *data, + prs_struct *rparam, prs_struct *rdata) +{ + int len; - /* prepare return data and params */ + uint16 setup[2]; /* only need 2 uint16 setup parameters */ + uint32 err; + uint8 pkt_type = 0xff; + BOOL first = True; + BOOL last = True; - /* create setup parameters. */ - setup[0] = cmd; - setup[1] = fnum; /* pipe file handle. got this from an SMBcreateX. */ + /* prepare return data and params */ - /* send the data: receive a response. */ - if (!cli_api_pipe(cli, t_idx, "\\PIPE\\\0\0\0", 8, + /* create setup parameters. */ + setup[0] = cmd; + setup[1] = fnum; /* pipe file handle. got this from an SMBcreateX. */ + /* send the data: receive a response. */ + if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, param != NULL ? param->data->data_used : 0, data != NULL ? data ->data->data_used : 0, 2, - 0, data != NULL ? 1024 : 0 , - param != NULL ? param->data->data : NULL, data != NULL ? data ->data->data : NULL, setup, - rparam != NULL ? rparam->data : NULL, rdata != NULL ? rdata ->data : NULL)) - { - DEBUG(5, ("cli_pipe: return critical error\n")); - return False; - } + { + DEBUG(5, ("cli_pipe: return critical error\n")); + return False; + } - if (cli_error(cli, NULL, &err)) return False; + if (cli_error(cli, NULL, &err)) + return False; - if (rdata->data->data == NULL) return False; + if (rdata->data->data == NULL) + return False; - /**** parse the header: check it's a response record */ + /**** parse the header: check it's a response record */ - rdata->data->offset.start = 0; - rdata->data->offset.end = rdata->data->data_used; - rdata->offset = 0; + rdata->data->offset.start = 0; + rdata->data->offset.end = rdata->data->data_used; + rdata->offset = 0; - if (!rpc_check_hdr(rdata, &pkt_type, &first, &last, &len)) return False; + if (!rpc_check_hdr(rdata, &pkt_type, &first, &last, &len)) + return False; + + if (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: %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)) + 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; + } + + while (!last) /* read more fragments until we get the last one */ + { + RPC_HDR rhdr; + RPC_HDR_RESP rhdr_resp; + int num_read; + prs_struct hps; + + prs_init(&hps, 0x18, 4, 0, True); - if (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: %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, t_idx, fnum, rdata, len, rdata->data->data_used)) 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; - } - - while (!last) /* read more fragments until we get the last one */ - { - RPC_HDR rhdr; - RPC_HDR_RESP rhdr_resp; - int num_read; - prs_struct hps; - - prs_init(&hps, 0x18, 4, 0, True); - - num_read = cli_readx(cli, t_idx, fnum, hps.data->data, 0, 0x18); - DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); - - if (num_read != 0x18) return False; - - smb_io_rpc_hdr ("rpc_hdr ", &rhdr , &hps, 0); - smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0); - - prs_mem_free(&hps); - - if (cli_error(cli, NULL, &err)) return False; - - first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST); - last = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST ); - - if (first) - { - DEBUG(4,("rpc_api_pipe: wierd rpc header received\n")); - return False; - } - - len = rhdr.frag_len - hps.offset; - if (!rpc_read(cli, t_idx, fnum, rdata, len, rdata->data->data_used)) return False; - } - - return True; + num_read = cli_read(cli, fnum, hps.data->data, 0, 0x18); + DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); + + if (num_read != 0x18) + return False; + + smb_io_rpc_hdr ("rpc_hdr ", &rhdr , &hps, 0); + smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0); + + prs_mem_free(&hps); + + if (cli_error(cli, NULL, &err)) + return False; + + first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST); + last = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST ); + + if (first) + { + DEBUG(4,("rpc_api_pipe: wierd rpc header received\n")); + return False; + } + + len = rhdr.frag_len - hps.offset; + if (!rpc_read(cli, fnum, rdata, len, rdata->data->data_used)) + return False; + } + + return True; } /******************************************************************* @@ -266,72 +275,72 @@ BOOL rpc_api_pipe(struct cli_state *cli, int t_idx, - 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 *auth_req, - RPC_IFACE *abstract, RPC_IFACE *transfer, - char *my_name, char *domain) + prs_struct *rhdr_rb, + prs_struct *auth_req, + RPC_IFACE *abstract, RPC_IFACE *transfer, + char *my_name, char *domain) { - RPC_HDR_RB hdr_rb; - RPC_HDR hdr; - RPC_AUTH_NTLMSSP_REQ ntlmssp_req; - - /* create the bind request RPC_HDR_RB */ - make_rpc_hdr_rb(&hdr_rb, - 0x1630, 0x1630, 0x0, - 0x1, 0x0, 0x1, - abstract, transfer); - - /* 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 (auth_req != NULL) - { - make_rpc_auth_ntlmssp_req(&ntlmssp_req, - "NTLMSSP", 0x1, - 0x0000b2b3, - my_name, domain); - smb_io_rpc_auth_ntlmssp_req("", &ntlmssp_req, auth_req, 0); - mem_realloc_data(auth_req->data, auth_req->offset); - } - - /* create the request RPC_HDR */ - make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(), - rhdr_rb->offset, - auth_req != NULL ? auth_req->offset : 0); - - smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0); - mem_realloc_data(rhdr->data, rhdr->offset); - - if (rhdr->data == NULL || rhdr_rb->data == NULL) return False; - - /***/ - /*** link rpc header, bind acknowledgment and authentication responses ***/ - /***/ - - rhdr->data->offset.start = 0; - rhdr->data->offset.end = rhdr->offset; - rhdr->data->next = rhdr_rb->data; - - if (auth_req != NULL) - { - rhdr_rb->data->offset.start = rhdr->offset; - rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; - rhdr_rb->data->next = auth_req->data; - - auth_req->data->offset.start = rhdr->offset + rhdr_rb->offset; - auth_req->data->offset.end = rhdr->offset + auth_req->offset + rhdr_rb->offset; - auth_req->data->next = NULL; - } - else - { - rhdr_rb->data->offset.start = rhdr->offset; - rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; - rhdr_rb->data->next = NULL; - } - - return True; + RPC_HDR_RB hdr_rb; + RPC_HDR hdr; + RPC_AUTH_NTLMSSP_REQ ntlmssp_req; + + /* create the bind request RPC_HDR_RB */ + make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0, + 0x1, 0x0, 0x1, abstract, transfer); + + /* 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 (auth_req != NULL) + { + /* + * I have a feeling this is broken right now... JRA. + */ + make_rpc_auth_ntlmssp_req(&ntlmssp_req, "NTLMSSP", 0x1, + 0x0000b2b3, my_name, domain); + smb_io_rpc_auth_ntlmssp_req("", &ntlmssp_req, auth_req, 0); + mem_realloc_data(auth_req->data, auth_req->offset); + } + + /* create the request RPC_HDR */ + make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(), + rhdr_rb->offset, auth_req != NULL ? auth_req->offset : 0); + + smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0); + mem_realloc_data(rhdr->data, rhdr->offset); + + if (rhdr->data == NULL || rhdr_rb->data == NULL) + return False; + + /***/ + /*** link rpc header, bind acknowledgment and authentication responses ***/ + /***/ + + rhdr->data->offset.start = 0; + rhdr->data->offset.end = rhdr->offset; + rhdr->data->next = rhdr_rb->data; + + if (auth_req != NULL) + { + rhdr_rb->data->offset.start = rhdr->offset; + rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; + rhdr_rb->data->next = auth_req->data; + + auth_req->data->offset.start = rhdr->offset + rhdr_rb->offset; + auth_req->data->offset.end = rhdr->offset + auth_req->offset + rhdr_rb->offset; + auth_req->data->next = NULL; + } + else + { + rhdr_rb->data->offset.start = rhdr->offset; + rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; + rhdr_rb->data->next = NULL; + } + + return True; } @@ -343,354 +352,353 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, - caller is expected to free the header data structure once used. ********************************************************************/ + static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len) { - RPC_HDR_REQ hdr_req; - RPC_HDR hdr; + RPC_HDR_REQ hdr_req; + RPC_HDR hdr; - 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, - get_rpc_call_id(), data_len + 0x18, 0); + /* create the rpc header RPC_HDR */ + make_rpc_hdr(&hdr , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST, + get_rpc_call_id(), data_len + 0x18, 0); - /* create the rpc request RPC_HDR_REQ */ - make_rpc_hdr_req(&hdr_req, data_len, op_num); + /* create the rpc request RPC_HDR_REQ */ + make_rpc_hdr_req(&hdr_req, data_len, op_num); - /* stream-time... */ - smb_io_rpc_hdr ("hdr ", &hdr , rhdr, 0); - smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0); + /* stream-time... */ + smb_io_rpc_hdr ("hdr ", &hdr , rhdr, 0); + smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0); - if (rhdr->data == NULL || rhdr->offset != 0x18) return False; + if (rhdr->data == NULL || rhdr->offset != 0x18) + return False; - rhdr->data->offset.start = 0; - rhdr->data->offset.end = rhdr->offset; + rhdr->data->offset.start = 0; + rhdr->data->offset.end = rhdr->offset; - return True; + return True; } /**************************************************************************** send a request on an rpc pipe. ****************************************************************************/ -BOOL rpc_api_pipe_req(struct cli_state *cli, int t_idx, uint16 fnum, - uint8 op_num, - prs_struct *data, prs_struct *rdata) +BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 fnum, uint8 op_num, + prs_struct *data, prs_struct *rdata) { - /* fudge this, at the moment: create the header; memcpy the data. oops. */ - prs_struct rparam; - prs_struct hdr; - int data_len; - BOOL ret; + /* fudge this, at the moment: create the header; memcpy the data. oops. */ + prs_struct rparam; + prs_struct hdr; + int data_len; + BOOL ret; - data_len = data->offset + 0x18; - data->data->offset.end = data->offset; + data_len = data->offset + 0x18; + data->data->offset.end = data->offset; - prs_init(&hdr , data_len, 4, SAFETY_MARGIN, False); - prs_init(&rparam, 0 , 4, 0 , True ); + prs_init(&hdr , data_len, 4, SAFETY_MARGIN, False); + prs_init(&rparam, 0 , 4, 0 , True ); - create_rpc_request(&hdr, op_num, data_len); + create_rpc_request(&hdr, op_num, data_len); - mem_realloc_data(hdr.data, data_len); - hdr.data->offset.end = data_len; - mem_buf_copy(mem_data(&(hdr.data), 0x18), data->data, 0, data->offset); + mem_realloc_data(hdr.data, data_len); + hdr.data->offset.end = data_len; + mem_buf_copy(mem_data(&(hdr.data), 0x18), data->data, 0, data->offset); - ret = rpc_api_pipe(cli, t_idx, 0x0026, fnum, NULL, &hdr, &rparam, rdata); + ret = rpc_api_pipe(cli, 0x0026, fnum, NULL, &hdr, &rparam, rdata); - prs_mem_free(&rparam); - prs_mem_free(&hdr); + prs_mem_free(&rparam); + prs_mem_free(&hdr); - return ret; + return ret; } /**************************************************************************** do an rpc bind ****************************************************************************/ -BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, int t_idx, - char *pipe_name, uint16 fnum, uint16 device_state) -{ - prs_struct param; - prs_struct rdata; - prs_struct rparam; - BOOL state_set = False; - uint16 setup[2]; /* only need 2 uint16 setup parameters */ - - if (pipe_name == NULL) return False; - prs_init(¶m , 2, 4, 0 , False); - prs_init(&rdata , 0, 4, SAFETY_MARGIN, True ); - prs_init(&rparam, 0, 4, SAFETY_MARGIN, True ); - - param.data->offset.start = 0; - param.data->offset.end = 2; - - DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", - fnum, pipe_name, device_state)); - - /* create data parameters: device state */ - SSVAL(param.data->data, 0, device_state); - - /* create setup parameters. */ - setup[0] = 0x0001; - setup[1] = fnum; /* pipe file handle. got this from an SMBcreateX. */ - - /* send the data on \PIPE\ */ - if (cli_api_pipe(cli, t_idx, "\\PIPE\\\0\0\0", 8, - - 2, 0, 2, - - 0, 1024, - - param.data->data, NULL, setup, - - rparam.data, rdata.data)) - { - DEBUG(5, ("Set Handle state: return OK\n")); - state_set = True; - } - - prs_mem_free(¶m ); - prs_mem_free(&rparam); - prs_mem_free(&rdata ); - - return state_set; +BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, + uint16 fnum, uint16 device_state) +{ + prs_struct param; + prs_struct rdata; + prs_struct rparam; + BOOL state_set = False; + uint16 setup[2]; /* only need 2 uint16 setup parameters */ + + if (pipe_name == NULL) + return False; + + prs_init(¶m , 2, 4, 0 , False); + prs_init(&rdata , 0, 4, SAFETY_MARGIN, True ); + prs_init(&rparam, 0, 4, SAFETY_MARGIN, True ); + + param.data->offset.start = 0; + param.data->offset.end = 2; + + DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", + fnum, pipe_name, device_state)); + + /* create data parameters: device state */ + SSVAL(param.data->data, 0, device_state); + + /* create setup parameters. */ + setup[0] = 0x0001; + setup[1] = fnum; /* pipe file handle. got this from an SMBcreateX. */ + + /* send the data on \PIPE\ */ + if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, + 2, 0, 2, + 0, 1024, + param.data->data, NULL, setup, + rparam.data, rdata.data)) + { + DEBUG(5, ("Set Handle state: return OK\n")); + state_set = True; + } + + prs_mem_free(¶m ); + prs_mem_free(&rparam); + prs_mem_free(&rdata ); + + return state_set; } /**************************************************************************** check the rpc bind acknowledge response ****************************************************************************/ -static BOOL valid_pipe_name(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 (strcmp(pipe_name, pipe_names[pipe_idx].client_pipe ) == 0) - { - DEBUG(5,("Bind Abstract Syntax: ")); - dump_data(5, (uchar*)&(pipe_names[pipe_idx].abstr_syntax), sizeof(pipe_names[pipe_idx].abstr_syntax)); - DEBUG(5,("Bind Transfer Syntax: ")); - dump_data(5, (uchar*)&(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)); - - return True; - } - pipe_idx++; - }; - - DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name)); - return False; + 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: ")); + dump_data(5, (uchar*)&(pipe_names[pipe_idx].abstr_syntax), + sizeof(pipe_names[pipe_idx].abstr_syntax)); + DEBUG(5,("Bind Transfer Syntax: ")); + dump_data(5, (uchar*)&(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)); + + return True; + } + pipe_idx++; + }; + + DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name)); + return False; } /**************************************************************************** check the rpc bind acknowledge response ****************************************************************************/ + 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)) - { - DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n", - pipe_names[i].client_pipe , pipe_names[i].server_pipe )); - - if ((strcmp(pipe_name, pipe_names[i].client_pipe ) == 0)) - { - if (strcmp(hdr_ba->addr.str, pipe_names[i].server_pipe ) == 0) - { - DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", - pipe_names[i].server_pipe )); - break; - } - else - { - DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n", - pipe_names[i].server_pipe , hdr_ba->addr.str)); - return False; - } - } - else - { - i++; - } - } - - 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))) - { - DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n")); - return False; - } + int i = 0; + + while ((pipe_names[i].client_pipe != NULL)) + { + 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 )) + { + DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", + pipe_names[i].server_pipe )); + break; + } + else + { + DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n", + pipe_names[i].server_pipe , hdr_ba->addr.str)); + return False; + } + } + else + { + i++; + } + } + + 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))) + { + DEBUG(2,("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) - { - DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n", - hdr_ba->res.num_results, - hdr_ba->res.reason)); - } - - DEBUG(5,("bind_rpc_pipe: accepted!\n")); - return True; + /* lkclXXXX only accept one result: check the result(s) */ + 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)); + } + + DEBUG(5,("bind_rpc_pipe: accepted!\n")); + return True; } /**************************************************************************** do an rpc bind ****************************************************************************/ -BOOL rpc_pipe_bind(struct cli_state *cli, int t_idx, char *pipe_name, uint16 fnum, - RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth, - char *my_name, char *domain) + +BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, uint16 fnum, + RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth, + char *my_name, char *domain) { - prs_struct hdr; - prs_struct hdr_rb; - prs_struct auth_req; - prs_struct data; - prs_struct rdata; - prs_struct rparam; + prs_struct hdr; + prs_struct hdr_rb; + prs_struct auth_req; + prs_struct data; + prs_struct rdata; + prs_struct rparam; - BOOL valid_ack = False; + BOOL valid_ack = False; - if (pipe_name == NULL || abstract == NULL || transfer == NULL) return False; + if (pipe_name == NULL || abstract == NULL || transfer == NULL) + return False; - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name)); + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name)); - if (!valid_pipe_name(pipe_name, abstract, transfer)) return False; + if (!valid_pipe_name(pipe_name, abstract, transfer)) + return False; - prs_init(&hdr , 0x10 , 4, 0x0 , False); - prs_init(&hdr_rb , 1024 , 4, SAFETY_MARGIN, False); - prs_init(&auth_req, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False); + prs_init(&hdr , 0x10 , 4, 0x0 , False); + prs_init(&hdr_rb , 1024 , 4, SAFETY_MARGIN, False); + prs_init(&auth_req, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False); - prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True ); - prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True ); + prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True ); - create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL, - abstract, transfer, - my_name, domain); + create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL, + abstract, transfer, my_name, domain); - /* 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)); + /* 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)); - /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, t_idx, 0x0026, fnum, NULL, &data, &rparam, &rdata)) - { - RPC_HDR_BA hdr_ba; + /* send data on \PIPE\. receive a response */ + if (rpc_api_pipe(cli, 0x0026, fnum, NULL, &data, &rparam, &rdata)) + { + RPC_HDR_BA hdr_ba; - DEBUG(5, ("rpc_api_pipe: return OK\n")); + DEBUG(5, ("rpc_api_pipe: return OK\n")); - smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0); + smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0); - if (rdata.offset != 0) valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer); - } + if (rdata.offset != 0) + valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer); + } - prs_mem_free(&data ); - prs_mem_free(&hdr ); - prs_mem_free(&hdr_rb ); - prs_mem_free(&auth_req); - prs_mem_free(&rdata ); - prs_mem_free(&rparam ); + prs_mem_free(&data ); + prs_mem_free(&hdr ); + prs_mem_free(&hdr_rb ); + prs_mem_free(&auth_req); + prs_mem_free(&rdata ); + prs_mem_free(&rparam ); - return valid_ack; + return valid_ack; } /**************************************************************************** open a session ****************************************************************************/ -BOOL do_session_open(struct cli_state *cli, int t_idx, - char *pipe_name, uint16 *fnum) + +BOOL do_session_open(struct cli_state *cli, char *pipe_name, uint16 *fnum) { - RPC_IFACE abstract; - RPC_IFACE transfer; - - - /******************* open the pipe *****************/ - if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_WRONLY, DENY_NONE, - NULL, NULL, NULL)) == 0xffff) - { - DEBUG(1,("do_session_open: cli_open failed\n")); - return False; - } - - /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, t_idx, pipe_name, (*fnum), 0x4300)) - { - DEBUG(1,("do_session_open: pipe hnd state failed\n")); - return False; - } - - /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, t_idx, pipe_name, (*fnum), - &abstract, &transfer, - False, NULL, NULL)) - { - DEBUG(1,("do_session_open: rpc bind failed\n")); - return False; - } - - return True; + RPC_IFACE abstract; + RPC_IFACE transfer; + + /******************* open the pipe *****************/ + if (((*fnum) = cli_open(cli, pipe_name, O_CREAT|O_WRONLY, DENY_NONE)) == 0xffff) + { + DEBUG(1,("do_session_open: cli_open failed\n")); + return False; + } + + /**************** Set Named Pipe State ***************/ + if (!rpc_pipe_set_hnd_state(cli, pipe_name, (*fnum), 0x4300)) + { + DEBUG(1,("do_session_open: pipe hnd state failed\n")); + return False; + } + + /******************* bind request on pipe *****************/ + if (!rpc_pipe_bind(cli, pipe_name, (*fnum), &abstract, &transfer, + False, NULL, NULL)) + { + DEBUG(1,("do_session_open: rpc bind failed\n")); + return False; + } + + return True; } - /**************************************************************************** open an encrypted session ****************************************************************************/ -BOOL do_ntlm_session_open(struct cli_state *cli, int t_idx, - char *pipe_name, uint16 *fnum, - char *my_name, char *domain) + +BOOL do_ntlm_session_open(struct cli_state *cli, char *pipe_name, uint16 *fnum, + char *my_name, char *domain) { - RPC_IFACE abstract; - RPC_IFACE transfer; - - /******************* open the pipe *****************/ - if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_WRONLY, DENY_NONE, - NULL, NULL, NULL)) == 0xffff) - { - DEBUG(1,("do_ntlm_session_open: cli_open failed\n")); - return False; - } - - /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, t_idx, pipe_name, (*fnum), 0x4300)) - { - DEBUG(1,("do_ntlm_session_open: pipe hnd state failed\n")); - return False; - } - - /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, t_idx, pipe_name, (*fnum), - &abstract, &transfer, - True, my_name, domain)) - { - DEBUG(1,("do_ntlm_session_open: rpc bind failed\n")); - return False; - } - - return True; + RPC_IFACE abstract; + RPC_IFACE transfer; + + /******************* open the pipe *****************/ + if (((*fnum) = cli_open(cli, pipe_name, O_CREAT|O_WRONLY, DENY_NONE)) == 0xffff) + { + DEBUG(1,("do_ntlm_session_open: cli_open failed\n")); + return False; + } + + /**************** Set Named Pipe State ***************/ + if (!rpc_pipe_set_hnd_state(cli, pipe_name, (*fnum), 0x4300)) + { + DEBUG(1,("do_ntlm_session_open: pipe hnd state failed\n")); + return False; + } + + /******************* bind request on pipe *****************/ + if (!rpc_pipe_bind(cli, pipe_name, (*fnum), &abstract, &transfer, + True, my_name, domain)) + { + DEBUG(1,("do_ntlm_session_open: rpc bind failed\n")); + return False; + } + + return True; } - /**************************************************************************** close the session ****************************************************************************/ -void do_session_close(struct cli_state *cli, int t_idx, uint16 fnum) + +void do_session_close(struct cli_state *cli, uint16 fnum) { - if (fnum != 0xffff) - { - cli_close(cli, t_idx, fnum, 0); - } + if (fnum != 0xffff) + { + cli_close(cli, fnum); + } } - -- cgit From 42058f3c662b2bf6e442ea7667de038a21ec82be Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Apr 1998 00:34:21 +0000 Subject: cli_pipe.c: Corrected cli_api_pipe() calls. Jeremy. (This used to be commit 2571ba0213c0630a96657fd6591e19adce1d9304) --- source3/rpc_client/cli_pipe.c | 71 +++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 30 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index e4853f8da9..7ac0f72c77 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -165,7 +165,22 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 fnum, BOOL first = True; BOOL last = True; - /* prepare return data and params */ + /* + * Setup the pointers from the incoming. + */ + char *pparams = param ? param->data->data; + int params_len = param ? param->data->data_used; + char *pdata = data ? data->data->data; + int data_len = data ? data->data->data_used; + + /* + * 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. */ setup[0] = cmd; @@ -173,16 +188,11 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 fnum, /* send the data: receive a response. */ if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, - param != NULL ? param->data->data_used : 0, - data != NULL ? data ->data->data_used : 0, - 2, - 0, - data != NULL ? 1024 : 0 , - param != NULL ? param->data->data : NULL, - data != NULL ? data ->data->data : NULL, - setup, - rparam != NULL ? rparam->data : NULL, - rdata != NULL ? rdata ->data : NULL)) + setup, 2, 0, /* Setup, length, max */ + pparams, params_len, 0, /* Params, length, max */ + pdata, data_len, 1024, /* data, length, max */ + pp_ret_params, p_ret_params_len, /* return params, len */ + pp_ret_data, p_ret_data_len)) /* return data, len */ { DEBUG(5, ("cli_pipe: return critical error\n")); return False; @@ -200,6 +210,11 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 fnum, rdata->data->offset.end = rdata->data->data_used; rdata->offset = 0; + /* 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, &pkt_type, &first, &last, &len)) return False; @@ -422,27 +437,21 @@ do an rpc bind BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 fnum, uint16 device_state) { - prs_struct param; - prs_struct rdata; - prs_struct rparam; BOOL state_set = False; + char param[2]; uint16 setup[2]; /* only need 2 uint16 setup parameters */ + char *rparam = NULL; + char *rdata = NULL; + uint32 rparam_len, rdata_len; if (pipe_name == NULL) return False; - prs_init(¶m , 2, 4, 0 , False); - prs_init(&rdata , 0, 4, SAFETY_MARGIN, True ); - prs_init(&rparam, 0, 4, SAFETY_MARGIN, True ); - - param.data->offset.start = 0; - param.data->offset.end = 2; - DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", fnum, pipe_name, device_state)); - /* create data parameters: device state */ - SSVAL(param.data->data, 0, device_state); + /* create parameters: device state */ + SSVAL(param, 0, device_state); /* create setup parameters. */ setup[0] = 0x0001; @@ -450,18 +459,20 @@ BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, /* send the data on \PIPE\ */ if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, - 2, 0, 2, - 0, 1024, - param.data->data, NULL, setup, - rparam.data, rdata.data)) + setup, 2, 0, /* setup, length, max */ + param, 2, 0, /* param, length, max */ + NULL, 0, 1024, /* data, length, max */ + &rparam, rparam_len, /* return param, length */ + &rdata, rdata_len)) /* return data, length */ { DEBUG(5, ("Set Handle state: return OK\n")); state_set = True; } - prs_mem_free(¶m ); - prs_mem_free(&rparam); - prs_mem_free(&rdata ); + if(rparam) + free(rparam); + if(rdata) + free(rdata); return state_set; } -- cgit From e7ac86607c80912e55ac7179b100cea22749c16f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 25 Apr 1998 01:12:08 +0000 Subject: This looks like a big change but really isn't. It is changing the global variables "myname" and "myworkgroup" to "global_myname" and "global_myworkgroup" respectively. This is to make it very explicit when we are messing with a global (don't ask - it makes the domain client code much clearer :-). Jeremy. (This used to be commit 866406bfe399cf757c8275093dacd5ce4843afa0) --- source3/rpc_client/cli_pipe.c | 100 +++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 64 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7ac0f72c77..d57009a47a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -46,7 +46,7 @@ uint32 get_rpc_call_id(void) uses SMBreadX to get rest of rpc data ********************************************************************/ -static BOOL rpc_read(struct cli_state *cli, uint16 fnum, +static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 rdata_offset) { @@ -83,7 +83,7 @@ static BOOL rpc_read(struct cli_state *cli, uint16 fnum, DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used)); } - num_read = cli_read(cli, fnum, data, file_offset + 0x100000, size); + num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset + 0x100000, size); DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n", file_offset, num_read, data_to_read)); @@ -153,7 +153,7 @@ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, ****************************************************************************/ -BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 fnum, +BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *param , prs_struct *data, prs_struct *rparam, prs_struct *rdata) { @@ -184,7 +184,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 fnum, /* create setup parameters. */ setup[0] = cmd; - setup[1] = fnum; /* pipe file handle. got this from an SMBcreateX. */ + setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ /* send the data: receive a response. */ if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, @@ -231,7 +231,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 fnum, /* 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)) + if (!rpc_read(cli, rdata, len, rdata->data->data_used)) return False; } @@ -251,7 +251,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 fnum, prs_init(&hps, 0x18, 4, 0, True); - num_read = cli_read(cli, fnum, hps.data->data, 0, 0x18); + num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18); DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); if (num_read != 0x18) @@ -275,7 +275,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 fnum, } len = rhdr.frag_len - hps.offset; - if (!rpc_read(cli, fnum, rdata, len, rdata->data->data_used)) + if (!rpc_read(cli, rdata, len, rdata->data->data_used)) return False; } @@ -400,7 +400,7 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len) /**************************************************************************** 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. */ @@ -421,7 +421,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 fnum, uint8 op_num, hdr.data->offset.end = data_len; mem_buf_copy(mem_data(&(hdr.data), 0x18), data->data, 0, data->offset); - ret = rpc_api_pipe(cli, 0x0026, fnum, NULL, &hdr, &rparam, rdata); + ret = rpc_api_pipe(cli, 0x0026, NULL, &hdr, &rparam, rdata); prs_mem_free(&rparam); prs_mem_free(&hdr); @@ -434,8 +434,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 fnum, uint8 op_num, do an rpc bind ****************************************************************************/ -BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, - uint16 fnum, uint16 device_state) +BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state) { BOOL state_set = False; char param[2]; @@ -448,14 +447,14 @@ BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, 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 SMBcreateX. */ + 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, @@ -575,9 +574,8 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * do an rpc bind ****************************************************************************/ -BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, uint16 fnum, - RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth, - char *my_name, char *domain) +BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, + RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth) { prs_struct hdr; prs_struct hdr_rb; @@ -591,7 +589,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, uint16 fnum, if (pipe_name == NULL || abstract == NULL || transfer == NULL) return False; - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name)); + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name)); if (!valid_pipe_name(pipe_name, abstract, transfer)) return False; @@ -604,14 +602,14 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, uint16 fnum, prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True ); create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL, - abstract, transfer, my_name, domain); + abstract, transfer, myname, myworkgroup); /* 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)); /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, 0x0026, fnum, NULL, &data, &rparam, &rdata)) + if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata)) { RPC_HDR_BA hdr_ba; @@ -637,67 +635,44 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, uint16 fnum, open a session ****************************************************************************/ -BOOL do_session_open(struct cli_state *cli, char *pipe_name, uint16 *fnum) +BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) { RPC_IFACE abstract; RPC_IFACE transfer; + int fnum; /******************* open the pipe *****************/ - if (((*fnum) = cli_open(cli, pipe_name, O_CREAT|O_WRONLY, DENY_NONE)) == 0xffff) + if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) { - DEBUG(1,("do_session_open: cli_open failed\n")); + DEBUG(1,("do_session_open: cli_open failed on pipe %s to machine %s. \ +Error was %s.\n", pipe_name, 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_name, (*fnum), 0x4300)) + if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) { - DEBUG(1,("do_session_open: pipe hnd state failed\n")); + DEBUG(1,("do_session_open: pipe hnd state failed.\n")); return False; } /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, pipe_name, (*fnum), &abstract, &transfer, - False, NULL, NULL)) + if (!rpc_pipe_bind(cli, pipe_name, &abstract, &transfer, encrypted)) { - DEBUG(1,("do_session_open: rpc bind failed\n")); + DEBUG(1,("do_session_open: rpc bind failed.\n")); return False; } - return True; -} - -/**************************************************************************** - open an encrypted session - ****************************************************************************/ - -BOOL do_ntlm_session_open(struct cli_state *cli, char *pipe_name, uint16 *fnum, - char *my_name, char *domain) -{ - RPC_IFACE abstract; - RPC_IFACE transfer; - - /******************* open the pipe *****************/ - if (((*fnum) = cli_open(cli, pipe_name, O_CREAT|O_WRONLY, DENY_NONE)) == 0xffff) - { - DEBUG(1,("do_ntlm_session_open: cli_open failed\n")); - return False; - } + /* + * Setup the remote server name prefixed by \ and the machine account name. + */ - /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, pipe_name, (*fnum), 0x4300)) - { - DEBUG(1,("do_ntlm_session_open: pipe hnd state failed\n")); - return False; - } + sprintf(cli->srv_name, "\\\\%s", cli->desthost); + strupper(cli->srv_name); - /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, pipe_name, (*fnum), &abstract, &transfer, - True, my_name, domain)) - { - DEBUG(1,("do_ntlm_session_open: rpc bind failed\n")); - return False; - } + sprintf(cli->mach_acct, "%s$", myname); return True; } @@ -706,10 +681,7 @@ BOOL do_ntlm_session_open(struct cli_state *cli, char *pipe_name, uint16 *fnum, close the session ****************************************************************************/ -void do_session_close(struct cli_state *cli, uint16 fnum) +void nt_session_close(struct cli_state *cli) { - if (fnum != 0xffff) - { - cli_close(cli, fnum); - } + cli_close(cli, cli->nt_pipe_fnum); } -- cgit From 22abe47e29bf25a52e39026d03e38b49bab25ac9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Apr 1998 01:24:40 +0000 Subject: First version that compiles. Much more to do..... Jeremy. (This used to be commit 45393a19adb31820725fbdfaaf7ab64793fc9bc5) --- source3/rpc_client/cli_pipe.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d57009a47a..4058538f21 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -31,6 +31,8 @@ extern int DEBUGLEVEL; extern struct pipe_id_info pipe_names[]; +extern fstring global_myworkgroup; +extern pstring global_myname; /******************************************************************** rpc pipe call id @@ -55,6 +57,7 @@ static BOOL rpc_read(struct cli_state *cli, int num_read; char *data = rdata->data->data; uint32 err; + uint32 errclass; uint32 new_data_size = rdata->data->data_used + data_to_read; data += rdata_offset; @@ -92,7 +95,8 @@ static BOOL rpc_read(struct cli_state *cli, file_offset += num_read; data += num_read; - if (cli_error(cli, NULL, &err)) + cli_error(cli, &errclass, &err); + if (errclass != 0) return False; } while (num_read > 0 && data_to_read > 0); @@ -161,6 +165,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, uint16 setup[2]; /* only need 2 uint16 setup parameters */ uint32 err; + uint32 errclass; uint8 pkt_type = 0xff; BOOL first = True; BOOL last = True; @@ -168,10 +173,10 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, /* * Setup the pointers from the incoming. */ - char *pparams = param ? param->data->data; - int params_len = param ? param->data->data_used; - char *pdata = data ? data->data->data; - int data_len = data ? data->data->data_used; + 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. @@ -198,9 +203,6 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, return False; } - if (cli_error(cli, NULL, &err)) - return False; - if (rdata->data->data == NULL) return False; @@ -262,7 +264,8 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_mem_free(&hps); - if (cli_error(cli, NULL, &err)) + cli_error(cli, &errclass, &err); + if (errclass != 0) return False; first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST); @@ -461,8 +464,8 @@ BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 devic setup, 2, 0, /* setup, length, max */ param, 2, 0, /* param, length, max */ NULL, 0, 1024, /* data, length, max */ - &rparam, rparam_len, /* return param, length */ - &rdata, rdata_len)) /* return data, length */ + &rparam, &rparam_len, /* return param, length */ + &rdata, &rdata_len)) /* return data, length */ { DEBUG(5, ("Set Handle state: return OK\n")); state_set = True; @@ -602,7 +605,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True ); create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL, - abstract, transfer, myname, myworkgroup); + abstract, transfer, global_myname, global_myworkgroup); /* this is a hack due to limitations in rpc_api_pipe */ prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False); @@ -645,7 +648,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) { DEBUG(1,("do_session_open: cli_open failed on pipe %s to machine %s. \ -Error was %s.\n", pipe_name, cli->desthost, cli_errstr(&cli))); +Error was %s.\n", pipe_name, cli->desthost, cli_errstr(cli))); return False; } @@ -669,10 +672,11 @@ Error was %s.\n", pipe_name, cli->desthost, cli_errstr(&cli))); * Setup the remote server name prefixed by \ and the machine account name. */ - sprintf(cli->srv_name, "\\\\%s", cli->desthost); - strupper(cli->srv_name); + sprintf(cli->srv_name_slash, "\\\\%s", cli->desthost); + strupper(cli->srv_name_slash); - sprintf(cli->mach_acct, "%s$", myname); + sprintf(cli->mach_acct, "%s$", global_myname); + strupper(cli->mach_acct); return True; } -- cgit From e305c2c9e2e657974d34d1d58a8f9372921fdae2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Apr 1998 19:22:01 +0000 Subject: clientgen.c: Fixed null session setup bug. password.c: Stopped cli_nt_logout call (we don't have it correct yet). Added Luke object-orientation fix :-). smb.h: Added clnt_name_slash to cli_state. lib/rpc/client/cli_login.c: Changed global_myname to clnt_name_slash where needed. lib/rpc/client/cli_netlogon.c: Fixed debug messages, don't check creds on error. lib/rpc/client/cli_pipe.c: Fixed debug messages, Added Luke object-orientation fix. lib/rpc/parse/parse_misc.c: Fixed STRING2 linearization bug that was adding 1. Jeremy. (This used to be commit c6c22df20196cb7f0ae84b1a1dd202a87adb8d4e) --- source3/rpc_client/cli_pipe.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4058538f21..3076df3bb7 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -124,7 +124,7 @@ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, if (!rdata->offset || rdata->offset != 0x10) { - DEBUG(5,("cli_pipe: error in rpc header\n")); + DEBUG(0,("cli_pipe: error in rpc header\n")); return False; } @@ -199,7 +199,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, pp_ret_params, p_ret_params_len, /* return params, len */ pp_ret_data, p_ret_data_len)) /* return data, len */ { - DEBUG(5, ("cli_pipe: return critical error\n")); + DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli))); return False; } @@ -273,7 +273,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, if (first) { - DEBUG(4,("rpc_api_pipe: wierd rpc header received\n")); + DEBUG(0,("rpc_api_pipe: wierd rpc header received\n")); return False; } @@ -558,7 +558,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * (memcmp(hdr_ba->transfer.data, transfer->data, sizeof(transfer->version)) ==0))) { - DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n")); + DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n")); return False; } @@ -647,8 +647,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) /******************* open the pipe *****************/ if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) { - DEBUG(1,("do_session_open: cli_open failed on pipe %s to machine %s. \ -Error was %s.\n", pipe_name, cli->desthost, cli_errstr(cli))); + DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. \ +Error was %s\n", pipe_name, cli->desthost, cli_errstr(cli))); return False; } @@ -657,14 +657,17 @@ Error was %s.\n", pipe_name, cli->desthost, cli_errstr(cli))); /**************** Set Named Pipe State ***************/ if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) { - DEBUG(1,("do_session_open: pipe hnd state failed.\n")); + DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", + cli_errstr(cli))); + cli_close(cli, cli->nt_pipe_fnum); return False; } /******************* bind request on pipe *****************/ if (!rpc_pipe_bind(cli, pipe_name, &abstract, &transfer, encrypted)) { - DEBUG(1,("do_session_open: rpc bind failed.\n")); + DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", cli_errstr(cli))); + cli_close(cli, cli->nt_pipe_fnum); return False; } @@ -675,6 +678,9 @@ Error was %s.\n", pipe_name, cli->desthost, cli_errstr(cli))); sprintf(cli->srv_name_slash, "\\\\%s", cli->desthost); strupper(cli->srv_name_slash); + sprintf(cli->clnt_name_slash, "\\\\%s", global_myname); + strupper(cli->clnt_name_slash); + sprintf(cli->mach_acct, "%s$", global_myname); strupper(cli->mach_acct); @@ -685,7 +691,7 @@ Error was %s.\n", pipe_name, cli->desthost, cli_errstr(cli))); close the session ****************************************************************************/ -void nt_session_close(struct cli_state *cli) +void cli_nt_session_close(struct cli_state *cli) { cli_close(cli, cli->nt_pipe_fnum); } -- cgit From 3dfc0c847240ac7e12c39f4ed9c31a888949ade1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 May 1998 06:38:36 +0000 Subject: changed to use slprintf() instead of sprintf() just about everywhere. I've implemented slprintf() as a bounds checked sprintf() using mprotect() and a non-writeable page. This should prevent any sprintf based security holes. (This used to be commit ee09e9dadb69aaba5a751dd20ccc6d587d841bd6) --- source3/rpc_client/cli_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3076df3bb7..c458aa102a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -95,7 +95,7 @@ static BOOL rpc_read(struct cli_state *cli, file_offset += num_read; data += num_read; - cli_error(cli, &errclass, &err); + cli_error(cli, (int *)&errclass, (int *)&err); if (errclass != 0) return False; @@ -264,7 +264,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_mem_free(&hps); - cli_error(cli, &errclass, &err); + cli_error(cli, (int *)&errclass, (int *)&err); if (errclass != 0) return False; @@ -492,10 +492,10 @@ static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *tra if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) { DEBUG(5,("Bind Abstract Syntax: ")); - dump_data(5, (uchar*)&(pipe_names[pipe_idx].abstr_syntax), + dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), sizeof(pipe_names[pipe_idx].abstr_syntax)); DEBUG(5,("Bind Transfer Syntax: ")); - dump_data(5, (uchar*)&(pipe_names[pipe_idx].trans_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 */ -- cgit From f888868f46a5418bac9ab528497136c152895305 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 May 1998 00:55:32 +0000 Subject: This is a security audit change of the main source. It removed all ocurrences of the following functions : sprintf strcpy strcat The replacements are slprintf, safe_strcpy and safe_strcat. It should not be possible to use code in Samba that uses sprintf, strcpy or strcat, only the safe_equivalents. Once Andrew has fixed the slprintf implementation then this code will be moved back to the 1.9.18 code stream. Jeremy. (This used to be commit 2d774454005f0b54e5684cf618da7060594dfcbb) --- source3/rpc_client/cli_pipe.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c458aa102a..899c0437e6 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -675,13 +675,16 @@ Error was %s\n", pipe_name, cli->desthost, cli_errstr(cli))); * Setup the remote server name prefixed by \ and the machine account name. */ - sprintf(cli->srv_name_slash, "\\\\%s", cli->desthost); + fstrcpy(cli->srv_name_slash, "\\\\"); + fstrcat(cli->srv_name_slash, cli->desthost); strupper(cli->srv_name_slash); - sprintf(cli->clnt_name_slash, "\\\\%s", global_myname); + fstrcpy(cli->clnt_name_slash, "\\\\"); + fstrcat(cli->clnt_name_slash, global_myname); strupper(cli->clnt_name_slash); - sprintf(cli->mach_acct, "%s$", global_myname); + fstrcpy(cli->mach_acct, global_myname); + fstrcat(cli->mach_acct, "$"); strupper(cli->mach_acct); return True; -- cgit From e9ea36e4d2270bd7d32da12ef6d6e2299641582d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Sep 1998 05:07:05 +0000 Subject: tridge the destroyer returns! prompted by the interpret_security() dead code that Jean-Francois pointed out I added a make target "finddead" that finds potentially dead (ie. unused) code. It spat out 304 function names ... I went through these are deleted many of them, making others static (finddead also reports functions that are used only in the local file). in doing this I have almost certainly deleted some useful code. I may have even prevented compilation with some compile options. I apologise. I decided it was better to get rid of this code now and add back the one or two functions that are needed than to keep all this baggage. So, if I have done a bit too much "destroying" then let me know. Keep the swearing to a minimum :) One bit I didn't do is the ubibt code. Chris, can you look at that? Heaps of unused functions there. Can they be made static? (This used to be commit 2204475c87f3024ea8fd1fbd7385b2def617a46f) --- source3/rpc_client/cli_pipe.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 899c0437e6..1689ae0e69 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -37,8 +37,7 @@ extern pstring global_myname; /******************************************************************** rpc pipe call id ********************************************************************/ - -uint32 get_rpc_call_id(void) +static uint32 get_rpc_call_id(void) { static uint32 call_id = 1; return ++call_id; @@ -157,7 +156,7 @@ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, ****************************************************************************/ -BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, +static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *param , prs_struct *data, prs_struct *rparam, prs_struct *rdata) { @@ -437,7 +436,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, do an rpc bind ****************************************************************************/ -BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, 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]; @@ -577,7 +576,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * do an rpc bind ****************************************************************************/ -BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, +static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth) { prs_struct hdr; -- cgit From c43c53b886ec62b249ffebcd4e6656042e4753bc Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 2 Oct 1998 18:14:38 +0000 Subject: microsoft is slowly fixing some buffer overflow errors in dce/rpc code (SP4). therefore, they are being more strict, first in the server-side code, and now in the client-side code. this fixes a bind-request that was too short by 16 bytes, and an rpc-request that was too long by 24 bytes. (This used to be commit a69ed7846a1e1403ea51d76d6962b97e8c768b29) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1689ae0e69..b178f38a58 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -324,7 +324,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, /* create the request RPC_HDR */ make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(), - rhdr_rb->offset, auth_req != NULL ? auth_req->offset : 0); + rhdr_rb->offset + 0x10, auth_req != NULL ? auth_req->offset : 0); smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0); mem_realloc_data(rhdr->data, rhdr->offset); @@ -380,7 +380,7 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len) /* create the rpc header RPC_HDR */ make_rpc_hdr(&hdr , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST, - get_rpc_call_id(), data_len + 0x18, 0); + get_rpc_call_id(), data_len, 0); /* create the rpc request RPC_HDR_REQ */ make_rpc_hdr_req(&hdr_req, data_len, op_num); -- cgit From 732d4ff7dacce985fb209ee99569cef907e2cbf4 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 2 Oct 1998 21:09:23 +0000 Subject: Makefile.in : - added srvsvc client files clientgen.c : - replaced cli_error(cli, int *cls, int *err) with cli_error(cli, uint8 cls, uint32 *err). this version detects 32 bit status messages. the DOS error "MORE_DATA", the equivalent of the 32 bit *warning* 0x8000 0005 (STATUS_BUFFER_OVERFLOW), was being processed as an error, terminating the cli_receive_trans() call. cli_pipe.c : - replaced calls that had been incorrectly modified from 32 bit warnings (0x8000 0005 - STATUS_BUFFER_OVERFLOW) to 8 bit DOS errors (0x01 0xEA - MORE_DATA). the use of the old version of cli_error (DOS only) instead of the new one (DOS and 32 bit) caused the dce/rpc client code to fail. - replaced 2 space indentation with tab indentation in all functions. cli_srvsvc.c : cmd_srvsvc.c : - added these files back in, fixing them up to use jeremy's modified versions of the dce/rpc client functions. parse_srv.c : - added back in some "unused" functions required by dce/rpc client-side code. it would be helpful if all such "unused" functions could be added back in. rpcclient.c : - added "session", "file", "share", "connection" enumeration functions back in. these are equivalent to nt's "NetXXXXXEnum" Win32 (MSDN) functions. - added "srvinfo" function back in. this is equivalent to nt's NetServerGetInfo Win32 (MSDN) function. (This used to be commit bcf39ffdcc64e049bca2d70a394a99976291e81d) --- source3/rpc_client/cli_pipe.c | 941 +++++++++++++++++++++--------------------- 1 file changed, 467 insertions(+), 474 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b178f38a58..0258c1a0e7 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -51,62 +51,59 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 rdata_offset) { - int size = 0x1630; - int file_offset = rdata_offset; - int num_read; - char *data = rdata->data->data; - uint32 err; - uint32 errclass; - uint32 new_data_size = rdata->data->data_used + data_to_read; + int size = 0x1630; + int file_offset = rdata_offset; + int num_read; + char *data = rdata->data->data; + uint32 err; + uint32 new_data_size = rdata->data->data_used + data_to_read; - data += rdata_offset; + data += rdata_offset; - file_offset -= rdata_offset; + file_offset -= rdata_offset; - 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: %d data offset: %d file offset: %d\n", + data_to_read, rdata_offset, file_offset)); - 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)); - } + 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)); + } - do /* read data using SMBreadX */ - { - if (size > data_to_read) - size = data_to_read; + do /* read data using SMBreadX */ + { + if (size > data_to_read) + size = data_to_read; - new_data_size = rdata->data->data_used + size; + new_data_size = rdata->data->data_used + 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)); - } + 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)); + } - num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset + 0x100000, size); + num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset + 0x100000, 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: read offset: %d read: %d to read: %d\n", + file_offset, num_read, data_to_read)); - data_to_read -= num_read; - file_offset += num_read; - data += num_read; + data_to_read -= num_read; + file_offset += num_read; + data += num_read; - cli_error(cli, (int *)&errclass, (int *)&err); - if (errclass != 0) - return False; + if (cli_error(cli, NULL, &err)) return False; - } while (num_read > 0 && data_to_read > 0); - /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ + } while (num_read > 0 && data_to_read > 0); + /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ - mem_realloc_data(rdata->data, file_offset + rdata_offset); - rdata->data->offset.end = file_offset + rdata_offset; + mem_realloc_data(rdata->data, file_offset + rdata_offset); + rdata->data->offset.end = file_offset + rdata_offset; - DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read)); + DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read)); - return data_to_read == 0; + return data_to_read == 0; } /**************************************************************************** @@ -115,27 +112,27 @@ static BOOL rpc_read(struct cli_state *cli, static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, BOOL *first, BOOL *last, int *len) { - RPC_HDR rhdr; + RPC_HDR rhdr; - DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used)); + DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used)); - smb_io_rpc_hdr ("rpc_hdr ", &rhdr , rdata, 0); + smb_io_rpc_hdr ("rpc_hdr ", &rhdr , rdata, 0); - if (!rdata->offset || rdata->offset != 0x10) - { - DEBUG(0,("cli_pipe: error in rpc header\n")); - return False; - } + if (!rdata->offset || rdata->offset != 0x10) + { + DEBUG(0,("cli_pipe: error in rpc header\n")); + return False; + } - DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n", - rdata->data->data_used)); + DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n", + 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 ) = rhdr.frag_len - rdata->data->data_used; - (*pkt_type) = rhdr.pkt_type; + (*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; + (*pkt_type) = rhdr.pkt_type; - return True; + return True; } /**************************************************************************** @@ -160,128 +157,125 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *param , prs_struct *data, prs_struct *rparam, prs_struct *rdata) { - int len; - - uint16 setup[2]; /* only need 2 uint16 setup parameters */ - uint32 err; - uint32 errclass; - uint8 pkt_type = 0xff; - BOOL first = True; - BOOL last = True; - - /* - * 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. */ - setup[0] = cmd; - setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ - - /* 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, 1024, /* data, length, max */ - pp_ret_params, p_ret_params_len, /* return params, len */ - pp_ret_data, p_ret_data_len)) /* return data, len */ - { - DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli))); - return False; - } - - if (rdata->data->data == NULL) - return False; - - /**** parse the header: check it's a response record */ - - rdata->data->offset.start = 0; - rdata->data->offset.end = rdata->data->data_used; - rdata->offset = 0; - - /* 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, &pkt_type, &first, &last, &len)) - return False; - - if (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: %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, rdata, len, rdata->data->data_used)) - 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; - } - - while (!last) /* read more fragments until we get the last one */ - { - RPC_HDR rhdr; - RPC_HDR_RESP rhdr_resp; - int num_read; - prs_struct hps; - - prs_init(&hps, 0x18, 4, 0, True); - - num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18); - DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); - - if (num_read != 0x18) - return False; - - smb_io_rpc_hdr ("rpc_hdr ", &rhdr , &hps, 0); - smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0); - - prs_mem_free(&hps); - - cli_error(cli, (int *)&errclass, (int *)&err); - if (errclass != 0) - return False; - - first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST); - last = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST ); - - if (first) - { - DEBUG(0,("rpc_api_pipe: wierd rpc header received\n")); - return False; - } - - len = rhdr.frag_len - hps.offset; - if (!rpc_read(cli, rdata, len, rdata->data->data_used)) - return False; - } - - return True; + int len; + + uint16 setup[2]; /* only need 2 uint16 setup parameters */ + uint32 err; + uint8 pkt_type = 0xff; + BOOL first = True; + BOOL last = True; + + /* + * 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. */ + setup[0] = cmd; + setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ + + /* 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, 1024, /* data, length, max */ + pp_ret_params, p_ret_params_len, /* return params, len */ + pp_ret_data, p_ret_data_len)) /* return data, len */ + { + DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli))); + return False; + } + + if (rdata->data->data == NULL) return False; + + /**** parse the header: check it's a response record */ + + rdata->data->offset.start = 0; + rdata->data->offset.end = rdata->data->data_used; + rdata->offset = 0; + + /* 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, &pkt_type, &first, &last, &len)) return False; + + if (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: %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, rdata, len, rdata->data->data_used)) + { + 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; + } + + while (!last) /* read more fragments until we get the last one */ + { + RPC_HDR rhdr; + RPC_HDR_RESP rhdr_resp; + int num_read; + prs_struct hps; + + prs_init(&hps, 0x18, 4, 0, True); + + num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18); + DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); + + if (num_read != 0x18) return False; + + smb_io_rpc_hdr ("rpc_hdr ", &rhdr , &hps, 0); + smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0); + + prs_mem_free(&hps); + + if (cli_error(cli, NULL, &err)) return False; + + first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST); + last = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST ); + + if (first) + { + DEBUG(0,("rpc_api_pipe: wierd rpc header received\n")); + return False; + } + + len = rhdr.frag_len - hps.offset; + if (!rpc_read(cli, rdata, len, rdata->data->data_used)) + { + return False; + } + } + + return True; } /******************************************************************* @@ -299,65 +293,65 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name, char *domain) { - RPC_HDR_RB hdr_rb; - RPC_HDR hdr; - RPC_AUTH_NTLMSSP_REQ ntlmssp_req; - - /* create the bind request RPC_HDR_RB */ - make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0, - 0x1, 0x0, 0x1, abstract, transfer); - - /* 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 (auth_req != NULL) - { - /* - * I have a feeling this is broken right now... JRA. - */ - make_rpc_auth_ntlmssp_req(&ntlmssp_req, "NTLMSSP", 0x1, - 0x0000b2b3, my_name, domain); - smb_io_rpc_auth_ntlmssp_req("", &ntlmssp_req, auth_req, 0); - mem_realloc_data(auth_req->data, auth_req->offset); - } - - /* create the request RPC_HDR */ - make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(), - rhdr_rb->offset + 0x10, auth_req != NULL ? auth_req->offset : 0); - - smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0); - mem_realloc_data(rhdr->data, rhdr->offset); - - if (rhdr->data == NULL || rhdr_rb->data == NULL) - return False; - - /***/ - /*** link rpc header, bind acknowledgment and authentication responses ***/ - /***/ - - rhdr->data->offset.start = 0; - rhdr->data->offset.end = rhdr->offset; - rhdr->data->next = rhdr_rb->data; - - if (auth_req != NULL) - { - rhdr_rb->data->offset.start = rhdr->offset; - rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; - rhdr_rb->data->next = auth_req->data; - - auth_req->data->offset.start = rhdr->offset + rhdr_rb->offset; - auth_req->data->offset.end = rhdr->offset + auth_req->offset + rhdr_rb->offset; - auth_req->data->next = NULL; - } - else - { - rhdr_rb->data->offset.start = rhdr->offset; - rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; - rhdr_rb->data->next = NULL; - } - - return True; + RPC_HDR_RB hdr_rb; + RPC_HDR hdr; + RPC_AUTH_NTLMSSP_REQ ntlmssp_req; + + /* create the bind request RPC_HDR_RB */ + make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0, + 0x1, 0x0, 0x1, abstract, transfer); + + /* 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 (auth_req != NULL) + { + /* + * I have a feeling this is broken right now... JRA. + */ + make_rpc_auth_ntlmssp_req(&ntlmssp_req, "NTLMSSP", 0x1, + 0x0000b2b3, my_name, domain); + smb_io_rpc_auth_ntlmssp_req("", &ntlmssp_req, auth_req, 0); + mem_realloc_data(auth_req->data, auth_req->offset); + } + + /* create the request RPC_HDR */ + make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(), + rhdr_rb->offset + 0x10, + auth_req != NULL ? auth_req->offset : 0); + + smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0); + mem_realloc_data(rhdr->data, rhdr->offset); + + if (rhdr->data == NULL || rhdr_rb->data == NULL) return False; + + /***/ + /*** link rpc header, bind acknowledgment and authentication responses ***/ + /***/ + + rhdr->data->offset.start = 0; + rhdr->data->offset.end = rhdr->offset; + rhdr->data->next = rhdr_rb->data; + + if (auth_req != NULL) + { + rhdr_rb->data->offset.start = rhdr->offset; + rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; + rhdr_rb->data->next = auth_req->data; + + auth_req->data->offset.start = rhdr->offset + rhdr_rb->offset; + auth_req->data->offset.end = rhdr->offset + auth_req->offset + rhdr_rb->offset; + auth_req->data->next = NULL; + } + else + { + rhdr_rb->data->offset.start = rhdr->offset; + rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; + rhdr_rb->data->next = NULL; + } + + return True; } @@ -372,30 +366,29 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len) { - RPC_HDR_REQ hdr_req; - RPC_HDR hdr; + RPC_HDR_REQ hdr_req; + RPC_HDR hdr; - 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, - get_rpc_call_id(), data_len, 0); + /* create the rpc header RPC_HDR */ + make_rpc_hdr(&hdr , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST, + get_rpc_call_id(), data_len, 0); - /* create the rpc request RPC_HDR_REQ */ - make_rpc_hdr_req(&hdr_req, data_len, op_num); + /* create the rpc request RPC_HDR_REQ */ + make_rpc_hdr_req(&hdr_req, data_len, op_num); - /* stream-time... */ - smb_io_rpc_hdr ("hdr ", &hdr , rhdr, 0); - smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0); + /* stream-time... */ + smb_io_rpc_hdr ("hdr ", &hdr , rhdr, 0); + smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0); - if (rhdr->data == NULL || rhdr->offset != 0x18) - return False; + if (rhdr->data == NULL || rhdr->offset != 0x18) return False; - rhdr->data->offset.start = 0; - rhdr->data->offset.end = rhdr->offset; + rhdr->data->offset.start = 0; + rhdr->data->offset.end = rhdr->offset; - return True; + return True; } @@ -405,30 +398,30 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len) 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 rparam; - prs_struct hdr; - int data_len; - BOOL ret; + /* fudge this, at the moment: create the header; memcpy the data. oops. */ + prs_struct rparam; + prs_struct hdr; + int data_len; + BOOL ret; - data_len = data->offset + 0x18; - data->data->offset.end = data->offset; + data_len = data->offset + 0x18; + data->data->offset.end = data->offset; - prs_init(&hdr , data_len, 4, SAFETY_MARGIN, False); - prs_init(&rparam, 0 , 4, 0 , True ); + prs_init(&hdr , data_len, 4, SAFETY_MARGIN, False); + prs_init(&rparam, 0 , 4, 0 , True ); - create_rpc_request(&hdr, op_num, data_len); + create_rpc_request(&hdr, op_num, data_len); - mem_realloc_data(hdr.data, data_len); - hdr.data->offset.end = data_len; - mem_buf_copy(mem_data(&(hdr.data), 0x18), data->data, 0, data->offset); + mem_realloc_data(hdr.data, data_len); + hdr.data->offset.end = data_len; + mem_buf_copy(mem_data(&(hdr.data), 0x18), data->data, 0, data->offset); - ret = rpc_api_pipe(cli, 0x0026, NULL, &hdr, &rparam, rdata); + ret = rpc_api_pipe(cli, 0x0026, NULL, &hdr, &rparam, rdata); - prs_mem_free(&rparam); - prs_mem_free(&hdr); + prs_mem_free(&rparam); + prs_mem_free(&hdr); - return ret; + return ret; } @@ -438,44 +431,41 @@ do an rpc bind static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state) { - BOOL state_set = False; - char param[2]; - uint16 setup[2]; /* only need 2 uint16 setup parameters */ - char *rparam = NULL; - char *rdata = NULL; - uint32 rparam_len, rdata_len; - - if (pipe_name == NULL) - return False; - - DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", - 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] = 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, - setup, 2, 0, /* setup, length, max */ - param, 2, 0, /* param, length, max */ - NULL, 0, 1024, /* data, length, max */ - &rparam, &rparam_len, /* return param, length */ - &rdata, &rdata_len)) /* return data, length */ - { - DEBUG(5, ("Set Handle state: return OK\n")); - state_set = True; - } - - if(rparam) - free(rparam); - if(rdata) - free(rdata); - - return state_set; + BOOL state_set = False; + char param[2]; + uint16 setup[2]; /* only need 2 uint16 setup parameters */ + char *rparam = NULL; + char *rdata = NULL; + uint32 rparam_len, rdata_len; + + if (pipe_name == NULL) return False; + + DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", + 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] = 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, + setup, 2, 0, /* setup, length, max */ + param, 2, 0, /* param, length, max */ + NULL, 0, 1024, /* data, length, max */ + &rparam, &rparam_len, /* return param, length */ + &rdata, &rdata_len)) /* return data, length */ + { + DEBUG(5, ("Set Handle state: return OK\n")); + state_set = True; + } + + if (rparam) free(rparam); + if (rdata ) free(rdata ); + + return state_set; } /**************************************************************************** @@ -484,32 +474,32 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1 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: ")); - dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), - sizeof(pipe_names[pipe_idx].abstr_syntax)); - 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)); - - return True; - } - pipe_idx++; - }; - - DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name)); - return False; + 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: ")); + dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), + sizeof(pipe_names[pipe_idx].abstr_syntax)); + 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)); + + return True; + } + pipe_idx++; + }; + + DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name)); + return False; } /**************************************************************************** @@ -518,58 +508,59 @@ static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *tra 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)) - { - 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 )) - { - DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", - pipe_names[i].server_pipe )); - break; - } - else - { - DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n", - pipe_names[i].server_pipe , hdr_ba->addr.str)); - return False; - } - } - else - { - i++; - } - } - - 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))) - { - 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) - { - DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n", - hdr_ba->res.num_results, hdr_ba->res.reason)); - } - - DEBUG(5,("bind_rpc_pipe: accepted!\n")); - return True; + int i = 0; + + while ((pipe_names[i].client_pipe != NULL)) + { + 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 )) + { + DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", + pipe_names[i].server_pipe )); + break; + } + else + { + DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n", + pipe_names[i].server_pipe , + hdr_ba->addr.str)); + return False; + } + } + else + { + i++; + } + } + + 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))) + { + 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) + { + DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n", + hdr_ba->res.num_results, hdr_ba->res.reason)); + } + + DEBUG(5,("bind_rpc_pipe: accepted!\n")); + return True; } /**************************************************************************** @@ -579,58 +570,59 @@ do an rpc bind static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth) { - prs_struct hdr; - prs_struct hdr_rb; - prs_struct auth_req; - prs_struct data; - prs_struct rdata; - prs_struct rparam; + prs_struct hdr; + prs_struct hdr_rb; + prs_struct auth_req; + prs_struct data; + prs_struct rdata; + prs_struct rparam; - BOOL valid_ack = False; + BOOL valid_ack = False; - if (pipe_name == NULL || abstract == NULL || transfer == NULL) - return False; + if (pipe_name == NULL || abstract == NULL || transfer == NULL) + return False; - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name)); + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name)); - if (!valid_pipe_name(pipe_name, abstract, transfer)) - return False; + if (!valid_pipe_name(pipe_name, abstract, transfer)) return False; - prs_init(&hdr , 0x10 , 4, 0x0 , False); - prs_init(&hdr_rb , 1024 , 4, SAFETY_MARGIN, False); - prs_init(&auth_req, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False); + prs_init(&hdr , 0x10 , 4, 0x0 , False); + prs_init(&hdr_rb , 1024 , 4, SAFETY_MARGIN, False); + prs_init(&auth_req, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False); - prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True ); - prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True ); + prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True ); - create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL, - abstract, transfer, global_myname, global_myworkgroup); + create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL, + abstract, transfer, global_myname, global_myworkgroup); - /* 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)); + /* 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)); - /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata)) - { - RPC_HDR_BA hdr_ba; + /* send data on \PIPE\. receive a response */ + if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata)) + { + RPC_HDR_BA hdr_ba; - DEBUG(5, ("rpc_api_pipe: return OK\n")); + DEBUG(5, ("rpc_api_pipe: return OK\n")); - smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0); + smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0); - if (rdata.offset != 0) - valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer); - } + if (rdata.offset != 0) + { + valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer); + } + } - prs_mem_free(&data ); - prs_mem_free(&hdr ); - prs_mem_free(&hdr_rb ); - prs_mem_free(&auth_req); - prs_mem_free(&rdata ); - prs_mem_free(&rparam ); + prs_mem_free(&data ); + prs_mem_free(&hdr ); + prs_mem_free(&hdr_rb ); + prs_mem_free(&auth_req); + prs_mem_free(&rdata ); + prs_mem_free(&rparam ); - return valid_ack; + return valid_ack; } /**************************************************************************** @@ -639,54 +631,55 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) { - RPC_IFACE abstract; - RPC_IFACE transfer; - int fnum; - - /******************* open the pipe *****************/ - 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, cli_errstr(cli))); - return False; - } - - cli->nt_pipe_fnum = (uint16)fnum; - - /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) - { - DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", - cli_errstr(cli))); - cli_close(cli, cli->nt_pipe_fnum); - return False; - } - - /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, pipe_name, &abstract, &transfer, encrypted)) - { - DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", cli_errstr(cli))); - cli_close(cli, cli->nt_pipe_fnum); - return False; - } - - /* - * 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; + RPC_IFACE abstract; + RPC_IFACE transfer; + int fnum; + + /******************* open the pipe *****************/ + 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, cli_errstr(cli))); + return False; + } + + cli->nt_pipe_fnum = (uint16)fnum; + + /**************** Set Named Pipe State ***************/ + if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) + { + DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", + cli_errstr(cli))); + cli_close(cli, cli->nt_pipe_fnum); + return False; + } + + /******************* bind request on pipe *****************/ + if (!rpc_pipe_bind(cli, pipe_name, &abstract, &transfer, encrypted)) + { + DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", + cli_errstr(cli))); + cli_close(cli, cli->nt_pipe_fnum); + return False; + } + + /* + * 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; } /**************************************************************************** @@ -695,5 +688,5 @@ close the session void cli_nt_session_close(struct cli_state *cli) { - cli_close(cli, cli->nt_pipe_fnum); + cli_close(cli, cli->nt_pipe_fnum); } -- cgit From c07b2bdf9032c870f7f50a9671e8d9fb0a56739a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 6 Oct 1998 22:03:04 +0000 Subject: dce/rpc (This used to be commit eb279cabd059603b6c8d9b74e4fd31c4ffe87593) --- source3/rpc_client/cli_pipe.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0258c1a0e7..392877f2dc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -293,9 +293,10 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name, char *domain) { - RPC_HDR_RB hdr_rb; - RPC_HDR hdr; - RPC_AUTH_NTLMSSP_REQ ntlmssp_req; + RPC_HDR_RB hdr_rb; + RPC_HDR hdr; + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; /* create the bind request RPC_HDR_RB */ make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0, @@ -307,12 +308,17 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, if (auth_req != NULL) { - /* - * I have a feeling this is broken right now... JRA. - */ - make_rpc_auth_ntlmssp_req(&ntlmssp_req, "NTLMSSP", 0x1, - 0x0000b2b3, my_name, domain); - smb_io_rpc_auth_ntlmssp_req("", &ntlmssp_req, auth_req, 0); + make_rpc_auth_verifier(&auth_verifier, + 0x0a, 0x06, 0x00, + "NTLMSSP", NTLMSSP_NEGOTIATE); + + smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_req, 0); + mem_realloc_data(auth_req->data, auth_req->offset); + + make_rpc_auth_ntlmssp_neg(&ntlmssp_neg, + 0x0000b2b3, my_name, domain); + + smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, auth_req, 0); mem_realloc_data(auth_req->data, auth_req->offset); } -- cgit From 48b31ae44fb2a1961bd738b0b3e7a986259168a2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 7 Oct 1998 21:42:24 +0000 Subject: dce/rpc (This used to be commit 6677b888bdb45df00646eb7cc13005b9465ff971) --- source3/rpc_client/cli_pipe.c | 87 ++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 29 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 392877f2dc..44440d9fba 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -289,12 +289,15 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, 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, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name, char *domain) { RPC_HDR_RB hdr_rb; RPC_HDR hdr; + RPC_HDR_AUTH hdr_auth; RPC_AUTH_VERIFIER auth_verifier; RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; @@ -306,10 +309,13 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, smb_io_rpc_hdr_rb("", &hdr_rb, rhdr_rb, 0); mem_realloc_data(rhdr_rb->data, rhdr_rb->offset); - if (auth_req != NULL) + if (auth_req != NULL && rhdr_auth != NULL && auth_ntlm != NULL) { + make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00); + smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rhdr_auth, 0); + mem_realloc_data(rhdr_auth->data, rhdr_auth->offset); + make_rpc_auth_verifier(&auth_verifier, - 0x0a, 0x06, 0x00, "NTLMSSP", NTLMSSP_NEGOTIATE); smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_req, 0); @@ -325,7 +331,8 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, /* create the request RPC_HDR */ make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(), rhdr_rb->offset + 0x10, - auth_req != NULL ? auth_req->offset : 0); + 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); @@ -336,25 +343,18 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, /*** link rpc header, bind acknowledgment and authentication responses ***/ /***/ - rhdr->data->offset.start = 0; - rhdr->data->offset.end = rhdr->offset; - rhdr->data->next = rhdr_rb->data; - if (auth_req != NULL) { - rhdr_rb->data->offset.start = rhdr->offset; - rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; - rhdr_rb->data->next = auth_req->data; - - auth_req->data->offset.start = rhdr->offset + rhdr_rb->offset; - auth_req->data->offset.end = rhdr->offset + auth_req->offset + rhdr_rb->offset; - auth_req->data->next = 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 ); } else { - rhdr_rb->data->offset.start = rhdr->offset; - rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset; - rhdr_rb->data->next = NULL; + prs_link(NULL, rhdr , rhdr_rb); + prs_link(rhdr, rhdr_rb, NULL ); } return True; @@ -578,7 +578,9 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, { 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; @@ -592,15 +594,20 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, if (!valid_pipe_name(pipe_name, abstract, transfer)) return False; - prs_init(&hdr , 0x10 , 4, 0x0 , False); - prs_init(&hdr_rb , 1024 , 4, SAFETY_MARGIN, False); - prs_init(&auth_req, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False); + 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); prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True ); prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True ); - create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL, - abstract, transfer, global_myname, global_myworkgroup); + create_rpc_bind_req(&hdr, &hdr_rb, + ntlmssp_auth ? &hdr_auth : NULL, + ntlmssp_auth ? &auth_req : NULL, + ntlmssp_auth ? &auth_ntlm : NULL, + abstract, transfer, global_myname, global_myworkgroup); /* this is a hack due to limitations in rpc_api_pipe */ prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False); @@ -609,7 +616,10 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, /* send data on \PIPE\. receive a response */ if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata)) { - RPC_HDR_BA hdr_ba; + RPC_HDR_BA hdr_ba; + RPC_HDR_AUTH rhdr_auth; + RPC_AUTH_VERIFIER rhdr_verf; + RPC_AUTH_NTLMSSP_CHAL rhdr_chal; DEBUG(5, ("rpc_api_pipe: return OK\n")); @@ -619,14 +629,33 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, { valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer); } + + if (valid_ack && ntlmssp_auth) + { + smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0); + if (rdata.offset == 0) valid_ack = False; + } + + if (valid_ack && ntlmssp_auth) + { + smb_io_rpc_auth_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; + } } - prs_mem_free(&data ); - prs_mem_free(&hdr ); - prs_mem_free(&hdr_rb ); - prs_mem_free(&auth_req); - prs_mem_free(&rdata ); - prs_mem_free(&rparam ); + 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; } -- cgit From 6909350ed9b87875ee40191b2e636c6049749195 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 8 Oct 1998 23:57:46 +0000 Subject: dce/rpc (This used to be commit 62fdeef1b79c5c4c9bf0e860881651711bb80b9a) --- source3/rpc_client/cli_pipe.c | 258 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 234 insertions(+), 24 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 44440d9fba..f7060e0f71 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -286,12 +286,12 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, - 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 call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name, char *domain) { @@ -303,7 +303,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, /* create the bind request RPC_HDR_RB */ make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0, - 0x1, 0x0, 0x1, abstract, transfer); + 0x1, 0x0, 0x1, abstract, transfer); /* stream the bind request data */ smb_io_rpc_hdr_rb("", &hdr_rb, rhdr_rb, 0); @@ -329,7 +329,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, } /* create the request RPC_HDR */ - make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(), + make_rpc_hdr(&hdr, RPC_BIND, 0x0, call_id, rhdr_rb->offset + 0x10, auth_req != NULL ? auth_req ->offset : 0 + auth_ntlm != NULL ? auth_ntlm->offset : 0); @@ -361,6 +361,71 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, } +/******************************************************************* + 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. + + ********************************************************************/ +static BOOL create_rpc_bind_resp(struct pwd_info *pwd, + char *domain, char *user_name, char *my_name, + uint32 ntlmssp_cli_flgs, + uint32 call_id, + prs_struct *rhdr, + prs_struct *rhdr_autha, + prs_struct *auth_resp) +{ + 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; + + 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); + + make_rpc_auth_verifier(&auth_verifier, + "NTLMSSP", NTLMSSP_AUTH); + + smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_resp, 0); + mem_realloc_data(auth_resp->data, auth_resp->offset); + + pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf); + + make_rpc_auth_ntlmssp_resp(&ntlmssp_resp, + lm_owf, nt_owf, + domain, user_name, my_name, + ntlmssp_cli_flgs); + + smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0); + mem_realloc_data(auth_resp->data, auth_resp->offset); + + /* create the request RPC_HDR */ + make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, call_id, + auth_resp->offset + rhdr_autha->offset + 0x10, + auth_resp->offset); + + smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0); + mem_realloc_data(rhdr->data, rhdr->offset); + + if (rhdr->data == NULL || rhdr_autha->data == NULL) return False; + + /***/ + /*** link rpc header and authentication responses ***/ + /***/ + + prs_link(NULL , rhdr , rhdr_autha); + prs_link(rhdr , rhdr_autha , auth_resp ); + prs_link(rhdr_autha, auth_resp , NULL ); + + return True; +} + + /******************************************************************* creates a DCE/RPC bind request @@ -370,8 +435,10 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, ********************************************************************/ -static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len) +static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len, + int auth_len) { + uint32 alloc_hint; RPC_HDR_REQ hdr_req; RPC_HDR hdr; @@ -380,10 +447,22 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len) /* create the rpc header RPC_HDR */ make_rpc_hdr(&hdr , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST, - get_rpc_call_id(), data_len, 0); + get_rpc_call_id(), data_len, auth_len); + + if (auth_len != 0) + { + alloc_hint = data_len - 0x18 - auth_len - 12; + } + else + { + alloc_hint = data_len - 0x18; + } + + 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, data_len, op_num); + make_rpc_hdr_req(&hdr_req, alloc_hint, op_num); /* stream-time... */ smb_io_rpc_hdr ("hdr ", &hdr , rhdr, 0); @@ -405,32 +484,85 @@ 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; BOOL ret; + BOOL auth_verify; + BOOL auth_seal; + uint32 crc32; - data_len = data->offset + 0x18; + 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; - prs_init(&hdr , data_len, 4, SAFETY_MARGIN, False); - prs_init(&rparam, 0 , 4, 0 , True ); + 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 ); - create_rpc_request(&hdr, op_num, data_len); + create_rpc_request(&hdr, op_num, data_len, auth_len); + + if (auth_seal) + { + crc32 = crc32_calc_buffer(data->offset, mem_data(&data->data, 0)); + NTLMSSPcalc(cli->ntlmssp_hash, mem_data(&data->data, 0), data->offset); + } + + if (auth_verify) + { + RPC_AUTH_NTLMSSP_CHK chk; + RPC_HDR_AUTH rhdr_auth; + + make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x02); + smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0); + + make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, 0); + smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0); + NTLMSSPcalc(cli->ntlmssp_hash, mem_data(&auth_verf.data, 4), 12); + } + + 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 ); + } + else + { + prs_link(NULL, &hdr, data); + prs_link(&hdr, data, NULL); + } mem_realloc_data(hdr.data, data_len); - hdr.data->offset.end = data_len; - mem_buf_copy(mem_data(&(hdr.data), 0x18), data->data, 0, data->offset); - ret = rpc_api_pipe(cli, 0x0026, NULL, &hdr, &rparam, rdata); + DEBUG(100,("data_len: %x data_calc_len: %x\n", + data_len, mem_buf_len(data->data))); + + /* this is a hack due to limitations in rpc_api_pipe */ + prs_init(&dataa, mem_buf_len(hdr.data), 4, 0x0, False); + mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data)); - prs_mem_free(&rparam); - prs_mem_free(&hdr); + ret = rpc_api_pipe(cli, 0x0026, NULL, &dataa, &rparam, rdata); + + prs_mem_free(&hdr_auth ); + prs_mem_free(&auth_verf); + prs_mem_free(&rparam ); + prs_mem_free(&hdr ); + prs_mem_free(&dataa ); return ret; } - /**************************************************************************** do an rpc bind ****************************************************************************/ @@ -574,11 +706,13 @@ do an rpc bind ****************************************************************************/ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, - RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth) + RPC_IFACE *abstract, RPC_IFACE *transfer, + char *my_name) { prs_struct hdr; prs_struct hdr_rb; prs_struct hdr_auth; + prs_struct hdr_autha; prs_struct auth_req; prs_struct auth_ntlm; prs_struct data; @@ -586,9 +720,13 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, prs_struct rparam; BOOL valid_ack = False; + BOOL ntlmssp_auth = cli->ntlmssp_cli_flgs != 0; + uint32 call_id; if (pipe_name == NULL || abstract == NULL || transfer == NULL) - return False; + { + return False; + } DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name)); @@ -600,14 +738,16 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, prs_init(&auth_req , ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False); prs_init(&auth_ntlm, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False); - prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True ); - prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True ); + prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True); + prs_init(&rparam , 0 , 4, SAFETY_MARGIN, True); + 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, - abstract, transfer, global_myname, global_myworkgroup); + call_id, + abstract, transfer, global_myname, cli->domain); /* this is a hack due to limitations in rpc_api_pipe */ prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False); @@ -646,6 +786,57 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, 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->pwd, rhdr_chal.challenge); + 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); + bzero(lm_hash, sizeof(lm_hash)); + NTLMSSPhash(cli->ntlmssp_hash, p24); + + create_rpc_bind_resp(&cli->pwd, cli->domain, + cli->user_name, global_myname, + cli->ntlmssp_cli_flgs, + call_id, + &hdra, &hdr_autha, &auth_resp); + + /* 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, cli->nt_pipe_fnum, 0x0008, + dataa.data->data, 0, + dataa.data->data_used) < 0) + { + valid_ack = False; + } + + if (valid_ack) + { + cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags; + } + + prs_mem_free(&hdra); + prs_mem_free(&dataa); + prs_mem_free(&hdr_autha); + prs_mem_free(&auth_resp); + } } prs_mem_free(&data ); @@ -690,7 +881,26 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) } /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, pipe_name, &abstract, &transfer, encrypted)) + + if (encrypted) + { + cli->ntlmssp_cli_flgs = + NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_OEM | + NTLMSSP_NEGOTIATE_SIGN | + NTLMSSP_NEGOTIATE_SEAL | + NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_ALWAYS_SIGN | + NTLMSSP_NEGOTIATE_00001000 | + NTLMSSP_NEGOTIATE_00002000; + DEBUG(5,("cli_nt_session_open: neg_flags: %lx\n", + cli->ntlmssp_cli_flgs)); + } + + if (!rpc_pipe_bind(cli, pipe_name, + &abstract, &transfer, + global_myname)) { DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", cli_errstr(cli))); @@ -699,8 +909,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) } /* - * Setup the remote server name prefixed by \ and the machine account 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); -- cgit From 755986764f5a6b0ec25c7f20fde0a80eb4d121ba Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 19:05:19 +0000 Subject: dce/rpc (This used to be commit 32d0f5e4a564686ad6b270dd24423ee49a81f223) --- source3/rpc_client/cli_pipe.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f7060e0f71..761f23f885 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -293,7 +293,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, prs_struct *auth_ntlm, uint32 call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, - char *my_name, char *domain) + char *my_name, char *domain, uint32 neg_flags) { RPC_HDR_RB hdr_rb; RPC_HDR hdr; @@ -322,7 +322,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, mem_realloc_data(auth_req->data, auth_req->offset); make_rpc_auth_ntlmssp_neg(&ntlmssp_neg, - 0x0000b2b3, my_name, domain); + neg_flags, my_name, domain); smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, auth_req, 0); mem_realloc_data(auth_req->data, auth_req->offset); @@ -451,7 +451,7 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len, if (auth_len != 0) { - alloc_hint = data_len - 0x18 - auth_len - 12; + alloc_hint = data_len - 0x18 - auth_len - 10; } else { @@ -522,7 +522,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, RPC_AUTH_NTLMSSP_CHK chk; RPC_HDR_AUTH rhdr_auth; - make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x02); + make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08); smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0); make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, 0); @@ -747,7 +747,8 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, ntlmssp_auth ? &auth_req : NULL, ntlmssp_auth ? &auth_ntlm : NULL, call_id, - abstract, transfer, global_myname, cli->domain); + abstract, transfer, + global_myname, cli->domain, cli->ntlmssp_cli_flgs); /* this is a hack due to limitations in rpc_api_pipe */ prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False); @@ -884,16 +885,19 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) if (encrypted) { - cli->ntlmssp_cli_flgs = + cli->ntlmssp_cli_flgs = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_OEM | +/* NTLMSSP_NEGOTIATE_OEM | + */ NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_LM_KEY | NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_ALWAYS_SIGN | + NTLMSSP_NEGOTIATE_ALWAYS_SIGN; +/* NTLMSSP_NEGOTIATE_00001000 | NTLMSSP_NEGOTIATE_00002000; + */ DEBUG(5,("cli_nt_session_open: neg_flags: %lx\n", cli->ntlmssp_cli_flgs)); } -- cgit From 4e004a0b5e7521a361444f6d67a3c2910c5688c2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 19:34:57 +0000 Subject: basic client-side ntcreateX function (hard-wired values except filename) (This used to be commit caeb99201a1471bd709b4e8f07c57e5caabf0795) --- source3/rpc_client/cli_pipe.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 761f23f885..0b9a4e95e5 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -863,22 +863,37 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) int fnum; /******************* open the pipe *****************/ - if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) + if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS)) { - DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n", - pipe_name, cli->desthost, cli_errstr(cli))); - return False; + 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, cli_errstr(cli))); + return False; + } + + 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, cli_errstr(cli))); + return False; + } - cli->nt_pipe_fnum = (uint16)fnum; + cli->nt_pipe_fnum = (uint16)fnum; + + /**************** Set Named Pipe State ***************/ + if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) + { + DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", + cli_errstr(cli))); + cli_close(cli, cli->nt_pipe_fnum); + return False; + } - /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) - { - DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", - cli_errstr(cli))); - cli_close(cli, cli->nt_pipe_fnum); - return False; } /******************* bind request on pipe *****************/ -- cgit From 8158620124504a1ece1f1191cb8f273709039bd2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 20:17:11 +0000 Subject: dce/rpc. (This used to be commit e0445419b2d50ae6efef36f4f295ebcfdbf1ad82) --- source3/rpc_client/cli_pipe.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0b9a4e95e5..732161ad82 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -37,12 +37,17 @@ extern pstring global_myname; /******************************************************************** rpc pipe call id ********************************************************************/ +static uint32 call_id = 0; static uint32 get_rpc_call_id(void) { - static uint32 call_id = 1; return ++call_id; } +static uint32 reset_rpc_call_id(void) +{ + call_id = 0; +} + /******************************************************************* uses SMBreadX to get rest of rpc data ********************************************************************/ @@ -451,7 +456,7 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len, if (auth_len != 0) { - alloc_hint = data_len - 0x18 - auth_len - 10; + alloc_hint = data_len - 0x18 - auth_len - 16; } else { @@ -849,6 +854,8 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, prs_mem_free(&rdata ); prs_mem_free(&rparam ); + reset_rpc_call_id(); + return valid_ack; } @@ -862,6 +869,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) RPC_IFACE transfer; int fnum; + reset_rpc_call_id(); + /******************* open the pipe *****************/ if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS)) { -- cgit From abb67ee6deac030c4bc38e166cd3e3ab086ae285 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 20:31:52 +0000 Subject: signed / unsigned issues spotted by herb (This used to be commit 0b90442021aa3adb5ae7f09c53c9e54c7655d8c5) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 732161ad82..d21840ec46 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -519,7 +519,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, if (auth_seal) { crc32 = crc32_calc_buffer(data->offset, mem_data(&data->data, 0)); - NTLMSSPcalc(cli->ntlmssp_hash, mem_data(&data->data, 0), data->offset); + NTLMSSPcalc(cli->ntlmssp_hash, (uchar*)mem_data(&data->data, 0), data->offset); } if (auth_verify) @@ -532,7 +532,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, 0); smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0); - NTLMSSPcalc(cli->ntlmssp_hash, mem_data(&auth_verf.data, 4), 12); + NTLMSSPcalc(cli->ntlmssp_hash, (uchar*)mem_data(&auth_verf.data, 4), 12); } if (auth_seal || auth_verify) -- cgit From 935dc98f6670ba630bd2086ef9eddcc94a0562e2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 14 Oct 1998 06:29:20 +0000 Subject: dce/rpc (This used to be commit 69f5f9f88935de1f63ffc9aa19c0629b395e66e6) --- source3/rpc_client/cli_pipe.c | 166 +++++++++++++++++++++++++++++++----------- 1 file changed, 125 insertions(+), 41 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d21840ec46..93befe7ac4 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -114,14 +114,12 @@ static BOOL rpc_read(struct cli_state *cli, /**************************************************************************** checks the header ****************************************************************************/ -static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, +static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, BOOL *first, BOOL *last, int *len) { - RPC_HDR rhdr; - DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used)); - smb_io_rpc_hdr ("rpc_hdr ", &rhdr , rdata, 0); + smb_io_rpc_hdr ("rpc_hdr ", rhdr , rdata, 0); if (!rdata->offset || rdata->offset != 0x10) { @@ -132,14 +130,78 @@ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type, DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n", 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 ) = rhdr.frag_len - rdata->data->data_used; - (*pkt_type) = rhdr.pkt_type; + (*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; return True; } +/**************************************************************************** + decrypt data on an rpc pipe + ****************************************************************************/ + +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 = (uchar*)mem_data(&rdata->data, 0x18); + + 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); + + DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n", + len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal))); + +/* RPC_HDR_AUTH rhdr_auth; + prs_struct auth_req; + prs_init(&auth_req , 0x10, 4, 0, True); + smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0); + prs_mem_free(&auth_req); + +*/ + if (auth_seal) + { + DEBUG(10,("rpc_auth_pipe: seal\n")); + dump_data(100, reply_data, data_len); + NTLMSSPcalc(cli->ntlmssp_hash, reply_data, data_len); + dump_data(100, reply_data, data_len); + } + + if (auth_verify) + { + prs_struct auth_verf; + char *data = (uchar*)mem_data(&rdata->data, len - auth_len); + prs_init(&auth_verf, 0x08, 4, 0, True); + DEBUG(10,("rpc_auth_pipe: verify\n")); + dump_data(100, data, auth_len); + NTLMSSPcalc(cli->ntlmssp_hash, data + 4, auth_len - 4); + 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 (chk.crc32 != crc32 || + chk.ver != NTLMSSP_SIGN_VERSION || + chk.seq_num != cli->ntlmssp_seq_num++) + { + DEBUG(5,("rpc_auth_pipe: verify failed - crc %x ver %x seq %d\n", + crc32, NTLMSSP_SIGN_VERSION, cli->ntlmssp_seq_num)); + DEBUG(5,("rpc_auth_pipe: verify expect - crc %x ver %x seq %d\n", + chk.crc32, chk.ver, chk.seq_num)); + return False; + } + } + return True; +} + + /**************************************************************************** send data on an rpc pipe, which *must* be in one fragment. receive response data from an rpc pipe, which may be large... @@ -163,12 +225,13 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *rparam, prs_struct *rdata) { int len; + int alloc_hint = 0; uint16 setup[2]; /* only need 2 uint16 setup parameters */ uint32 err; - uint8 pkt_type = 0xff; BOOL first = True; BOOL last = True; + RPC_HDR rhdr; /* * Setup the pointers from the incoming. @@ -215,12 +278,16 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, rdata->data->margin = 0; if (rparam) rparam->data->margin = 0; - if (!rpc_check_hdr(rdata, &pkt_type, &first, &last, &len)) return False; + if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) + { + return False; + } - if (pkt_type == RPC_RESPONSE) + if (rhdr.pkt_type == RPC_RESPONSE) { RPC_HDR_RESP rhdr_resp; smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0); + alloc_hint = rhdr_resp.alloc_hint; } DEBUG(5,("rpc_api_pipe: len left: %d smbtrans read: %d\n", @@ -236,6 +303,11 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, } } + if (rhdr.auth_len != 0 && !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) { @@ -245,39 +317,43 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, while (!last) /* read more fragments until we get the last one */ { - RPC_HDR rhdr; RPC_HDR_RESP rhdr_resp; int num_read; prs_struct hps; - prs_init(&hps, 0x18, 4, 0, True); + prs_init(&hps, 0x8, 4, 0, True); num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18); DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); if (num_read != 0x18) return False; - smb_io_rpc_hdr ("rpc_hdr ", &rhdr , &hps, 0); + if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len)) + { + return False; + } + smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0); prs_mem_free(&hps); if (cli_error(cli, NULL, &err)) return False; - first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST); - last = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST ); - if (first) { DEBUG(0,("rpc_api_pipe: wierd rpc header received\n")); return False; } - len = rhdr.frag_len - hps.offset; if (!rpc_read(cli, rdata, len, rdata->data->data_used)) { return False; } + + if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) + { + return False; + } } return True; @@ -316,7 +392,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, if (auth_req != NULL && rhdr_auth != NULL && auth_ntlm != NULL) { - make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00); + 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); @@ -335,9 +411,12 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, /* create the request RPC_HDR */ make_rpc_hdr(&hdr, RPC_BIND, 0x0, 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); + (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); @@ -505,7 +584,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, 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; + auth_len = (auth_verify ? 16 : 0); data_len = data->offset + auth_len + (auth_verify ? 8 : 0) + 0x18; data->data->offset.end = data->offset; @@ -522,15 +601,19 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, NTLMSSPcalc(cli->ntlmssp_hash, (uchar*)mem_data(&data->data, 0), data->offset); } - if (auth_verify) + if (auth_seal || auth_verify) { - RPC_AUTH_NTLMSSP_CHK chk; RPC_HDR_AUTH rhdr_auth; - make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08); + 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); + } - make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, 0); + if (auth_verify) + { + RPC_AUTH_NTLMSSP_CHK chk; + + 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(cli->ntlmssp_hash, (uchar*)mem_data(&auth_verf.data, 4), 12); } @@ -737,11 +820,11 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, if (!valid_pipe_name(pipe_name, abstract, transfer)) return False; - 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); + 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); prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True); prs_init(&rparam , 0 , 4, SAFETY_MARGIN, True); @@ -810,11 +893,6 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False); pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge); - 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); - bzero(lm_hash, sizeof(lm_hash)); - NTLMSSPhash(cli->ntlmssp_hash, p24); create_rpc_bind_resp(&cli->pwd, cli->domain, cli->user_name, global_myname, @@ -822,6 +900,12 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, call_id, &hdra, &hdr_autha, &auth_resp); + 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); + bzero(lm_hash, sizeof(lm_hash)); + NTLMSSPhash(cli->ntlmssp_hash, p24); + /* 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)); @@ -909,16 +993,16 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) if (encrypted) { - cli->ntlmssp_cli_flgs = - NTLMSSP_NEGOTIATE_UNICODE | -/* NTLMSSP_NEGOTIATE_OEM | - */ + cli->ntlmssp_cli_flgs = 0xb2b3; +/* NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_OEM | + NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_LM_KEY | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_ALWAYS_SIGN; -/* + NTLMSSP_NEGOTIATE_00001000 | NTLMSSP_NEGOTIATE_00002000; */ -- cgit From 948f81a5920c5204438e41d4fd41a32948ce7321 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 14 Oct 1998 07:00:00 +0000 Subject: warnings spotted by ./configure.developer options (This used to be commit 29434bf195b438f4ab41a10ac5ce03f9c2d2ac2f) --- source3/rpc_client/cli_pipe.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 93befe7ac4..405b6abe66 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -37,17 +37,12 @@ extern pstring global_myname; /******************************************************************** rpc pipe call id ********************************************************************/ -static uint32 call_id = 0; static uint32 get_rpc_call_id(void) { + static uint32 call_id = 0; return ++call_id; } -static uint32 reset_rpc_call_id(void) -{ - call_id = 0; -} - /******************************************************************* uses SMBreadX to get rest of rpc data ********************************************************************/ @@ -372,7 +367,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, prs_struct *rhdr_auth, prs_struct *auth_req, prs_struct *auth_ntlm, - uint32 call_id, + uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name, char *domain, uint32 neg_flags) { @@ -410,7 +405,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, } /* create the request RPC_HDR */ - make_rpc_hdr(&hdr, RPC_BIND, 0x0, call_id, + 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) + @@ -456,7 +451,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, static BOOL create_rpc_bind_resp(struct pwd_info *pwd, char *domain, char *user_name, char *my_name, uint32 ntlmssp_cli_flgs, - uint32 call_id, + uint32 rpc_call_id, prs_struct *rhdr, prs_struct *rhdr_autha, prs_struct *auth_resp) @@ -489,7 +484,7 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, mem_realloc_data(auth_resp->data, auth_resp->offset); /* create the request RPC_HDR */ - make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, call_id, + make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id, auth_resp->offset + rhdr_autha->offset + 0x10, auth_resp->offset); @@ -800,7 +795,6 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, prs_struct hdr; prs_struct hdr_rb; prs_struct hdr_auth; - prs_struct hdr_autha; prs_struct auth_req; prs_struct auth_ntlm; prs_struct data; @@ -809,7 +803,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, BOOL valid_ack = False; BOOL ntlmssp_auth = cli->ntlmssp_cli_flgs != 0; - uint32 call_id; + uint32 rpc_call_id; if (pipe_name == NULL || abstract == NULL || transfer == NULL) { @@ -829,12 +823,12 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True); prs_init(&rparam , 0 , 4, SAFETY_MARGIN, True); - call_id = get_rpc_call_id(); + 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, - call_id, + rpc_call_id, abstract, transfer, global_myname, cli->domain, cli->ntlmssp_cli_flgs); @@ -897,7 +891,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, create_rpc_bind_resp(&cli->pwd, cli->domain, cli->user_name, global_myname, cli->ntlmssp_cli_flgs, - call_id, + rpc_call_id, &hdra, &hdr_autha, &auth_resp); pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL); @@ -938,8 +932,6 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, prs_mem_free(&rdata ); prs_mem_free(&rparam ); - reset_rpc_call_id(); - return valid_ack; } @@ -953,8 +945,6 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) RPC_IFACE transfer; int fnum; - reset_rpc_call_id(); - /******************* open the pipe *****************/ if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS)) { @@ -1006,7 +996,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) NTLMSSP_NEGOTIATE_00001000 | NTLMSSP_NEGOTIATE_00002000; */ - DEBUG(5,("cli_nt_session_open: neg_flags: %lx\n", + DEBUG(5,("cli_nt_session_open: neg_flags: %x\n", cli->ntlmssp_cli_flgs)); } -- cgit From a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 15 Oct 1998 05:47:29 +0000 Subject: bug-fixing against: AS/U: it returns dce/rpc "first" and "last" bits _clear_ in a bind/ack response, when they should be set in a (small) packet. they also, in the bind/ack do not set a secondary address string at all, so we can't check against that... Win95: client-side dce/rpc code is a bit odd. it does a "WaitNamedPipeState" and has slightly different pipe-naming (\PIPE\LANMAN is joined by \PIPE\SRVSVC, \PIPE\WINREG etc whereas nt just has \PIPE\LANMAN and \PIPE\). Win95-USRMGR.EXE: added LsaOpenPolicy (renamed existing to LsaOpenPolicy2). added SamrConnect (renamed existing to SamrConnect2). (This used to be commit a7fccd807b938cbb51002ebae8c7a48b40dbb655) --- source3/rpc_client/cli_pipe.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 405b6abe66..4ea38fa828 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -51,7 +51,7 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 rdata_offset) { - int size = 0x1630; + int size = cli->max_recv_frag; int file_offset = rdata_offset; int num_read; char *data = rdata->data->data; @@ -249,6 +249,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, setup[0] = cmd; setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ + DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, cli->nt_pipe_fnum)); + /* send the data: receive a response. */ if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, setup, 2, 0, /* Setup, length, max */ @@ -278,6 +280,16 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, return False; } + 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; @@ -731,7 +743,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * { int i = 0; - while ((pipe_names[i].client_pipe != NULL)) + 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 )); @@ -746,10 +758,10 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * } else { - DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n", + DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n", pipe_names[i].server_pipe , hdr_ba->addr.str)); - return False; + break; } } else @@ -853,6 +865,12 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer); } + if (valid_ack) + { + cli->max_xmit_frag = hdr_ba.bba.max_tsize; + cli->max_recv_frag = hdr_ba.bba.max_rsize; + } + if (valid_ack && ntlmssp_auth) { smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0); -- cgit From d4a82ea26d5b9501f210a5c441b1ac09c256a187 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 16 Oct 1998 20:07:02 +0000 Subject: rpc client mods (ntlmssp flags) (This used to be commit 16256f86bf451535c7955b8f51a9b88fc33a8e4d) --- source3/rpc_client/cli_pipe.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4ea38fa828..9a54e15dae 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -953,11 +953,21 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, return valid_ack; } +/**************************************************************************** + set ntlmssp negotiation flags + ****************************************************************************/ + +BOOL cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) +{ + cli->ntlmssp_cli_flgs = ntlmssp_flgs; +} + + /**************************************************************************** open a session ****************************************************************************/ -BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) +BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) { RPC_IFACE abstract; RPC_IFACE transfer; @@ -999,25 +1009,6 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted) /******************* bind request on pipe *****************/ - if (encrypted) - { - cli->ntlmssp_cli_flgs = 0xb2b3; -/* NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_OEM | - - NTLMSSP_NEGOTIATE_SIGN | - NTLMSSP_NEGOTIATE_SEAL | - NTLMSSP_NEGOTIATE_LM_KEY | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_ALWAYS_SIGN; - - NTLMSSP_NEGOTIATE_00001000 | - NTLMSSP_NEGOTIATE_00002000; - */ - DEBUG(5,("cli_nt_session_open: neg_flags: %x\n", - cli->ntlmssp_cli_flgs)); - } - if (!rpc_pipe_bind(cli, pipe_name, &abstract, &transfer, global_myname)) -- cgit From 97f0c9d55014db221fdceaaf07318ae9df9688a1 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 16 Oct 1998 21:36:19 +0000 Subject: made pass_check_smb() available for dce/rpc use. (This used to be commit 95e8a910c5d9ba0ef57669fb1256eaa932e0bb09) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9a54e15dae..0fe248068e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -957,7 +957,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, set ntlmssp negotiation flags ****************************************************************************/ -BOOL cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) +void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) { cli->ntlmssp_cli_flgs = ntlmssp_flgs; } -- cgit From fc62d6bf368c950e1e51bc42771cce8b299df42c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Oct 1998 17:41:13 +0000 Subject: Small tidyups for gcc in 'preen' mode.... Jeremy. (This used to be commit 60dc1a4a00a22088d33369588b0d5eb292cf084a) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0fe248068e..f252c99d97 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -585,7 +585,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, BOOL ret; BOOL auth_verify; BOOL auth_seal; - uint32 crc32; + uint32 crc32 = 0; 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); -- cgit From 01de6030843f5f402dee8bf72f564a91ae8437ca Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 19 Oct 1998 17:32:10 +0000 Subject: - dce/rpc code - removed debug info in struni2 and unistr2 (security risk) - rpc_pipe function was getting pointer to data then calling realloc *dur* - password check function, the start of "credential checking", user, wks, domain, pass as the credentials (not just user,pass which is incorrect in a domain context) - cli_write needs to return ssize_t not size_t, because total can be -1 if the write fails. - fixed signed / unsigned warnings (how come i don't get those any more when i compile with gcc???) - nt password change added in smbd. yes, jeremy, i verified that the SMBtrans2 version still works. (This used to be commit fcfb40d2b0fc565ee4f66b3a3761c246366a2ef3) --- source3/rpc_client/cli_pipe.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f252c99d97..08b3575733 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -142,7 +142,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, RPC_AUTH_NTLMSSP_CHK chk; uint32 crc32; int data_len = len - 0x18 - auth_len - 8; - char *reply_data = (uchar*)mem_data(&rdata->data, 0x18); + char *reply_data = mem_data(&rdata->data, 0x18); 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); @@ -150,13 +150,8 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n", len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal))); -/* RPC_HDR_AUTH rhdr_auth; - prs_struct auth_req; - prs_init(&auth_req , 0x10, 4, 0, True); - smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0); - prs_mem_free(&auth_req); + if (reply_data == NULL) return False; -*/ if (auth_seal) { DEBUG(10,("rpc_auth_pipe: seal\n")); @@ -165,14 +160,32 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, dump_data(100, reply_data, data_len); } + 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)) + { + return False; + } + } + if (auth_verify) { prs_struct auth_verf; char *data = (uchar*)mem_data(&rdata->data, len - auth_len); - prs_init(&auth_verf, 0x08, 4, 0, True); + if (data == NULL) return False; + DEBUG(10,("rpc_auth_pipe: verify\n")); dump_data(100, data, auth_len); - NTLMSSPcalc(cli->ntlmssp_hash, data + 4, auth_len - 4); + NTLMSSPcalc(cli->ntlmssp_hash, (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); @@ -182,14 +195,8 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, if (auth_verify) { crc32 = crc32_calc_buffer(data_len, reply_data); - if (chk.crc32 != crc32 || - chk.ver != NTLMSSP_SIGN_VERSION || - chk.seq_num != cli->ntlmssp_seq_num++) + if (!rpc_auth_ntlmssp_chk(&chk, crc32 , &cli->ntlmssp_seq_num)) { - DEBUG(5,("rpc_auth_pipe: verify failed - crc %x ver %x seq %d\n", - crc32, NTLMSSP_SIGN_VERSION, cli->ntlmssp_seq_num)); - DEBUG(5,("rpc_auth_pipe: verify expect - crc %x ver %x seq %d\n", - chk.crc32, chk.ver, chk.seq_num)); return False; } } @@ -585,7 +592,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, BOOL ret; BOOL auth_verify; BOOL auth_seal; - uint32 crc32 = 0; + uint32 crc32; 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); @@ -915,8 +922,8 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, 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); - bzero(lm_hash, sizeof(lm_hash)); 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); -- cgit From 1ebeb54932de01323356e8201d465656b8723d46 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 20 Oct 1998 18:27:49 +0000 Subject: some quite important bug-fixes i missed because i transferred the wrong smb.tgz file from my portable. particularly the call to mem_data followed by a realloc of that data in cli_pipe.c's rpc_read() function. smbd responses now use p->rdata_i which is a faked-up pointer into p->rdata's response data. rdata can be very long; rdata_i is limited to point to no more than max_tsize - 0x18 in length. this will make it an almost trivial task to add the encrypted rpc headers after rdata_i, and mem_buf_copy will cope admirably with rhdr chained to rdata_i chained to auth_verifier etc etc... (This used to be commit 05a297e3a98c14360782af4ad0d851638fb5da9a) --- source3/rpc_client/cli_pipe.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 08b3575733..f5587567cd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -54,12 +54,10 @@ static BOOL rpc_read(struct cli_state *cli, int size = cli->max_recv_frag; int file_offset = rdata_offset; int num_read; - char *data = rdata->data->data; + char *data; uint32 err; uint32 new_data_size = rdata->data->data_used + data_to_read; - data += rdata_offset; - file_offset -= rdata_offset; DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n", @@ -71,6 +69,8 @@ static BOOL rpc_read(struct cli_state *cli, DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used)); } + data = rdata->data->data + rdata_offset; + do /* read data using SMBreadX */ { if (size > data_to_read) @@ -84,7 +84,7 @@ static BOOL rpc_read(struct cli_state *cli, DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used)); } - num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset + 0x100000, size); + num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset, size); DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n", file_offset, num_read, data_to_read)); @@ -101,9 +101,10 @@ static BOOL rpc_read(struct cli_state *cli, mem_realloc_data(rdata->data, file_offset + rdata_offset); rdata->data->offset.end = file_offset + rdata_offset; - DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read)); + DEBUG(5,("rpc_read: offset end: 0x%x. data left to read:0x%x\n", + rdata->data->offset.end, data_to_read)); - return data_to_read == 0; + return data_to_read >= 0; } /**************************************************************************** -- cgit From d8f0e60195ff8447df9235f60095c4e2bb4561e7 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 20 Oct 1998 22:37:44 +0000 Subject: signed / unsigned warnings (found by herb). how do i switch on these warnings in gcc????? (This used to be commit 39db385a0c47c11adb6bf3bac89c4bb76f675049) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f5587567cd..1a72f930c5 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -157,7 +157,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, { DEBUG(10,("rpc_auth_pipe: seal\n")); dump_data(100, reply_data, data_len); - NTLMSSPcalc(cli->ntlmssp_hash, reply_data, data_len); + NTLMSSPcalc(cli->ntlmssp_hash, (uchar*)reply_data, data_len); dump_data(100, reply_data, data_len); } @@ -180,7 +180,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, if (auth_verify) { prs_struct auth_verf; - char *data = (uchar*)mem_data(&rdata->data, len - auth_len); + char *data = mem_data(&rdata->data, len - auth_len); if (data == NULL) return False; DEBUG(10,("rpc_auth_pipe: verify\n")); -- cgit From 9307940876a6c226969e9169d55c0408cd7ab032 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 21 Oct 1998 01:35:01 +0000 Subject: fixing smbd encrypted rpcs (data lens, alloc hints, sequence nums argh). put unicode strings after SAMLOGON query regardless of whether it's an NT mailslot or a non-NT mailslot, after having observed this behaviour out of NT machines. (This used to be commit c101113ec20ed0ba633e78e4ee45596cdccaf1b5) --- source3/rpc_client/cli_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1a72f930c5..12e2cc243c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -196,10 +196,11 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, if (auth_verify) { crc32 = crc32_calc_buffer(data_len, reply_data); - if (!rpc_auth_ntlmssp_chk(&chk, crc32 , &cli->ntlmssp_seq_num)) + if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num)) { return False; } + cli->ntlmssp_seq_num++; } return True; } -- cgit From 477350638399b8ff264100c7832c14df719055f3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 21 Oct 1998 16:28:44 +0000 Subject: signed / unsigned issues (This used to be commit bd2fc6bb85739cb8e7ed2254e2a553486daed054) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 12e2cc243c..002c86cafc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -104,7 +104,7 @@ static BOOL rpc_read(struct cli_state *cli, DEBUG(5,("rpc_read: offset end: 0x%x. data left to read:0x%x\n", rdata->data->offset.end, data_to_read)); - return data_to_read >= 0; + return rdata->data.data != NULL; } /**************************************************************************** -- cgit From ac9be4ddca99c5efae518a985b97fb1fb6374289 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 21 Oct 1998 16:54:23 +0000 Subject: oops! (This used to be commit 500e5536bee8ea8e58d5991bfab2cff923068926) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 002c86cafc..e412bad2a7 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -104,7 +104,7 @@ static BOOL rpc_read(struct cli_state *cli, DEBUG(5,("rpc_read: offset end: 0x%x. data left to read:0x%x\n", rdata->data->offset.end, data_to_read)); - return rdata->data.data != NULL; + return rdata->data->data != NULL; } /**************************************************************************** -- cgit From 6e3af45afe237790f1d7cd94ab2b22e1ca772157 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Oct 1998 16:58:34 +0000 Subject: Fixed mainly signed/unsigned issues found by SGI cc in -fullwarn mode. smbd/chgpasswd.c: Fixed (my) stupid bug where I was returning stack based variables. Doh ! smbd/trans2.c: Allows SETFILEINFO as well as QFILEINFO on directory handles. Jeremy. (This used to be commit 0b44d27d0b5cc3948a6c2d78370ccddf1a84cd80) --- source3/rpc_client/cli_pipe.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index e412bad2a7..15025ceef3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -104,7 +104,7 @@ static BOOL rpc_read(struct cli_state *cli, DEBUG(5,("rpc_read: offset end: 0x%x. data left to read:0x%x\n", rdata->data->offset.end, data_to_read)); - return rdata->data->data != NULL; + return True; } /**************************************************************************** @@ -229,7 +229,6 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *rparam, prs_struct *rdata) { int len; - int alloc_hint = 0; uint16 setup[2]; /* only need 2 uint16 setup parameters */ uint32 err; @@ -303,7 +302,6 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, { RPC_HDR_RESP rhdr_resp; smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0); - alloc_hint = rhdr_resp.alloc_hint; } DEBUG(5,("rpc_api_pipe: len left: %d smbtrans read: %d\n", -- cgit From 1ee499385c1ea0b4add82d3d4513ea997d048af1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Oct 1998 16:55:03 +0000 Subject: libsmb/smbdes.c: #ifdef'ed out code prior to removal. rpc_client/cli_pipe.c: Inlined code removed from smbdes.c rpc_server/srv_samr.c: Fixed unused variable warning. rpc_server/srv_util.c: Inlined code removed from smbdes.c Luke - the above changes are the first part of the changes you and I discussed as being neccessary at the CIFS conference. *PLEASE REVIEW THESE CHANGES* - make sure I haven't broken any of the authenticated DCE/RPC code. smbd/nttrans.c: Fixed to allow NT5.0beta2 to use Samba shares with NT SMB support. smbd/open.c: Fixed mkdir when called from nttrans calls. smbd/server.c: Set correct size for strcpy of global_myworkgroup. Jeremy. (This used to be commit d891421d16ff80998dee429227bd391455f9d1a1) --- source3/rpc_client/cli_pipe.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 15025ceef3..e02bb889cc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -922,7 +922,36 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, 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); - NTLMSSPhash(cli->ntlmssp_hash, 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 */ -- cgit From 10a9addc222b29acdcfe6afed0597dd17551fa5c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 12 Nov 1998 04:17:54 +0000 Subject: Moved some code (NTLMSSPcalc) out of smbdes and inline for paranioa resons and my own piece of mind... Jeremy. (This used to be commit 45131501f23ce1eec2f23fe2c1060cd5a2736ec9) --- source3/rpc_client/cli_pipe.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index e02bb889cc..b899c6e08e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -133,6 +133,33 @@ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, return True; } +static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, int len) +{ + unsigned char *hash = cli->ntlmssp_hash; + 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; + + index_i++; + index_j += hash[index_i]; + + 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]; + } + + hash[256] = index_i; + hash[257] = index_j; +} + /**************************************************************************** decrypt data on an rpc pipe ****************************************************************************/ @@ -157,7 +184,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, { DEBUG(10,("rpc_auth_pipe: seal\n")); dump_data(100, reply_data, data_len); - NTLMSSPcalc(cli->ntlmssp_hash, (uchar*)reply_data, data_len); + NTLMSSPcalc_ap(cli, (uchar*)reply_data, data_len); dump_data(100, reply_data, data_len); } @@ -185,7 +212,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, DEBUG(10,("rpc_auth_pipe: verify\n")); dump_data(100, data, auth_len); - NTLMSSPcalc(cli->ntlmssp_hash, (uchar*)(data+4), auth_len - 4); + 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); @@ -612,7 +639,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, if (auth_seal) { crc32 = crc32_calc_buffer(data->offset, mem_data(&data->data, 0)); - NTLMSSPcalc(cli->ntlmssp_hash, (uchar*)mem_data(&data->data, 0), data->offset); + NTLMSSPcalc_ap(cli, (uchar*)mem_data(&data->data, 0), data->offset); } if (auth_seal || auth_verify) @@ -629,7 +656,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, 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(cli->ntlmssp_hash, (uchar*)mem_data(&auth_verf.data, 4), 12); + NTLMSSPcalc_ap(cli, (uchar*)mem_data(&auth_verf.data, 4), 12); } if (auth_seal || auth_verify) -- cgit From 5b863af4c0179f0bee17e77690d99a54cc762531 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 12 Nov 1998 16:07:00 +0000 Subject: cleaning up conflicts between group code not yet committed and changes from yesterday by me, jeremy and andrew. jeremy, your ACB_PWNOTREQ mod would have caused a crash if the user didn't exist (first check should be for smb_pass != NULL) (This used to be commit cbac0f165d351ba9497c222e55e453d781376e58) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b899c6e08e..cb93f61b2d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -130,7 +130,7 @@ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, (*last ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST ); (*len ) = rhdr->frag_len - rdata->data->data_used; - return True; + return rhdr->pkt_type != RPC_FAULT; } static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, int len) -- cgit From 8fc1504ff8204dd1ca735f31c769f6dadf0f88cb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Nov 1998 21:41:01 +0000 Subject: Makefile.in configure configure.in include/config.h.in: Changes for DGUX and UNIXWARE. groupdb/aliasdb.c groupdb/aliasfile.c groupdb/groupfile.c: Don't use snprinf, use slprintf. include/includes.h: Fix YP problem. include/smb.h: Fix ZERO_STRUCTP. lib/util_sock.c: Added strerror() in debugs. passdb/ldap.c: Don't use snprinf, use slprintf. rpc_client/cli_lsarpc.c rpc_client/cli_pipe.c rpc_parse/parse_sec.c rpc_server/srv_pipe.c: Don't use snprinf, use slprintf. script/installman.sh: DGUX changes. smbd/open.c smbd/oplock.c: Fixed gcc warnings. web/swat.c: Changes USER to SWAT_USER. (This used to be commit 4c2b5a00983501e5d4aad1456ba8b5ab0dfd9b4c) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index cb93f61b2d..579eeebdac 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -619,7 +619,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, BOOL ret; BOOL auth_verify; BOOL auth_seal; - uint32 crc32; + uint32 crc32 = 0; 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); -- cgit From 74d539f5573a3ed3ff1b96c54752a389da4c3e14 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 17 Nov 1998 16:19:04 +0000 Subject: - group database API. oops and oh dear, the threat has been carried out: the pre-alpha "domain group" etc parameters have disappeared. - interactive debug detection - re-added mem_man (andrew's memory management, detects memory corruption) - american spellings of "initialise" replaced with english spelling of "initialise". - started on "lookup_name()" and "lookup_sid()" functions. proper ones. - moved lots of functions around. created some modules of commonly used code. e.g the password file locking code, which is used in groupfile.c and aliasfile.c and smbpass.c - moved RID_TYPE_MASK up another bit. this is really unfortunate, but there is no other "fast" way to identify users from groups from aliases. i do not believe that this code saves us anything (the multipliers) and puts us at a disadvantage (reduces the useable rid space). the designers of NT aren't silly: if they can get away with a user- interface-speed LsaLookupNames / LsaLookupSids, then so can we. i spoke with isaac at the cifs conference, the only time for example that they do a security context check is on file create. certainly not on individual file reads / writes, which would drastically hit their performance and ours, too. - renamed myworkgroup to global_sam_name, amongst other things, when used in the rpc code. there is also a global_member_name, as we are always responsible for a SAM database, the scope of which is limited by the role of the machine (e.g if a member of a workgroup, your SAM is for _local_ logins only, and its name is the name of your server. you even still have a SID. see LsaQueryInfoPolicy, levels 3 and 5). - updated functionality of groupname.c to be able to cope with names like DOMAIN\group and SERVER\alias. used this code to be able to do aliases as well as groups. this code may actually be better off being used in username mapping, too. - created a connect to serverlist function in clientgen.c and used it in password.c - initialisation in server.c depends on the role of the server. well, it does now. - rpctorture. smbtorture. EXERCISE EXTREME CAUTION. (This used to be commit 0d21e1e6090b933f396c764af535ca3388a562db) --- source3/rpc_client/cli_pipe.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 579eeebdac..712e608847 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -31,7 +31,6 @@ extern int DEBUGLEVEL; extern struct pipe_id_info pipe_names[]; -extern fstring global_myworkgroup; extern pstring global_myname; /******************************************************************** -- cgit From 9c848ec329a6ce86cffb2304746590116d9292f0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 7 Dec 1998 20:23:41 +0000 Subject: removed nt_pipe_fnum from struct cli_state. need to be able to call LsaLookupSids etc from within SamrQueryAliasMembers, for example. fnum is now a parameter to client functions. thanks to mike black for starting the ball rolling. (This used to be commit bee8f7fa6b0f7f995f71303f4e14a4aaed0c2437) --- source3/rpc_client/cli_pipe.c | 54 ++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 712e608847..9d2ee533d6 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -46,7 +46,7 @@ static uint32 get_rpc_call_id(void) uses SMBreadX to get rest of rpc data ********************************************************************/ -static BOOL rpc_read(struct cli_state *cli, +static BOOL rpc_read(struct cli_state *cli, uint16 nt_pipe_fnum, prs_struct *rdata, uint32 data_to_read, uint32 rdata_offset) { @@ -83,7 +83,7 @@ static BOOL rpc_read(struct cli_state *cli, DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used)); } - num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset, size); + num_read = cli_read(cli, nt_pipe_fnum, data, file_offset, size); DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n", file_offset, num_read, data_to_read)); @@ -250,7 +250,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, ****************************************************************************/ -static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, +static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, prs_struct *param , prs_struct *data, prs_struct *rparam, prs_struct *rdata) { @@ -281,9 +281,9 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, /* create setup parameters. */ setup[0] = cmd; - setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ + setup[1] = nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ - DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, cli->nt_pipe_fnum)); + DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, nt_pipe_fnum)); /* send the data: receive a response. */ if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, @@ -337,7 +337,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, /* err status is only informational: the _real_ check is on the length */ if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */ { - if (!rpc_read(cli, rdata, len, rdata->data->data_used)) + if (!rpc_read(cli, nt_pipe_fnum, rdata, len, rdata->data->data_used)) { return False; } @@ -363,7 +363,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_init(&hps, 0x8, 4, 0, True); - num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18); + num_read = cli_read(cli, nt_pipe_fnum, hps.data->data, 0, 0x18); DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); if (num_read != 0x18) return False; @@ -385,7 +385,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, return False; } - if (!rpc_read(cli, rdata, len, rdata->data->data_used)) + if (!rpc_read(cli, nt_pipe_fnum, rdata, len, rdata->data->data_used)) { return False; } @@ -604,7 +604,7 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len, /**************************************************************************** send a request on an rpc pipe. ****************************************************************************/ -BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, +BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 nt_pipe_fnum, uint8 op_num, prs_struct *data, prs_struct *rdata) { /* fudge this, at the moment: create the header; memcpy the data. oops. */ @@ -680,7 +680,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, prs_init(&dataa, mem_buf_len(hdr.data), 4, 0x0, False); mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data)); - ret = rpc_api_pipe(cli, 0x0026, NULL, &dataa, &rparam, rdata); + ret = rpc_api_pipe(cli, nt_pipe_fnum, 0x0026, NULL, &dataa, &rparam, rdata); prs_mem_free(&hdr_auth ); prs_mem_free(&auth_verf); @@ -695,7 +695,8 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, do an rpc bind ****************************************************************************/ -static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state) +static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 nt_pipe_fnum, + char *pipe_name, uint16 device_state) { BOOL state_set = False; char param[2]; @@ -707,14 +708,14 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1 if (pipe_name == NULL) return False; DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", - cli->nt_pipe_fnum, pipe_name, device_state)); + nt_pipe_fnum, pipe_name, device_state)); /* create parameters: device state */ SSVAL(param, 0, device_state); /* create setup parameters. */ setup[0] = 0x0001; - setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ + setup[1] = 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, @@ -833,7 +834,8 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * do an rpc bind ****************************************************************************/ -static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, +static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 nt_pipe_fnum, + char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name) { @@ -855,7 +857,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, return False; } - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name)); + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", nt_pipe_fnum, pipe_name)); if (!valid_pipe_name(pipe_name, abstract, transfer)) return False; @@ -882,7 +884,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data)); /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata)) + if (rpc_api_pipe(cli, nt_pipe_fnum, 0x0026, NULL, &data, &rparam, &rdata)) { RPC_HDR_BA hdr_ba; RPC_HDR_AUTH rhdr_auth; @@ -984,7 +986,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, 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, cli->nt_pipe_fnum, 0x0008, + if (cli_write(cli, nt_pipe_fnum, 0x0008, dataa.data->data, 0, dataa.data->data_used) < 0) { @@ -1029,7 +1031,7 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) open a session ****************************************************************************/ -BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) +BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* nt_pipe_fnum) { RPC_IFACE abstract; RPC_IFACE transfer; @@ -1045,7 +1047,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) return False; } - cli->nt_pipe_fnum = (uint16)fnum; + *nt_pipe_fnum = (uint16)fnum; } else { @@ -1056,14 +1058,14 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) return False; } - cli->nt_pipe_fnum = (uint16)fnum; + *nt_pipe_fnum = (uint16)fnum; /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) + if (!rpc_pipe_set_hnd_state(cli, *nt_pipe_fnum, pipe_name, 0x4300)) { DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", cli_errstr(cli))); - cli_close(cli, cli->nt_pipe_fnum); + cli_close(cli, *nt_pipe_fnum); return False; } @@ -1071,13 +1073,13 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, pipe_name, + if (!rpc_pipe_bind(cli, *nt_pipe_fnum, pipe_name, &abstract, &transfer, global_myname)) { DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", cli_errstr(cli))); - cli_close(cli, cli->nt_pipe_fnum); + cli_close(cli, *nt_pipe_fnum); return False; } @@ -1104,7 +1106,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) close the session ****************************************************************************/ -void cli_nt_session_close(struct cli_state *cli) +void cli_nt_session_close(struct cli_state *cli, uint16 nt_pipe_fnum) { - cli_close(cli, cli->nt_pipe_fnum); + cli_close(cli, nt_pipe_fnum); } -- cgit From 877db70926195076b979821270bcd473c34e7709 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Tue, 23 Mar 1999 15:01:37 +0000 Subject: Fixed a typo where the RPC header mem_buffer was initialised as 0x8 bytes long rather than 0x18. Rather nasty, I doubt the client ever worked for multiple PDU's. (This used to be commit 90b6fce780c8dff37a389493be0568923b189ff0) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9d2ee533d6..482dbe71ce 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -361,7 +361,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, int num_read; prs_struct hps; - prs_init(&hps, 0x8, 4, 0, True); + prs_init(&hps, 0x18, 4, 0, True); num_read = cli_read(cli, nt_pipe_fnum, hps.data->data, 0, 0x18); DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); -- cgit From 73891ca8e4f6cca6aa8bb0ae043f660a64baa056 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 29 Jun 1999 18:47:06 +0000 Subject: improving authentication code (tidyup). (This used to be commit ab1a6aa42db5217f025941fb5107436556bc23b7) --- source3/rpc_client/cli_pipe.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 482dbe71ce..3ced236281 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -502,7 +502,8 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, prs_struct *auth_resp) { unsigned char lm_owf[24]; - unsigned char nt_owf[24]; + unsigned char nt_owf[128]; + size_t nt_owf_len; RPC_HDR hdr; RPC_HDR_AUTHA hdr_autha; RPC_AUTH_VERIFIER auth_verifier; @@ -518,10 +519,10 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_resp, 0); mem_realloc_data(auth_resp->data, auth_resp->offset); - pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf); + pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len); make_rpc_auth_ntlmssp_resp(&ntlmssp_resp, - lm_owf, nt_owf, + lm_owf, nt_owf, nt_owf_len, domain, user_name, my_name, ntlmssp_cli_flgs); @@ -947,7 +948,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 nt_pipe_fnum, rpc_call_id, &hdra, &hdr_autha, &auth_resp); - pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL); + pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL, NULL); pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL); NTLMSSPOWFencrypt(lm_hash, lm_owf, p24); { -- cgit From 7672761567005733cd0c82ac44a5973b6ff8ccd1 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 6 Jul 1999 21:29:54 +0000 Subject: use of safe_cli_errstr() and cli_establish_connection(). (This used to be commit b60eb8c9fc61bf207ab3600eec3ca722403c4d19) --- source3/rpc_client/cli_pipe.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3ced236281..54ddac6f78 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -293,7 +293,9 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, pp_ret_params, p_ret_params_len, /* return params, len */ pp_ret_data, p_ret_data_len)) /* return data, len */ { - DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli))); + fstring errstr; + cli_safe_errstr(cli, errstr, sizeof(errstr)); + DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", errstr)); return False; } @@ -1043,8 +1045,10 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* nt_pipe { if ((fnum = cli_nt_create(cli, &(pipe_name[5]))) == -1) { + fstring errstr; + cli_safe_errstr(cli, errstr, sizeof(errstr)); 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, cli_errstr(cli))); + &(pipe_name[5]), cli->desthost, errstr)); return False; } @@ -1054,8 +1058,10 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* nt_pipe { if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) { + fstring errstr; + cli_safe_errstr(cli, errstr, sizeof(errstr)); DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n", - pipe_name, cli->desthost, cli_errstr(cli))); + pipe_name, cli->desthost, errstr)); return False; } @@ -1064,8 +1070,10 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* nt_pipe /**************** Set Named Pipe State ***************/ if (!rpc_pipe_set_hnd_state(cli, *nt_pipe_fnum, pipe_name, 0x4300)) { + fstring errstr; + cli_safe_errstr(cli, errstr, sizeof(errstr)); DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", - cli_errstr(cli))); + errstr)); cli_close(cli, *nt_pipe_fnum); return False; } @@ -1078,8 +1086,10 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* nt_pipe &abstract, &transfer, global_myname)) { + fstring errstr; + cli_safe_errstr(cli, errstr, sizeof(errstr)); DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", - cli_errstr(cli))); + errstr)); cli_close(cli, *nt_pipe_fnum); return False; } -- cgit From 30beb2dd109e26abbe4d773671909b1fdf3a0e62 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Thu, 22 Jul 1999 10:54:49 +0000 Subject: BDC support. Added synchronise_passdb function to update accounts in a BDC's smbpasswd. Improved rpc_read, which was still somewhat broken for multiple PDU's. modify_trust_password must initialise cli.pwd (pwd_set_nullpwd). (This used to be commit 4783ac3968df1c5c8aa0b6ba9144df8b01ae0b99) --- source3/rpc_client/cli_pipe.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 54ddac6f78..c8f2593858 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -51,13 +51,10 @@ static BOOL rpc_read(struct cli_state *cli, uint16 nt_pipe_fnum, uint32 rdata_offset) { int size = cli->max_recv_frag; - int file_offset = rdata_offset; + int file_offset = 0; int num_read; char *data; - uint32 err; - uint32 new_data_size = rdata->data->data_used + data_to_read; - - file_offset -= rdata_offset; + uint32 new_data_size = rdata_offset + data_to_read; DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n", data_to_read, rdata_offset, file_offset)); @@ -75,14 +72,6 @@ static BOOL rpc_read(struct cli_state *cli, uint16 nt_pipe_fnum, if (size > data_to_read) size = data_to_read; - new_data_size = rdata->data->data_used + 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)); - } - num_read = cli_read(cli, nt_pipe_fnum, data, file_offset, size); DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n", @@ -92,13 +81,11 @@ static BOOL rpc_read(struct cli_state *cli, uint16 nt_pipe_fnum, file_offset += num_read; data += num_read; - if (cli_error(cli, NULL, &err)) return False; + if (cli_error(cli, NULL, NULL)) return False; } while (num_read > 0 && data_to_read > 0); - /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ - mem_realloc_data(rdata->data, file_offset + rdata_offset); - rdata->data->offset.end = file_offset + rdata_offset; + rdata->data->offset.end = new_data_size; DEBUG(5,("rpc_read: offset end: 0x%x. data left to read:0x%x\n", rdata->data->offset.end, data_to_read)); -- cgit From f2e0bbffb5e40df4850b6bd0eae73a8fb0edc6d7 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 26 Jul 1999 21:47:23 +0000 Subject: renaming AUTH VERIFIER to AUTH NTLMSSP VERIFIER. ready for adding another RPC authentication system. (This used to be commit 1a211bafebad8c63d98b5ef275a6272013527c65) --- source3/rpc_client/cli_pipe.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c8f2593858..d5745adb55 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -408,7 +408,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, RPC_HDR_RB hdr_rb; RPC_HDR hdr; RPC_HDR_AUTH hdr_auth; - RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_VERIFIER auth_verifier; RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; /* create the bind request RPC_HDR_RB */ @@ -425,10 +425,10 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rhdr_auth, 0); mem_realloc_data(rhdr_auth->data, rhdr_auth->offset); - make_rpc_auth_verifier(&auth_verifier, + make_rpc_auth_ntlmssp_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_NEGOTIATE); - smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_req, 0); + smb_io_rpc_auth_ntlmssp_verifier("auth_verifier", &auth_verifier, auth_req, 0); mem_realloc_data(auth_req->data, auth_req->offset); make_rpc_auth_ntlmssp_neg(&ntlmssp_neg, @@ -493,19 +493,19 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, unsigned char lm_owf[24]; unsigned char nt_owf[128]; size_t nt_owf_len; - RPC_HDR hdr; - RPC_HDR_AUTHA hdr_autha; - RPC_AUTH_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; + RPC_HDR hdr; + RPC_HDR_AUTHA hdr_autha; + RPC_AUTH_NTLMSSP_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; 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); - make_rpc_auth_verifier(&auth_verifier, + make_rpc_auth_ntlmssp_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH); - smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_resp, 0); + smb_io_rpc_auth_ntlmssp_verifier("auth_verifier", &auth_verifier, auth_resp, 0); mem_realloc_data(auth_resp->data, auth_resp->offset); pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len); @@ -876,10 +876,10 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 nt_pipe_fnum, /* send data on \PIPE\. receive a response */ if (rpc_api_pipe(cli, nt_pipe_fnum, 0x0026, NULL, &data, &rparam, &rdata)) { - RPC_HDR_BA hdr_ba; - RPC_HDR_AUTH rhdr_auth; - RPC_AUTH_VERIFIER rhdr_verf; - RPC_AUTH_NTLMSSP_CHAL rhdr_chal; + RPC_HDR_BA hdr_ba; + RPC_HDR_AUTH rhdr_auth; + RPC_AUTH_NTLMSSP_VERIFIER rhdr_verf; + RPC_AUTH_NTLMSSP_CHAL rhdr_chal; DEBUG(5, ("rpc_api_pipe: return OK\n")); @@ -904,7 +904,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 nt_pipe_fnum, if (valid_ack && ntlmssp_auth) { - smb_io_rpc_auth_verifier("", &rhdr_verf, &rdata, 0); + smb_io_rpc_auth_ntlmssp_verifier("", &rhdr_verf, &rdata, 0); if (rdata.offset == 0) valid_ack = False; } if (valid_ack && ntlmssp_auth) -- cgit From cba7662da1fd9ed8bd9f9969417adf1fe5f0d33b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 7 Oct 1999 22:10:29 +0000 Subject: - added rudimentary CAP_UNICODE support because i thought it was part of a problem i was having. - added rudimentary CAP_STATUS32 support for same reason. - added hard-coded, copy-the-same-data-from-over-the-wire version of CAP_EXTENDED_SECURITY, which is a security-blob to encapsulate GSSAPI which encodes SPNEGO which is used to negotiate Kerberos or NTLMSSP. i have implemented NTLMSSP which negotiates NTLMv1 or NTLMv2 and 40-bit or 128-bit etc. i have implemented NTLMv1 / 40-bit. *whew*. (This used to be commit e5b80bd2f76fda70e41e4a9007eb035dab92ed8e) --- source3/rpc_client/cli_pipe.c | 45 +++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d5745adb55..0453bb3125 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -473,6 +473,34 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, 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. + + ********************************************************************/ +void create_ntlmssp_resp(struct pwd_info *pwd, + char *domain, char *user_name, char *my_name, + uint32 ntlmssp_cli_flgs, + prs_struct *auth_resp) +{ + RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; + unsigned char lm_owf[24]; + unsigned char nt_owf[128]; + size_t nt_owf_len; + + pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len); + + make_rpc_auth_ntlmssp_resp(&ntlmssp_resp, + lm_owf, nt_owf, nt_owf_len, + domain, user_name, my_name, + ntlmssp_cli_flgs); + + smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0); + mem_realloc_data(auth_resp->data, auth_resp->offset); +} /******************************************************************* creates a DCE/RPC bind authentication response @@ -482,7 +510,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, - caller is expected to free the header data structure once used. ********************************************************************/ -static BOOL create_rpc_bind_resp(struct pwd_info *pwd, +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, @@ -490,13 +518,9 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, prs_struct *rhdr_autha, prs_struct *auth_resp) { - unsigned char lm_owf[24]; - unsigned char nt_owf[128]; - size_t nt_owf_len; RPC_HDR hdr; RPC_HDR_AUTHA hdr_autha; RPC_AUTH_NTLMSSP_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; make_rpc_hdr_autha(&hdr_autha, 0x1630, 0x1630, 0x0a, 0x06, 0x00); smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rhdr_autha, 0); @@ -508,15 +532,8 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, smb_io_rpc_auth_ntlmssp_verifier("auth_verifier", &auth_verifier, auth_resp, 0); mem_realloc_data(auth_resp->data, auth_resp->offset); - pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len); - - make_rpc_auth_ntlmssp_resp(&ntlmssp_resp, - lm_owf, nt_owf, nt_owf_len, - domain, user_name, my_name, - ntlmssp_cli_flgs); - - smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0); - mem_realloc_data(auth_resp->data, auth_resp->offset); + create_ntlmssp_resp(pwd, domain, user_name, my_name, ntlmssp_cli_flgs, + auth_resp); /* create the request RPC_HDR */ make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id, -- cgit From 09e6f6eb9cdd14dcd63c828eddef92abdcc5819c Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 14 Oct 1999 18:49:24 +0000 Subject: adding CAP_EXTENDED_SECURITY support in a hurry last week. forgot to deal with linking issues in other binaries (This used to be commit 57f95a01988fb4035b2e4448f4fd3ef0d652c106) --- source3/rpc_client/cli_pipe.c | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0453bb3125..6b50fa53ad 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -473,35 +473,6 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, 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. - - ********************************************************************/ -void create_ntlmssp_resp(struct pwd_info *pwd, - char *domain, char *user_name, char *my_name, - uint32 ntlmssp_cli_flgs, - prs_struct *auth_resp) -{ - RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; - unsigned char lm_owf[24]; - unsigned char nt_owf[128]; - size_t nt_owf_len; - - pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len); - - make_rpc_auth_ntlmssp_resp(&ntlmssp_resp, - lm_owf, nt_owf, nt_owf_len, - domain, user_name, my_name, - ntlmssp_cli_flgs); - - smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0); - mem_realloc_data(auth_resp->data, auth_resp->offset); -} - /******************************************************************* creates a DCE/RPC bind authentication response -- cgit From 6f9105c853020fde1691a28cd707d6d3f6561b4d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 21 Oct 1999 16:53:50 +0000 Subject: various. debug levels changed. nmbd doesn't need libsmb/clienttrust.c. samr_lookup_rids() moved to a dynamic memory structure not a static one limited to 32 RIDs. cli_pipe.c reading wasn't checking ERRmoredata when DOS error codes negotiated (this terminates MSRPC code with prejudice). (This used to be commit 8976eca2db43576c32069dcda017e8777048e007) --- source3/rpc_client/cli_pipe.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6b50fa53ad..ab99eb84f3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -50,11 +50,13 @@ static BOOL rpc_read(struct cli_state *cli, uint16 nt_pipe_fnum, prs_struct *rdata, uint32 data_to_read, uint32 rdata_offset) { - int size = cli->max_recv_frag; + size_t size = cli->max_recv_frag; int file_offset = 0; int num_read; char *data; uint32 new_data_size = rdata_offset + data_to_read; + uint8 cls; + uint32 type; DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n", data_to_read, rdata_offset, file_offset)); @@ -81,7 +83,13 @@ static BOOL rpc_read(struct cli_state *cli, uint16 nt_pipe_fnum, file_offset += num_read; data += num_read; - if (cli_error(cli, NULL, NULL)) return False; + if (cli_error(cli, &cls, &type)) + { + if (cls != ERRDOS || type != ERRmoredata) + { + return False; + } + } } while (num_read > 0 && data_to_read > 0); @@ -244,7 +252,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, int len; uint16 setup[2]; /* only need 2 uint16 setup parameters */ - uint32 err; + uint8 cls; + uint32 type; BOOL first = True; BOOL last = True; RPC_HDR rhdr; @@ -366,7 +375,13 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, prs_mem_free(&hps); - if (cli_error(cli, NULL, &err)) return False; + if (cli_error(cli, &cls, &type)) + { + if (cls != ERRDOS || type != ERRmoredata) + { + return False; + } + } if (first) { @@ -725,10 +740,10 @@ static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *tra { if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) { - DEBUG(5,("Bind Abstract Syntax: ")); + DEBUG(5,("Bind Abstract Syntax:\n")); dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), sizeof(pipe_names[pipe_idx].abstr_syntax)); - DEBUG(5,("Bind Transfer Syntax: ")); + DEBUG(5,("Bind Transfer Syntax:\n")); dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax), sizeof(pipe_names[pipe_idx].trans_syntax)); -- cgit From 23dc6eb70d4abc02b5e588478825424cf70d1052 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 6 Nov 1999 22:45:31 +0000 Subject: horrible code to do SMBwriteX / SMBreadX for large MSRPC reads. ARGH! (This used to be commit 0f9d661ca2560e88a04bc529ba41ac4cf1579fa4) --- source3/rpc_client/cli_pipe.c | 220 ++++++++++++++++++++++++------------------ 1 file changed, 127 insertions(+), 93 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ab99eb84f3..7e2bf426fa 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -46,9 +46,9 @@ static uint32 get_rpc_call_id(void) uses SMBreadX to get rest of rpc data ********************************************************************/ -static BOOL rpc_read(struct cli_state *cli, uint16 nt_pipe_fnum, +static BOOL rpc_read(struct cli_state *cli, uint16 fnum, prs_struct *rdata, uint32 data_to_read, - uint32 rdata_offset) + uint32 rdata_offset, BOOL one_only) { size_t size = cli->max_recv_frag; int file_offset = 0; @@ -72,9 +72,11 @@ static BOOL rpc_read(struct cli_state *cli, uint16 nt_pipe_fnum, do /* read data using SMBreadX */ { if (size > data_to_read) - size = data_to_read; + { + size = data_to_read; + } - num_read = cli_read(cli, nt_pipe_fnum, data, file_offset, size); + num_read = cli_read(cli, fnum, data, file_offset, size); DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n", file_offset, num_read, data_to_read)); @@ -91,7 +93,7 @@ static BOOL rpc_read(struct cli_state *cli, uint16 nt_pipe_fnum, } } - } while (num_read > 0 && data_to_read > 0); + } while (!one_only && num_read > 0 && data_to_read > 0); rdata->data->offset.end = new_data_size; @@ -245,9 +247,10 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, ****************************************************************************/ -static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, - prs_struct *param , prs_struct *data, - prs_struct *rparam, prs_struct *rdata) +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) { int len; @@ -256,6 +259,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, uint32 type; BOOL first = True; BOOL last = True; + BOOL used_smb_trans = False; RPC_HDR rhdr; /* @@ -277,80 +281,107 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, /* create setup parameters. */ setup[0] = cmd; - setup[1] = nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ + setup[1] = fnum; /* pipe file handle. got this from an SMBOpenX. */ - DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, nt_pipe_fnum)); - - /* 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, 1024, /* data, length, max */ - pp_ret_params, p_ret_params_len, /* return params, len */ - pp_ret_data, p_ret_data_len)) /* return data, len */ + if (data_len > 1024 && !bind_rq) { - fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)); - DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", errstr)); - return False; + ssize_t written; + + DEBUG(5,("rpc_api_pipe: cli_write %d\n", data_len)); + + written = cli_write(cli, fnum, 0x0008, pdata, 0, data_len); + + 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; + } + + DEBUG(5,("rpc_api_pipe: rpc_read after write\n")); + + first = False; + last = False; } + 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, 1024, /* 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 (rdata->data->data == NULL) return False; - /**** parse the header: check it's a response record */ + /**** parse the header: check it's a response record */ - rdata->data->offset.start = 0; - rdata->data->offset.end = rdata->data->data_used; - rdata->offset = 0; + rdata->data->offset.start = 0; + rdata->data->offset.end = rdata->data->data_used; + rdata->offset = 0; - /* cli_api_pipe does an ordinary Realloc - we have no margins now. */ - rdata->data->margin = 0; - if (rparam) rparam->data->margin = 0; + /* 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)) - { - return False; - } + if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) + { + return False; + } - if (rhdr.pkt_type == RPC_BINDACK) - { - if (!last && !first) + if (rhdr.pkt_type == RPC_BINDACK) { - DEBUG(5,("rpc_api_pipe: bug in AS/U, setting fragment first/last ON\n")); - first = True; - last = True; + 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; - smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0); - } + 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: %d smbtrans read: %d\n", - len, rdata->data->data_used)); + 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, nt_pipe_fnum, rdata, 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; + } + } + + if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) { return False; } - } - if (rhdr.auth_len != 0 && !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; + } - /* 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 */ @@ -361,7 +392,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, prs_init(&hps, 0x18, 4, 0, True); - num_read = cli_read(cli, nt_pipe_fnum, hps.data->data, 0, 0x18); + num_read = cli_read(cli, fnum, hps.data->data, 0, 0x18); DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); if (num_read != 0x18) return False; @@ -383,13 +414,13 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 nt_pipe_fnum, uint16 cmd, } } - if (first) + if (first && used_smb_trans) { DEBUG(0,("rpc_api_pipe: wierd rpc header received\n")); return False; } - if (!rpc_read(cli, nt_pipe_fnum, rdata, len, rdata->data->data_used)) + if (!rpc_read(cli, fnum, rdata, len, rdata->data->data_used, False)) { return False; } @@ -597,7 +628,7 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len, /**************************************************************************** send a request on an rpc pipe. ****************************************************************************/ -BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 nt_pipe_fnum, uint8 op_num, +BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 fnum, uint8 op_num, prs_struct *data, prs_struct *rdata) { /* fudge this, at the moment: create the header; memcpy the data. oops. */ @@ -673,7 +704,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 nt_pipe_fnum, uint8 op_num, prs_init(&dataa, mem_buf_len(hdr.data), 4, 0x0, False); mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data)); - ret = rpc_api_pipe(cli, nt_pipe_fnum, 0x0026, NULL, &dataa, &rparam, rdata); + ret = rpc_api_pipe(cli, fnum, False, 0x0026, NULL, &dataa, &rparam, rdata); prs_mem_free(&hdr_auth ); prs_mem_free(&auth_verf); @@ -688,7 +719,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 nt_pipe_fnum, uint8 op_num, do an rpc bind ****************************************************************************/ -static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 nt_pipe_fnum, +static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum, char *pipe_name, uint16 device_state) { BOOL state_set = False; @@ -701,14 +732,14 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 nt_pipe_fnum, if (pipe_name == NULL) return False; DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", - nt_pipe_fnum, pipe_name, device_state)); + fnum, pipe_name, device_state)); /* create parameters: device state */ SSVAL(param, 0, device_state); /* create setup parameters. */ setup[0] = 0x0001; - setup[1] = nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ + setup[1] = fnum; /* pipe file handle. got this from an SMBOpenX. */ /* send the data on \PIPE\ */ if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, @@ -827,7 +858,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * do an rpc bind ****************************************************************************/ -static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 nt_pipe_fnum, +static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 fnum, char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name) @@ -850,7 +881,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 nt_pipe_fnum, return False; } - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", nt_pipe_fnum, pipe_name)); + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name)); if (!valid_pipe_name(pipe_name, abstract, transfer)) return False; @@ -876,8 +907,10 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 nt_pipe_fnum, 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)); + cli->max_recv_frag = 0x1000; + /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, nt_pipe_fnum, 0x0026, NULL, &data, &rparam, &rdata)) + if (rpc_api_pipe(cli, fnum, True, 0x0026, NULL, &data, &rparam, &rdata)) { RPC_HDR_BA hdr_ba; RPC_HDR_AUTH rhdr_auth; @@ -979,7 +1012,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 nt_pipe_fnum, 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, nt_pipe_fnum, 0x0008, + if (cli_write(cli, fnum, 0x0008, dataa.data->data, 0, dataa.data->data_used) < 0) { @@ -1024,47 +1057,48 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) open a session ****************************************************************************/ -BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* nt_pipe_fnum) +BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* fnum) { RPC_IFACE abstract; RPC_IFACE transfer; - int fnum; /******************* open the pipe *****************/ if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS)) { - if ((fnum = cli_nt_create(cli, &(pipe_name[5]))) == -1) + int f; + f = cli_nt_create(cli, &(pipe_name[5])); + if (f == -1) { fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)); + cli_safe_errstr(cli, errstr, sizeof(errstr)-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)); return False; } - - *nt_pipe_fnum = (uint16)fnum; + *fnum = (uint16)f; } else { - if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) + 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)); + cli_safe_errstr(cli, errstr, sizeof(errstr)-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)); return False; } - - *nt_pipe_fnum = (uint16)fnum; + *fnum = (uint16)f; /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, *nt_pipe_fnum, pipe_name, 0x4300)) + if (!rpc_pipe_set_hnd_state(cli, *fnum, pipe_name, 0x4300)) { fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)); + cli_safe_errstr(cli, errstr, sizeof(errstr)-1); DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", errstr)); - cli_close(cli, *nt_pipe_fnum); + cli_close(cli, *fnum); return False; } @@ -1072,15 +1106,15 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* nt_pipe /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, *nt_pipe_fnum, pipe_name, + if (!rpc_pipe_bind(cli, *fnum, pipe_name, &abstract, &transfer, global_myname)) { fstring errstr; - cli_safe_errstr(cli, errstr, sizeof(errstr)); + cli_safe_errstr(cli, errstr, sizeof(errstr)-1); DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", errstr)); - cli_close(cli, *nt_pipe_fnum); + cli_close(cli, *fnum); return False; } @@ -1107,7 +1141,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* nt_pipe close the session ****************************************************************************/ -void cli_nt_session_close(struct cli_state *cli, uint16 nt_pipe_fnum) +void cli_nt_session_close(struct cli_state *cli, uint16 fnum) { - cli_close(cli, nt_pipe_fnum); + cli_close(cli, fnum); } -- cgit From 826ad16b363accc4029178cf9087b02362245e11 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 9 Nov 1999 19:35:30 +0000 Subject: debugging rpcclient spoolenum and spooljobs commands. oh, did i forget to mention, there's a spooljobs command, and it uses command-line completion? prints out NT print jobs really nicely, too. (This used to be commit e6e5caf16c8d120f0c11fa63061f2786098e3357) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7e2bf426fa..df09f02398 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -283,7 +283,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 fnum, setup[0] = cmd; setup[1] = fnum; /* pipe file handle. got this from an SMBOpenX. */ - if (data_len > 1024 && !bind_rq) + if (data_len > 2048 && !bind_rq) { ssize_t written; @@ -314,7 +314,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 fnum, 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, 1024, /* data, 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 */ { -- cgit From dab1a1227873f1a88dc7a4b8f63edcccd60ada85 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 19:24:01 +0000 Subject: you know what? this sort of thing makes me laugh. hmm, what functions have we got. and what data do we have. hmm.. i wonder what the NTLMv2 user session key can be... hmmm... weell.... there's some hidden data here, generated from the user password that doesn't go over-the-wire, so that's _got_ to be involved. and... that bit of data took a lot of computation to produce, so it's probably _also_ involved... and md4 no, md5? no, how about hmac_md5 yes let's try that one (the other's didn't work) oh goodie, it worked! i love it when this sort of thing happens. took all of fifteen minutes to guess it. tried concatenating client and server challenges. tried concatenating _random_ bits of client and server challenges. tried md5 of the above. tried hmac_md5 of the above. eventually, it boils down to this: kr = MD4(NT#,username,domainname) hmacntchal=hmac_md5(kr, nt server challenge) sess_key = hmac_md5(kr, hmacntchal); (This used to be commit ab174759cd210fe1be888d0c589a5b2669f7ff1e) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index df09f02398..71670c0d84 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -973,7 +973,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 fnum, rpc_call_id, &hdra, &hdr_autha, &auth_resp); - pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL, NULL); + pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL, NULL, NULL); pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL); NTLMSSPOWFencrypt(lm_hash, lm_owf, p24); { -- cgit From f8b82a7b9507e11595bc924def179dc1d7d79a54 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 24 Nov 1999 20:24:33 +0000 Subject: first stages of removing struct cli_state* and uint16 fnum from all msrpc client code. the intent is to hide / abstract / associate connection info behind policy handles. this makes the msrpc functions look more and more like their nt equivalents. who-hou! (This used to be commit c01b18e632aede6fce7264ef6971d7ddba945cfb) --- source3/rpc_client/cli_pipe.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 71670c0d84..1c8c406bae 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -720,7 +720,7 @@ do an rpc bind ****************************************************************************/ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum, - char *pipe_name, uint16 device_state) + const char *pipe_name, uint16 device_state) { BOOL state_set = False; char param[2]; @@ -763,7 +763,8 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum, check the rpc bind acknowledge response ****************************************************************************/ -static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer) +static BOOL valid_pipe_name(const char *pipe_name, + RPC_IFACE *abstract, RPC_IFACE *transfer) { int pipe_idx = 0; @@ -797,7 +798,8 @@ static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *tra check the rpc bind acknowledge response ****************************************************************************/ -static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer) +static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name, + RPC_IFACE *transfer) { int i = 0; @@ -859,7 +861,7 @@ do an rpc bind ****************************************************************************/ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 fnum, - char *pipe_name, + const char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name) { @@ -1057,7 +1059,8 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) open a session ****************************************************************************/ -BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, uint16* fnum) +BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name, + uint16* fnum) { RPC_IFACE abstract; RPC_IFACE transfer; -- cgit From 2803a72751cf511aa0b5e6745e1b169faa66f68a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 24 Nov 1999 22:45:09 +0000 Subject: ok. *whew*. this is the first completed part of the restructure. verified that lsaquery, lsalookupsids work, and found some bugs in the parameters of these commands :-) soo... we now have an lsa_* api that has the same arguments as the nt Lsa* api! cool! the only significant coding difference is the introduction of a user_credentials structure, containing user, domain, pass and ntlmssp flags. (This used to be commit 57bff6fe82d777e599d535f076efb2328ba1188b) --- source3/rpc_client/cli_pipe.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1c8c406bae..9aad93246e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -903,7 +903,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 fnum, ntlmssp_auth ? &auth_ntlm : NULL, rpc_call_id, abstract, transfer, - global_myname, cli->domain, cli->ntlmssp_cli_flgs); + global_myname, cli->usr.domain, cli->usr.ntlmssp_flags); /* this is a hack due to limitations in rpc_api_pipe */ prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False); @@ -967,16 +967,16 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, uint16 fnum, prs_init(&hdr_autha, 1024, 4, SAFETY_MARGIN, False); prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False); - pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge); + pwd_make_lm_nt_owf(&cli->usr.pwd, rhdr_chal.challenge); - create_rpc_bind_resp(&cli->pwd, cli->domain, - cli->user_name, global_myname, + 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->pwd, lm_owf, NULL, NULL, NULL); - pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL); + 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; -- cgit From 75bc1009438c2ff1696205ab0ee5667ec3ef3062 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 25 Nov 1999 05:26:48 +0000 Subject: cool! completed a samr* API that _would_ look like an msdn samr* api... if microsoft bothered to publish it. actually, there are good reasons for not publishing it: people might write programs for it, and then those programs wouldn't work on nt5, for example... (This used to be commit 8ce93b80d3b4e1c1e28aa1dde38cdef184eff3c1) --- source3/rpc_client/cli_pipe.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9aad93246e..08d7e42270 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -625,6 +625,23 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len, } +/**************************************************************************** + send a request on an rpc pipe. + ****************************************************************************/ +BOOL rpc_hnd_pipe_req(const POLICY_HND *hnd, uint8 op_num, + prs_struct *data, prs_struct *rdata) +{ + struct cli_state *cli = NULL; + uint16 fnum = 0xffff; + + if (!cli_state_get(hnd, &cli, &fnum)) + { + return False; + } + + return rpc_api_pipe_req(cli, fnum, op_num, data, rdata); +} + /**************************************************************************** send a request on an rpc pipe. ****************************************************************************/ -- cgit From 3fc5ec73be6009d50ec1e8e83505572ad16c1943 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 27 Nov 1999 21:50:11 +0000 Subject: further abstraction involving client states. main client-side code is pretty much independent of SMB client states, which will make it easier to add other transports. (This used to be commit a1ff7e8fc3129ba4a04722f977bc2d3725d13624) --- source3/rpc_client/cli_pipe.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 08d7e42270..8ca5255203 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -625,23 +625,6 @@ static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len, } -/**************************************************************************** - send a request on an rpc pipe. - ****************************************************************************/ -BOOL rpc_hnd_pipe_req(const POLICY_HND *hnd, uint8 op_num, - prs_struct *data, prs_struct *rdata) -{ - struct cli_state *cli = NULL; - uint16 fnum = 0xffff; - - if (!cli_state_get(hnd, &cli, &fnum)) - { - return False; - } - - return rpc_api_pipe_req(cli, fnum, op_num, data, rdata); -} - /**************************************************************************** send a request on an rpc pipe. ****************************************************************************/ @@ -1163,5 +1146,8 @@ close the session void cli_nt_session_close(struct cli_state *cli, uint16 fnum) { - cli_close(cli, fnum); + if (fnum != 0xffff) + { + cli_close(cli, fnum); + } } -- cgit From e302cb2b189f679bcf7efe60d5ae9fb4218c1411 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 29 Nov 1999 19:46:57 +0000 Subject: first attempt at getting \PIPE\NETLOGON working. it's pretty horrible. (This used to be commit 44dd3efa6380544e9a515e91960f9271498cefaf) --- source3/rpc_client/cli_pipe.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8ca5255203..f8216cb1e0 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1125,18 +1125,6 @@ BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name, * Setup the remote server name prefixed by \ and the machine account name. */ - fstrcpy(cli->srv_name_slash, "\\\\"); - fstrcat(cli->srv_name_slash, cli->desthost); - strupper(cli->srv_name_slash); - - fstrcpy(cli->clnt_name_slash, "\\\\"); - fstrcat(cli->clnt_name_slash, global_myname); - strupper(cli->clnt_name_slash); - - fstrcpy(cli->mach_acct, global_myname); - fstrcat(cli->mach_acct, "$"); - strupper(cli->mach_acct); - return True; } -- cgit From 0ce128e3550794d4dbbd1def00e87c020f72c992 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 01:25:49 +0000 Subject: delineation between smb and msrpc more marked. smbd now constructs pdus, and then feeds them over either a "local" function call or a "remote" function call to an msrpc service. the "remote" msrpc daemon, on the other side of a unix socket, then calls the same "local" function that smbd would, if the msrpc service were being run from inside smbd. this allows a transition from local msrpc services (inside the same smbd process) to remote (over a unix socket). removed reference to pipes_struct in msrpc services. all msrpc processing functions take rpcsrv_struct which is a structure containing state info for the msrpc functions to decode and create pdus. created become_vuser() which does everything not related to connection_struct that become_user() does. removed, as best i could, connection_struct dependencies from the nt spoolss printing code. todo: remove dcinfo from rpcsrv_struct because this stores NETLOGON-specific info on a per-connection basis, and if the connection dies then so does the info, and that's a fairly serious problem. had to put pretty much everything that is in user_struct into parse_creds.c to feed unix user info over to the msrpc daemons. why? because it's expensive to do unix password/group database lookups, and it's definitely expensive to do nt user profile lookups, not to mention pretty difficult and if you did either of these it would introduce a complication / unnecessary interdependency. so, send uid/gid/num_groups/gid_t* + SID+num_rids+domain_group_rids* + unix username + nt username + nt domain + user session key etc. this is the MINIMUM info identified so far that's actually implemented. missing bits include the called and calling netbios names etc. (basically, anything that can be loaded into standard_sub() and standard_sub_basic()...) (This used to be commit aa3c659a8dba0437c17c60055a6ed30fdfecdb6d) --- source3/rpc_client/cli_pipe.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f8216cb1e0..a8debd87fd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -695,13 +695,11 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint16 fnum, uint8 op_num, prs_link(&hdr, data, NULL); } - mem_realloc_data(hdr.data, data_len); - DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, mem_buf_len(data->data))); /* this is a hack due to limitations in rpc_api_pipe */ - prs_init(&dataa, mem_buf_len(hdr.data), 4, 0x0, False); + prs_init(&dataa, data_len, 4, 0x0, False); mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data)); ret = rpc_api_pipe(cli, fnum, False, 0x0026, NULL, &dataa, &rparam, rdata); -- cgit 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_pipe.c | 1439 ++++++++++++++++++++++------------------- 1 file changed, 766 insertions(+), 673 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') 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); } -- cgit From d2b40a7de259377d937492acedd39988ddd108a4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 Jul 2000 06:20:46 +0000 Subject: More rpcclient merge issues: * fixes some readline bugs from the merge * first attempt at commands (spoolenum almost works) * no changes to existing functions in HEAD; only additions of new functions. I'll weed out what I can as I go. --jerry (This used to be commit 61d2aad5dc2b212b11c981f1eca47efa627e9fc8) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8711ab116e..ade31dbb5b 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1079,7 +1079,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 Do an rpc bind. ****************************************************************************/ -static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) +BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) { RPC_IFACE abstract; RPC_IFACE transfer; -- cgit From 8213b96fd9b3959c9500aa2a595182526c865402 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 14 Jul 2000 17:04:04 +0000 Subject: More functions merged from TNG for rpcclient. They don't all work currently as I have to do something about the policy handle caching issues. --jerry (This used to be commit 233b074f490b3b01f3a462284aa8117536df0082) --- source3/rpc_client/cli_pipe.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ade31dbb5b..d39f742579 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -522,7 +522,7 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_ca prs_struct auth_info; int auth_len = 0; - prs_init(&auth_info, 0, 4, MARSHALL); + prs_init(&auth_info, MAX_PDU_FRAG_LEN, 4, MARSHALL); if (do_auth) { RPC_HDR_AUTH hdr_auth; @@ -1087,20 +1087,13 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) prs_struct rdata; BOOL do_auth = (cli->ntlmssp_cli_flgs != 0); uint32 rpc_call_id; - char buffer[MAX_PDU_FRAG_LEN]; DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name)); if (!valid_pipe_name(pipe_name, &abstract, &transfer)) return False; - prs_init(&rpc_out, 0, 4, MARSHALL); - - /* - * Use the MAX_PDU_FRAG_LEN buffer to store the bind request. - */ - - prs_give_memory( &rpc_out, buffer, sizeof(buffer), False); + prs_init(&rpc_out, MAX_PDU_FRAG_LEN, 4, MARSHALL); rpc_call_id = get_rpc_call_id(); -- cgit From d39eaf1776cc0bfd3cf4d11089cfa35a64538c06 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 17 Jul 2000 05:40:48 +0000 Subject: Reverted changes from rpcclient merge - contains memory leak! (This used to be commit dea06ad7a554089a7394cdcb6bf5a766e8e8a6c3) --- source3/rpc_client/cli_pipe.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d39f742579..ade31dbb5b 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -522,7 +522,7 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_ca prs_struct auth_info; int auth_len = 0; - prs_init(&auth_info, MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&auth_info, 0, 4, MARSHALL); if (do_auth) { RPC_HDR_AUTH hdr_auth; @@ -1087,13 +1087,20 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) prs_struct rdata; BOOL do_auth = (cli->ntlmssp_cli_flgs != 0); uint32 rpc_call_id; + char buffer[MAX_PDU_FRAG_LEN]; DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name)); if (!valid_pipe_name(pipe_name, &abstract, &transfer)) return False; - prs_init(&rpc_out, MAX_PDU_FRAG_LEN, 4, MARSHALL); + prs_init(&rpc_out, 0, 4, MARSHALL); + + /* + * Use the MAX_PDU_FRAG_LEN buffer to store the bind request. + */ + + prs_give_memory( &rpc_out, buffer, sizeof(buffer), False); rpc_call_id = get_rpc_call_id(); -- cgit From 5ec1642809d9de83da8c88c65d6595c6eb0270f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Jul 2000 00:47:19 +0000 Subject: Ok - this is a *BIG* change - but it fixes the problems with static strings in the RPC code. This change was prompted by trying to save a long (>256) character comment in the printer properties page. The new system associates a TALLOC_CTX with the pipe struct, and frees the pool on return of a complete PDU. A global TALLOC_CTX is used for the odd buffer allocated in the BUFFERxx code, and is freed in the main loop. This code works with insure, and seems to be free of memory leaks and crashes (so far) but there are probably the occasional problem with code that uses UNISTRxx structs on the stack and expects them to contain storage without doing a init_unistrXX(). This means that rpcclient will probably be horribly broken. A TALLOC_CTX also needed associating with the struct cli_state also, to make the prs_xx code there work. The main interface change is the addition of a TALLOC_CTX to the prs_init calls - used for dynamic allocation in the prs_XXX calls. Now this is in place it should make dynamic allocation of all RPC memory on unmarshall *much* easier to fix. Jeremy. (This used to be commit 0ff2ce543ee54f7364e6d839db6d06e7ef1edcf4) --- source3/rpc_client/cli_pipe.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ade31dbb5b..8136b7894c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -223,7 +223,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int memcpy(data, dp, sizeof(data)); - prs_init(&auth_req , 0, 4, UNMARSHALL); + prs_init(&auth_req , 0, 4, cli->mem_ctx, UNMARSHALL); prs_give_memory(&auth_req, data, RPC_HDR_AUTH_LEN, False); /* @@ -267,7 +267,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int memcpy(data, dp, RPC_AUTH_NTLMSSP_CHK_LEN); dump_data(100, data, auth_len); - prs_init(&auth_verf, 0, 4, UNMARSHALL); + prs_init(&auth_verf, 0, 4, cli->mem_ctx, 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)) { @@ -446,7 +446,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr * First read the header of the next PDU. */ - prs_init(&hps, 0, 4, UNMARSHALL); + prs_init(&hps, 0, 4, cli->mem_ctx, UNMARSHALL); prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); @@ -522,7 +522,7 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_ca prs_struct auth_info; int auth_len = 0; - prs_init(&auth_info, 0, 4, MARSHALL); + prs_init(&auth_info, 0, 4, prs_get_mem_context(rpc_out), MARSHALL); if (do_auth) { RPC_HDR_AUTH hdr_auth; @@ -626,7 +626,7 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, * Marshall the variable length data into a temporary parse * struct, pointing into a 4k local buffer. */ - prs_init(&auth_info, 0, 4, MARSHALL); + prs_init(&auth_info, 0, 4, prs_get_mem_context(rpc_out), MARSHALL); /* * Use the 4k buffer to store the auth info. @@ -784,7 +784,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, * Malloc a parse struct to hold it (and enough for alignments). */ - if(!prs_init(&outgoing_packet, data_len + 8, 4, MARSHALL)) { + if(!prs_init(&outgoing_packet, data_len + 8, 4, cli->mem_ctx, MARSHALL)) { DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len )); return False; } @@ -1022,7 +1022,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge); - prs_init(&rpc_out, 0, 4, MARSHALL); + prs_init(&rpc_out, 0, 4, cli->mem_ctx, MARSHALL); prs_give_memory( &rpc_out, buffer, sizeof(buffer), False); @@ -1094,7 +1094,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) if (!valid_pipe_name(pipe_name, &abstract, &transfer)) return False; - prs_init(&rpc_out, 0, 4, MARSHALL); + prs_init(&rpc_out, 0, 4, cli->mem_ctx, MARSHALL); /* * Use the MAX_PDU_FRAG_LEN buffer to store the bind request. @@ -1110,7 +1110,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) global_myname, cli->domain, cli->ntlmssp_cli_flgs); /* Initialize the incoming data struct. */ - prs_init(&rdata, 0, 4, UNMARSHALL); + prs_init(&rdata, 0, 4, cli->mem_ctx, UNMARSHALL); /* send data on \PIPE\. receive a response */ if (rpc_api_pipe(cli, 0x0026, &rpc_out, &rdata)) { -- cgit From 7f36df301e28dc8ca0e5bfadc109d6e907d9ba2b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Aug 2000 18:32:34 +0000 Subject: Tidyup removing many of the 0xC0000000 | NT_STATUS_XXX stuff (only need NT_STATUS_XXX). Removed IS_BITS_xxx macros as they were just reproducing "C" syntax in a more obscure way. Jeremy. (This used to be commit c55bcec817f47d6162466b193d533c877194124a) --- source3/rpc_client/cli_pipe.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8136b7894c..3a875cc46b 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -124,8 +124,8 @@ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, return False; } - (*first) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_FIRST); - (*last) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST ); + (*first) = ((rhdr->flags & RPC_FLG_FIRST) != 0); + (*last) = ((rhdr->flags & RPC_FLG_LAST ) != 0); (*len) = (uint32)rhdr->frag_len - prs_data_size(rdata); return (rhdr->pkt_type != RPC_FAULT); @@ -188,8 +188,8 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int */ 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_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); + BOOL auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 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))); @@ -756,8 +756,8 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, 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); + auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); + auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0); /* * The auth_len doesn't include the RPC_HDR_AUTH_LEN. @@ -1168,7 +1168,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) { int fnum; - if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS)) { + if (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, cli_errstr(cli))); -- cgit From d93101300820514c038ae52ffaf8150594701d07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Dec 2000 07:26:56 +0000 Subject: pass the desired access into cli_nt_create() (This used to be commit a2d07994e0376a8d530d262573c96710bdff2236) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3a875cc46b..7ca274efc3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1169,7 +1169,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) int fnum; if (cli->capabilities & CAP_NT_SMBS) { - if ((fnum = cli_nt_create(cli, &(pipe_name[5]))) == -1) { + if ((fnum = cli_nt_create(cli, &(pipe_name[5], DESIRED_ACCESS_PIPE))) == -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, cli_errstr(cli))); return False; -- cgit From d7a502f5a8f532367bca51b584fd028957df9197 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Dec 2000 07:39:22 +0000 Subject: fixed a typo (This used to be commit c9e4dea1cbcf6aa748f5cb10f226345dd2f1adbf) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7ca274efc3..0b119de5a1 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1169,7 +1169,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) int fnum; if (cli->capabilities & CAP_NT_SMBS) { - if ((fnum = cli_nt_create(cli, &(pipe_name[5], DESIRED_ACCESS_PIPE))) == -1) { + if ((fnum = cli_nt_create(cli, &(pipe_name[5]), DESIRED_ACCESS_PIPE)) == -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, cli_errstr(cli))); return False; -- cgit From c565c98723f1fab04d47ae6076d742c8ee2dcb49 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 10:11:40 +0000 Subject: pipe opening now works with unicode (This used to be commit ba3ce3404e1cd2e9da3ba1708f6fc8a12c085ef2) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0b119de5a1..67cf65a4ff 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -336,7 +336,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd, (int)cli->nt_pipe_fnum)); /* send the data: receive a response. */ - if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, + if (!cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ pdata, data_len, data_len, /* data, length, max */ @@ -889,7 +889,7 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1 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, + if (cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* setup, length, max */ param, 2, 0, /* param, length, max */ NULL, 0, 1024, /* data, length, max */ -- cgit From 00ab9021b0cc5fe2667d383eb9cc2973072cdaaa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Mar 2001 23:48:58 +0000 Subject: Serious (and I *mean* serious) attempt to fix little/bigendian RPC issues. We were reading the endainness in the RPC header and then never propagating it to the internal parse_structs used to parse the data. Also removed the "align" argument to prs_init as it was *always* set to 4, and if needed can be set differently on a case by case basis. Now ready for AS/U testing when Herb gets it set up :-). Jeremy. (This used to be commit 0cd37c831d79a12a10e479bf4fa89ffe64c1292a) --- source3/rpc_client/cli_pipe.c | 44 +++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 67cf65a4ff..b4ca34ea7d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -106,7 +106,7 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re } /**************************************************************************** - Checks the header. + Checks the header. This will set the endian bit in the rdata prs_struct. JRA. ****************************************************************************/ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, @@ -114,6 +114,8 @@ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, { DEBUG(5,("rpc_check_hdr: rdata->data_size = %u\n", (uint32)prs_data_size(rdata) )); + /* Next call sets endian bit. */ + if(!smb_io_rpc_hdr("rpc_hdr ", rhdr, rdata, 0)) { DEBUG(0,("rpc_check_hdr: Failed to unmarshall RPC_HDR.\n")); return False; @@ -223,7 +225,12 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int memcpy(data, dp, sizeof(data)); - prs_init(&auth_req , 0, 4, cli->mem_ctx, UNMARSHALL); + prs_init(&auth_req , 0, cli->mem_ctx, UNMARSHALL); + + /* The endianness must be preserved... JRA. */ + + prs_set_endian_data(&auth_req, rdata->bigendian_data); + prs_give_memory(&auth_req, data, RPC_HDR_AUTH_LEN, False); /* @@ -267,7 +274,11 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int memcpy(data, dp, RPC_AUTH_NTLMSSP_CHK_LEN); dump_data(100, data, auth_len); - prs_init(&auth_verf, 0, 4, cli->mem_ctx, UNMARSHALL); + 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_NTLMSSP_CHK_LEN, False); if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0)) { @@ -369,6 +380,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr prs_give_memory(rdata, prdata, rdata_len, True); current_offset = rdata_len; + /* This next call sets the endian bit correctly in rdata. */ + if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) { prs_mem_free(rdata); return False; @@ -446,7 +459,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr * First read the header of the next PDU. */ - prs_init(&hps, 0, 4, cli->mem_ctx, UNMARSHALL); + prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL); prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); @@ -463,9 +476,20 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr return False; } + /* This call sets the endianness in hps. */ + if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len)) return False; + /* Ensure the endianness in rdata is set correctly - must be same as hps. */ + + if (hps.bigendian_data != rdata->bigendian_data) { + DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n", + rdata->bigendian_data ? "big" : "little", + hps.bigendian_data ? "big" : "little" )); + 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; @@ -522,7 +546,7 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_ca prs_struct auth_info; int auth_len = 0; - prs_init(&auth_info, 0, 4, prs_get_mem_context(rpc_out), MARSHALL); + prs_init(&auth_info, 0, prs_get_mem_context(rpc_out), MARSHALL); if (do_auth) { RPC_HDR_AUTH hdr_auth; @@ -626,7 +650,7 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, * Marshall the variable length data into a temporary parse * struct, pointing into a 4k local buffer. */ - prs_init(&auth_info, 0, 4, prs_get_mem_context(rpc_out), MARSHALL); + prs_init(&auth_info, 0, prs_get_mem_context(rpc_out), MARSHALL); /* * Use the 4k buffer to store the auth info. @@ -784,7 +808,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, * Malloc a parse struct to hold it (and enough for alignments). */ - if(!prs_init(&outgoing_packet, data_len + 8, 4, cli->mem_ctx, MARSHALL)) { + if(!prs_init(&outgoing_packet, data_len + 8, cli->mem_ctx, MARSHALL)) { DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len )); return False; } @@ -1022,7 +1046,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge); - prs_init(&rpc_out, 0, 4, cli->mem_ctx, MARSHALL); + prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL); prs_give_memory( &rpc_out, buffer, sizeof(buffer), False); @@ -1094,7 +1118,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) if (!valid_pipe_name(pipe_name, &abstract, &transfer)) return False; - prs_init(&rpc_out, 0, 4, cli->mem_ctx, MARSHALL); + prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL); /* * Use the MAX_PDU_FRAG_LEN buffer to store the bind request. @@ -1110,7 +1134,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name) global_myname, cli->domain, cli->ntlmssp_cli_flgs); /* Initialize the incoming data struct. */ - prs_init(&rdata, 0, 4, cli->mem_ctx, UNMARSHALL); + prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL); /* send data on \PIPE\. receive a response */ if (rpc_api_pipe(cli, 0x0026, &rpc_out, &rdata)) { -- cgit From 4ca3b30aec403ce025f10a7553c9444e307eea63 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 4 May 2001 07:25:43 +0000 Subject: Added a SMB_ASSERT() so that two cli_state structures aren't opened on different pipes. This seriously confuses NT. Unfortunately HEAD branch is limited to one rpc pipe per connection as the fnum is stored inside the cli_state structure. It should really be broken out into it's own structure so multiple pipes can be opened on one TCP/IP socket. What a good idea! But look over here! I've already done it in another workarea but it will require a day or two to refactor some of the internal samba rpc client stuff (i.e netlogon requests) so it will remain uncommitted for another while. (This used to be commit 657804f3be2b621c8ee15bdb905879e208f9ca2f) --- source3/rpc_client/cli_pipe.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b4ca34ea7d..0ae0732504 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1192,6 +1192,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) { int fnum; + SMB_ASSERT(cli->nt_pipe_fnum == 0); + if (cli->capabilities & CAP_NT_SMBS) { if ((fnum = cli_nt_create(cli, &(pipe_name[5]), DESIRED_ACCESS_PIPE)) == -1) { DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n", @@ -1253,4 +1255,5 @@ close the session void cli_nt_session_close(struct cli_state *cli) { cli_close(cli, cli->nt_pipe_fnum); + cli->nt_pipe_fnum = 0; } -- cgit From 3bc291f55d202f9ba6b2efe7358db8a939447fd4 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 2 Jun 2001 05:33:43 +0000 Subject: Removed irritating and unecessary debug message. (This used to be commit b49c4cd441717b0edf4ad3da0edddca474a08748) --- source3/rpc_client/cli_pipe.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0ae0732504..3709574942 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -971,9 +971,6 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE * int i = 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 )) { DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", -- cgit From 024250d6cab02185771c7c5c010a7873b8bf91df Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 22 Jun 2001 01:19:45 +0000 Subject: Use cli_read_one() for reading DCE/RPC reply fragments. We need to check for and ignore ERRmoredata errors as the client library doesn't support 32-bit error messages. Added some annotations for the RPC pipe code to make it a bit clearer maybe. (This used to be commit f179e0ff61794073aedcf77544865ad2f18c6e6d) --- source3/rpc_client/cli_pipe.c | 65 ++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 29 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3709574942..c3ebf28809 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1,4 +1,3 @@ - /* * Unix SMB/Netbios implementation. * Version 1.9. @@ -23,11 +22,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifdef SYSLOG -#undef SYSLOG -#endif - #include "includes.h" extern int DEBUGLEVEL; @@ -55,7 +49,6 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re int stream_offset = 0; int num_read; 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: %u rdata offset: %u extra_data_size: %d\n", @@ -77,16 +70,21 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re do /* read data using SMBreadX */ { + uint32 ecode; + uint8 eclass; + if (size > (size_t)data_to_read) size = (size_t)data_to_read; - num_read = (int)cli_read(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size); + num_read = (int)cli_read_one(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size); DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", num_read, stream_offset, data_to_read)); - if (cli_error(cli, NULL, &err, NULL)) { - DEBUG(0,("rpc_read: Error %u in cli_read\n", (unsigned int)err )); + if (cli_error(cli, &eclass, &ecode, NULL) && + (eclass != ERRDOS && ecode != ERRmoredata)) { + DEBUG(0,("rpc_read: Error %d/%u in cli_read\n", + eclass, (unsigned int)ecode)); return False; } @@ -328,7 +326,6 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr char *rparam = NULL; uint32 rparam_len = 0; uint16 setup[2]; - uint32 err; BOOL first = True; BOOL last = True; RPC_HDR rhdr; @@ -338,15 +335,19 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr uint32 rdata_len = 0; uint32 current_offset = 0; - /* - * Create setup parameters - must be in native byte order. - */ + /* Create setup parameters - must be in native byte order. */ + setup[0] = cmd; setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */ - DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd, (int)cli->nt_pipe_fnum)); + DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd, + (int)cli->nt_pipe_fnum)); + + /* Send the RPC request and receive a response. For short RPC + calls (about 1024 bytes or so) the RPC request and response + appears in a SMBtrans request and response. Larger RPC + responses are received further on. */ - /* send the data: receive a response. */ if (!cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ @@ -358,9 +359,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr return False; } - /* - * Throw away returned params - we know we won't use them. - */ + /* Throw away returned params - we know we won't use them. */ if(rparam) { free(rparam); @@ -374,7 +373,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr } /* - * Give this memory as dynamically allocated to the return parse struct. + * Give this memory as dynamically allocated to the return parse + * struct. */ prs_give_memory(rdata, prdata, rdata_len, True); @@ -407,13 +407,15 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr 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 */ + /* check if data to be sent back was too large for one SMBtrans */ + /* 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. - */ + + /* Read the remaining part of the first response fragment */ + if (!rpc_read(cli, rdata, len, ¤t_offset)) { prs_mem_free(rdata); return False; @@ -446,7 +448,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr } /* - * Read more fragments until we get the last one. + * Read more fragments using SMBreadX until we get one with the + * last bit set. */ while (!last) { @@ -454,6 +457,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr int num_read; char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN]; prs_struct hps; + uint8 eclass; + uint32 ecode; /* * First read the header of the next PDU. @@ -462,9 +467,11 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL); prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); - 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 )); + num_read = cli_read_one(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); + if (cli_error(cli, &eclass, &ecode, NULL) && + (eclass != ERRDOS && ecode != ERRmoredata)) { + DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", + eclass, ecode)); return False; } -- cgit From 5fb9a869b7e56ca567eae43d85079c37f246daec Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 Jun 2001 00:22:22 +0000 Subject: Use a logical cli_read(), removed the cli_read_one() hack. Jeremy. (This used to be commit 2999eab5abe86bf08e693800c01ad544f04e4d6c) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c3ebf28809..4bbbac17ed 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -76,7 +76,7 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re if (size > (size_t)data_to_read) size = (size_t)data_to_read; - num_read = (int)cli_read_one(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size); + num_read = (int)cli_read(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size); DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", num_read, stream_offset, data_to_read)); @@ -467,7 +467,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL); prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); - num_read = cli_read_one(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); + num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); if (cli_error(cli, &eclass, &ecode, NULL) && (eclass != ERRDOS && ecode != ERRmoredata)) { DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", -- cgit From 62f7f6a022dea6fd4fbe514dcb3154bda334a07f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 06:01:11 +0000 Subject: Use the new client error api. (This used to be commit 688da3c41dd944f7f69083518d25e9edbc55406f) --- source3/rpc_client/cli_pipe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4bbbac17ed..d4e161e212 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -81,7 +81,8 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", num_read, stream_offset, data_to_read)); - if (cli_error(cli, &eclass, &ecode, NULL) && + if (cli_is_dos_error(cli) && + cli_dos_error(cli, &eclass, &ecode) && (eclass != ERRDOS && ecode != ERRmoredata)) { DEBUG(0,("rpc_read: Error %d/%u in cli_read\n", eclass, (unsigned int)ecode)); @@ -468,7 +469,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); - if (cli_error(cli, &eclass, &ecode, NULL) && + if (cli_is_dos_error(cli) && + cli_dos_error(cli, &eclass, &ecode) && (eclass != ERRDOS && ecode != ERRmoredata)) { DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode)); -- cgit From 5836e1f7febc1361f695258f7c0a8f7f95dc3617 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 06:11:31 +0000 Subject: Use new client error api. (This used to be commit b196a52483a6e4ac1e4c311ff43d3c07fca031df) --- source3/rpc_client/cli_pipe.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d4e161e212..1496f05504 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -81,12 +81,13 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", num_read, stream_offset, data_to_read)); - if (cli_is_dos_error(cli) && - cli_dos_error(cli, &eclass, &ecode) && - (eclass != ERRDOS && ecode != ERRmoredata)) { - DEBUG(0,("rpc_read: Error %d/%u in cli_read\n", - eclass, (unsigned int)ecode)); - return False; + if (cli_is_dos_error(cli)) { + cli_dos_error(cli, &eclass, &ecode); + if (eclass != ERRDOS && ecode != ERRmoredata) { + DEBUG(0,("rpc_read: Error %d/%u in cli_read\n", + eclass, (unsigned int)ecode)); + return False; + } } data_to_read -= num_read; @@ -469,12 +470,12 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); - if (cli_is_dos_error(cli) && - cli_dos_error(cli, &eclass, &ecode) && - (eclass != ERRDOS && ecode != ERRmoredata)) { - DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", - eclass, ecode)); - return False; + if (cli_is_dos_error(cli)) { + cli_dos_error(cli, &eclass, &ecode); + if (eclass != ERRDOS && ecode != ERRmoredata) { + DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode)); + return False; + } } DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); -- cgit From 941a3a5d3a46fd4fb913fddc6aa956361d218d23 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 09:41:30 +0000 Subject: move to SAFE_FREE() (This used to be commit 549fe42bd48b3418e63ba4872bc5992dae46d514) --- source3/rpc_client/cli_pipe.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1496f05504..4415b461d9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -363,10 +363,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr /* Throw away returned params - we know we won't use them. */ - if(rparam) { - free(rparam); - rparam = NULL; - } + SAFE_FREE(rparam); if (prdata == NULL) { DEBUG(0,("rpc_api_pipe: cmd %x on pipe %x failed to return data.\n", @@ -934,10 +931,8 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1 state_set = True; } - if (rparam) - free(rparam); - if (rdata) - free(rdata ); + SAFE_FREE(rparam); + SAFE_FREE(rdata); return state_set; } -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/rpc_client/cli_pipe.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4415b461d9..9251f879d2 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -24,7 +24,6 @@ #include "includes.h" -extern int DEBUGLEVEL; extern struct pipe_id_info pipe_names[]; extern fstring global_myworkgroup; extern pstring global_myname; -- cgit From f8e2baf39eb864481dd48f61404136b325cd73c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2001 23:34:24 +0000 Subject: Added NT_USER_TOKEN into server_info to fix extra groups problem. Got "medieval on our ass" about const warnings (as many as I could :-). Jeremy. (This used to be commit ee5e7ca547eff016818ba5c43b8ea0c9fa69b808) --- source3/rpc_client/cli_pipe.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9251f879d2..6eaab39bcc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -896,7 +896,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, Set the handle state. ****************************************************************************/ -static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state) +static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, const char *pipe_name, uint16 device_state) { BOOL state_set = False; char param[2]; @@ -940,7 +940,7 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1 check the rpc bind acknowledge response ****************************************************************************/ -static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer) +static BOOL valid_pipe_name(const char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer) { int pipe_idx = 0; @@ -970,7 +970,7 @@ static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *tra check the rpc bind acknowledge response ****************************************************************************/ -static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer) +static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const char *pipe_name, RPC_IFACE *transfer) { int i = 0; @@ -1104,7 +1104,7 @@ 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, char *pipe_name, char *my_name) +BOOL rpc_pipe_bind(struct cli_state *cli, const char *pipe_name, char *my_name) { RPC_IFACE abstract; RPC_IFACE transfer; @@ -1189,16 +1189,16 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) Open a session. ****************************************************************************/ -BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name) +BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name) { int fnum; SMB_ASSERT(cli->nt_pipe_fnum == 0); if (cli->capabilities & CAP_NT_SMBS) { - if ((fnum = cli_nt_create(cli, &(pipe_name[5]), DESIRED_ACCESS_PIPE)) == -1) { + if ((fnum = cli_nt_create(cli, &pipe_name[5], DESIRED_ACCESS_PIPE)) == -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, cli_errstr(cli))); + &pipe_name[5], cli->desthost, cli_errstr(cli))); return False; } -- cgit From f23cc6ab25b8b642c713b571ca77304178070339 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 2 Jan 2002 05:39:49 +0000 Subject: struct cli_state remembers the pipe name that it's talking to, if any, so that we can print it in later debug messages. Call prs_dump to dump out requests sent by the client at sufficiently high debug levels. (This used to be commit 9973b22b34dc2a88a20b821d4e69f39d2a6aa6a3) --- source3/rpc_client/cli_pipe.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6eaab39bcc..829692ccc3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -770,9 +770,12 @@ static BOOL create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, } -/**************************************************************************** - Send a request on an rpc pipe. - ****************************************************************************/ +/** + * Send a request on an RPC pipe and get a response. + * + * @param data NDR contents of the request to be sent. + * @param rdata Unparsed NDR response data. +**/ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, prs_struct *data, prs_struct *rdata) @@ -785,10 +788,16 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, BOOL auth_seal; uint32 crc32 = 0; char *pdata_out = NULL; + fstring dump_name; auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0); + /* Optionally capture for use in debugging */ + slprintf(dump_name, sizeof(dump_name) - 1, "call_%s", + cli_pipe_get_name(cli)); + prs_dump(dump_name, op_num, data); + /* * The auth_len doesn't include the RPC_HDR_AUTH_LEN. */ @@ -1246,9 +1255,19 @@ BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name) fstrcat(cli->mach_acct, "$"); strupper(cli->mach_acct); + /* Remember which pipe we're talking to */ + fstrcpy(cli->pipe_name, pipe_name); + return True; } + +const char *cli_pipe_get_name(struct cli_state *cli) +{ + return cli->pipe_name; +} + + /**************************************************************************** close the session ****************************************************************************/ -- cgit From 05ae7ca1cb4ace159e846ee2f15871f45f32ff90 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 2 Jan 2002 06:08:02 +0000 Subject: Also capture received data (This used to be commit 93fadcd1118b390605d2504bee63a1e8b6373ac5) --- source3/rpc_client/cli_pipe.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 829692ccc3..0d2f6b17e0 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -896,6 +896,11 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, ret = rpc_api_pipe(cli, 0x0026, &outgoing_packet, rdata); + /* Also capture received data */ + slprintf(dump_name, sizeof(dump_name) - 1, "reply_%s", + cli_pipe_get_name(cli)); + prs_dump(dump_name, op_num, rdata); + prs_mem_free(&outgoing_packet); return ret; -- cgit From 4f3a2be2b9b566a33c5205142666e7e697d8f93f Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 2 Jan 2002 07:48:07 +0000 Subject: Add prs_dump_before to dump everything from the start of the prs buffer up to the current position, and use this to dump pipe buffers just before parsing. (This used to be commit 92a3ab274e6cf09a8ba39b91f8bbacba6de40b37) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0d2f6b17e0..63abbc1c56 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -796,7 +796,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, /* Optionally capture for use in debugging */ slprintf(dump_name, sizeof(dump_name) - 1, "call_%s", cli_pipe_get_name(cli)); - prs_dump(dump_name, op_num, data); + prs_dump_before(dump_name, op_num, data); /* * The auth_len doesn't include the RPC_HDR_AUTH_LEN. -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/rpc_client/cli_pipe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 63abbc1c56..a7049f78df 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1,6 +1,5 @@ /* - * Unix SMB/Netbios implementation. - * Version 1.9. + * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1998, * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/rpc_client/cli_pipe.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a7049f78df..eae6be5128 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -23,6 +23,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_CLI + extern struct pipe_id_info pipe_names[]; extern fstring global_myworkgroup; extern pstring global_myname; -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index eae6be5128..0416ed3b9b 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -354,7 +354,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr if (!cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ - pdata, data_len, data_len, /* data, length, max */ + pdata, data_len, 1024, /* data, length, max */ &rparam, &rparam_len, /* return params, len */ &prdata, &rdata_len)) /* return data, len */ { -- cgit From 36ef82a52953384acedbd51f54ded9357fa8ca3e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Oct 2002 04:10:23 +0000 Subject: merge of new client side support the Win2k LSARPC UUID in rpcbind from APP_HEAD (This used to be commit 1cfd2ee433305e91e87804dd55d10e025d30a69e) --- source3/rpc_client/cli_pipe.c | 107 ++++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 29 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0416ed3b9b..b6b58d2237 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -952,6 +952,8 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, const char *pipe_name, return state_set; } +#if 0 /* JERRY */ + /**************************************************************************** check the rpc bind acknowledge response ****************************************************************************/ @@ -982,32 +984,73 @@ static BOOL valid_pipe_name(const char *pipe_name, RPC_IFACE *abstract, RPC_IFAC return False; } +#endif + +/**************************************************************************** + check the rpc bind acknowledge response +****************************************************************************/ + +int get_pipe_index( const char *pipe_name ) +{ + int pipe_idx = 0; + + while (pipe_names[pipe_idx].client_pipe != NULL) { + if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) + return pipe_idx; + pipe_idx++; + }; + + return -1; +} + /**************************************************************************** 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 valid_pipe_name_by_idx(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer) +{ + if ( pipe_idx >= PI_MAX_PIPES ) { + DEBUG(0,("valid_pipe_name_by_idx: Programmer error! Invalid pipe index [%d]\n", + pipe_idx)); + return False; + } + + 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: ")); + 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 */ + + *transfer = pipe_names[pipe_idx].trans_syntax; + *abstract = pipe_names[pipe_idx].abstr_syntax; + + return True; +} + +/**************************************************************************** + check the rpc bind acknowledge response +****************************************************************************/ + +static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer) { int i = 0; - while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0) { - 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 { - 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 { - i++; - } + if ( hdr_ba->addr.len <= 0) + return False; + + if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe )) + { + DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n", + pipe_names[i].server_pipe ,hdr_ba->addr.str)); + return False; } + + DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", pipe_names[i].server_pipe )); - if (pipe_names[i].server_pipe == NULL) { + if (pipe_names[pipe_idx].server_pipe == NULL) { DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str)); return False; } @@ -1120,7 +1163,7 @@ 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, const char *pipe_name, char *my_name) +BOOL rpc_pipe_bind(struct cli_state *cli, const int pipe_idx, char *my_name) { RPC_IFACE abstract; RPC_IFACE transfer; @@ -1130,9 +1173,12 @@ BOOL rpc_pipe_bind(struct cli_state *cli, const char *pipe_name, char *my_name) uint32 rpc_call_id; char buffer[MAX_PDU_FRAG_LEN]; - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name)); + if ( (pipe_idx < 0) || (pipe_idx >= PI_MAX_PIPES) ) + return False; + + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_names[pipe_idx].client_pipe)); - if (!valid_pipe_name(pipe_name, &abstract, &transfer)) + if (!valid_pipe_name_by_idx(pipe_idx, &abstract, &transfer)) return False; prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL); @@ -1165,7 +1211,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, const char *pipe_name, char *my_name) return False; } - if(!check_bind_response(&hdr_ba, pipe_name, &transfer)) { + if(!check_bind_response(&hdr_ba, pipe_idx, &transfer)) { DEBUG(0,("rpc_pipe_bind: check_bind_response failed.\n")); prs_mem_free(&rdata); return False; @@ -1205,31 +1251,34 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) Open a session. ****************************************************************************/ -BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name) +BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) { int fnum; SMB_ASSERT(cli->nt_pipe_fnum == 0); + + if ( (pipe_idx < 0) || (pipe_idx >= PI_MAX_PIPES) ) + return False; if (cli->capabilities & CAP_NT_SMBS) { - if ((fnum = cli_nt_create(cli, &pipe_name[5], DESIRED_ACCESS_PIPE)) == -1) { + if ((fnum = cli_nt_create(cli, &pipe_names[pipe_idx].client_pipe[5], DESIRED_ACCESS_PIPE)) == -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, cli_errstr(cli))); + &pipe_names[pipe_idx].client_pipe[5], cli->desthost, cli_errstr(cli))); return False; } cli->nt_pipe_fnum = (uint16)fnum; } else { - if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) { + if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, 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, cli_errstr(cli))); + pipe_names[pipe_idx].client_pipe, 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_name, 0x4300)) { + if (!rpc_pipe_set_hnd_state(cli, pipe_names[pipe_idx].client_pipe, 0x4300)) { DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", cli_errstr(cli))); cli_close(cli, cli->nt_pipe_fnum); @@ -1239,7 +1288,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name) /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, pipe_name, global_myname)) { + if (!rpc_pipe_bind(cli, pipe_idx, global_myname)) { DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", cli_errstr(cli))); cli_close(cli, cli->nt_pipe_fnum); @@ -1263,7 +1312,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name) strupper(cli->mach_acct); /* Remember which pipe we're talking to */ - fstrcpy(cli->pipe_name, pipe_name); + fstrcpy(cli->pipe_name, pipe_names[pipe_idx].client_pipe); return True; } -- cgit From 9c1b62c0fd06cc65853269db3c63b169daa90664 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Oct 2002 19:33:41 +0000 Subject: merge of working dsrolegetprimdominfo() client code from APP_HEAD (This used to be commit 028477e35208e76fedbc7c743426fd9be94b7cf0) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b6b58d2237..2732c53e5c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -599,7 +599,7 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_ca } /* create the request RPC_HDR */ - init_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id, + init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id, RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info), auth_len); -- cgit From 055e6d1491d56c85f01e70cf83a928fa6492e2aa Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Oct 2002 21:42:04 +0000 Subject: * merge native_mode flag in winbindd_domain struct from app-head * add some files missing from a previous commit (This used to be commit 29159c97371c75327e377f9d13406dad46095568) --- source3/rpc_client/cli_pipe.c | 42 +++++++++++------------------------------- 1 file changed, 11 insertions(+), 31 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2732c53e5c..7e1289edff 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -952,65 +952,45 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, const char *pipe_name, return state_set; } -#if 0 /* JERRY */ - /**************************************************************************** check the rpc bind acknowledge response ****************************************************************************/ -static BOOL valid_pipe_name(const char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer) +int get_pipe_index( const char *pipe_name ) { 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: ")); - dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), - sizeof(pipe_names[pipe_idx].abstr_syntax)); - 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 */ - *transfer = pipe_names[pipe_idx].trans_syntax; - *abstract = pipe_names[pipe_idx].abstr_syntax; - - return True; - } + if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) + return pipe_idx; pipe_idx++; }; - DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name)); - return False; + return -1; } -#endif /**************************************************************************** check the rpc bind acknowledge response ****************************************************************************/ -int get_pipe_index( const char *pipe_name ) +char* get_pipe_name_from_index( const int pipe_index ) { - int pipe_idx = 0; - while (pipe_names[pipe_idx].client_pipe != NULL) { - if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) - return pipe_idx; - pipe_idx++; - }; + if ( (pipe_index < 0) || (pipe_index >= PI_MAX_PIPES) ) + return NULL; - return -1; + return pipe_names[pipe_index].client_pipe; } /**************************************************************************** check the rpc bind acknowledge response ****************************************************************************/ -static BOOL valid_pipe_name_by_idx(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer) +static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer) { if ( pipe_idx >= PI_MAX_PIPES ) { - DEBUG(0,("valid_pipe_name_by_idx: Programmer error! Invalid pipe index [%d]\n", + DEBUG(0,("valid_pipe_name: Programmer error! Invalid pipe index [%d]\n", pipe_idx)); return False; } @@ -1178,7 +1158,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, const int pipe_idx, char *my_name) DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_names[pipe_idx].client_pipe)); - if (!valid_pipe_name_by_idx(pipe_idx, &abstract, &transfer)) + if (!valid_pipe_name(pipe_idx, &abstract, &transfer)) return False; prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL); -- cgit From bfa93735abe52fe07fde1b10ece0c31f5cf73ef8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 8 Oct 2002 18:32:42 +0000 Subject: merge from APP_HEAD of winbindd's domain local group fix (This used to be commit 09c6f6329d6ae9327b7ef06de0ea78d24d805456) --- source3/rpc_client/cli_pipe.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7e1289edff..71e422f251 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -983,6 +983,22 @@ char* get_pipe_name_from_index( const int pipe_index ) return pipe_names[pipe_index].client_pipe; } +/**************************************************************************** + Check to see if this pipe index points to one of + the pipes only supported by Win2k + ****************************************************************************/ + +BOOL is_win2k_pipe( const int pipe_idx ) +{ + switch ( pipe_idx ) + { + case PI_LSARPC_DS: + return True; + } + + return False; +} + /**************************************************************************** check the rpc bind acknowledge response ****************************************************************************/ -- cgit From 14a85b0008a6bf227d5464a4e29a9a53d6695bd0 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 17 Oct 2002 05:23:14 +0000 Subject: Merge of SMB_ASSERT. (This used to be commit 1094e1ffde09b0393b11d2cce148b6da893348c1) --- source3/rpc_client/cli_pipe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 71e422f251..61c6f2889f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1253,8 +1253,9 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) SMB_ASSERT(cli->nt_pipe_fnum == 0); - if ( (pipe_idx < 0) || (pipe_idx >= PI_MAX_PIPES) ) - return False; + /* The pipe index must fall within our array */ + + SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); if (cli->capabilities & CAP_NT_SMBS) { if ((fnum = cli_nt_create(cli, &pipe_names[pipe_idx].client_pipe[5], DESIRED_ACCESS_PIPE)) == -1) { -- cgit From 5dd341d647d3677b26060ce4cd3795ef0210274b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 1 Nov 2002 00:37:45 +0000 Subject: Tidyup of some DCERPC pipe connection debugs. The new LSA_DS stuff generates some errors we haven't seen before which are inappropriately logged at level 0. (This used to be commit 40d5112048ab0943caef7149b7a0d9dee5256b87) --- source3/rpc_client/cli_pipe.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 61c6f2889f..62bf44e3ef 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1054,7 +1054,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC /* check the transfer syntax */ 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")); + DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n")); return False; } @@ -1208,7 +1208,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, const int pipe_idx, char *my_name) } if(!check_bind_response(&hdr_ba, pipe_idx, &transfer)) { - DEBUG(0,("rpc_pipe_bind: check_bind_response failed.\n")); + DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n")); prs_mem_free(&rdata); return False; } @@ -1286,8 +1286,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)) { - DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n", - cli_errstr(cli))); + DEBUG(2,("cli_nt_session_open: rpc bind failed\n")); cli_close(cli, cli->nt_pipe_fnum); return False; } -- cgit From c49573e59f06e25031fa84022005166e62cd7506 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 2 Nov 2002 00:43:38 +0000 Subject: Display pipe name in rpc bind failure debug. (This used to be commit 70838b33a61a10e9bd1622611a6be3b0cac08479) --- source3/rpc_client/cli_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 62bf44e3ef..995697d885 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1286,7 +1286,8 @@ 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)) { - DEBUG(2,("cli_nt_session_open: rpc bind failed\n")); + 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); return False; } -- cgit From 98f9e758f0f0db0472038fdf72d30f17de04d55c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Nov 2002 18:54:02 +0000 Subject: Merge Jim's new rpc client code to 3.0. Jeremy. (This used to be commit 121c456d4347bbefd9b2ce0141e3f53a21f37066) --- source3/rpc_client/cli_pipe.c | 255 ++++++++++++++++++++++++------------------ 1 file changed, 145 insertions(+), 110 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 995697d885..f685f38754 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -300,7 +300,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int /**************************************************************************** - Send data on an rpc pipe, which *must* be in one fragment. + Send data on an rpc pipe via trans, which *must* be the last fragment. receive response data from an rpc pipe, which may be large... Read the first fragment: unfortunately have to use SMBtrans for the first @@ -323,7 +323,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int ****************************************************************************/ -static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, prs_struct *rdata) +static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rdata) { uint32 len; char *rparam = NULL; @@ -337,14 +337,14 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr char *prdata = NULL; uint32 rdata_len = 0; uint32 current_offset = 0; + uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024; /* Create setup parameters - must be in native byte order. */ - setup[0] = cmd; + setup[0] = TRANSACT_DCERPCCMD; setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */ - DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd, - (int)cli->nt_pipe_fnum)); + DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum)); /* Send the RPC request and receive a response. For short RPC calls (about 1024 bytes or so) the RPC request and response @@ -354,7 +354,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr if (!cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ - pdata, data_len, 1024, /* data, length, max */ + pdata, data_len, max_data, /* data, length, max */ &rparam, &rparam_len, /* return params, len */ &prdata, &rdata_len)) /* return data, len */ { @@ -367,8 +367,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr SAFE_FREE(rparam); 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)); + DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n", + (int)cli->nt_pipe_fnum)); return False; } @@ -730,17 +730,18 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, Creates a DCE/RPC request. ********************************************************************/ -static BOOL create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, int auth_len) +static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, int auth_len, uint8 flags, uint32 oldid, uint32 data_left) { uint32 alloc_hint; RPC_HDR hdr; RPC_HDR_REQ hdr_req; + uint32 callid = oldid ? oldid : get_rpc_call_id(); DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n", op_num, data_len)); /* create the rpc header RPC_HDR */ - init_rpc_hdr(&hdr, RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST, - get_rpc_call_id(), data_len, auth_len); + init_rpc_hdr(&hdr, RPC_REQUEST, flags, + callid, data_len, auth_len); /* * The alloc hint should be the amount of data, not including @@ -748,9 +749,9 @@ static BOOL create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, */ if (auth_len != 0) - alloc_hint = data_len - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len; + alloc_hint = data_left - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len; else - alloc_hint = data_len - RPC_HEADER_LEN; + alloc_hint = data_left - RPC_HEADER_LEN; DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n", data_len, auth_len, alloc_hint)); @@ -760,17 +761,59 @@ static BOOL create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, /* stream-time... */ if(!smb_io_rpc_hdr("hdr ", &hdr, rpc_out, 0)) - return False; + return 0; if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, rpc_out, 0)) - return False; + return 0; if (prs_offset(rpc_out) != RPC_HEADER_LEN + RPC_HDR_REQ_LEN) - return False; + return 0; + + return callid; +} + +/******************************************************************* + Puts an auth header into an rpc request. + ********************************************************************/ +static BOOL create_auth_hdr(prs_struct *outgoing_packet, BOOL 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,("create_auth_hdr:Failed to marshal RPC_HDR_AUTH.\n")); + return False; + } return True; } +/******************************************************************* + Puts auth data into an rpc request. + ********************************************************************/ + +static BOOL create_auth_data(struct cli_state *cli, uint32 crc32, + prs_struct *outgoing_packet) +{ + char *pdata_out = prs_data_p(outgoing_packet); + 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,("create_auth_data: Failed to marshal RPC_AUTH_NTLMSSP_CHK.\n")); + return False; + } + NTLMSSPcalc_ap(cli, (unsigned char*) + &pdata_out[current_offset+4], + RPC_AUTH_NTLMSSP_CHK_LEN - 4); + return True; +} /** * Send a request on an RPC pipe and get a response. @@ -782,129 +825,121 @@ static BOOL create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, prs_struct *data, prs_struct *rdata) { - 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; + uint32 auth_len, max_data, data_left, data_sent; + BOOL ret = False; + BOOL auth_verify, auth_seal; fstring dump_name; auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); auth_seal = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SEAL) != 0); - /* Optionally capture for use in debugging */ - slprintf(dump_name, sizeof(dump_name) - 1, "call_%s", - cli_pipe_get_name(cli)); - prs_dump_before(dump_name, op_num, data); - - /* - * The auth_len doesn't include the RPC_HDR_AUTH_LEN. - */ - auth_len = (auth_verify ? RPC_AUTH_NTLMSSP_CHK_LEN : 0); /* - * 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. + * 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; - if((prs_offset(data) % 8) != 0) { - DEBUG(5,("rpc_api_pipe_req: Outgoing data not a multiple of 8 bytes....\n")); - } + for (data_left = prs_offset(data), data_sent = 0; data_left > 0;) { + prs_struct outgoing_packet; + uint32 data_len, send_size; + uint8 flags = 0; + uint32 crc32 = 0; + uint32 callid; - data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(data) + + /* + * how much will we send this time + */ + send_size = MIN(data_left, max_data); + data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + send_size + (auth_verify ? RPC_HDR_AUTH_LEN : 0) + auth_len; - /* - * Malloc a parse struct to hold it (and enough for alignments). - */ - - if(!prs_init(&outgoing_packet, data_len + 8, cli->mem_ctx, MARSHALL)) { - DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len )); - return False; - } - - 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. - */ - - 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)); - } - - /* - * 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; - } - - /* - * Add a trailing auth_verifier if needed. - */ - - if (auth_seal || auth_verify) { - RPC_HDR_AUTH hdr_auth; + /* + * Malloc parse struct to hold it (and enough for alignments). + */ + if(!prs_init(&outgoing_packet, data_len + 8, + cli->mem_ctx, MARSHALL)) { + DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len )); + return False; + } - 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")); + if (data_left == prs_offset(data)) { + flags |= RPC_FLG_FIRST; + callid = 0; + } + if (data_left < max_data) + flags |= RPC_FLG_LAST; + /* + * Write out the RPC header and the request header. + */ + if(!(callid = create_rpc_request(&outgoing_packet, op_num, + data_len, auth_len, flags, + callid, data_left))) { + DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n")); prs_mem_free(&outgoing_packet); return False; } - } - /* - * Finally the auth data itself. - */ - - if (auth_verify) { - RPC_AUTH_NTLMSSP_CHK chk; - uint32 current_offset = prs_offset(&outgoing_packet); + /* + * Seal the outgoing data if requested. + */ + if (auth_seal) { + crc32 = crc32_calc_buffer(prs_data_p(data) + data_sent, + send_size); + NTLMSSPcalc_ap(cli, (unsigned char*)prs_data_p(data) + + data_sent, send_size); + } - 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")); + /* + * 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; } - NTLMSSPcalc_ap(cli, (unsigned char*)&pdata_out[current_offset+4], RPC_AUTH_NTLMSSP_CHK_LEN - 4); - } - DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, prs_offset(&outgoing_packet))); + /* + * Add a trailing auth_verifier if needed. + */ + if (auth_seal || auth_verify) { + if(!create_auth_hdr(&outgoing_packet, auth_verify)) { + prs_mem_free(&outgoing_packet); + return False; + } + } - ret = rpc_api_pipe(cli, 0x0026, &outgoing_packet, rdata); + /* + * Finally the auth data itself. + */ + if (auth_verify) { + if (!create_auth_data(cli, crc32, &outgoing_packet)) { + prs_mem_free(&outgoing_packet); + return False; + } + } + DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, + prs_offset(&outgoing_packet))); + + if (flags & RPC_FLG_LAST) + ret = rpc_api_pipe(cli, &outgoing_packet, rdata); + else { + cli_write(cli, cli->nt_pipe_fnum, 0x0008, + prs_data_p(&outgoing_packet), + data_sent, data_len); + } + prs_mem_free(&outgoing_packet); + data_sent += send_size; + data_left -= send_size; + } /* Also capture received data */ slprintf(dump_name, sizeof(dump_name) - 1, "reply_%s", cli_pipe_get_name(cli)); prs_dump(dump_name, op_num, rdata); - prs_mem_free(&outgoing_packet); - return ret; } @@ -1196,7 +1231,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, const int pipe_idx, char *my_name) prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL); /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, 0x0026, &rpc_out, &rdata)) { + if (rpc_api_pipe(cli, &rpc_out, &rdata)) { RPC_HDR_BA hdr_ba; DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n")); -- cgit From 2f194322d419350f35a48dff750066894d68eccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/rpc_client/cli_pipe.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f685f38754..90f08148ef 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -27,8 +27,6 @@ #define DBGC_CLASS DBGC_RPC_CLI extern struct pipe_id_info pipe_names[]; -extern fstring global_myworkgroup; -extern pstring global_myname; /******************************************************************** Rpc pipe call id. @@ -546,7 +544,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, RPC_IFACE *abstract, RPC_IFACE *transfer, - char *my_name, char *domain, uint32 neg_flags) + const char *my_name, const char *domain, uint32 neg_flags) { RPC_HDR hdr; RPC_HDR_RB hdr_rb; @@ -640,7 +638,7 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_ca ********************************************************************/ static BOOL create_rpc_bind_resp(struct pwd_info *pwd, - char *domain, char *user_name, char *my_name, + const char *domain, const char *user_name, const char *my_name, uint32 ntlmssp_cli_flgs, uint32 rpc_call_id, prs_struct *rpc_out) @@ -1142,7 +1140,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 prs_give_memory( &rpc_out, buffer, sizeof(buffer), False); create_rpc_bind_resp(&cli->pwd, cli->domain, - cli->user_name, global_myname, + cli->user_name, global_myname(), cli->ntlmssp_cli_flgs, rpc_call_id, &rpc_out); @@ -1194,7 +1192,7 @@ 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, const int pipe_idx, char *my_name) +BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name) { RPC_IFACE abstract; RPC_IFACE transfer; @@ -1225,7 +1223,7 @@ BOOL rpc_pipe_bind(struct cli_state *cli, const int pipe_idx, char *my_name) /* 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); + global_myname(), cli->domain, cli->ntlmssp_cli_flgs); /* Initialize the incoming data struct. */ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL); @@ -1320,7 +1318,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())) { 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); @@ -1336,10 +1334,10 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) strupper(cli->srv_name_slash); fstrcpy(cli->clnt_name_slash, "\\\\"); - fstrcat(cli->clnt_name_slash, global_myname); + fstrcat(cli->clnt_name_slash, global_myname()); strupper(cli->clnt_name_slash); - fstrcpy(cli->mach_acct, global_myname); + fstrcpy(cli->mach_acct, global_myname()); fstrcat(cli->mach_acct, "$"); strupper(cli->mach_acct); -- cgit From 1c8e1e04480c5c050a0112ac70f3e66fab80ebba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 2 Dec 2002 23:51:53 +0000 Subject: Ensure callid is not used uninitialized. Jeremy. (This used to be commit ddd70995951c072a02fc3bddd7a94ccbf301f62c) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 90f08148ef..4da0233934 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -844,7 +844,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, uint32 data_len, send_size; uint8 flags = 0; uint32 crc32 = 0; - uint32 callid; + uint32 callid = 0; /* * how much will we send this time -- cgit From 634c54310c92c48dd4eceec602e230a021bdcfc5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jan 2003 08:28:12 +0000 Subject: Merge from HEAD - make Samba compile with -Wwrite-strings without additional warnings. (Adds a lot of const). Andrew Bartlett (This used to be commit 3a7458f9472432ef12c43008414925fd1ce8ea0c) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4da0233934..ac43d8994c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1007,7 +1007,7 @@ int get_pipe_index( const char *pipe_name ) check the rpc bind acknowledge response ****************************************************************************/ -char* get_pipe_name_from_index( const int pipe_index ) +const char* get_pipe_name_from_index( const int pipe_index ) { if ( (pipe_index < 0) || (pipe_index >= PI_MAX_PIPES) ) -- cgit From 4242eda183393b0535ac8ef880b4f441c60137af Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Jan 2003 17:22:48 +0000 Subject: merging some rpcclient and net functionality from HEAD (This used to be commit 7a4c87484237308cb3ad0d671687da7e0f6e733b) --- source3/rpc_client/cli_pipe.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ac43d8994c..a241744466 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -862,10 +862,9 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, return False; } - if (data_left == prs_offset(data)) { + if (data_left == prs_offset(data)) flags |= RPC_FLG_FIRST; - callid = 0; - } + if (data_left < max_data) flags |= RPC_FLG_LAST; /* @@ -1284,6 +1283,9 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) { int fnum; + /* At the moment we can't have more than one pipe open over + a cli connection. )-: */ + SMB_ASSERT(cli->nt_pipe_fnum == 0); /* The pipe index must fall within our array */ -- cgit From f27d292efcc60a7ce3bf12e54a918c8177032199 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 22 Jan 2003 23:33:18 +0000 Subject: Merge: remove dead function. (This used to be commit 648307ab3d16cb557cead27d6799a741a266c0d5) --- source3/rpc_client/cli_pipe.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a241744466..bbbf194fbd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1265,16 +1265,6 @@ BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name) return True; } -/**************************************************************************** - Set ntlmssp negotiation flags. - ****************************************************************************/ - -void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs) -{ - cli->ntlmssp_cli_flgs = ntlmssp_flgs; -} - - /**************************************************************************** Open a session. ****************************************************************************/ -- cgit From 7238bf5f40e16360439e028fa7607a5a28e02965 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Apr 2003 15:54:17 +0000 Subject: 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 (This used to be commit eaef0d8aeff1aa5a067679be3f17e08d7434e1e8) --- source3/rpc_client/cli_pipe.c | 323 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 305 insertions(+), 18 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bbbf194fbd..c4a9b37127 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/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; } -- cgit From e9a4e1bb2e7da382a58c57797bcfef79ed455905 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 14 Apr 2003 05:28:09 +0000 Subject: Merge: remove unused variables. (This used to be commit dfa9412da567d2477ee5b1e6ecdc96b8dea3c21d) --- source3/rpc_client/cli_pipe.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c4a9b37127..93c6b98bc3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1016,8 +1016,6 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, 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)); -- cgit From 09a50497d1360659eb8bd1b9f4be510680267bd2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Apr 2003 15:39:57 +0000 Subject: Fixes to make SCHANNEL work in 3.0 against a W2K DC. Still need to fix multi-PDU encode/decode with SCHANNEL. Also need to test against WNT DC. Jeremy. (This used to be commit ff66d4097088409205b6bad5124a78ef9946010d) --- source3/rpc_client/cli_pipe.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 93c6b98bc3..a0be3d9774 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -193,8 +193,8 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int 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))); + DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s schannel %s\n", + len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal), BOOLSTR(auth_schannel))); /* * Unseal any sealed data in the PDU, not including the @@ -302,16 +302,16 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int prs_struct auth_verf; if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { - DEBUG(0,("rpc_auth_pipe: wrong auth len %d\n", auth_len)); + DEBUG(0,("rpc_auth_pipe: wrong schannel 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")); + DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n")); return False; } - DEBUG(10,("rpc_auth_pipe: verify netsec\n")); + DEBUG(10,("rpc_auth_pipe: schannel verify netsec\n")); dump_data(100, dp, auth_len); memcpy(data, dp, sizeof(data)); @@ -324,17 +324,18 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int 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 " + if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", &chk, &auth_verf, 0)) { + DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " "RPC_AUTH_NETSECK_CHK failed\n")); return False; } + cli->auth_info.seq_num++; + 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; } @@ -360,7 +361,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int +------------+-----------------+-------------+---------------+-------------+ Where the presence of the AUTH_HDR and AUTH are dependent on the - signing & sealing being neogitated. + signing & sealing being negotiated. ****************************************************************************/ @@ -649,7 +650,7 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netse init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, 0x00, 1); - init_rpc_auth_netsec_neg(&netsec_neg, my_name, domain); + init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name); /* * Use the 4k buffer to store the auth info. @@ -1018,8 +1019,15 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, uchar sign[8]; prs_struct netsec_blob; - memset(sign, 0, sizeof(sign)); - sign[4] = 0x80; + if ((cli->auth_info.seq_num & 1) != 0) { + DEBUG(0,("SCHANNEL ERROR: seq_num must be even in client (seq_num=%d)\n", + cli->auth_info.seq_num)); + } + + DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num)); + + RSIVAL(sign, 0, cli->auth_info.seq_num); + SIVAL(sign, 4, 0x80); if (!prs_init(&netsec_blob, send_size+auth_padding, cli->mem_ctx, MARSHALL)) { @@ -1047,12 +1055,15 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, sign, nullbytes); - netsec_encode(&(cli->auth_info), &verf, + 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); + + cli->auth_info.seq_num++; + } else { if(!prs_append_some_prs_data(&outgoing_packet, data, data_sent, send_size)) { -- cgit From e156cf7df48e37306baefb8563724996b016687f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Apr 2003 21:09:48 +0000 Subject: Fixes for multi-PDU schannel - based on Volker's code. This code needs tidying up. Samsync still doesn't work due to bad parsing of net_io_sam_alias_info with a blank description. Still working on this.... Jeremy. (This used to be commit 942fede9a57a9319cf67388004dd45fa8a045f41) --- source3/rpc_client/cli_pipe.c | 45 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a0be3d9774..b3e8deeeef 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -174,7 +174,8 @@ static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, uint32 l 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, + uint32 fragment_start, int len, int auth_len, int *pauth_padding_len) { /* * The following is that length of the data we must sign or seal. @@ -187,12 +188,14 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int /* * 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; + char *reply_data = prs_data_p(rdata) + fragment_start + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; 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); + *pauth_padding_len = 0; + DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s schannel %s\n", len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal), BOOLSTR(auth_schannel))); @@ -297,8 +300,10 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int if (auth_schannel) { RPC_AUTH_NETSEC_CHK chk; - char data[RPC_AUTH_NETSEC_CHK_LEN]; - char *dp = prs_data_p(rdata) + len - auth_len; + RPC_HDR_AUTH rhdr_auth; + char data[RPC_HDR_AUTH_LEN+RPC_AUTH_NETSEC_CHK_LEN]; + char *dp = prs_data_p(rdata) + fragment_start + len - + RPC_HDR_AUTH_LEN - RPC_AUTH_NETSEC_CHK_LEN; prs_struct auth_verf; if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { @@ -322,7 +327,19 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int /* 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); + prs_give_memory(&auth_verf, data, sizeof(data), False); + + if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) { + DEBUG(0, ("rpc_auth_pipe: Could not parse schannel auth header\n")); + return False; + } + + if ((rhdr_auth.auth_type != NETSEC_AUTH_TYPE) || + (rhdr_auth.auth_level != NETSEC_AUTH_LEVEL)) { + DEBUG(0, ("rpc_auth_pipe: Got wrong schannel auth type/level: %d/%d\n", + rhdr_auth.auth_type, rhdr_auth.auth_level)); + return False; + } if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", &chk, &auth_verf, 0)) { DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " @@ -336,6 +353,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n")); return False; } + *pauth_padding_len = rhdr_auth.padding; } return True; } @@ -379,6 +397,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd char *prdata = NULL; uint32 rdata_len = 0; uint32 current_offset = 0; + uint32 fragment_start = 0; uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024; /* Create setup parameters - must be in native byte order. */ @@ -469,7 +488,10 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd */ if (rhdr.auth_len != 0) { - if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) + int auth_padding_len = 0; + + if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, + rhdr.auth_len, &auth_padding_len)) return False; /* * Drop the auth footers from the current offset. @@ -477,7 +499,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd * The auth footers consist of the auth_data and the * preceeding 8 byte auth_header. */ - current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN); + current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len); } /* @@ -557,12 +579,17 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd if (!rpc_read(cli, rdata, len, ¤t_offset)) return False; + fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; + /* * Verify any authentication footer. */ if (rhdr.auth_len != 0 ) { - if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len)) + int auth_padding_len = 0; + + if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, + rhdr.auth_len, &auth_padding_len)) return False; /* * Drop the auth footers from the current offset. @@ -570,7 +597,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd * preceeding 8 byte auth_header. * We need this if there are more fragments. */ - current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN); + current_offset -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len); } } -- cgit From fa497c6c76afbaafa07978c7e4dafd0c371f265f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Apr 2003 18:42:34 +0000 Subject: Fixes from Ronan Waide for large RPC writes. Jeremy. (This used to be commit a330bf170eb8e78200367c90833cbc90255642cb) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b3e8deeeef..f8472f3cfc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -952,6 +952,7 @@ 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, auth_schannel; + uint32 callid = 0; fstring dump_name; auth_verify = ((cli->ntlmssp_srv_flgs & NTLMSSP_NEGOTIATE_SIGN) != 0); @@ -977,7 +978,6 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, uint32 data_len, send_size; uint8 flags = 0; uint32 crc32 = 0; - uint32 callid = 0; uint32 auth_padding = 0; RPC_AUTH_NETSEC_CHK verf; @@ -1013,7 +1013,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, if (data_left == prs_offset(data)) flags |= RPC_FLG_FIRST; - if (data_left < max_data) + if (data_left <= max_data) flags |= RPC_FLG_LAST; /* * Write out the RPC header and the request header. -- cgit From d1da999e0a84939e372ebe590861376e2c0075b3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 May 2003 08:02:52 +0000 Subject: This puts real netlogon connection caching to winbind. This becomes important once we start doing schannel, as there would be a lot more roundtrips for the second PIPE open and bind. With this patch logging in to a member server is a matter of two (three if you count the ack...) packets between us and the DC. Volker (This used to be commit 5b3cb7725a974629d0bd8b707bc2940c36b8745e) --- source3/rpc_client/cli_pipe.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f8472f3cfc..223d6a707e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1563,8 +1563,8 @@ 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 cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, + const char *trust_password) { NTSTATUS result; uint32 neg_flags = 0x000001ff; @@ -1573,22 +1573,12 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, 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; + return result; } if ((lp_client_schannel() == True) && @@ -1596,12 +1586,12 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, DEBUG(3, ("Server did not offer schannel\n")); cli_nt_session_close(cli); - return False; + return NT_STATUS_UNSUCCESSFUL; } if ((lp_client_schannel() == False) || ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { - return True; + return NT_STATUS_OK; } /* Server offered schannel, so try it. */ @@ -1624,7 +1614,7 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, "Error was %s\n", PIPE_NETLOGON, cli->desthost, cli_errstr(cli))); - return False; + return NT_STATUS_UNSUCCESSFUL; } cli->nt_pipe_fnum = (uint16)fnum; @@ -1635,7 +1625,7 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, "Error was %s\n", PIPE_NETLOGON, cli->desthost, cli_errstr(cli))); - return False; + return NT_STATUS_UNSUCCESSFUL; } cli->nt_pipe_fnum = (uint16)fnum; @@ -1645,17 +1635,17 @@ BOOL cli_nt_open_netlogon(struct cli_state *cli, const char *trust_password, DEBUG(0,("Pipe hnd state failed. Error was %s\n", cli_errstr(cli))); cli_close(cli, cli->nt_pipe_fnum); - return False; + return NT_STATUS_UNSUCCESSFUL; } } 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 NT_STATUS_UNSUCCESSFUL; } - return True; + return NT_STATUS_OK; } -- cgit From 914ef37419ebc8660fed3bb645f990ce27295d34 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 11 May 2003 08:08:25 +0000 Subject: Ok, this is a hack. On a netsec bind reply I did not see anything useful in the auth verifier yet. So this patch ignores it. Really checking this would be a lot more intrusive: in rpc_api_pipe we would have to distinguish between binds and normal requests, or have more state in the netsec info of cli_state, which is also somewhat hackish. Volker (This used to be commit 8de04fcf680a9bc5054965577eb500e0541ffe66) --- source3/rpc_client/cli_pipe.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 223d6a707e..4f465d7453 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -307,6 +307,26 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, prs_struct auth_verf; if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + + if ( (auth_len == 12) && + (cli->auth_info.seq_num == 0) ) { + + /* This is the reply to our bind. Ok, + the sequence number can wrap + around. But this only means that + every 4 billion request we + misdetect a wrong length in a + reply. This is an error condition + which will lead to failure anyway + later. + + The reply contains a + RPC_AUTH_VERIFIER with no content + (12 bytes), so ignore it. + */ + return True; + } + DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); return False; } -- cgit From 5b776f179aa7ac7af731e317e51ec6d560e1d463 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 12 May 2003 07:16:21 +0000 Subject: Fix two bugs that were stopping net rpc vampire from working over secure channel: - If the domain name passed to create_rpc_bind_req() is empty, use lp_workgroup() - Correctly set the auth_padding field when the send_size is a multiple of 8 bytes I've tested with nt4sp6 and win2ksp0 and it seems to work, although there are no password hashes transferred from win2k. The empty passwords are being protected by the secure channel encryption though. (This used to be commit a8c11e855611c91e94787387c62ac629232cacfa) --- source3/rpc_client/cli_pipe.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 4f465d7453..08cf8b1ef3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -697,6 +697,12 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netse init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, 0x00, 1); + + /* Use lp_workgroup() if domain not specified */ + + if (!domain || !domain[0]) + domain = lp_workgroup(); + init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name); /* @@ -1014,8 +1020,10 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, * be stored in the auth header. */ - if (auth_schannel) - auth_padding = 8 - (send_size & 7); + if (auth_schannel) { + if (send_size % 8) + auth_padding = 8 - (send_size % 8); + } data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + send_size + ((auth_verify|auth_schannel) ? RPC_HDR_AUTH_LEN : 0) + -- cgit From 627aa735fbd33b8b62661f6456b04593a2727841 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 16 May 2003 01:57:57 +0000 Subject: Clarify a comment: The secure channel connection must be opened on the same session (TCP connection) as the one the challenge was requested from. (This used to be commit 5cb9b99f0f5dad589ac7def667e354d6f92f8822) --- source3/rpc_client/cli_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 08cf8b1ef3..a6a49dd3eb 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1632,10 +1632,10 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, if (cli->capabilities & CAP_NT_SMBS) { - /* If we open \\PIPE\NETLOGON here, NT4SP6 - gives us an ACCESS_DENIED. Do I have to - understand this? - */ + /* The secure channel connection must be opened on the same + session (TCP connection) as the one the challenge was + requested from. */ + if ((fnum = cli_nt_create(cli, PIPE_NETLOGON_PLAIN, DESIRED_ACCESS_PIPE)) == -1) { DEBUG(0,("cli_nt_create failed to %s machine %s. " -- cgit From ce72beb2b558d86fb49063c6b1fa00e07952ce56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Jul 2003 19:11:31 +0000 Subject: Removed strupper/strlower macros that automatically map to strupper_m/strlower_m. I really want people to think about when they're using multibyte strings. Jeremy. (This used to be commit ff222716a08af65d26ad842ce4c2841cc6540959) --- source3/rpc_client/cli_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a6a49dd3eb..5fb0205bfa 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1570,15 +1570,15 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) fstrcpy(cli->srv_name_slash, "\\\\"); fstrcat(cli->srv_name_slash, cli->desthost); - strupper(cli->srv_name_slash); + strupper_m(cli->srv_name_slash); fstrcpy(cli->clnt_name_slash, "\\\\"); fstrcat(cli->clnt_name_slash, global_myname()); - strupper(cli->clnt_name_slash); + strupper_m(cli->clnt_name_slash); fstrcpy(cli->mach_acct, global_myname()); fstrcat(cli->mach_acct, "$"); - strupper(cli->mach_acct); + strupper_m(cli->mach_acct); /* Remember which pipe we're talking to */ fstrcpy(cli->pipe_name, pipe_names[pipe_idx].client_pipe); -- cgit From 456f51bcbe04ccbb37a27b6e115a851cc134adcd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Jul 2003 08:46:32 +0000 Subject: Jeremy requested that I get my NTLMSSP patch into CVS. He didn't request the schannel code, but I've included that anyway. :-) This patch revives the client-side NTLMSSP support for RPC named pipes in Samba, and cleans up the client and server schannel code. The use of the new code is enabled by the 'sign', 'seal' and 'schannel' commands in rpcclient. The aim was to prove that our separate NTLMSSP client library actually implements NTLMSSP signing and sealing as per Microsoft's NTLMv1 implementation, in the hope that knowing this will assist us in correctly implementing NTLMSSP signing for SMB packets. (Still not yet functional) This patch replaces the NTLMSSP implementation in rpc_client/cli_pipe.c with calls to libsmb/ntlmssp.c. In the process, we have gained the ability to use the more secure NT password, and the ability to sign-only, instead of having to seal the pipe connection. (Previously we were limited to sealing, and could only use the LM-password derived key). Our new client-side NTLMSSP code also needed alteration to cope with our comparatively simple server-side implementation. A future step is to replace it with calls to the same NTLMSSP library. Also included in this patch is the schannel 'sign only' patch I submitted to the team earlier. While not enabled (and not functional, at this stage) the work in this patch makes the code paths *much* easier to follow. I have also included similar hooks in rpccleint to allow the use of schannel on *any* pipe. rpcclient now defaults to not using schannel (or any other extra per-pipe authenticiation) for any connection. The 'schannel' command enables schannel for all pipes until disabled. This code is also much more secure than the previous code, as changes to our cli_pipe routines ensure that the authentication footer cannot be removed by an attacker, and more error states are correctly handled. (The same needs to be done to our server) Andrew Bartlett (This used to be commit 5472ddc9eaf4e79c5b2e1c8ee8c7f190dc285f19) --- source3/rpc_client/cli_pipe.c | 1057 +++++++++++++++++++---------------------- 1 file changed, 493 insertions(+), 564 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5fb0205bfa..5ac7aaa441 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -28,6 +28,23 @@ extern struct pipe_id_info pipe_names[]; +void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level) +{ + *auth_type = 0; + *auth_level = 0; + if (pipe_auth_flags & AUTH_PIPE_SEAL) { + *auth_level = RPC_PIPE_AUTH_SEAL_LEVEL; + } else if (pipe_auth_flags & AUTH_PIPE_SIGN) { + *auth_level = RPC_PIPE_AUTH_SIGN_LEVEL; + } + + if (pipe_auth_flags & AUTH_PIPE_NETSEC) { + *auth_type = NETSEC_AUTH_TYPE; + } else if (pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + *auth_type = NTLMSSP_AUTH_TYPE; + } +} + /******************************************************************** Rpc pipe call id. ********************************************************************/ @@ -132,32 +149,6 @@ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, return (rhdr->pkt_type != RPC_FAULT); } -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; - - for( ind = 0; ind < len; ind++) { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += hash[index_i]; - - 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]; - } - - hash[256] = index_i; - hash[257] = index_j; -} - /**************************************************************************** Verify data on an rpc pipe. The VERIFY & SEAL code is only executed on packets that look like this : @@ -175,8 +166,10 @@ static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, uint32 l ****************************************************************************/ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, - uint32 fragment_start, int len, int auth_len, int *pauth_padding_len) + uint32 fragment_start, int len, int auth_len, uint8 pkt_type, + int *pauth_padding_len) { + /* * 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 @@ -190,190 +183,194 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, */ char *reply_data = prs_data_p(rdata) + fragment_start + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; - 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); + RPC_HDR_AUTH rhdr_auth; *pauth_padding_len = 0; - DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s schannel %s\n", - len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal), BOOLSTR(auth_schannel))); - - /* - * Unseal any sealed data in the PDU, not including the - * 8 byte auth_header or the auth_data. - */ + if (auth_len == 0) { + if (cli->pipe_auth_flags == 0) { + /* move along, nothing to see here */ + return True; + } - 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); + DEBUG(2, ("No authenticaton header recienved on reply, but this pipe is authenticated\n")); + return False; } - if (auth_verify || auth_seal) { - RPC_HDR_AUTH rhdr_auth; - prs_struct auth_req; - 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; + DEBUG(5,("rpc_auth_pipe: pkt_type: %d len: %d auth_len: %d NTLMSSP %s schannel %s sign %s seal %s \n", + pkt_type, len, auth_len, + BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP), + BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NETSEC), + BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN), + BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL))); - if(dp - prs_data_p(rdata) > prs_data_size(rdata)) { - DEBUG(0,("rpc_auth_pipe: auth data > data size !\n")); + { + int auth_type; + int auth_level; + char *dp = prs_data_p(rdata) + fragment_start + len - + RPC_HDR_AUTH_LEN - auth_len; + prs_struct auth_verf; + + if (dp - prs_data_p(rdata) > prs_data_size(rdata)) { + DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n")); return False; } - memcpy(data, dp, sizeof(data)); - - prs_init(&auth_req , 0, cli->mem_ctx, UNMARSHALL); + DEBUG(10,("rpc_auth_pipe: packet:\n")); + dump_data(100, dp, auth_len); - /* The endianness must be preserved... JRA. */ + prs_init(&auth_verf, RPC_HDR_AUTH_LEN, cli->mem_ctx, UNMARSHALL); - prs_set_endian_data(&auth_req, rdata->bigendian_data); + /* The endinness must be preserved. JRA. */ + prs_set_endian_data( &auth_verf, rdata->bigendian_data); - prs_give_memory(&auth_req, data, RPC_HDR_AUTH_LEN, False); + prs_copy_data_in(&auth_verf, dp, RPC_HDR_AUTH_LEN); + prs_set_offset(&auth_verf, 0); - /* - * 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")); + if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) { + DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n")); return False; } - if (!rpc_hdr_auth_chk(&rhdr_auth)) { - DEBUG(0,("rpc_auth_pipe: rpc_hdr_auth_chk failed.\n")); + /* Let the caller know how much padding at the end of the data */ + *pauth_padding_len = rhdr_auth.padding; + + /* Check it's the type of reply we were expecting to decode */ + + get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); + if (rhdr_auth.auth_type != auth_type) { + DEBUG(0, ("BAD auth type %d (should be %d)\n", + rhdr_auth.auth_type, auth_type)); return False; } - } - - /* - * 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[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")); + + if (rhdr_auth.auth_level != auth_level) { + DEBUG(0, ("BAD auth level %d (should be %d)\n", + rhdr_auth.auth_level, auth_level)); 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); - - prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL); - - /* The endinness must be preserved. JRA. */ - prs_set_endian_data( &auth_verf, rdata->bigendian_data); + if (pkt_type == RPC_BINDACK) { + if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + 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; + } + + /* save the reply away, for use a little later */ + return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state, + data_blob(dp, auth_len)))); + } + if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + /* nothing to do here - we don't seem to be able to validate the + bindack based on VL's comments */ + return True; + } + } + + if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + NTSTATUS nt_status; + DATA_BLOB sig; + if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) || + (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) { + 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; + } + + if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) { + DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len)); + return False; + } + + sig = data_blob(dp, auth_len); + } + + /* + * Unseal any sealed data in the PDU, not including the + * 8 byte auth_header or the auth_data. + */ - prs_give_memory(&auth_verf, data, RPC_AUTH_NTLMSSP_CHK_LEN, False); + /* + * Now unseal and check the auth verifier in the auth_data at + * the end of the packet. + */ - 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; + if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { + if (data_len < 0) { + DEBUG(1, ("Can't unseal - data_len < 0!!\n")); + return False; + } + nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state, + reply_data, data_len, + &sig); + } + else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { + nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state, + reply_data, data_len, + &sig); } - crc32 = crc32_calc_buffer(reply_data, data_len); + data_blob_free(&sig); - if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num)) { - DEBUG(0,("rpc_auth_pipe: rpc_auth_ntlmssp_chk failed.\n")); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("rpc_auth_pipe: could not validate " + "incoming NTLMSSP packet!\n")); return False; } - cli->ntlmssp_seq_num++; } - if (auth_schannel) { + if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { RPC_AUTH_NETSEC_CHK chk; - RPC_HDR_AUTH rhdr_auth; - char data[RPC_HDR_AUTH_LEN+RPC_AUTH_NETSEC_CHK_LEN]; - char *dp = prs_data_p(rdata) + fragment_start + len - - RPC_HDR_AUTH_LEN - RPC_AUTH_NETSEC_CHK_LEN; - prs_struct auth_verf; - - if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { - - if ( (auth_len == 12) && - (cli->auth_info.seq_num == 0) ) { - - /* This is the reply to our bind. Ok, - the sequence number can wrap - around. But this only means that - every 4 billion request we - misdetect a wrong length in a - reply. This is an error condition - which will lead to failure anyway - later. - - The reply contains a - RPC_AUTH_VERIFIER with no content - (12 bytes), so ignore it. - */ - return True; - } + prs_struct netsec_verf; - DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_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; } - if (dp - prs_data_p(rdata) > prs_data_size(rdata)) { - DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n")); + if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); return False; } - DEBUG(10,("rpc_auth_pipe: schannel 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); + prs_init(&netsec_verf, RPC_AUTH_NETSEC_CHK_LEN, + 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, sizeof(data), False); - - if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) { - DEBUG(0, ("rpc_auth_pipe: Could not parse schannel auth header\n")); - return False; - } + prs_set_endian_data( &netsec_verf, rdata->bigendian_data); - if ((rhdr_auth.auth_type != NETSEC_AUTH_TYPE) || - (rhdr_auth.auth_level != NETSEC_AUTH_LEVEL)) { - DEBUG(0, ("rpc_auth_pipe: Got wrong schannel auth type/level: %d/%d\n", - rhdr_auth.auth_type, rhdr_auth.auth_level)); - return False; - } + prs_copy_data_in(&netsec_verf, dp, auth_len); + prs_set_offset(&netsec_verf, 0); - if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", &chk, &auth_verf, 0)) { + if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", + &chk, &netsec_verf, 0)) { DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " "RPC_AUTH_NETSECK_CHK failed\n")); + prs_mem_free(&netsec_verf); return False; } - cli->auth_info.seq_num++; - - if (!netsec_decode(&cli->auth_info, &chk, reply_data, data_len)) { + if (!netsec_decode(&cli->auth_info, + cli->pipe_auth_flags, + SENDER_IS_ACCEPTOR, + &chk, reply_data, data_len)) { DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n")); + prs_mem_free(&netsec_verf); return False; } - *pauth_padding_len = rhdr_auth.padding; + + cli->auth_info.seq_num++; + + prs_mem_free(&netsec_verf); } return True; } @@ -403,7 +400,8 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, ****************************************************************************/ -static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rdata) +static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rdata, + uint8 expected_pkt_type) { uint32 len; char *rparam = NULL; @@ -419,6 +417,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd uint32 current_offset = 0; uint32 fragment_start = 0; uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024; + int auth_padding_len = 0; /* Create setup parameters - must be in native byte order. */ @@ -476,6 +475,12 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd } } + if (rhdr.pkt_type == RPC_BINDNACK) { + DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum)); + prs_mem_free(rdata); + return False; + } + if (rhdr.pkt_type == RPC_RESPONSE) { RPC_HDR_RESP rhdr_resp; if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0)) { @@ -485,6 +490,12 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd } } + if (rhdr.pkt_type != expected_pkt_type) { + DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum, rhdr.pkt_type, expected_pkt_type)); + prs_mem_free(rdata); + return False; + } + DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n", (unsigned int)len, (unsigned int)rdata_len )); @@ -507,12 +518,13 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd * Now we have a complete PDU, check the auth struct if any was sent. */ - if (rhdr.auth_len != 0) { - int auth_padding_len = 0; + if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, + rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) { + prs_mem_free(rdata); + return False; + } - if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, - rhdr.auth_len, &auth_padding_len)) - return False; + if (rhdr.auth_len != 0) { /* * Drop the auth footers from the current offset. * We need this if there are more fragments. @@ -543,7 +555,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd prs_struct hps; uint8 eclass; uint32 ecode; - + /* * First read the header of the next PDU. */ @@ -596,8 +608,10 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd * Now read the rest of the PDU. */ - if (!rpc_read(cli, rdata, len, ¤t_offset)) + if (!rpc_read(cli, rdata, len, ¤t_offset)) { + prs_mem_free(rdata); return False; + } fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; @@ -605,12 +619,15 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd * Verify any authentication footer. */ + + if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, + rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) { + prs_mem_free(rdata); + return False; + } + if (rhdr.auth_len != 0 ) { - int auth_padding_len = 0; - - if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, - rhdr.auth_len, &auth_padding_len)) - return False; + /* * Drop the auth footers from the current offset. * The auth footers consist of the auth_data and the @@ -633,70 +650,72 @@ 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, BOOL do_netsec, uint32 rpc_call_id, - RPC_IFACE *abstract, RPC_IFACE *transfer, - const char *my_name, const char *domain, uint32 neg_flags) +static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, + uint32 rpc_call_id, + RPC_IFACE *abstract, RPC_IFACE *transfer, + const char *my_name, const char *domain) { RPC_HDR hdr; RPC_HDR_RB hdr_rb; - char buffer[4096]; - prs_struct auth_info; + RPC_HDR_AUTH hdr_auth; int auth_len = 0; + int auth_type, auth_level; + size_t saved_hdr_offset; - prs_init(&auth_info, 0, prs_get_mem_context(rpc_out), MARSHALL); - - if (do_auth) { - RPC_HDR_AUTH hdr_auth; - RPC_AUTH_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; + prs_struct auth_info; + prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */ + prs_get_mem_context(rpc_out), MARSHALL); + if (cli->pipe_auth_flags) { + get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); + /* * 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); - + + init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0x00, 1); + /* * Now marshall the data into the temporary parse_struct. */ - + 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; + prs_mem_free(&auth_info); + return NT_STATUS_NO_MEMORY; } + saved_hdr_offset = prs_offset(&auth_info); + } + + if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - 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; - } + NTSTATUS nt_status; + DATA_BLOB null_blob = data_blob(NULL, 0); + DATA_BLOB request; - 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; + DEBUG(5, ("Processing NTLMSSP Negotiate\n")); + nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state, + null_blob, + &request); + + if (!NT_STATUS_EQUAL(nt_status, + NT_STATUS_MORE_PROCESSING_REQUIRED)) { + prs_mem_free(&auth_info); + return nt_status; } /* Auth len in the rpc header doesn't include auth_header. */ - auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN; - } + auth_len = request.length; + prs_copy_data_in(&auth_info, request.data, request.length); - if (do_netsec) { - RPC_HDR_AUTH hdr_auth; - RPC_AUTH_NETSEC_NEG netsec_neg; + DEBUG(5, ("NTLMSSP Negotiate:\n")); + dump_data(5, request.data, request.length); - /* - * Create the auth structs we will marshall. - */ + data_blob_free(&request); - init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, - 0x00, 1); + } + else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + RPC_AUTH_NETSEC_NEG netsec_neg; /* Use lp_workgroup() if domain not specified */ @@ -705,31 +724,20 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netse init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name); - /* - * 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; + prs_mem_free(&auth_info); + return NT_STATUS_NO_MEMORY; } /* Auth len in the rpc header doesn't include auth_header. */ - auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN; + auth_len = prs_offset(&auth_info) - saved_hdr_offset; } - /* 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), @@ -737,7 +745,8 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netse if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) { DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n")); - return False; + prs_mem_free(&auth_info); + return NT_STATUS_NO_MEMORY; } /* create the bind request RPC_HDR_RB */ @@ -747,21 +756,22 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netse /* 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; + prs_mem_free(&auth_info); + return NT_STATUS_NO_MEMORY; } /* * Grow the outgoing buffer to store any auth info. */ - if(hdr.auth_len != 0) { + if(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; + prs_mem_free(&auth_info); + return NT_STATUS_NO_MEMORY; } } - - return True; + return NT_STATUS_OK; } /******************************************************************* @@ -771,90 +781,71 @@ static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, BOOL do_netse the authentication handshake. ********************************************************************/ -static BOOL create_rpc_bind_resp(struct pwd_info *pwd, - const char *domain, const char *user_name, const char *my_name, - uint32 ntlmssp_cli_flgs, - uint32 rpc_call_id, - prs_struct *rpc_out) +static NTSTATUS create_rpc_bind_resp(struct cli_state *cli, + uint32 rpc_call_id, + prs_struct *rpc_out) { - unsigned char lm_owf[24]; - unsigned char nt_owf[24]; + NTSTATUS nt_status; 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; - - /* - * Marshall the variable length data into a temporary parse - * struct, pointing into a 4k local buffer. - */ - prs_init(&auth_info, 0, prs_get_mem_context(rpc_out), MARSHALL); - - /* - * Use the 4k buffer to store the auth info. - */ - - prs_give_memory( &auth_info, buffer, sizeof(buffer), False); - - /* - * Create the variable length auth_data. - */ - - 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; + DATA_BLOB ntlmssp_null_response = data_blob(NULL, 0); + DATA_BLOB ntlmssp_reply; + int auth_type, auth_level; + + /* The response is picked up from the internal cache, + where it was placed by the rpc_auth_pipe() code */ + nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state, + ntlmssp_null_response, + &ntlmssp_reply); + + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + return nt_status; } /* 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) ); - + RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN + ntlmssp_reply.length, + ntlmssp_reply.length ); + /* 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; + data_blob_free(&ntlmssp_reply); + return NT_STATUS_NO_MEMORY; } + get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); + /* 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); + auth_type, auth_level, 0x00); 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; + data_blob_free(&ntlmssp_reply); + return NT_STATUS_NO_MEMORY; } /* * Append the auth data to the outgoing buffer. */ - if(!prs_append_prs_data(rpc_out, &auth_info)) { + if(!prs_copy_data_in(rpc_out, ntlmssp_reply.data, ntlmssp_reply.length)) { DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n")); - return False; + data_blob_free(&ntlmssp_reply); + return NT_STATUS_NO_MEMORY; } - return True; + if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { + nt_status = ntlmssp_client_sign_init(cli->ntlmssp_pipe_state); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + } + + data_blob_free(&ntlmssp_reply); + return NT_STATUS_OK; } @@ -905,34 +896,17 @@ static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len } /******************************************************************* - Puts an NTLMSSP auth header into an rpc request. - ********************************************************************/ - -static BOOL create_ntlmssp_auth_hdr(prs_struct *outgoing_packet, BOOL 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,("create_auth_hdr:Failed to marshal RPC_HDR_AUTH.\n")); - return False; - } - return True; -} - -/******************************************************************* - Puts a NETLOGON schannel auth header into an rpc request. + Puts an auth header into an rpc request. ********************************************************************/ -static BOOL create_netsec_auth_hdr(prs_struct *outgoing_packet, int padding) +static BOOL create_auth_hdr(prs_struct *outgoing_packet, + int auth_type, + int auth_level, int padding) { RPC_HDR_AUTH hdr_auth; - init_rpc_hdr_auth(&hdr_auth, NETSEC_AUTH_TYPE, - NETSEC_AUTH_LEVEL, padding, 1); + init_rpc_hdr_auth(&hdr_auth, auth_type, 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")); @@ -941,30 +915,6 @@ static BOOL create_netsec_auth_hdr(prs_struct *outgoing_packet, int padding) return True; } -/******************************************************************* - Puts auth data into an rpc request. - ********************************************************************/ - -static BOOL create_auth_data(struct cli_state *cli, uint32 crc32, - prs_struct *outgoing_packet) -{ - char *pdata_out = prs_data_p(outgoing_packet); - 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,("create_auth_data: Failed to marshal RPC_AUTH_NTLMSSP_CHK.\n")); - return False; - } - NTLMSSPcalc_ap(cli, (unsigned char*) - &pdata_out[current_offset+4], - RPC_AUTH_NTLMSSP_CHK_LEN - 4); - return True; -} - /** * Send a request on an RPC pipe and get a response. * @@ -975,43 +925,60 @@ static BOOL create_auth_data(struct cli_state *cli, uint32 crc32, BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, prs_struct *data, prs_struct *rdata) { - uint32 auth_len, max_data, data_left, data_sent; + uint32 auth_len, real_auth_len, auth_hdr_len, max_data, data_left, data_sent; + NTSTATUS nt_status; BOOL ret = False; - BOOL auth_verify, auth_seal, auth_schannel; uint32 callid = 0; 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; + real_auth_len = 0; + auth_hdr_len = 0; - if (auth_verify) - auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; - - if (auth_schannel) - auth_len = RPC_AUTH_NETSEC_CHK_LEN; + if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { + if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; + } + if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + auth_len = RPC_AUTH_NETSEC_CHK_LEN; + } + auth_hdr_len = RPC_HDR_AUTH_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 - 8; - + auth_hdr_len - auth_len - 8; + for (data_left = prs_offset(data), data_sent = 0; data_left > 0;) { prs_struct outgoing_packet; + prs_struct sec_blob; uint32 data_len, send_size; uint8 flags = 0; - uint32 crc32 = 0; uint32 auth_padding = 0; RPC_AUTH_NETSEC_CHK verf; + DATA_BLOB sign_blob; /* * how much will we send this time */ send_size = MIN(data_left, max_data); + if (!prs_init(&sec_blob, send_size, /* will need at least this much */ + cli->mem_ctx, MARSHALL)) { + DEBUG(0,("Could not malloc %u bytes", + send_size+auth_padding)); + return False; + } + + if(!prs_append_some_prs_data(&sec_blob, data, + data_sent, send_size)) { + DEBUG(0,("Failed to append data to netsec blob\n")); + prs_mem_free(&sec_blob); + return False; + } + /* * NT expects the data that is sealed to be 8-byte * aligned. The padding must be encrypted as well and @@ -1020,14 +987,105 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, * be stored in the auth header. */ - if (auth_schannel) { - if (send_size % 8) - auth_padding = 8 - (send_size % 8); + if (cli->pipe_auth_flags) { + size_t data_and_padding_size; + prs_align_uint64(&sec_blob); + int auth_type = 0; + int auth_level = 0; + + if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { + auth_level = RPC_PIPE_AUTH_SEAL_LEVEL; + } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { + auth_level = RPC_PIPE_AUTH_SIGN_LEVEL; + } + + if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + auth_type = NETSEC_AUTH_TYPE; + } else if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + auth_type = NTLMSSP_AUTH_TYPE; + } + + data_and_padding_size = prs_offset(&sec_blob); + auth_padding = data_and_padding_size - send_size; + + /* insert the auth header */ + + if(!create_auth_hdr(&sec_blob, auth_type, auth_level, auth_padding)) { + prs_mem_free(&sec_blob); + return False; + } + + /* create an NTLMSSP signature */ + if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + /* + * Seal the outgoing data if requested. + */ + if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { + + nt_status = ntlmssp_client_seal_packet(cli->ntlmssp_pipe_state, + (unsigned char*)prs_data_p(&sec_blob), + data_and_padding_size, + &sign_blob); + if (!NT_STATUS_IS_OK(nt_status)) { + prs_mem_free(&sec_blob); + return False; + } + } + else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { + + nt_status = ntlmssp_client_sign_packet(cli->ntlmssp_pipe_state, + (unsigned char*)prs_data_p(&sec_blob), + data_and_padding_size, &sign_blob); + if (!NT_STATUS_IS_OK(nt_status)) { + prs_mem_free(&sec_blob); + return False; + } + } + + + /* write auth footer onto the packet */ + real_auth_len = sign_blob.length; + + prs_copy_data_in(&sec_blob, sign_blob.data, sign_blob.length); + data_blob_free(&sign_blob); + + } + else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + static const uchar netsec_sig[8] = NETSEC_SIGNATURE; + static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 }; + size_t parse_offset_marker; + if ((cli->auth_info.seq_num & 1) != 0) { + DEBUG(0,("SCHANNEL ERROR: seq_num must be even in client (seq_num=%d)\n", + cli->auth_info.seq_num)); + } + + DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num)); + + init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, + nullbytes, nullbytes); + + netsec_encode(&cli->auth_info, + cli->pipe_auth_flags, + SENDER_IS_INITIATOR, + &verf, + prs_data_p(&sec_blob), + data_and_padding_size); + + cli->auth_info.seq_num++; + + /* write auth footer onto the packet */ + + parse_offset_marker = prs_offset(&sec_blob); + if (!smb_io_rpc_auth_netsec_chk("", &verf, + &sec_blob, 0)) { + prs_mem_free(&sec_blob); + return False; + } + real_auth_len = prs_offset(&sec_blob) - parse_offset_marker; + } } - data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + send_size + - ((auth_verify|auth_schannel) ? RPC_HDR_AUTH_LEN : 0) + - auth_len + auth_padding; + data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(&sec_blob); /* * Malloc parse struct to hold it (and enough for alignments). @@ -1047,128 +1105,23 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, * Write out the RPC header and the request header. */ if(!(callid = create_rpc_request(&outgoing_packet, op_num, - data_len, auth_len, flags, + data_len, real_auth_len, flags, callid, data_left))) { DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n")); prs_mem_free(&outgoing_packet); + prs_mem_free(&sec_blob); return False; } - /* - * Seal the outgoing data if requested. - */ - if (auth_seal) { - crc32 = crc32_calc_buffer(prs_data_p(data) + data_sent, - send_size); - NTLMSSPcalc_ap(cli, (unsigned char*)prs_data_p(data) + - data_sent, send_size); - } - - /* - * Now copy the data into the outgoing packet. - */ - - 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]; - prs_struct netsec_blob; - - if ((cli->auth_info.seq_num & 1) != 0) { - DEBUG(0,("SCHANNEL ERROR: seq_num must be even in client (seq_num=%d)\n", - cli->auth_info.seq_num)); - } - - DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num)); - - RSIVAL(sign, 0, cli->auth_info.seq_num); - SIVAL(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); - - cli->auth_info.seq_num++; - - } 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_ntlmssp_auth_hdr(&outgoing_packet, auth_verify)) { - prs_mem_free(&outgoing_packet); - return False; - } - } - - /* - * Finally the auth data itself. - */ - if (auth_verify) { - if (!create_auth_data(cli, crc32, &outgoing_packet)) { - prs_mem_free(&outgoing_packet); - return False; - } - } - - 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; - } - } + prs_append_prs_data(&outgoing_packet, &sec_blob); + prs_mem_free(&sec_blob); DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, prs_offset(&outgoing_packet))); if (flags & RPC_FLG_LAST) - ret = rpc_api_pipe(cli, &outgoing_packet, rdata); + ret = rpc_api_pipe(cli, &outgoing_packet, + rdata, RPC_RESPONSE); else { cli_write(cli, cli->nt_pipe_fnum, 0x0008, prs_data_p(&outgoing_packet), @@ -1352,84 +1305,23 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 rpc_call_id) { - 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]; + prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */ + cli->mem_ctx, MARSHALL); - 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; - } - - cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags; - - pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge); - - prs_init(&rpc_out, 0, cli->mem_ctx, 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, + create_rpc_bind_resp(cli, 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); - - { - 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)); + prs_mem_free(&rpc_out); return False; } - cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags; + prs_mem_free(&rpc_out); return True; } @@ -1437,14 +1329,12 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 Do an rpc bind. ****************************************************************************/ -static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name, - BOOL do_netsec) +static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const 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]; @@ -1466,16 +1356,54 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na rpc_call_id = get_rpc_call_id(); + if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + NTSTATUS nt_status; + fstring password; + + DEBUG(5, ("NTLMSSP authenticated pipe selected\n")); + + nt_status = ntlmssp_client_start(&cli->ntlmssp_pipe_state); + + if (!NT_STATUS_IS_OK(nt_status)) + return False; + + nt_status = ntlmssp_set_username(cli->ntlmssp_pipe_state, + cli->user_name); + if (!NT_STATUS_IS_OK(nt_status)) + return False; + + nt_status = ntlmssp_set_domain(cli->ntlmssp_pipe_state, + cli->domain); + if (!NT_STATUS_IS_OK(nt_status)) + return False; + + pwd_get_cleartext(&cli->pwd, password); + nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, + password); + if (!NT_STATUS_IS_OK(nt_status)) + return False; + + if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { + cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + + if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { + cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } + } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + cli->auth_info.seq_num = 0; + } + /* Marshall the outgoing data. */ - create_rpc_bind_req(&rpc_out, do_auth, do_netsec, rpc_call_id, + create_rpc_bind_req(cli, &rpc_out, rpc_call_id, &abstract, &transfer, - global_myname(), cli->domain, cli->ntlmssp_cli_flgs); + global_myname(), cli->domain); /* Initialize the incoming data struct. */ prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL); /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, &rpc_out, &rdata)) { + if (rpc_api_pipe(cli, &rpc_out, &rdata, RPC_BINDACK)) { RPC_HDR_BA hdr_ba; DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n")); @@ -1501,15 +1429,17 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na * handshake. */ - if (do_auth && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) { + if ((cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) + && !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(&rdata); + return True; } - prs_mem_free(&rdata); - return True; + return False; } /**************************************************************************** @@ -1557,7 +1487,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(), False)) { + if (!rpc_pipe_bind(cli, pipe_idx, global_myname())) { 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); @@ -1589,15 +1519,19 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) /**************************************************************************** Open a session to the NETLOGON pipe using schannel. + + (Assumes that the netlogon pipe is already open) ****************************************************************************/ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, - const char *trust_password) + const uchar trust_password[16]) { - NTSTATUS result; + NTSTATUS result; uint32 neg_flags = 0x000001ff; int fnum; + cli_nt_netlogon_netsec_session_close(cli); + if (lp_client_schannel() != False) neg_flags |= NETLOGON_NEG_SCHANNEL; @@ -1620,22 +1554,27 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, if ((lp_client_schannel() == False) || ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { return NT_STATUS_OK; + + /* keep the existing connection to NETLOGON open */ + } /* 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; + cli->pipe_auth_flags = AUTH_PIPE_NETSEC; + cli->pipe_auth_flags |= AUTH_PIPE_SIGN; + cli->pipe_auth_flags |= AUTH_PIPE_SEAL; + if (cli->capabilities & CAP_NT_SMBS) { /* The secure channel connection must be opened on the same session (TCP connection) as the one the challenge was requested from. */ - if ((fnum = cli_nt_create(cli, PIPE_NETLOGON_PLAIN, DESIRED_ACCESS_PIPE)) == -1) { DEBUG(0,("cli_nt_create failed to %s machine %s. " @@ -1666,8 +1605,11 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, return NT_STATUS_UNSUCCESSFUL; } } - - if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname(), True)) { + + /* doing schannel, not per-user auth */ + cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL; + + if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) { DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON)); cli_close(cli, cli->nt_pipe_fnum); return NT_STATUS_UNSUCCESSFUL; @@ -1683,16 +1625,3 @@ const char *cli_pipe_get_name(struct cli_state *cli) } -/**************************************************************************** -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; -} -- cgit From 0b0fa60900c381aecec55b609f75c5c832f6bac5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Jul 2003 12:56:30 +0000 Subject: Fix compile error noticed by Ken Cross, use the utility function instead of an inline replacement... Andrew Bartlett (This used to be commit d941255a97fc6d0d62eae1602075b1aa0481cde5) --- source3/rpc_client/cli_pipe.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5ac7aaa441..2229a9f2cf 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -28,7 +28,7 @@ extern struct pipe_id_info pipe_names[]; -void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level) +static void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level) { *auth_type = 0; *auth_level = 0; @@ -989,21 +989,11 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, if (cli->pipe_auth_flags) { size_t data_and_padding_size; + int auth_type; + int auth_level; prs_align_uint64(&sec_blob); - int auth_type = 0; - int auth_level = 0; - if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { - auth_level = RPC_PIPE_AUTH_SEAL_LEVEL; - } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - auth_level = RPC_PIPE_AUTH_SIGN_LEVEL; - } - - if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - auth_type = NETSEC_AUTH_TYPE; - } else if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - auth_type = NTLMSSP_AUTH_TYPE; - } + get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); data_and_padding_size = prs_offset(&sec_blob); auth_padding = data_and_padding_size - send_size; -- cgit From b8ddc6238b9c29a65065df8ff318171d8e913f12 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 15 Jul 2003 21:33:28 +0000 Subject: fix schannel processing on fragmented PDUs. 'net rpc vampire' works again. (This used to be commit ff0c71148e405eeb49efbc51461325c7f2207433) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2229a9f2cf..d8f5e01cc2 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -330,7 +330,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, RPC_AUTH_NETSEC_CHK chk; prs_struct netsec_verf; - char *dp = prs_data_p(rdata) + len - auth_len; + char *dp = prs_data_p(rdata) + fragment_start + len - auth_len; if(dp - prs_data_p(rdata) > prs_data_size(rdata)) { DEBUG(0,("rpc_auth_pipe: auth data > data size !\n")); -- cgit From 8a4577cc22be9937dbd5f5334bf4e8b01f81b199 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Jul 2003 03:22:43 +0000 Subject: Fix up our auth_pipe code to always cope with fragmented datagrams, in both SCHANNEL and NTLMSSP. (Try not to deal with a general case as individual special cases...) Andrew Bartlett (This used to be commit 6ca77bd28f16f9f65ff40bf8996e39356de5b4f8) --- source3/rpc_client/cli_pipe.c | 105 +++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 64 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d8f5e01cc2..d6307ddb46 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -185,6 +185,10 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, RPC_HDR_AUTH rhdr_auth; + char *dp = prs_data_p(rdata) + fragment_start + len - + RPC_HDR_AUTH_LEN - auth_len; + prs_struct auth_verf; + *pauth_padding_len = 0; if (auth_len == 0) { @@ -204,30 +208,29 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN), BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL))); - { - int auth_type; - int auth_level; - char *dp = prs_data_p(rdata) + fragment_start + len - - RPC_HDR_AUTH_LEN - auth_len; - prs_struct auth_verf; - - if (dp - prs_data_p(rdata) > prs_data_size(rdata)) { - DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n")); - return False; - } - - DEBUG(10,("rpc_auth_pipe: packet:\n")); - dump_data(100, dp, auth_len); - - prs_init(&auth_verf, RPC_HDR_AUTH_LEN, cli->mem_ctx, UNMARSHALL); - - /* The endinness must be preserved. JRA. */ - prs_set_endian_data( &auth_verf, rdata->bigendian_data); + if (dp - prs_data_p(rdata) > prs_data_size(rdata)) { + DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n")); + return False; + } - prs_copy_data_in(&auth_verf, dp, RPC_HDR_AUTH_LEN); - prs_set_offset(&auth_verf, 0); + DEBUG(10,("rpc_auth_pipe: packet:\n")); + dump_data(100, dp, auth_len); + prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL); + + /* The endinness must be preserved. JRA. */ + prs_set_endian_data( &auth_verf, rdata->bigendian_data); + + /* Point this new parse struct at the auth section of the main + parse struct - rather than copying it. Avoids needing to + free it on every error + */ + prs_give_memory(&auth_verf, dp, RPC_HDR_AUTH_LEN + auth_len, False /* not dynamic */); + prs_set_offset(&auth_verf, 0); + { + int auth_type; + int auth_level; if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) { DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n")); return False; @@ -254,20 +257,21 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, if (pkt_type == RPC_BINDACK) { if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - 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; - } + /* copy the next auth_len bytes into a buffer for + later use */ + + DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len); /* save the reply away, for use a little later */ + prs_copy_data_out(ntlmssp_verf.data, &auth_verf, auth_len); + + return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state, - data_blob(dp, auth_len)))); - } - if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - /* nothing to do here - we don't seem to be able to validate the - bindack based on VL's comments */ + ntlmssp_verf))); + } + else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + /* nothing to do here - we don't seem to be able to + validate the bindack based on VL's comments */ return True; } } @@ -277,19 +281,12 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, DATA_BLOB sig; if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) || (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) { - 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; - } - if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) { DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len)); return False; } - - sig = data_blob(dp, auth_len); + sig = data_blob(NULL, auth_len); + prs_copy_data_out(sig.data, &auth_verf, auth_len); } /* @@ -308,8 +305,8 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, return False; } nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state, - reply_data, data_len, - &sig); + reply_data, data_len, + &sig); } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state, @@ -328,34 +325,16 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { RPC_AUTH_NETSEC_CHK chk; - prs_struct netsec_verf; - - char *dp = prs_data_p(rdata) + fragment_start + 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; - } if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); return False; } - prs_init(&netsec_verf, RPC_AUTH_NETSEC_CHK_LEN, - cli->mem_ctx, UNMARSHALL); - - /* The endinness must be preserved. JRA. */ - prs_set_endian_data( &netsec_verf, rdata->bigendian_data); - - prs_copy_data_in(&netsec_verf, dp, auth_len); - prs_set_offset(&netsec_verf, 0); - if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", - &chk, &netsec_verf, 0)) { + &chk, &auth_verf, 0)) { DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " "RPC_AUTH_NETSECK_CHK failed\n")); - prs_mem_free(&netsec_verf); return False; } @@ -364,13 +343,11 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, SENDER_IS_ACCEPTOR, &chk, reply_data, data_len)) { DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n")); - prs_mem_free(&netsec_verf); return False; } cli->auth_info.seq_num++; - prs_mem_free(&netsec_verf); } return True; } -- cgit From 4c53bb6b90fec8e03c812a70a84889fcdf3b1081 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Jul 2003 01:34:05 +0000 Subject: In the presense of RPC fragments, schannel is not strictly request/reply, so the shared sequence number will not be strictly odd/even. Andrew Bartlett (This used to be commit 77c3e69aef545d3f9b7cec9efdc366cbeb0c745e) --- source3/rpc_client/cli_pipe.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d6307ddb46..01b4c83235 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1021,11 +1021,6 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, static const uchar netsec_sig[8] = NETSEC_SIGNATURE; static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 }; size_t parse_offset_marker; - if ((cli->auth_info.seq_num & 1) != 0) { - DEBUG(0,("SCHANNEL ERROR: seq_num must be even in client (seq_num=%d)\n", - cli->auth_info.seq_num)); - } - DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num)); init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, -- cgit From c9305f1c647abf4dc180c93e9f481a6da9220b57 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Jul 2003 01:26:19 +0000 Subject: Schannel, once setup, may be used on *ANY* TCP/IP connection until the connection that set it up has been shut down. (Also, pipes still connected, and reconnections to the same pipe (eg SAMR) may continue to use that session key until their TCP/IP connection is shut down) Allow further testing by printing out the session key, and allowing it's input into rpcclient. Next step is automatic storage in a TDB. Andrew Bartlett (This used to be commit fa4d7be1619b51aacec37ddf995c940b8100aef9) --- source3/rpc_client/cli_pipe.c | 55 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 01b4c83235..53ff58b966 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -5,6 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1998. * Copyright (C) Jeremy Allison 1999. + * Copyright (C) Andrew Bartlett 2003. * * 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 @@ -1568,9 +1569,6 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, } } - /* doing schannel, not per-user auth */ - cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL; - if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) { DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON)); cli_close(cli, cli->nt_pipe_fnum); @@ -1581,6 +1579,57 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, } +NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, + const uchar trust_password[16]) +{ + NTSTATUS result; + uint32 neg_flags = 0x000001ff; + cli->pipe_auth_flags = 0; + + if (lp_client_schannel() == False) { + return NT_STATUS_OK; + } + + if (!cli_nt_session_open(cli, PI_NETLOGON)) { + DEBUG(0, ("Could not initialise %s\n", + get_pipe_name_from_index(PI_NETLOGON))); + return NT_STATUS_UNSUCCESSFUL; + } + + if (lp_client_schannel() != False) + neg_flags |= NETLOGON_NEG_SCHANNEL; + + neg_flags |= NETLOGON_NEG_SCHANNEL; + + result = cli_nt_setup_creds(cli, sec_chan, trust_password, + &neg_flags, 2); + + if (!(neg_flags & NETLOGON_NEG_SCHANNEL) + && lp_client_schannel() == True) { + DEBUG(1, ("Could not negotiate SCHANNEL with the DC!\n")); + result = NT_STATUS_UNSUCCESSFUL; + } + + if (!NT_STATUS_IS_OK(result)) { + ZERO_STRUCT(cli->auth_info.sess_key); + ZERO_STRUCT(cli->sess_key); + cli->pipe_auth_flags = 0; + cli_nt_session_close(cli); + return result; + } + + memcpy(cli->auth_info.sess_key, cli->sess_key, + sizeof(cli->auth_info.sess_key)); + + cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum; + cli->nt_pipe_fnum = 0; + + /* doing schannel, not per-user auth */ + cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL; + + return NT_STATUS_OK; +} + const char *cli_pipe_get_name(struct cli_state *cli) { return cli->pipe_name; -- cgit From 6ec2213bdb163b5301196a0dddb53086e6aa0fe8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 25 Jul 2003 18:00:57 +0000 Subject: domain in schannel bind credentials must be the dest domain, not ours (This used to be commit e12f6a8c13f27c3caea96b467cc4294e20dad341) --- source3/rpc_client/cli_pipe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 53ff58b966..2554d8c06b 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -697,8 +697,10 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, /* Use lp_workgroup() if domain not specified */ - if (!domain || !domain[0]) + if (!domain || !domain[0]) { + DEBUG(10,("create_rpc_bind_req: no domain; assuming my own\n")); domain = lp_workgroup(); + } init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name); -- cgit From d6ee1d167c81d3b632af0415445745a180d58b3c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2003 23:33:56 +0000 Subject: Save us from possibly uninitialised variable (caught by gcc). Jeremy. (This used to be commit f3f29665bd2c396c4756cd23f603ac768fea66fd) --- source3/rpc_client/cli_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2554d8c06b..ebe54c2c06 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -638,7 +638,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, RPC_HDR_AUTH hdr_auth; int auth_len = 0; int auth_type, auth_level; - size_t saved_hdr_offset; + size_t saved_hdr_offset = 0; prs_struct auth_info; prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */ @@ -691,8 +691,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, data_blob_free(&request); - } - else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { RPC_AUTH_NETSEC_NEG netsec_neg; /* Use lp_workgroup() if domain not specified */ @@ -718,7 +717,8 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, /* Auth len in the rpc header doesn't include auth_header. */ auth_len = prs_offset(&auth_info) - saved_hdr_offset; } - /* create the request RPC_HDR */ + + /* 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), auth_len); -- cgit From cdf562f5b231a0a398204356dded8c5ab773036d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 4 Aug 2003 02:51:30 +0000 Subject: Memory leak fix for create_rpc_bind_req() (This used to be commit 4d26feabd75d5b298276b0c5880b9765507bb6ae) --- source3/rpc_client/cli_pipe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ebe54c2c06..5467c022f2 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -751,6 +751,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, return NT_STATUS_NO_MEMORY; } } + prs_mem_free(&auth_info); return NT_STATUS_OK; } -- cgit From 172766eea7a374e910ea91c857fcce45996783a2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 14 Aug 2003 01:08:00 +0000 Subject: Change Samba to always use extended security for it's guest logins, (ie, NTLMSSP with "" username, NULL password), and add --machine-pass (-P) to all of Samba's clients. When connecting to an Active Directory DC, you must initiate the CIFS level session setup with Kerberos, not a guest login. If you don't, your machine account is demoted to NT4. Andrew Bartlett (This used to be commit 3547cb3def45a90f99f67829a533eac1ccba5e77) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5467c022f2..52395b39c9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1586,7 +1586,7 @@ NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, const uchar trust_password[16]) { NTSTATUS result; - uint32 neg_flags = 0x000001ff; + uint32 neg_flags = 0x000701ff; cli->pipe_auth_flags = 0; if (lp_client_schannel() == False) { -- cgit From aa39cc37dab9c4f8c3295d872bb8cc143890b378 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 04:42:05 +0000 Subject: get rid of more compiler warnings (This used to be commit 398bd14fc6e2f8ab2f34211270e179b8928a6669) --- source3/rpc_client/cli_pipe.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 52395b39c9..13a7841455 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -264,7 +264,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len); /* save the reply away, for use a little later */ - prs_copy_data_out(ntlmssp_verf.data, &auth_verf, auth_len); + prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len); return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state, @@ -287,7 +287,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, return False; } sig = data_blob(NULL, auth_len); - prs_copy_data_out(sig.data, &auth_verf, auth_len); + prs_copy_data_out((char *)sig.data, &auth_verf, auth_len); } /* @@ -306,12 +306,12 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, return False; } nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state, - reply_data, data_len, + (unsigned char *)reply_data, data_len, &sig); } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state, - reply_data, data_len, + (const unsigned char *)reply_data, data_len, &sig); } @@ -684,10 +684,10 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, /* Auth len in the rpc header doesn't include auth_header. */ auth_len = request.length; - prs_copy_data_in(&auth_info, request.data, request.length); + prs_copy_data_in(&auth_info, (char *)request.data, request.length); DEBUG(5, ("NTLMSSP Negotiate:\n")); - dump_data(5, request.data, request.length); + dump_data(5, (const char *)request.data, request.length); data_blob_free(&request); @@ -811,7 +811,7 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli, * Append the auth data to the outgoing buffer. */ - if(!prs_copy_data_in(rpc_out, ntlmssp_reply.data, ntlmssp_reply.length)) { + if(!prs_copy_data_in(rpc_out, (char *)ntlmssp_reply.data, ntlmssp_reply.length)) { DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n")); data_blob_free(&ntlmssp_reply); return NT_STATUS_NO_MEMORY; @@ -1017,7 +1017,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, /* write auth footer onto the packet */ real_auth_len = sign_blob.length; - prs_copy_data_in(&sec_blob, sign_blob.data, sign_blob.length); + prs_copy_data_in(&sec_blob, (char *)sign_blob.data, sign_blob.length); data_blob_free(&sign_blob); } -- cgit From f0cd6b35e551cdb2acb088f52edb0746da251b73 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 19 Aug 2003 20:39:32 +0000 Subject: - Fix the kerberos downgrade problem: - When connecting to the NETOGON pipe, we make a call to auth2, in order to verify our identity. This call was being made with negotiation flags of 0x1ff. This caused our account to be downgraded. If we instead make the call with flags > 1ff (such as 0x701ff), then this does not occour. - This is *not* related to the use of kerberos for the CIFS-level connection My theory is that Win2k has a test to see if we are sending *exactly* what NT4 sent - setting any other flags seems to cause us to remain intact. Also ensure that we only have 'setup schannel' code in a few places, not scattered around cmd_netlogon too. Andrew Bartlett (This used to be commit e10f0529fe9d8d245b3cd001cce6a9a86896679c) --- source3/rpc_client/cli_pipe.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 13a7841455..dedbf017a9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1493,7 +1493,9 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, const uchar trust_password[16]) { NTSTATUS result; - uint32 neg_flags = 0x000001ff; + /* The 7 here seems to be required to get Win2k not to downgrade us + to NT4. Actually, anything other than 1ff would seem to do... */ + uint32 neg_flags = 0x000701ff; int fnum; cli_nt_netlogon_netsec_session_close(cli); @@ -1586,6 +1588,8 @@ NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, const uchar trust_password[16]) { NTSTATUS result; + /* The 7 here seems to be required to get Win2k not to downgrade us + to NT4. Actually, anything other than 1ff would seem to do... */ uint32 neg_flags = 0x000701ff; cli->pipe_auth_flags = 0; -- cgit From cbe69f65f69b0c7b7c2d0d32005da488b50e52ba Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 1 Oct 2003 21:18:32 +0000 Subject: commit sign only patch from Andrew; bug 167; tested using 2k & XP clientspreviously joined to the Samba domain (This used to be commit 3802f5895ee18507c6f467bd11db0b1147a6fdfd) --- source3/rpc_client/cli_pipe.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index dedbf017a9..9ce10202db 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -29,7 +29,9 @@ extern struct pipe_id_info pipe_names[]; -static void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level) +/* convert pipe auth flags into the RPC auth type and level */ + +void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level) { *auth_type = 0; *auth_level = 0; @@ -938,7 +940,6 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, uint32 data_len, send_size; uint8 flags = 0; uint32 auth_padding = 0; - RPC_AUTH_NETSEC_CHK verf; DATA_BLOB sign_blob; /* @@ -1022,14 +1023,10 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - static const uchar netsec_sig[8] = NETSEC_SIGNATURE; - static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 }; size_t parse_offset_marker; + RPC_AUTH_NETSEC_CHK verf; DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num)); - init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, - nullbytes, nullbytes); - netsec_encode(&cli->auth_info, cli->pipe_auth_flags, SENDER_IS_INITIATOR, @@ -1277,8 +1274,10 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */ cli->mem_ctx, MARSHALL); - create_rpc_bind_resp(cli, rpc_call_id, - &rpc_out); + if (!NT_STATUS_IS_OK(create_rpc_bind_resp(cli, rpc_call_id, + &rpc_out))) { + return False; + } 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)) { @@ -1493,9 +1492,7 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, const uchar trust_password[16]) { NTSTATUS result; - /* The 7 here seems to be required to get Win2k not to downgrade us - to NT4. Actually, anything other than 1ff would seem to do... */ - uint32 neg_flags = 0x000701ff; + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; int fnum; cli_nt_netlogon_netsec_session_close(cli); @@ -1584,13 +1581,11 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, } -NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, +NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, int auth_flags, const uchar trust_password[16]) { NTSTATUS result; - /* The 7 here seems to be required to get Win2k not to downgrade us - to NT4. Actually, anything other than 1ff would seem to do... */ - uint32 neg_flags = 0x000701ff; + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; cli->pipe_auth_flags = 0; if (lp_client_schannel() == False) { @@ -1632,7 +1627,7 @@ NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, cli->nt_pipe_fnum = 0; /* doing schannel, not per-user auth */ - cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL; + cli->pipe_auth_flags = auth_flags; return NT_STATUS_OK; } -- cgit From 5faae2df8aa6b8864cc42599d8a9c69925b94937 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 17 Nov 2003 18:00:43 +0000 Subject: This fixes a bug when establishing trust against a german W2k3 AD server. In the bind response to WKSSVC it does not send \PIPE\ntsvcs as NT4 (did not check w2k) but \PIPE\wkssvc. I'm not sure whether we should make this check at all, so making it a bit more liberal should hopefully not really hurt. Volker (This used to be commit 029dcb351bcfab70ed0afa4acf4bd64316bfd757) --- source3/rpc_client/cli_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9ce10202db..fdd9d3c3b1 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1231,7 +1231,8 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC if ( hdr_ba->addr.len <= 0) return False; - if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe )) + if ( (strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) != 0) && + (strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) != 0) ) { DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n", pipe_names[i].server_pipe ,hdr_ba->addr.str)); -- cgit From fcbfc7ad0669009957c65fa61bb20df75a9701b4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 13:19:38 +0000 Subject: Changes all over the shop, but all towards: - NTLM2 support in the server - KEY_EXCH support in the server - variable length session keys. In detail: - NTLM2 is an extension of NTLMv1, that is compatible with existing domain controllers (unlike NTLMv2, which requires a DC upgrade). * This is known as 'NTLMv2 session security' * (This is not yet implemented on the RPC pipes however, so there may well still be issues for PDC setups, particuarly around password changes. We do not fully understand the sign/seal implications of NTLM2 on RPC pipes.) This requires modifications to our authentication subsystem, as we must handle the 'challege' input into the challenge-response algorithm being changed. This also needs to be turned off for 'security=server', which does not support this. - KEY_EXCH is another 'security' mechanism, whereby the session key actually used by the server is sent by the client, rather than being the shared-secret directly or indirectly. - As both these methods change the session key, the auth subsystem needed to be changed, to 'override' session keys provided by the backend. - There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation. - The 'names blob' in NTLMSSP is always in unicode - never in ascii. Don't make an ascii version ever. - The other big change is to allow variable length session keys. We have always assumed that session keys are 16 bytes long - and padded to this length if shorter. However, Kerberos session keys are 8 bytes long, when the krb5 login uses DES. * This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. * - Add better DEBUG() messages to ntlm_auth, warning administrators of misconfigurations that prevent access to the privileged pipe. This should help reduce some of the 'it just doesn't work' issues. - Fix data_blob_talloc() to behave the same way data_blob() does when passed a NULL data pointer. (just allocate) REMEMBER to make clean after this commit - I have changed plenty of data structures... (This used to be commit f3bbc87b0dac63426cda6fac7a295d3aad810ecc) --- source3/rpc_client/cli_pipe.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index fdd9d3c3b1..aca0494dbd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -264,13 +264,16 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, later use */ DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len); - + BOOL store_ok; + /* save the reply away, for use a little later */ prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len); + store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state, + ntlmssp_verf))); - return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state, - ntlmssp_verf))); + data_blob_free(&ntlmssp_verf); + return store_ok; } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { /* nothing to do here - we don't seem to be able to @@ -307,12 +310,12 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, DEBUG(1, ("Can't unseal - data_len < 0!!\n")); return False; } - nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state, + nt_status = ntlmssp_unseal_packet(cli->ntlmssp_pipe_state, (unsigned char *)reply_data, data_len, &sig); } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state, + nt_status = ntlmssp_check_packet(cli->ntlmssp_pipe_state, (const unsigned char *)reply_data, data_len, &sig); } @@ -674,9 +677,9 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, DATA_BLOB request; DEBUG(5, ("Processing NTLMSSP Negotiate\n")); - nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state, - null_blob, - &request); + nt_status = ntlmssp_update(cli->ntlmssp_pipe_state, + null_blob, + &request); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { @@ -777,9 +780,9 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli, /* The response is picked up from the internal cache, where it was placed by the rpc_auth_pipe() code */ - nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state, - ntlmssp_null_response, - &ntlmssp_reply); + nt_status = ntlmssp_update(cli->ntlmssp_pipe_state, + ntlmssp_null_response, + &ntlmssp_reply); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { return nt_status; @@ -820,7 +823,7 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli, } if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - nt_status = ntlmssp_client_sign_init(cli->ntlmssp_pipe_state); + nt_status = ntlmssp_sign_init(cli->ntlmssp_pipe_state); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -994,7 +997,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, */ if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { - nt_status = ntlmssp_client_seal_packet(cli->ntlmssp_pipe_state, + nt_status = ntlmssp_seal_packet(cli->ntlmssp_pipe_state, (unsigned char*)prs_data_p(&sec_blob), data_and_padding_size, &sign_blob); @@ -1005,7 +1008,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - nt_status = ntlmssp_client_sign_packet(cli->ntlmssp_pipe_state, + nt_status = ntlmssp_sign_packet(cli->ntlmssp_pipe_state, (unsigned char*)prs_data_p(&sec_blob), data_and_padding_size, &sign_blob); if (!NT_STATUS_IS_OK(nt_status)) { -- cgit From 4e61fcbef17b48ffd76dd9b9399b6f6df63e8079 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 24 Nov 2003 20:22:12 +0000 Subject: strequal() returns a BOOL, not an int like strcmp(); this fixes a bug in check_bind_response() (This used to be commit 5e062f72baad6f7a70f1a3c8cf190535ccacc89e) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index aca0494dbd..7517777920 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1234,8 +1234,8 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC if ( hdr_ba->addr.len <= 0) return False; - if ( (strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) != 0) && - (strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) != 0) ) + if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) && + !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) ) { DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n", pipe_names[i].server_pipe ,hdr_ba->addr.str)); -- cgit From 1b6e6c98ba7175afb994a531bec06a7845950ff3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Nov 2003 11:25:38 +0000 Subject: Do not add NTLM2 to the NTLMSSP flags unconditionally - allow the defaults specified by the caller to prevail. Don't use NTLM2 for RPC pipes, until we know how it works in signing or sealing. Call ntlmssp_sign_init() unconditionally in the client - we setup the session key, why not setup the rest of the data. Andrew Bartlett (This used to be commit 48123f7e42c3fde85887de23c80ceee04c2f6281) --- source3/rpc_client/cli_pipe.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7517777920..49abf787ee 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -822,14 +822,6 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli, return NT_STATUS_NO_MEMORY; } - if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - nt_status = ntlmssp_sign_init(cli->ntlmssp_pipe_state); - - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - } - data_blob_free(&ntlmssp_reply); return NT_STATUS_OK; } @@ -1336,6 +1328,10 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na if (!NT_STATUS_IS_OK(nt_status)) return False; + /* Currently the NTLMSSP code does not implement NTLM2 correctly for signing or sealing */ + + cli->ntlmssp_pipe_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + nt_status = ntlmssp_set_username(cli->ntlmssp_pipe_state, cli->user_name); if (!NT_STATUS_IS_OK(nt_status)) -- cgit From 425699fce728a3d302a3e5288d0c59ec7b16aee2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 04:12:40 +0000 Subject: Correctly handle per-pipe NTLMSSP inside a NULL session. Previously we would attempt to supply a password to the 'inside' NTLMSSP, which the remote side naturally rejected. Andrew Bartlett (This used to be commit da408e0d5aa29ca1505c2fd96b32deae9ed940c4) --- source3/rpc_client/cli_pipe.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 49abf787ee..3213e955b6 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1342,11 +1342,18 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na if (!NT_STATUS_IS_OK(nt_status)) return False; - pwd_get_cleartext(&cli->pwd, password); - nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, - password); - if (!NT_STATUS_IS_OK(nt_status)) - return False; + if (cli->pwd.null_pwd) { + nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, + NULL); + if (!NT_STATUS_IS_OK(nt_status)) + return False; + } else { + pwd_get_cleartext(&cli->pwd, password); + nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, + password); + if (!NT_STATUS_IS_OK(nt_status)) + return False; + } if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; -- cgit From a92de03d9e2f22c7d8a6361f5d9d93738d9e3409 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 28 Feb 2004 18:41:16 +0000 Subject: Add 'net rpc group [add|del]mem' for domain groups and aliases. Volker (This used to be commit e597420421e085b17dcdc062c5900518d0d4e685) --- source3/rpc_client/cli_pipe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3213e955b6..b9511ae00f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1466,6 +1466,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) return False; } + cli->pipe_idx = pipe_idx; + /* * Setup the remote server name prefixed by \ and the machine account name. */ -- cgit From aad3d8aeb013211398c223472d563c088d27b7f7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 17 Mar 2004 17:38:38 +0000 Subject: asu/syntax/pc_netlink doesn't fill in the pipe name in the rpc_bind response so dont check for it (This used to be commit 4d68d3d5ddeda9589f2e3387144fdac616bb791f) --- source3/rpc_client/cli_pipe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b9511ae00f..72546947e4 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1223,6 +1223,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC { int i = 0; +# if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */ if ( hdr_ba->addr.len <= 0) return False; @@ -1240,6 +1241,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str)); return False; } +#endif /* JERRY */ /* check the transfer syntax */ if ((hdr_ba->transfer.version != transfer->version) || -- cgit From fd312721ea57c562b70a753a37fcefad66db2e32 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Mar 2004 17:48:08 +0000 Subject: missed some of Derrel's changes (This used to be commit 3aac1e549eaf4693ded84be432a2c94b6331ef6d) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 72546947e4..82a4b21754 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1443,7 +1443,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) cli->nt_pipe_fnum = (uint16)fnum; } else { if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, 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", + DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n", pipe_names[pipe_idx].client_pipe, cli->desthost, cli_errstr(cli))); return False; } -- cgit From f2e853d3455fe7db317769ef7906b26a09396db3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 22 Mar 2004 23:05:02 +0000 Subject: remove unused variable (This used to be commit 170c443b19604c3ec997ae494954c473e356e59d) --- source3/rpc_client/cli_pipe.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 82a4b21754..f425a24d08 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1221,8 +1221,6 @@ static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE * static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer) { - int i = 0; - # if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */ if ( hdr_ba->addr.len <= 0) return False; -- cgit From 59572d1297ca5c11067e98a8a01199d5f49c02f8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 05:39:19 +0000 Subject: Ensure we correctly set cli->nt_pipe_fnum on failure to correctly open the NT session. Andrew Bartlett (This used to be commit 01fff20e6e0212e9f70a5a66c3e46f7079b342f1) --- source3/rpc_client/cli_pipe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f425a24d08..df0d37a463 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1453,6 +1453,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", cli_errstr(cli))); cli_close(cli, cli->nt_pipe_fnum); + cli->nt_pipe_fnum = 0; return False; } } @@ -1463,6 +1464,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) 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); + cli->nt_pipe_fnum = 0; return False; } -- cgit From 41db2016adc464691ea2c3497aedca55fcf004ed Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 13 May 2004 20:32:21 +0000 Subject: r704: BUG 1315: fix for schannel client connections to server's that don't support 128 bit encryption (This used to be commit 316ba5ad89ddfa445d44d28141c5901fc64aec90) --- source3/rpc_client/cli_pipe.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index df0d37a463..b24dbb7d25 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -332,13 +332,24 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { RPC_AUTH_NETSEC_CHK chk; - if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + if ( (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) + && (auth_len != RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN) ) + { DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); return False; } - if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", - &chk, &auth_verf, 0)) { + /* can't seal with no nonce */ + if ( (cli->pipe_auth_flags & AUTH_PIPE_SEAL) + && (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) ) + { + DEBUG(0,("rpc_auth_pipe: sealing not supported with schannel auth len %d\n", auth_len)); + return False; + } + + + if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", auth_len, &chk, &auth_verf, 0)) + { DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " "RPC_AUTH_NETSECK_CHK failed\n")); return False; @@ -918,7 +929,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; } if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - auth_len = RPC_AUTH_NETSEC_CHK_LEN; + auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; } auth_hdr_len = RPC_HDR_AUTH_LEN; } @@ -1034,8 +1045,9 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, /* write auth footer onto the packet */ parse_offset_marker = prs_offset(&sec_blob); - if (!smb_io_rpc_auth_netsec_chk("", &verf, - &sec_blob, 0)) { + if (!smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, + &verf, &sec_blob, 0)) + { prs_mem_free(&sec_blob); return False; } -- cgit From 9dbf2e2419e2ba0f2293b4a7a5971123f34a09ad Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 3 Jun 2004 18:00:22 +0000 Subject: r991: Allow winbindd to use the domain trust account password for setting up an schannel connection. This solves the problem of a Samba DC running winbind, trusting a native mode AD domain, and needing to enumerate AD users via wbinfo -u. (This used to be commit e9f109d1b38e0b0adec9b7e9a907f90a79d297ea) --- source3/rpc_client/cli_pipe.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b24dbb7d25..9e2d5aa4a7 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1621,9 +1621,6 @@ NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, int auth_flags return NT_STATUS_UNSUCCESSFUL; } - if (lp_client_schannel() != False) - neg_flags |= NETLOGON_NEG_SCHANNEL; - neg_flags |= NETLOGON_NEG_SCHANNEL; result = cli_nt_setup_creds(cli, sec_chan, trust_password, -- cgit From dda9d7626475d4d01b91ecd0dd31c80a88cb90bc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 7 Jul 2004 18:14:16 +0000 Subject: r1380: adding debug message when encouting an ASU specific bug in an rpc_bind reply (This used to be commit c6e73ff091b4d87111b33735400fdd10d4c8671c) --- source3/rpc_client/cli_pipe.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9e2d5aa4a7..0720f87241 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1233,10 +1233,12 @@ static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE * static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer) { -# if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */ - if ( hdr_ba->addr.len <= 0) - return False; + if ( hdr_ba->addr.len == 0) { + DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)")); + } + +# if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */ if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) && !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) ) { -- cgit From f4ec52a0978dca900942e6001947e3b3d58eccd2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 6 Jan 2005 11:42:40 +0000 Subject: r4561: This looks a lot larger than it is, this is to reduce the clutter on future patches. Pass down the pipe_idx down to all functions in cli_pipe where nt_pipe_fnum is referenced. First step towards having multiple pipes on a cli_struct. The idea is to not have a single nt_pipe_fnum but an array for the pipes we support. Volker (This used to be commit 93eab050201d4e55096a8820226749f001597b5d) --- source3/rpc_client/cli_pipe.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0720f87241..a36fd80116 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -62,7 +62,7 @@ static uint32 get_rpc_call_id(void) Use SMBreadX to get rest of one fragment's worth of rpc data. ********************************************************************/ -static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 *rdata_offset) +static BOOL rpc_read(struct cli_state *cli, int pipe_idx, prs_struct *rdata, uint32 data_to_read, uint32 *rdata_offset) { size_t size = (size_t)cli->max_recv_frag; int stream_offset = 0; @@ -394,7 +394,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, ****************************************************************************/ -static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rdata, +static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, prs_struct *rdata, uint8 expected_pkt_type) { uint32 len; @@ -502,7 +502,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd /* Read the remaining part of the first response fragment */ - if (!rpc_read(cli, rdata, len, ¤t_offset)) { + if (!rpc_read(cli, pipe_idx, rdata, len, ¤t_offset)) { prs_mem_free(rdata); return False; } @@ -602,7 +602,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd * Now read the rest of the PDU. */ - if (!rpc_read(cli, rdata, len, ¤t_offset)) { + if (!rpc_read(cli, pipe_idx, rdata, len, ¤t_offset)) { prs_mem_free(rdata); return False; } @@ -911,7 +911,7 @@ static BOOL create_auth_hdr(prs_struct *outgoing_packet, * @param rdata Unparsed NDR response data. **/ -BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, +BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num, prs_struct *data, prs_struct *rdata) { uint32 auth_len, real_auth_len, auth_hdr_len, max_data, data_left, data_sent; @@ -1090,7 +1090,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, prs_offset(&outgoing_packet))); if (flags & RPC_FLG_LAST) - ret = rpc_api_pipe(cli, &outgoing_packet, + ret = rpc_api_pipe(cli, pipe_idx, &outgoing_packet, rdata, RPC_RESPONSE); else { cli_write(cli, cli->nt_pipe_fnum, 0x0008, @@ -1113,7 +1113,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, Set the handle state. ****************************************************************************/ -static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, const char *pipe_name, uint16 device_state) +static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, int pipe_idx, const char *pipe_name, uint16 device_state) { BOOL state_set = False; char param[2]; @@ -1276,7 +1276,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC Create and send the third packet in an RPC auth. ****************************************************************************/ -static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 rpc_call_id) +static BOOL rpc_send_auth_reply(struct cli_state *cli, int pipe_idx, prs_struct *rdata, uint32 rpc_call_id) { prs_struct rpc_out; ssize_t ret; @@ -1389,7 +1389,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL); /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, &rpc_out, &rdata, RPC_BINDACK)) { + if (rpc_api_pipe(cli, pipe_idx, &rpc_out, &rdata, RPC_BINDACK)) { RPC_HDR_BA hdr_ba; DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n")); @@ -1416,7 +1416,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na */ if ((cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) - && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) { + && !rpc_send_auth_reply(cli, pipe_idx, &rdata, rpc_call_id)) { DEBUG(0,("rpc_pipe_bind: rpc_send_auth_reply failed.\n")); prs_mem_free(&rdata); return False; @@ -1463,7 +1463,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) cli->nt_pipe_fnum = (uint16)fnum; /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, pipe_names[pipe_idx].client_pipe, 0x4300)) { + if (!rpc_pipe_set_hnd_state(cli, pipe_idx, pipe_names[pipe_idx].client_pipe, 0x4300)) { DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", cli_errstr(cli))); cli_close(cli, cli->nt_pipe_fnum); @@ -1588,7 +1588,7 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, cli->nt_pipe_fnum = (uint16)fnum; /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, PIPE_NETLOGON, 0x4300)) { + if (!rpc_pipe_set_hnd_state(cli, PI_NETLOGON, PIPE_NETLOGON, 0x4300)) { DEBUG(0,("Pipe hnd state failed. Error was %s\n", cli_errstr(cli))); cli_close(cli, cli->nt_pipe_fnum); -- cgit From c85d9e735c8294088203f1656ae07a4b0835292c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 6 Jan 2005 15:35:02 +0000 Subject: r4570: Replace cli->nt_pipe_fnum with an array of NT file numbers, one for each supported pipe. Netlogon is still special, as we open that twice, one to do the auth2, the other one with schannel. The client interface is completely unchanged for those who only use a single pie. cli->pipe_idx is used as the index for everything except the "real" client rpc calls, which have been explicitly converted in my last commit. Next step is to get winbind to just use a single smb connection for multiple pipes. Volker (This used to be commit dc294c52e0216424236057ca6cd35e1ebf51d0da) --- source3/rpc_client/cli_pipe.c | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a36fd80116..52cbae6326 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -95,7 +95,7 @@ static BOOL rpc_read(struct cli_state *cli, int pipe_idx, prs_struct *rdata, uin if (size > (size_t)data_to_read) size = (size_t)data_to_read; - num_read = (int)cli_read(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size); + num_read = (int)cli_read(cli, cli->nt_pipe_fnum[pipe_idx], pdata, (off_t)stream_offset, size); DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", num_read, stream_offset, data_to_read)); @@ -416,9 +416,9 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, /* Create setup parameters - must be in native byte order. */ setup[0] = TRANSACT_DCERPCCMD; - setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */ + setup[1] = cli->nt_pipe_fnum[pipe_idx]; /* Pipe file handle. */ - DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum)); + DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum[pipe_idx])); /* Send the RPC request and receive a response. For short RPC calls (about 1024 bytes or so) the RPC request and response @@ -442,7 +442,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, if (prdata == NULL) { DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n", - (int)cli->nt_pipe_fnum)); + (int)cli->nt_pipe_fnum[pipe_idx])); return False; } @@ -470,7 +470,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, } if (rhdr.pkt_type == RPC_BINDNACK) { - DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum)); + DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum[pipe_idx])); prs_mem_free(rdata); return False; } @@ -485,7 +485,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, } if (rhdr.pkt_type != expected_pkt_type) { - DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum, rhdr.pkt_type, expected_pkt_type)); + DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum[pipe_idx], rhdr.pkt_type, expected_pkt_type)); prs_mem_free(rdata); return False; } @@ -557,7 +557,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL); prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); - num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); + num_read = cli_read(cli, cli->nt_pipe_fnum[pipe_idx], hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRDOS && ecode != ERRmoredata) { @@ -1093,7 +1093,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num, ret = rpc_api_pipe(cli, pipe_idx, &outgoing_packet, rdata, RPC_RESPONSE); else { - cli_write(cli, cli->nt_pipe_fnum, 0x0008, + cli_write(cli, cli->nt_pipe_fnum[pipe_idx], 0x0008, prs_data_p(&outgoing_packet), data_sent, data_len); } @@ -1126,14 +1126,14 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, int pipe_idx, const ch return False; DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", - cli->nt_pipe_fnum, pipe_name, device_state)); + cli->nt_pipe_fnum[pipe_idx], pipe_name, device_state)); /* create parameters: device state */ SSVAL(param, 0, device_state); /* create setup parameters. */ setup[0] = 0x0001; - setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */ + setup[1] = cli->nt_pipe_fnum[pipe_idx]; /* pipe file handle. got this from an SMBOpenX. */ /* send the data on \PIPE\ */ if (cli_api_pipe(cli, "\\PIPE\\", @@ -1289,7 +1289,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, int pipe_idx, prs_struct return False; } - if ((ret = cli_write(cli, cli->nt_pipe_fnum, 0x8, prs_data_p(&rpc_out), + if ((ret = cli_write(cli, cli->nt_pipe_fnum[pipe_idx], 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)); prs_mem_free(&rpc_out); @@ -1316,7 +1316,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na if ( (pipe_idx < 0) || (pipe_idx >= PI_MAX_PIPES) ) return False; - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_names[pipe_idx].client_pipe)); + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum[pipe_idx], pipe_names[pipe_idx].client_pipe)); if (!valid_pipe_name(pipe_idx, &abstract, &transfer)) return False; @@ -1439,7 +1439,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) /* At the moment we can't have more than one pipe open over a cli connection. )-: */ - SMB_ASSERT(cli->nt_pipe_fnum == 0); + SMB_ASSERT(cli->nt_pipe_fnum[pipe_idx] == 0); /* The pipe index must fall within our array */ @@ -1452,7 +1452,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) return False; } - cli->nt_pipe_fnum = (uint16)fnum; + cli->nt_pipe_fnum[pipe_idx] = (uint16)fnum; } else { if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, O_CREAT|O_RDWR, DENY_NONE)) == -1) { DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n", @@ -1460,14 +1460,14 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) return False; } - cli->nt_pipe_fnum = (uint16)fnum; + cli->nt_pipe_fnum[pipe_idx] = (uint16)fnum; /**************** Set Named Pipe State ***************/ if (!rpc_pipe_set_hnd_state(cli, pipe_idx, pipe_names[pipe_idx].client_pipe, 0x4300)) { DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", cli_errstr(cli))); - cli_close(cli, cli->nt_pipe_fnum); - cli->nt_pipe_fnum = 0; + cli_close(cli, cli->nt_pipe_fnum[pipe_idx]); + cli->nt_pipe_fnum[pipe_idx] = 0; return False; } } @@ -1477,8 +1477,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) if (!rpc_pipe_bind(cli, pipe_idx, global_myname())) { 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); - cli->nt_pipe_fnum = 0; + cli_close(cli, cli->nt_pipe_fnum[pipe_idx]); + cli->nt_pipe_fnum[pipe_idx] = 0; return False; } @@ -1554,7 +1554,7 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, memcpy(cli->auth_info.sess_key, cli->sess_key, sizeof(cli->auth_info.sess_key)); - cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum; + cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum[PI_NETLOGON]; cli->pipe_auth_flags = AUTH_PIPE_NETSEC; cli->pipe_auth_flags |= AUTH_PIPE_SIGN; @@ -1574,7 +1574,7 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, return NT_STATUS_UNSUCCESSFUL; } - cli->nt_pipe_fnum = (uint16)fnum; + cli->nt_pipe_fnum[PI_NETLOGON] = (uint16)fnum; } else { if ((fnum = cli_open(cli, PIPE_NETLOGON, O_CREAT|O_RDWR, DENY_NONE)) == -1) { @@ -1585,20 +1585,20 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, return NT_STATUS_UNSUCCESSFUL; } - cli->nt_pipe_fnum = (uint16)fnum; + cli->nt_pipe_fnum[PI_NETLOGON] = (uint16)fnum; /**************** Set Named Pipe State ***************/ if (!rpc_pipe_set_hnd_state(cli, PI_NETLOGON, PIPE_NETLOGON, 0x4300)) { DEBUG(0,("Pipe hnd state failed. Error was %s\n", cli_errstr(cli))); - cli_close(cli, cli->nt_pipe_fnum); + cli_close(cli, cli->nt_pipe_fnum[PI_NETLOGON]); return NT_STATUS_UNSUCCESSFUL; } } if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) { DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON)); - cli_close(cli, cli->nt_pipe_fnum); + cli_close(cli, cli->nt_pipe_fnum[PI_NETLOGON]); return NT_STATUS_UNSUCCESSFUL; } @@ -1645,8 +1645,8 @@ NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, int auth_flags memcpy(cli->auth_info.sess_key, cli->sess_key, sizeof(cli->auth_info.sess_key)); - cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum; - cli->nt_pipe_fnum = 0; + cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum[PI_NETLOGON]; + cli->nt_pipe_fnum[PI_NETLOGON] = 0; /* doing schannel, not per-user auth */ cli->pipe_auth_flags = auth_flags; -- cgit From 04e07e8cc9d6615381e0501cd36cf7d78aeed189 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 8 Jun 2005 03:48:40 +0000 Subject: r7385: Rewrite the RPC bind parsing functions to follow the spec. I haven't yet tested this so I may have screwed this up - however it now follows the DCE spec. valgrinded tests to follow.... Jeremy. (This used to be commit 877e0a61f5821c89149b1403d08675dd7db8039e) --- source3/rpc_client/cli_pipe.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 52cbae6326..8f6576a165 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -652,6 +652,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, RPC_HDR hdr; RPC_HDR_RB hdr_rb; RPC_HDR_AUTH hdr_auth; + RPC_CONTEXT rpc_ctx; int auth_len = 0; int auth_type, auth_level; size_t saved_hdr_offset = 0; @@ -734,21 +735,25 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, auth_len = prs_offset(&auth_info) - saved_hdr_offset; } + /* create the RPC context. */ + init_rpc_context(&rpc_ctx, 0 /* context id */, + abstract, transfer); + + /* create the bind request RPC_HDR_RB */ + init_rpc_hdr_rb(&hdr_rb, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx); + /* 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), + RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb) + prs_offset(&auth_info), auth_len); + /* Marshall the RPC header */ if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) { DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n")); prs_mem_free(&auth_info); return NT_STATUS_NO_MEMORY; } - /* 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); - /* 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")); -- cgit From fed660877c16562265327c6093ea645cf4176b5c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 8 Jun 2005 22:10:34 +0000 Subject: r7415: * big change -- volker's new async winbindd from trunk (This used to be commit a0ac9a8ffd4af31a0ebc423b4acbb2f043d865b8) --- source3/rpc_client/cli_pipe.c | 325 +++++++++++++++++++++++++++--------------- 1 file changed, 214 insertions(+), 111 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8f6576a165..5f34fbde5d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -62,7 +62,8 @@ static uint32 get_rpc_call_id(void) Use SMBreadX to get rest of one fragment's worth of rpc data. ********************************************************************/ -static BOOL rpc_read(struct cli_state *cli, int pipe_idx, prs_struct *rdata, uint32 data_to_read, uint32 *rdata_offset) +static BOOL rpc_read(struct rpc_pipe_client *cli, prs_struct *rdata, + uint32 data_to_read, uint32 *rdata_offset) { size_t size = (size_t)cli->max_recv_frag; int stream_offset = 0; @@ -95,13 +96,14 @@ static BOOL rpc_read(struct cli_state *cli, int pipe_idx, prs_struct *rdata, uin if (size > (size_t)data_to_read) size = (size_t)data_to_read; - num_read = (int)cli_read(cli, cli->nt_pipe_fnum[pipe_idx], pdata, (off_t)stream_offset, size); + num_read = (int)cli_read(cli->cli, cli->fnum, pdata, + (off_t)stream_offset, size); DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", num_read, stream_offset, data_to_read)); - if (cli_is_dos_error(cli)) { - cli_dos_error(cli, &eclass, &ecode); + if (cli_is_dos_error(cli->cli)) { + cli_dos_error(cli->cli, &eclass, &ecode); if (eclass != ERRDOS && ecode != ERRmoredata) { DEBUG(0,("rpc_read: Error %d/%u in cli_read\n", eclass, (unsigned int)ecode)); @@ -168,7 +170,7 @@ static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, Never on bind requests/responses. ****************************************************************************/ -static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, +static BOOL rpc_auth_pipe(struct rpc_pipe_client *cli, prs_struct *rdata, uint32 fragment_start, int len, int auth_len, uint8 pkt_type, int *pauth_padding_len) { @@ -219,7 +221,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, DEBUG(10,("rpc_auth_pipe: packet:\n")); dump_data(100, dp, auth_len); - prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&auth_verf, 0, cli->cli->mem_ctx, UNMARSHALL); /* The endinness must be preserved. JRA. */ prs_set_endian_data( &auth_verf, rdata->bigendian_data); @@ -394,7 +396,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, ****************************************************************************/ -static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, prs_struct *rdata, +static BOOL rpc_api_pipe(struct rpc_pipe_client *cli, prs_struct *data, prs_struct *rdata, uint8 expected_pkt_type) { uint32 len; @@ -416,23 +418,24 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, /* Create setup parameters - must be in native byte order. */ setup[0] = TRANSACT_DCERPCCMD; - setup[1] = cli->nt_pipe_fnum[pipe_idx]; /* Pipe file handle. */ + setup[1] = cli->fnum; /* Pipe file handle. */ - DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum[pipe_idx])); + DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->fnum)); /* Send the RPC request and receive a response. For short RPC calls (about 1024 bytes or so) the RPC request and response appears in a SMBtrans request and response. Larger RPC responses are received further on. */ - if (!cli_api_pipe(cli, "\\PIPE\\", + if (!cli_api_pipe(cli->cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ pdata, data_len, max_data, /* 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))); + DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", + cli_errstr(cli->cli))); return False; } @@ -442,7 +445,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, if (prdata == NULL) { DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n", - (int)cli->nt_pipe_fnum[pipe_idx])); + (int)cli->fnum)); return False; } @@ -470,7 +473,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, } if (rhdr.pkt_type == RPC_BINDNACK) { - DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum[pipe_idx])); + DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->fnum)); prs_mem_free(rdata); return False; } @@ -485,7 +488,9 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, } if (rhdr.pkt_type != expected_pkt_type) { - DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum[pipe_idx], rhdr.pkt_type, expected_pkt_type)); + DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet " + "type - %d, not %d\n", (int)cli->fnum, + rhdr.pkt_type, expected_pkt_type)); prs_mem_free(rdata); return False; } @@ -502,7 +507,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, /* Read the remaining part of the first response fragment */ - if (!rpc_read(cli, pipe_idx, rdata, len, ¤t_offset)) { + if (!rpc_read(cli, rdata, len, ¤t_offset)) { prs_mem_free(rdata); return False; } @@ -554,12 +559,13 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, * First read the header of the next PDU. */ - prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&hps, 0, cli->cli->mem_ctx, UNMARSHALL); prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); - num_read = cli_read(cli, cli->nt_pipe_fnum[pipe_idx], hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN); - if (cli_is_dos_error(cli)) { - cli_dos_error(cli, &eclass, &ecode); + num_read = cli_read(cli->cli, cli->fnum, hdr_data, 0, + RPC_HEADER_LEN+RPC_HDR_RESP_LEN); + if (cli_is_dos_error(cli->cli)) { + cli_dos_error(cli->cli, &eclass, &ecode); if (eclass != ERRDOS && ecode != ERRmoredata) { DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode)); return False; @@ -602,7 +608,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, * Now read the rest of the PDU. */ - if (!rpc_read(cli, pipe_idx, rdata, len, ¤t_offset)) { + if (!rpc_read(cli, rdata, len, ¤t_offset)) { prs_mem_free(rdata); return False; } @@ -644,7 +650,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, ********************************************************************/ -static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, +static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli, + prs_struct *rpc_out, uint32 rpc_call_id, RPC_IFACE *abstract, RPC_IFACE *transfer, const char *my_name, const char *domain) @@ -783,7 +790,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out, the authentication handshake. ********************************************************************/ -static NTSTATUS create_rpc_bind_resp(struct cli_state *cli, +static NTSTATUS create_rpc_bind_resp(struct rpc_pipe_client *cli, uint32 rpc_call_id, prs_struct *rpc_out) { @@ -916,8 +923,8 @@ static BOOL create_auth_hdr(prs_struct *outgoing_packet, * @param rdata Unparsed NDR response data. **/ -BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num, - prs_struct *data, prs_struct *rdata) +BOOL rpc_api_pipe_req_int(struct rpc_pipe_client *cli, uint8 op_num, + prs_struct *data, prs_struct *rdata) { uint32 auth_len, real_auth_len, auth_hdr_len, max_data, data_left, data_sent; NTSTATUS nt_status; @@ -959,7 +966,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num, send_size = MIN(data_left, max_data); if (!prs_init(&sec_blob, send_size, /* will need at least this much */ - cli->mem_ctx, MARSHALL)) { + cli->cli->mem_ctx, MARSHALL)) { DEBUG(0,("Could not malloc %u bytes", send_size+auth_padding)); return False; @@ -1066,7 +1073,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num, * Malloc parse struct to hold it (and enough for alignments). */ if(!prs_init(&outgoing_packet, data_len + 8, - cli->mem_ctx, MARSHALL)) { + cli->cli->mem_ctx, MARSHALL)) { DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len )); return False; } @@ -1095,10 +1102,10 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num, prs_offset(&outgoing_packet))); if (flags & RPC_FLG_LAST) - ret = rpc_api_pipe(cli, pipe_idx, &outgoing_packet, + ret = rpc_api_pipe(cli, &outgoing_packet, rdata, RPC_RESPONSE); else { - cli_write(cli, cli->nt_pipe_fnum[pipe_idx], 0x0008, + cli_write(cli->cli, cli->fnum, 0x0008, prs_data_p(&outgoing_packet), data_sent, data_len); } @@ -1108,17 +1115,26 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num, } /* Also capture received data */ slprintf(dump_name, sizeof(dump_name) - 1, "reply_%s", - cli_pipe_get_name(cli)); + cli_pipe_get_name(cli->cli)); prs_dump(dump_name, op_num, rdata); return ret; } +BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num, + prs_struct *data, prs_struct *rdata) +{ + return rpc_api_pipe_req_int(&cli->pipes[pipe_idx], op_num, + data, rdata); +} + + /**************************************************************************** Set the handle state. ****************************************************************************/ -static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, int pipe_idx, const char *pipe_name, uint16 device_state) +static BOOL rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli, + const char *pipe_name, uint16 device_state) { BOOL state_set = False; char param[2]; @@ -1131,17 +1147,17 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, int pipe_idx, const ch return False; DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", - cli->nt_pipe_fnum[pipe_idx], pipe_name, device_state)); + cli->fnum, pipe_name, device_state)); /* create parameters: device state */ SSVAL(param, 0, device_state); /* create setup parameters. */ setup[0] = 0x0001; - setup[1] = cli->nt_pipe_fnum[pipe_idx]; /* pipe file handle. got this from an SMBOpenX. */ + setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */ /* send the data on \PIPE\ */ - if (cli_api_pipe(cli, "\\PIPE\\", + if (cli_api_pipe(cli->cli, "\\PIPE\\", setup, 2, 0, /* setup, length, max */ param, 2, 0, /* param, length, max */ NULL, 0, 1024, /* data, length, max */ @@ -1281,20 +1297,21 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC Create and send the third packet in an RPC auth. ****************************************************************************/ -static BOOL rpc_send_auth_reply(struct cli_state *cli, int pipe_idx, prs_struct *rdata, uint32 rpc_call_id) +static BOOL rpc_send_auth_reply(struct rpc_pipe_client *cli, + prs_struct *rdata, uint32 rpc_call_id) { prs_struct rpc_out; ssize_t ret; prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */ - cli->mem_ctx, MARSHALL); + cli->cli->mem_ctx, MARSHALL); if (!NT_STATUS_IS_OK(create_rpc_bind_resp(cli, rpc_call_id, &rpc_out))) { return False; } - if ((ret = cli_write(cli, cli->nt_pipe_fnum[pipe_idx], 0x8, prs_data_p(&rpc_out), + if ((ret = cli_write(cli->cli, cli->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)); prs_mem_free(&rpc_out); @@ -1309,7 +1326,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, int pipe_idx, prs_struct Do an rpc bind. ****************************************************************************/ -static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_name) +static BOOL rpc_pipe_bind(struct rpc_pipe_client *cli) { RPC_IFACE abstract; RPC_IFACE transfer; @@ -1318,15 +1335,16 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na uint32 rpc_call_id; char buffer[MAX_PDU_FRAG_LEN]; - if ( (pipe_idx < 0) || (pipe_idx >= PI_MAX_PIPES) ) + if ( (cli->pipe_idx < 0) || (cli->pipe_idx >= PI_MAX_PIPES) ) return False; - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum[pipe_idx], pipe_names[pipe_idx].client_pipe)); + DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->fnum, + pipe_names[cli->pipe_idx].client_pipe)); - if (!valid_pipe_name(pipe_idx, &abstract, &transfer)) + if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) return False; - prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL); + prs_init(&rpc_out, 0, cli->cli->mem_ctx, MARSHALL); /* * Use the MAX_PDU_FRAG_LEN buffer to store the bind request. @@ -1391,10 +1409,10 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na global_myname(), cli->domain); /* Initialize the incoming data struct. */ - prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&rdata, 0, cli->cli->mem_ctx, UNMARSHALL); /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, pipe_idx, &rpc_out, &rdata, RPC_BINDACK)) { + if (rpc_api_pipe(cli, &rpc_out, &rdata, RPC_BINDACK)) { RPC_HDR_BA hdr_ba; DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n")); @@ -1405,7 +1423,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na return False; } - if(!check_bind_response(&hdr_ba, pipe_idx, &transfer)) { + if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) { DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n")); prs_mem_free(&rdata); return False; @@ -1421,7 +1439,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na */ if ((cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) - && !rpc_send_auth_reply(cli, pipe_idx, &rdata, rpc_call_id)) { + && !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; @@ -1440,11 +1458,9 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) { int fnum; + struct rpc_pipe_client *cli_pipe; - /* At the moment we can't have more than one pipe open over - a cli connection. )-: */ - - SMB_ASSERT(cli->nt_pipe_fnum[pipe_idx] == 0); + SMB_ASSERT(cli->pipes[pipe_idx].fnum == 0); /* The pipe index must fall within our array */ @@ -1457,7 +1473,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) return False; } - cli->nt_pipe_fnum[pipe_idx] = (uint16)fnum; + cli->pipes[pipe_idx].fnum = (uint16)fnum; } else { if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, O_CREAT|O_RDWR, DENY_NONE)) == -1) { DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n", @@ -1465,25 +1481,32 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) return False; } - cli->nt_pipe_fnum[pipe_idx] = (uint16)fnum; + cli->pipes[pipe_idx].fnum = (uint16)fnum; /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, pipe_idx, pipe_names[pipe_idx].client_pipe, 0x4300)) { + if (!rpc_pipe_set_hnd_state(&cli->pipes[pipe_idx], pipe_names[pipe_idx].client_pipe, 0x4300)) { DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", cli_errstr(cli))); - cli_close(cli, cli->nt_pipe_fnum[pipe_idx]); - cli->nt_pipe_fnum[pipe_idx] = 0; + cli_close(cli, cli->pipes[pipe_idx].fnum); + cli->pipes[pipe_idx].fnum = 0; return False; } } + cli_pipe = &cli->pipes[pipe_idx]; + cli_pipe->pipe_idx = pipe_idx; + cli_pipe->cli = cli; + cli_pipe->pipe_auth_flags = cli->pipe_auth_flags; + memcpy(&cli_pipe->auth_info.sess_key, + cli->sess_key, sizeof(cli->sess_key)); + /******************* bind request on pipe *****************/ - if (!rpc_pipe_bind(cli, pipe_idx, global_myname())) { + if (!rpc_pipe_bind(&cli->pipes[pipe_idx])) { 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[pipe_idx]); - cli->nt_pipe_fnum[pipe_idx] = 0; + cli_close(cli, cli->pipes[pipe_idx].fnum); + cli->pipes[pipe_idx].fnum = 0; return False; } @@ -1523,7 +1546,6 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, { NTSTATUS result; uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; - int fnum; cli_nt_netlogon_netsec_session_close(cli); @@ -1554,60 +1576,20 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, } - /* Server offered schannel, so try it. */ + cli->netlogon_pipe = cli->pipes[PI_NETLOGON]; + ZERO_STRUCT(cli->pipes[PI_NETLOGON]); - memcpy(cli->auth_info.sess_key, cli->sess_key, - sizeof(cli->auth_info.sess_key)); + /* Server offered schannel, so try it. */ - cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum[PI_NETLOGON]; + memcpy(cli->pipes[PI_NETLOGON].auth_info.sess_key, cli->sess_key, + sizeof(cli->pipes[PI_NETLOGON].auth_info.sess_key)); cli->pipe_auth_flags = AUTH_PIPE_NETSEC; cli->pipe_auth_flags |= AUTH_PIPE_SIGN; cli->pipe_auth_flags |= AUTH_PIPE_SEAL; - if (cli->capabilities & CAP_NT_SMBS) { - - /* The secure channel connection must be opened on the same - session (TCP connection) as the one the challenge was - requested from. */ - 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 NT_STATUS_UNSUCCESSFUL; - } - - cli->nt_pipe_fnum[PI_NETLOGON] = (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 NT_STATUS_UNSUCCESSFUL; - } - - cli->nt_pipe_fnum[PI_NETLOGON] = (uint16)fnum; - - /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(cli, PI_NETLOGON, PIPE_NETLOGON, 0x4300)) { - DEBUG(0,("Pipe hnd state failed. Error was %s\n", - cli_errstr(cli))); - cli_close(cli, cli->nt_pipe_fnum[PI_NETLOGON]); - return NT_STATUS_UNSUCCESSFUL; - } - } - - if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) { - DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON)); - cli_close(cli, cli->nt_pipe_fnum[PI_NETLOGON]); - return NT_STATUS_UNSUCCESSFUL; - } - - return NT_STATUS_OK; + return cli_nt_session_open(cli, PI_NETLOGON) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } @@ -1640,19 +1622,20 @@ NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, int auth_flags } if (!NT_STATUS_IS_OK(result)) { - ZERO_STRUCT(cli->auth_info.sess_key); + ZERO_STRUCT(cli->pipes[cli->pipe_idx].auth_info.sess_key); ZERO_STRUCT(cli->sess_key); cli->pipe_auth_flags = 0; cli_nt_session_close(cli); return result; } - memcpy(cli->auth_info.sess_key, cli->sess_key, - sizeof(cli->auth_info.sess_key)); - - cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum[PI_NETLOGON]; - cli->nt_pipe_fnum[PI_NETLOGON] = 0; + memcpy(cli->pipes[PI_NETLOGON].auth_info.sess_key, cli->sess_key, + sizeof(cli->pipes[PI_NETLOGON].auth_info.sess_key)); + cli_close(cli, cli->pipes[PI_NETLOGON].fnum); + cli->pipes[PI_NETLOGON].fnum = 0; + cli->pipe_idx = -1; + /* doing schannel, not per-user auth */ cli->pipe_auth_flags = auth_flags; @@ -1664,4 +1647,124 @@ const char *cli_pipe_get_name(struct cli_state *cli) return cli->pipe_name; } +static struct rpc_pipe_client *cli_rpc_open(struct cli_state *cli, + int pipe_idx) +{ + TALLOC_CTX *mem_ctx; + struct rpc_pipe_client *result; + int fnum; + + /* The pipe index must fall within our array */ + SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); + + mem_ctx = talloc_init("struct rpc_pipe_client"); + if (mem_ctx == NULL) return NULL; + + result = TALLOC_P(mem_ctx, struct rpc_pipe_client); + if (result == NULL) return NULL; + + result->mem_ctx = mem_ctx; + + fnum = cli_nt_create(cli, &pipe_names[pipe_idx].client_pipe[5], + DESIRED_ACCESS_PIPE); + + if (fnum == -1) { + DEBUG(0,("cli_rpc_open failed on pipe %s " + "to machine %s. Error was %s\n", + &pipe_names[pipe_idx].client_pipe[5], cli->desthost, + cli_errstr(cli))); + talloc_destroy(result->mem_ctx); + return NULL; + } + + result->fnum = fnum; + result->cli = cli; + result->pipe_idx = pipe_idx; + + return result; +} + +struct rpc_pipe_client *cli_rpc_open_noauth(struct cli_state *cli, + int pipe_idx) +{ + struct rpc_pipe_client *result; + + result = cli_rpc_open(cli, pipe_idx); + if (result == NULL) return NULL; + + result->max_xmit_frag = 0; + result->pipe_auth_flags = 0; + + if (!rpc_pipe_bind(result)) { + DEBUG(0, ("rpc_pipe_bind failed\n")); + talloc_destroy(result->mem_ctx); + return NULL; + } + + return result; +} + +struct rpc_pipe_client *cli_rpc_open_ntlmssp(struct cli_state *cli, + int pipe_idx, + const char *domain, + const char *username, + const char *password) +{ + struct rpc_pipe_client *result; + + result = cli_rpc_open(cli, pipe_idx); + if (result == NULL) return NULL; + + result->max_xmit_frag = 0; + result->pipe_auth_flags = + AUTH_PIPE_NTLMSSP|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL; + result->domain = domain; + result->user_name = username; + pwd_set_cleartext(&result->pwd, password); + + if (!rpc_pipe_bind(result)) { + DEBUG(0, ("cli_rpc_pipe_bind failed\n")); + talloc_destroy(result->mem_ctx); + return NULL; + } + + return result; +} + +struct rpc_pipe_client *cli_rpc_open_schannel(struct cli_state *cli, + int pipe_idx, + const uchar session_key[16], + const char *domain) +{ + struct rpc_pipe_client *result; + + result = cli_rpc_open(cli, pipe_idx); + if (result == NULL) return NULL; + + result->max_xmit_frag = 0; + result->pipe_auth_flags = + AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL; + result->domain = domain; + memcpy(result->auth_info.sess_key, session_key, 16); + + if (!rpc_pipe_bind(result)) { + DEBUG(0, ("cli_rpc_pipe_bind failed\n")); + talloc_destroy(result->mem_ctx); + return NULL; + } + + return result; +} + +void cli_rpc_close(struct rpc_pipe_client *cli_pipe) +{ + if (!cli_close(cli_pipe->cli, cli_pipe->fnum)) + DEBUG(0,("cli_rpc_open failed on pipe %s " + "to machine %s. Error was %s\n", + &pipe_names[cli_pipe->pipe_idx].client_pipe[5], + cli_pipe->cli->desthost, + cli_errstr(cli_pipe->cli))); + + talloc_destroy(cli_pipe->mem_ctx); +} -- cgit From 8b2b177a8e07e3a0cb00fbd7fdbafc8aeba5b204 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Jul 2005 20:25:04 +0000 Subject: r8805: Merge a duplicate struct. Get ready to support SPNEGO rpc binds. Jeremy. (This used to be commit fd6e342746edfda2f25df1ae0067d359b756e0cd) --- source3/rpc_client/cli_pipe.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5f34fbde5d..230750817a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -242,7 +242,7 @@ static BOOL rpc_auth_pipe(struct rpc_pipe_client *cli, prs_struct *rdata, } /* Let the caller know how much padding at the end of the data */ - *pauth_padding_len = rhdr_auth.padding; + *pauth_padding_len = rhdr_auth.auth_pad_len; /* Check it's the type of reply we were expecting to decode */ @@ -796,6 +796,7 @@ static NTSTATUS create_rpc_bind_resp(struct rpc_pipe_client *cli, { NTSTATUS nt_status; RPC_HDR hdr; + RPC_HDR_AUTH hdr_auth; RPC_HDR_AUTHA hdr_autha; DATA_BLOB ntlmssp_null_response = data_blob(NULL, 0); DATA_BLOB ntlmssp_reply; @@ -826,8 +827,8 @@ static NTSTATUS create_rpc_bind_resp(struct rpc_pipe_client *cli, get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); /* Create the request RPC_HDR_AUTHA */ - init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, - auth_type, auth_level, 0x00); + init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0, 0x0014a0c0); + init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, &hdr_auth); 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")); -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/rpc_client/cli_pipe.c | 3161 ++++++++++++++++++++++++++--------------- 1 file changed, 2013 insertions(+), 1148 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 230750817a..df34b1c3d9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1,11 +1,7 @@ /* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1998, - * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - * Copyright (C) Paul Ashton 1998. - * Copyright (C) Jeremy Allison 1999. - * Copyright (C) Andrew Bartlett 2003. + * Largely rewritten by Jeremy Allison 2005. * * 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 @@ -29,23 +25,37 @@ extern struct pipe_id_info pipe_names[]; -/* convert pipe auth flags into the RPC auth type and level */ +/******************************************************************** + Map internal value to wire value. + ********************************************************************/ -void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level) +static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type) { - *auth_type = 0; - *auth_level = 0; - if (pipe_auth_flags & AUTH_PIPE_SEAL) { - *auth_level = RPC_PIPE_AUTH_SEAL_LEVEL; - } else if (pipe_auth_flags & AUTH_PIPE_SIGN) { - *auth_level = RPC_PIPE_AUTH_SIGN_LEVEL; - } - - if (pipe_auth_flags & AUTH_PIPE_NETSEC) { - *auth_type = NETSEC_AUTH_TYPE; - } else if (pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - *auth_type = NTLMSSP_AUTH_TYPE; + switch (auth_type) { + + case PIPE_AUTH_TYPE_NONE: + return RPC_ANONYMOUS_AUTH_TYPE; + + case PIPE_AUTH_TYPE_NTLMSSP: + return RPC_NTLMSSP_AUTH_TYPE; + + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + case PIPE_AUTH_TYPE_SPNEGO_KRB5: + return RPC_SPNEGO_AUTH_TYPE; + + case PIPE_AUTH_TYPE_SCHANNEL: + return RPC_SCHANNEL_AUTH_TYPE; + + case PIPE_AUTH_TYPE_KRB5: + return RPC_KRB5_AUTH_TYPE; + + default: + DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe " + "auth type %u\n", + (unsigned int)auth_type )); + break; } + return -1; } /******************************************************************** @@ -60,55 +70,81 @@ static uint32 get_rpc_call_id(void) /******************************************************************* Use SMBreadX to get rest of one fragment's worth of rpc data. + Will expand the current_pdu struct to the correct size. ********************************************************************/ -static BOOL rpc_read(struct rpc_pipe_client *cli, prs_struct *rdata, - uint32 data_to_read, uint32 *rdata_offset) +static NTSTATUS rpc_read(struct rpc_pipe_client *cli, + prs_struct *current_pdu, + uint32 data_to_read, + uint32 *current_pdu_offset) { size_t size = (size_t)cli->max_recv_frag; - int stream_offset = 0; - int num_read; + uint32 stream_offset = 0; + ssize_t num_read; char *pdata; - int extra_data_size = ((int)*rdata_offset) + ((int)data_to_read) - (int)prs_data_size(rdata); + ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu); - 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)); + DEBUG(5,("rpc_read: data_to_read: %u current_pdu offset: %u extra_data_size: %d\n", + (unsigned int)data_to_read, (unsigned int)*current_pdu_offset, (int)extra_data_size )); /* * 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; + if(!prs_force_grow(current_pdu, (uint32)extra_data_size)) { + DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", (int)extra_data_size )); + return NT_STATUS_NO_MEMORY; } - DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", extra_data_size, prs_data_size(rdata) )); + DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", (int)extra_data_size, prs_data_size(current_pdu) )); } - pdata = prs_data_p(rdata) + *rdata_offset; + pdata = prs_data_p(current_pdu) + *current_pdu_offset; - do /* read data using SMBreadX */ - { - uint32 ecode; - uint8 eclass; - - if (size > (size_t)data_to_read) + do { + /* read data using SMBreadX */ + if (size > (size_t)data_to_read) { size = (size_t)data_to_read; + } - num_read = (int)cli_read(cli->cli, cli->fnum, pdata, + num_read = cli_read(cli->cli, cli->fnum, pdata, (off_t)stream_offset, size); - DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n", - num_read, stream_offset, data_to_read)); + DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n", + (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read)); + /* + * A dos error of ERRDOS/ERRmoredata is not an error. + */ if (cli_is_dos_error(cli->cli)) { - cli_dos_error(cli->cli, &eclass, &ecode); - if (eclass != ERRDOS && ecode != ERRmoredata) { - DEBUG(0,("rpc_read: Error %d/%u in cli_read\n", - eclass, (unsigned int)ecode)); - return False; - } + uint32 ecode; + uint8 eclass; + cli_dos_error(cli->cli, &eclass, &ecode); + if (eclass != ERRDOS && ecode != ERRmoredata) { + DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n", + eclass, (unsigned int)ecode, + cli_errstr(cli->cli), + cli->pipe_name )); + return dos_to_ntstatus(eclass, ecode); + } + } + + /* + * Likewise for NT_STATUS_BUFFER_TOO_SMALL + */ + if (cli_is_nt_error(cli->cli)) { + if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) { + DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n", + nt_errstr(cli_nt_error(cli->cli)), + cli->pipe_name )); + return cli_nt_error(cli->cli); + } + } + + if (num_read == -1) { + DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n", + cli->pipe_name )); + return cli_get_nt_error(cli->cli); } data_to_read -= num_read; @@ -119,262 +155,565 @@ static BOOL rpc_read(struct rpc_pipe_client *cli, prs_struct *rdata, /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */ /* - * Update the current offset into rdata by the amount read. + * Update the current offset into current_pdu by the amount read. */ - *rdata_offset += stream_offset; - - return True; + *current_pdu_offset += stream_offset; + return NT_STATUS_OK; } /**************************************************************************** - Checks the header. This will set the endian bit in the rdata prs_struct. JRA. + Try and get a PDU's worth of data from current_pdu. If not, then read more + from the wire. ****************************************************************************/ -static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, - BOOL *first, BOOL *last, uint32 *len) +static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu) { - DEBUG(5,("rpc_check_hdr: rdata->data_size = %u\n", (uint32)prs_data_size(rdata) )); - - /* Next call sets endian bit. */ + NTSTATUS ret = NT_STATUS_OK; + uint32 current_pdu_len = prs_data_size(current_pdu); + + /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */ + if (current_pdu_len < RPC_HEADER_LEN) { + /* rpc_read expands the current_pdu struct as neccessary. */ + ret = rpc_read(cli, current_pdu, RPC_HEADER_LEN - current_pdu_len, ¤t_pdu_len); + if (!NT_STATUS_IS_OK(ret)) { + return ret; + } + } - if(!smb_io_rpc_hdr("rpc_hdr ", rhdr, rdata, 0)) { - DEBUG(0,("rpc_check_hdr: Failed to unmarshall RPC_HDR.\n")); - return False; + /* This next call sets the endian bit correctly in current_pdu. */ + /* We will propagate this to rbuf later. */ + if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) { + DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n")); + return NT_STATUS_BUFFER_TOO_SMALL; } - 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; + /* Ensure we have frag_len bytes of data. */ + if (current_pdu_len < prhdr->frag_len) { + /* rpc_read expands the current_pdu struct as neccessary. */ + ret = rpc_read(cli, current_pdu, (uint32)prhdr->frag_len - current_pdu_len, ¤t_pdu_len); + if (!NT_STATUS_IS_OK(ret)) { + return ret; + } } - (*first) = ((rhdr->flags & RPC_FLG_FIRST) != 0); - (*last) = ((rhdr->flags & RPC_FLG_LAST ) != 0); - (*len) = (uint32)rhdr->frag_len - prs_data_size(rdata); + if (current_pdu_len < prhdr->frag_len) { + return NT_STATUS_BUFFER_TOO_SMALL; + } - return (rhdr->pkt_type != RPC_FAULT); + return NT_STATUS_OK; } /**************************************************************************** - Verify data on an rpc pipe. - The VERIFY & SEAL code is only executed on packets that look like this : + NTLMSSP specific sign/seal. + Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process. + In fact I should probably abstract these into identical pieces of code... JRA. + ****************************************************************************/ - Request/Response PDU's look like the following... +static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr, + prs_struct *current_pdu, + uint8 *p_ss_padding_len) +{ + RPC_HDR_AUTH auth_info; + uint32 save_offset = prs_offset(current_pdu); + uint32 auth_len = prhdr->auth_len; + NTLMSSP_STATE *ntlmssp_state = cli->auth.a_u.ntlmssp_state; + unsigned char *data = NULL; + size_t data_len; + unsigned char *full_packet_data = NULL; + size_t full_packet_data_len; + DATA_BLOB auth_blob; + NTSTATUS status; + + if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) { + return NT_STATUS_OK; + } - |<------------------PDU len----------------------------------------------->| - |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->| + if (!ntlmssp_state) { + return NT_STATUS_INVALID_PARAMETER; + } - +------------+-----------------+-------------+---------------+-------------+ - | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA | - +------------+-----------------+-------------+---------------+-------------+ + /* Ensure there's enough data for an authenticated response. */ + if ((auth_len > RPC_MAX_SIGN_SIZE) || + (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) { + DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n", + (unsigned int)auth_len )); + return NT_STATUS_BUFFER_TOO_SMALL; + } - Never on bind requests/responses. - ****************************************************************************/ + /* + * We need the full packet data + length (minus auth stuff) as well as the packet data + length + * after the RPC header. + * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal + * functions as NTLMv2 checks the rpc headers also. + */ + + data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN); + data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len); + + full_packet_data = prs_data_p(current_pdu); + full_packet_data_len = prhdr->frag_len - auth_len; + + /* Pull the auth header and the following data into a blob. */ + if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) { + DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n", + (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len )); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) { + DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n")); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + auth_blob.data = prs_data_p(current_pdu) + prs_offset(current_pdu); + auth_blob.length = auth_len; + + switch (cli->auth.auth_level) { + case PIPE_AUTH_LEVEL_PRIVACY: + /* Data is encrypted. */ + status = ntlmssp_unseal_packet(ntlmssp_state, + data, data_len, + full_packet_data, + full_packet_data_len, + &auth_blob); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal " + "packet from remote machine %s on pipe %s " + "fnum 0x%x. Error was %s.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum, + nt_errstr(status) )); + return status; + } + break; + case PIPE_AUTH_LEVEL_INTEGRITY: + /* Data is signed. */ + status = ntlmssp_check_packet(ntlmssp_state, + data, data_len, + full_packet_data, + full_packet_data_len, + &auth_blob); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on " + "packet from remote machine %s on pipe %s " + "fnum 0x%x. Error was %s.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum, + nt_errstr(status) )); + return status; + } + break; + default: + DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n", + cli->auth.auth_level )); + return NT_STATUS_INVALID_INFO_CLASS; + } -static BOOL rpc_auth_pipe(struct rpc_pipe_client *cli, prs_struct *rdata, - uint32 fragment_start, int len, int auth_len, uint8 pkt_type, - int *pauth_padding_len) -{ - /* - * 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. + * Return the current pointer to the data offset. */ - int data_len = len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len; + if(!prs_set_offset(current_pdu, save_offset)) { + DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n", + (unsigned int)save_offset )); + return NT_STATUS_BUFFER_TOO_SMALL; + } /* - * The start of the data to sign/seal is just after the RPC headers. + * Remember the padding length. We must remove it from the real data + * stream once the sign/seal is done. */ - char *reply_data = prs_data_p(rdata) + fragment_start + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; - RPC_HDR_AUTH rhdr_auth; + *p_ss_padding_len = auth_info.auth_pad_len; + + return NT_STATUS_OK; +} + +/**************************************************************************** + schannel specific sign/seal. + ****************************************************************************/ - char *dp = prs_data_p(rdata) + fragment_start + len - - RPC_HDR_AUTH_LEN - auth_len; - prs_struct auth_verf; +static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr, + prs_struct *current_pdu, + uint8 *p_ss_padding_len) +{ + RPC_HDR_AUTH auth_info; + RPC_AUTH_SCHANNEL_CHK schannel_chk; + uint32 auth_len = prhdr->auth_len; + uint32 save_offset = prs_offset(current_pdu); + struct schannel_auth_struct *schannel_auth = cli->auth.a_u.schannel_auth; + uint32 data_len; + + if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) { + return NT_STATUS_OK; + } - *pauth_padding_len = 0; + if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) { + DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len )); + return NT_STATUS_INVALID_PARAMETER; + } - if (auth_len == 0) { - if (cli->pipe_auth_flags == 0) { - /* move along, nothing to see here */ - return True; - } + if (!schannel_auth) { + return NT_STATUS_INVALID_PARAMETER; + } - DEBUG(2, ("No authenticaton header recienved on reply, but this pipe is authenticated\n")); - return False; + /* Ensure there's enough data for an authenticated response. */ + if ((auth_len > RPC_MAX_SIGN_SIZE) || + (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) { + DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n", + (unsigned int)auth_len )); + return NT_STATUS_INVALID_PARAMETER; } - DEBUG(5,("rpc_auth_pipe: pkt_type: %d len: %d auth_len: %d NTLMSSP %s schannel %s sign %s seal %s \n", - pkt_type, len, auth_len, - BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP), - BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_NETSEC), - BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN), - BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL))); + data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len; - if (dp - prs_data_p(rdata) > prs_data_size(rdata)) { - DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n")); - return False; + if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) { + DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n", + (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len )); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) { + DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n")); + return NT_STATUS_BUFFER_TOO_SMALL; } - DEBUG(10,("rpc_auth_pipe: packet:\n")); - dump_data(100, dp, auth_len); + if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) { + DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n", + auth_info.auth_type)); + return NT_STATUS_BUFFER_TOO_SMALL; + } - prs_init(&auth_verf, 0, cli->cli->mem_ctx, UNMARSHALL); - - /* The endinness must be preserved. JRA. */ - prs_set_endian_data( &auth_verf, rdata->bigendian_data); - - /* Point this new parse struct at the auth section of the main - parse struct - rather than copying it. Avoids needing to - free it on every error - */ - prs_give_memory(&auth_verf, dp, RPC_HDR_AUTH_LEN + auth_len, False /* not dynamic */); - prs_set_offset(&auth_verf, 0); + if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN, + &schannel_chk, current_pdu, 0)) { + DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n")); + return NT_STATUS_BUFFER_TOO_SMALL; + } - { - int auth_type; - int auth_level; - if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) { - DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n")); - return False; - } + if (!schannel_decode(schannel_auth, + cli->auth.auth_level, + SENDER_IS_ACCEPTOR, + &schannel_chk, + prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN, + data_len)) { + DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU " + "Connection to remote machine %s " + "pipe %s fnum 0x%x.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum )); + return NT_STATUS_INVALID_PARAMETER; + } - /* Let the caller know how much padding at the end of the data */ - *pauth_padding_len = rhdr_auth.auth_pad_len; - - /* Check it's the type of reply we were expecting to decode */ + /* The sequence number gets incremented on both send and receive. */ + schannel_auth->seq_num++; - get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); - if (rhdr_auth.auth_type != auth_type) { - DEBUG(0, ("BAD auth type %d (should be %d)\n", - rhdr_auth.auth_type, auth_type)); - return False; - } - - if (rhdr_auth.auth_level != auth_level) { - DEBUG(0, ("BAD auth level %d (should be %d)\n", - rhdr_auth.auth_level, auth_level)); - return False; - } + /* + * Return the current pointer to the data offset. + */ + + if(!prs_set_offset(current_pdu, save_offset)) { + DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n", + (unsigned int)save_offset )); + return NT_STATUS_BUFFER_TOO_SMALL; } - if (pkt_type == RPC_BINDACK) { - if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - /* copy the next auth_len bytes into a buffer for - later use */ + /* + * Remember the padding length. We must remove it from the real data + * stream once the sign/seal is done. + */ + + *p_ss_padding_len = auth_info.auth_pad_len; + + return NT_STATUS_OK; +} - DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len); - BOOL store_ok; +/**************************************************************************** + Do the authentication checks on an incoming pdu. Check sign and unseal etc. + ****************************************************************************/ - /* save the reply away, for use a little later */ - prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len); +static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr, + prs_struct *current_pdu, + uint8 *p_ss_padding_len) +{ + NTSTATUS ret = NT_STATUS_OK; - store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state, - ntlmssp_verf))); + /* Paranioa checks for auth_len. */ + if (prhdr->auth_len) { + if (prhdr->auth_len > prhdr->frag_len) { + return NT_STATUS_INVALID_PARAMETER; + } - data_blob_free(&ntlmssp_verf); - return store_ok; - } - else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - /* nothing to do here - we don't seem to be able to - validate the bindack based on VL's comments */ - return True; + if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len || + prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) { + /* Integer wrap attempt. */ + return NT_STATUS_INVALID_PARAMETER; } } - - if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - NTSTATUS nt_status; - DATA_BLOB sig; - if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) || - (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) { - if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) { - DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len)); - return False; + + /* + * Now we have a complete RPC request PDU fragment, try and verify any auth data. + */ + + switch(cli->auth.auth_type) { + case PIPE_AUTH_TYPE_NONE: + if (prhdr->auth_len) { + DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s " + "pipe %s fnum 0x%x - got non-zero auth len %u.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum, + (unsigned int)prhdr->auth_len )); + return NT_STATUS_INVALID_PARAMETER; } - sig = data_blob(NULL, auth_len); - prs_copy_data_out((char *)sig.data, &auth_verf, auth_len); - } - - /* - * Unseal any sealed data in the PDU, not including the - * 8 byte auth_header or the auth_data. - */ + break; - /* - * Now unseal and check the auth verifier in the auth_data at - * the end of the packet. - */ + case PIPE_AUTH_TYPE_NTLMSSP: + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len); + if (!NT_STATUS_IS_OK(ret)) { + return ret; + } + break; - if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { - if (data_len < 0) { - DEBUG(1, ("Can't unseal - data_len < 0!!\n")); - return False; + case PIPE_AUTH_TYPE_SCHANNEL: + ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len); + if (!NT_STATUS_IS_OK(ret)) { + return ret; } - nt_status = ntlmssp_unseal_packet(cli->ntlmssp_pipe_state, - (unsigned char *)reply_data, data_len, - &sig); - } - else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - nt_status = ntlmssp_check_packet(cli->ntlmssp_pipe_state, - (const unsigned char *)reply_data, data_len, - &sig); - } + break; + + case PIPE_AUTH_TYPE_KRB5: + case PIPE_AUTH_TYPE_SPNEGO_KRB5: + default: + DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s " + "pipe %s fnum %x - unknown internal auth type %u.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum, + cli->auth.auth_type )); + return NT_STATUS_INVALID_INFO_CLASS; + } - data_blob_free(&sig); + return NT_STATUS_OK; +} - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0, ("rpc_auth_pipe: could not validate " - "incoming NTLMSSP packet!\n")); - return False; - } +/**************************************************************************** + Do basic authentication checks on an incoming pdu. + ****************************************************************************/ + +static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, + prs_struct *current_pdu, + uint8 expected_pkt_type, + char **ppdata, + uint32 *pdata_len, + prs_struct *return_data) +{ + + NTSTATUS ret = NT_STATUS_OK; + uint32 current_pdu_len = prs_data_size(current_pdu); + + if (current_pdu_len != prhdr->frag_len) { + DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n", + (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len )); + return NT_STATUS_INVALID_PARAMETER; } - if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - RPC_AUTH_NETSEC_CHK chk; + /* + * Point the return values at the real data including the RPC + * header. Just in case the caller wants it. + */ + *ppdata = prs_data_p(current_pdu); + *pdata_len = current_pdu_len; - if ( (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) - && (auth_len != RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN) ) - { - DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); - return False; - } + /* Ensure we have the correct type. */ + switch (prhdr->pkt_type) { + case RPC_ALTCONTRESP: + case RPC_BINDACK: + + /* Alter context and bind ack share the same packet definitions. */ + break; - /* can't seal with no nonce */ - if ( (cli->pipe_auth_flags & AUTH_PIPE_SEAL) - && (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) ) + + case RPC_RESPONSE: { - DEBUG(0,("rpc_auth_pipe: sealing not supported with schannel auth len %d\n", auth_len)); - return False; + RPC_HDR_RESP rhdr_resp; + uint8 ss_padding_len = 0; + + if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) { + DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n")); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* Here's where we deal with incoming sign/seal. */ + ret = cli_pipe_validate_rpc_response(cli, prhdr, + current_pdu, &ss_padding_len); + if (!NT_STATUS_IS_OK(ret)) { + return ret; + } + + /* Point the return values at the NDR data. Remember to remove any ss padding. */ + *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN; + + if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len; + + /* Remember to remove the auth footer. */ + if (prhdr->auth_len) { + /* We've already done integer wrap tests on auth_len in + cli_pipe_validate_rpc_response(). */ + if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len); + } + + DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n", + current_pdu_len, *pdata_len, ss_padding_len )); + + /* + * If this is the first reply, and the allocation hint is reasonably, try and + * set up the return_data parse_struct to the correct size. + */ + + if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) { + if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) { + DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u " + "too large to allocate\n", + (unsigned int)rhdr_resp.alloc_hint )); + return NT_STATUS_NO_MEMORY; + } + } + + break; } - - if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", auth_len, &chk, &auth_verf, 0)) + case RPC_BINDNACK: + DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s " + "pipe %s fnum 0x%x!\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum)); + /* Use this for now... */ + return NT_STATUS_NETWORK_ACCESS_DENIED; + + case RPC_FAULT: { - DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " - "RPC_AUTH_NETSECK_CHK failed\n")); - return False; - } + RPC_HDR_RESP rhdr_resp; + RPC_HDR_FAULT fault_resp; + + if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) { + DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n")); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) { + DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n")); + return NT_STATUS_BUFFER_TOO_SMALL; + } - if (!netsec_decode(&cli->auth_info, - cli->pipe_auth_flags, - SENDER_IS_ACCEPTOR, - &chk, reply_data, data_len)) { - DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n")); - return False; + DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s " + "pipe %s fnum 0x%x!\n", + nt_errstr(fault_resp.status), + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum)); + if (NT_STATUS_IS_OK(fault_resp.status)) { + return NT_STATUS_UNSUCCESSFUL; + } else { + return fault_resp.status; + } + } - cli->auth_info.seq_num++; + default: + DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received " + "from remote machine %s pipe %s fnum 0x%x!\n", + (unsigned int)prhdr->pkt_type, + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum)); + return NT_STATUS_INVALID_INFO_CLASS; + } + if (prhdr->pkt_type != expected_pkt_type) { + DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s " + "pipe %s fnum %x got an unexpected RPC packet " + "type - %u, not %u\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum, + prhdr->pkt_type, + expected_pkt_type)); + return NT_STATUS_INVALID_INFO_CLASS; } - return True; + + /* Do this just before return - we don't want to modify any rpc header + data before now as we may have needed to do cryptographic actions on + it before. */ + + if ((prhdr->pkt_type == RPC_BINDACK) && !(prhdr->flags & RPC_FLG_LAST)) { + DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), " + "setting fragment first/last ON.\n")); + prhdr->flags |= RPC_FLG_FIRST|RPC_FLG_LAST; + } + + return NT_STATUS_OK; } +/**************************************************************************** + Ensure we eat the just processed pdu from the current_pdu prs_struct. + Normally the frag_len and buffer size will match, but on the first trans + reply there is a theoretical chance that buffer size > frag_len, so we must + deal with that. + ****************************************************************************/ + +static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu) +{ + uint32 current_pdu_len = prs_data_size(current_pdu); + + if (current_pdu_len < prhdr->frag_len) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* Common case. */ + if (current_pdu_len == (uint32)prhdr->frag_len) { + prs_mem_free(current_pdu); + prs_init(current_pdu, 0, prs_get_mem_context(current_pdu), UNMARSHALL); + /* Make current_pdu dynamic with no memory. */ + prs_give_memory(current_pdu, 0, 0, True); + return NT_STATUS_OK; + } + + /* + * Oh no ! More data in buffer than we processed in current pdu. + * Cheat. Move the data down and shrink the buffer. + */ + + memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len, + current_pdu_len - prhdr->frag_len); + + /* Remember to set the read offset back to zero. */ + prs_set_offset(current_pdu, 0); + + /* Shrink the buffer. */ + if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + return NT_STATUS_OK; +} /**************************************************************************** - Send data on an rpc pipe via trans, which *must* be the last fragment. - receive response data from an rpc pipe, which may be large... + Send data on an rpc pipe via trans. The prs_struct data must be the last + pdu fragment of an NDR data stream. + + Receive response data from an rpc pipe, which may be large... Read the first fragment: unfortunately have to use SMBtrans for the first bit, then SMBreadX for subsequent bits. @@ -391,41 +730,50 @@ static BOOL rpc_auth_pipe(struct rpc_pipe_client *cli, prs_struct *rdata, | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA | +------------+-----------------+-------------+---------------+-------------+ - Where the presence of the AUTH_HDR and AUTH are dependent on the + Where the presence of the AUTH_HDR and AUTH DATA are dependent on the signing & sealing being negotiated. ****************************************************************************/ -static BOOL rpc_api_pipe(struct rpc_pipe_client *cli, prs_struct *data, prs_struct *rdata, - uint8 expected_pkt_type) +static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, + prs_struct *data, /* Outgoing pdu fragment, already formatted for send. */ + prs_struct *rbuf, /* Incoming reply - return as an NDR stream. */ + uint8 expected_pkt_type) { - uint32 len; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; char *rparam = NULL; uint32 rparam_len = 0; uint16 setup[2]; - BOOL first = True; - BOOL last = True; - 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; - uint32 fragment_start = 0; uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024; - int auth_padding_len = 0; + uint32 current_rbuf_offset = 0; + prs_struct current_pdu; + +#ifdef DEVELOPER + /* Ensure we're not sending too much. */ + SMB_ASSERT(data_len <= max_data); +#endif - /* Create setup parameters - must be in native byte order. */ + /* Set up the current pdu parse struct. */ + prs_init(¤t_pdu, 0, prs_get_mem_context(rbuf), UNMARSHALL); + /* Create setup parameters - must be in native byte order. */ setup[0] = TRANSACT_DCERPCCMD; setup[1] = cli->fnum; /* Pipe file handle. */ - DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->fnum)); + DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum )); - /* Send the RPC request and receive a response. For short RPC - calls (about 1024 bytes or so) the RPC request and response - appears in a SMBtrans request and response. Larger RPC - responses are received further on. */ + /* + * Send the last (or only) fragment of an RPC request. For small + * amounts of data (about 1024 bytes or so) the RPC request and response + * appears in a SMBtrans request and response. + */ if (!cli_api_pipe(cli->cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ @@ -434,9 +782,14 @@ static BOOL rpc_api_pipe(struct rpc_pipe_client *cli, prs_struct *data, prs_stru &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->cli))); - return False; + DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x" + "returned critical error. Error was %s\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum, + cli_errstr(cli->cli))); + ret = cli_get_nt_error(cli->cli); + goto err; } /* Throw away returned params - we know we won't use them. */ @@ -444,327 +797,343 @@ static BOOL rpc_api_pipe(struct rpc_pipe_client *cli, prs_struct *data, prs_stru SAFE_FREE(rparam); if (prdata == NULL) { - DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n", - (int)cli->fnum)); - return False; + DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s " + "fnum 0x%x failed to return data.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum)); + /* Yes - some calls can truely return no data... */ + prs_mem_free(¤t_pdu); + return NT_STATUS_OK; } /* - * Give this memory as dynamically allocated to the return parse - * struct. + * Give this memory as dynamic to the current pdu. */ - prs_give_memory(rdata, prdata, rdata_len, True); - current_offset = rdata_len; - - /* This next call sets the endian bit correctly in rdata. */ + prs_give_memory(¤t_pdu, prdata, rdata_len, True); - if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) { - prs_mem_free(rdata); - return False; - } + /* Ensure we can mess with the return prs_struct. */ + SMB_ASSERT(UNMARSHALLING(rbuf)); + SMB_ASSERT(prs_data_size(rbuf) == 0); - 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; - } - } + /* Make rbuf dynamic with no memory. */ + prs_give_memory(rbuf, 0, 0, True); - if (rhdr.pkt_type == RPC_BINDNACK) { - DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->fnum)); - prs_mem_free(rdata); - return False; - } + while(1) { + RPC_HDR rhdr; + char *ret_data; + uint32 ret_data_len; - 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; + /* Ensure we have enough data for a pdu. */ + ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu); + if (!NT_STATUS_IS_OK(ret)) { + goto err; } - } - if (rhdr.pkt_type != expected_pkt_type) { - DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet " - "type - %d, not %d\n", (int)cli->fnum, - rhdr.pkt_type, expected_pkt_type)); - prs_mem_free(rdata); - return False; - } + /* We pass in rbuf here so if the alloc hint is set correctly + we can set the output size and avoid reallocs. */ + + ret = cli_pipe_validate_current_pdu(cli, &rhdr, ¤t_pdu, expected_pkt_type, + &ret_data, &ret_data_len, rbuf); - DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n", - (unsigned int)len, (unsigned int)rdata_len )); + DEBUG(10,("rpc_api_pipe: got PDU len of %u at offset %u\n", + prs_data_size(¤t_pdu), current_rbuf_offset )); - /* check if data to be sent back was too large for one SMBtrans */ - /* err status is only informational: the _real_ check is on the - length */ + if (!NT_STATUS_IS_OK(ret)) { + goto err; + } - if (len > 0) { - /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */ + if ((rhdr.flags & RPC_FLG_FIRST)) { + if (rhdr.pack_type[0] == 0) { + /* Set the data type correctly for big-endian data on the first packet. */ + DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x " + "PDU data format is big-endian.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum)); + + prs_set_endian_data(rbuf, RPC_BIG_ENDIAN); + } else { + /* Check endianness on subsequent packets. */ + if (current_pdu.bigendian_data != rbuf->bigendian_data) { + DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n", + rbuf->bigendian_data ? "big" : "little", + current_pdu.bigendian_data ? "big" : "little" )); + ret = NT_STATUS_INVALID_PARAMETER; + goto err; + } + } + } - /* Read the remaining part of the first response fragment */ + /* Now copy the data portion out of the pdu into rbuf. */ + if (!prs_force_grow(rbuf, ret_data_len)) { + ret = NT_STATUS_NO_MEMORY; + goto err; + } + memcpy(prs_data_p(rbuf)+current_rbuf_offset, ret_data, (size_t)ret_data_len); + current_rbuf_offset += ret_data_len; + + /* See if we've finished with all the data in current_pdu yet ? */ + ret = cli_pipe_reset_current_pdu(cli, &rhdr, ¤t_pdu); + if (!NT_STATUS_IS_OK(ret)) { + goto err; + } - if (!rpc_read(cli, rdata, len, ¤t_offset)) { - prs_mem_free(rdata); - return False; + if (rhdr.flags & RPC_FLG_LAST) { + break; /* We're done. */ } } - /* - * Now we have a complete PDU, check the auth struct if any was sent. - */ + DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum, + (unsigned int)prs_data_size(rbuf) )); - if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, - rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) { - prs_mem_free(rdata); - return False; - } + prs_mem_free(¤t_pdu); + return NT_STATUS_OK; - if (rhdr.auth_len != 0) { - /* - * 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 -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len); - } - - /* - * Only one rpc fragment, and it has been read. - */ + err: - if (first && last) { - DEBUG(6,("rpc_api_pipe: fragment first and last both set\n")); - return True; - } + prs_mem_free(¤t_pdu); + prs_mem_free(rbuf); + return ret; +} - /* - * Read more fragments using SMBreadX until we get one with the - * last bit set. - */ +/******************************************************************* + Creates krb5 auth bind. + ********************************************************************/ - while (!last) { - RPC_HDR_RESP rhdr_resp; - int num_read; - char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN]; - prs_struct hps; - uint8 eclass; - uint32 ecode; - - /* - * First read the header of the next PDU. - */ +static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli, + enum pipe_auth_level auth_level, + RPC_HDR_AUTH *pauth_out, + prs_struct *auth_data) +{ +#ifdef HAVE_KRB5 + int ret; + struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth; + DATA_BLOB tkt = data_blob(NULL, 0); + DATA_BLOB tkt_wrapped = data_blob(NULL, 0); - prs_init(&hps, 0, cli->cli->mem_ctx, UNMARSHALL); - prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False); + /* We may change the pad length before marshalling. */ + init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1); - num_read = cli_read(cli->cli, cli->fnum, hdr_data, 0, - RPC_HEADER_LEN+RPC_HDR_RESP_LEN); - if (cli_is_dos_error(cli->cli)) { - cli_dos_error(cli->cli, &eclass, &ecode); - if (eclass != ERRDOS && ecode != ERRmoredata) { - DEBUG(0,("rpc_api_pipe: cli_read error : %d/%d\n", eclass, ecode)); - return False; - } - } + DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n", + a->service_principal )); - DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read)); + /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */ - 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; - } + ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt, + &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED); - /* This call sets the endianness in hps. */ + if (ret) { + DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s " + "failed with %s\n", + a->service_principal, + error_message(ret) )); - if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len)) - return False; + data_blob_free(&tkt); + prs_mem_free(auth_data); + return NT_STATUS_INVALID_PARAMETER; + } - /* Ensure the endianness in rdata is set correctly - must be same as hps. */ + /* wrap that up in a nice GSS-API wrapping */ + tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); - if (hps.bigendian_data != rdata->bigendian_data) { - DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to %s\n", - rdata->bigendian_data ? "big" : "little", - hps.bigendian_data ? "big" : "little" )); - return False; - } + data_blob_free(&tkt); - 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; - } + /* Auth len in the rpc header doesn't include auth_header. */ + if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) { + data_blob_free(&tkt_wrapped); + prs_mem_free(auth_data); + return NT_STATUS_NO_MEMORY; + } - if (first) { - DEBUG(0,("rpc_api_pipe: secondary PDU rpc header has 'first' set !\n")); - return False; - } + DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n")); + dump_data(5, (const char *)tkt_wrapped.data, tkt_wrapped.length); - /* - * Now read the rest of the PDU. - */ + data_blob_free(&tkt_wrapped); + return NT_STATUS_OK; +#else + return NT_STATUS_INVALID_PARAMETER; +#endif +} - if (!rpc_read(cli, rdata, len, ¤t_offset)) { - prs_mem_free(rdata); - return False; - } +/******************************************************************* + Creates SPNEGO NTLMSSP auth bind. + ********************************************************************/ + +static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli, + enum pipe_auth_level auth_level, + RPC_HDR_AUTH *pauth_out, + prs_struct *auth_data) +{ + NTSTATUS nt_status; + DATA_BLOB null_blob = data_blob(NULL, 0); + DATA_BLOB request = data_blob(NULL, 0); + DATA_BLOB spnego_msg = data_blob(NULL, 0); - fragment_start = current_offset - len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; + /* We may change the pad length before marshalling. */ + init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1); - /* - * Verify any authentication footer. - */ + DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n")); + nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, + null_blob, + &request); - - if(!rpc_auth_pipe(cli, rdata, fragment_start, rhdr.frag_len, - rhdr.auth_len, rhdr.pkt_type, &auth_padding_len)) { - prs_mem_free(rdata); - return False; - } - - if (rhdr.auth_len != 0 ) { - - /* - * 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 -= (auth_padding_len + RPC_HDR_AUTH_LEN + rhdr.auth_len); - } + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + data_blob_free(&request); + prs_mem_free(auth_data); + return nt_status; } - return True; -} + /* Wrap this in SPNEGO. */ + spnego_msg = gen_negTokenInit(OID_NTLMSSP, request); -/******************************************************************* - creates a DCE/RPC bind request + data_blob_free(&request); - - initialises the parse structure. - - dynamically allocates the header data structure - - caller is expected to free the header data structure once used. + /* Auth len in the rpc header doesn't include auth_header. */ + if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) { + data_blob_free(&spnego_msg); + prs_mem_free(auth_data); + return NT_STATUS_NO_MEMORY; + } - ********************************************************************/ + DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n")); + dump_data(5, (const char *)spnego_msg.data, spnego_msg.length); -static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli, - prs_struct *rpc_out, - uint32 rpc_call_id, - RPC_IFACE *abstract, RPC_IFACE *transfer, - const char *my_name, const char *domain) + data_blob_free(&spnego_msg); + return NT_STATUS_OK; +} + +/******************************************************************* + Creates NTLMSSP auth bind. + ********************************************************************/ + +static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli, + enum pipe_auth_level auth_level, + RPC_HDR_AUTH *pauth_out, + prs_struct *auth_data) { - RPC_HDR hdr; - RPC_HDR_RB hdr_rb; - RPC_HDR_AUTH hdr_auth; - RPC_CONTEXT rpc_ctx; - int auth_len = 0; - int auth_type, auth_level; - size_t saved_hdr_offset = 0; + NTSTATUS nt_status; + DATA_BLOB null_blob = data_blob(NULL, 0); + DATA_BLOB request = data_blob(NULL, 0); - prs_struct auth_info; - prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */ - prs_get_mem_context(rpc_out), MARSHALL); - - if (cli->pipe_auth_flags) { - get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); - - /* - * Create the auth structs we will marshall. - */ - - init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0x00, 1); - - /* - * Now marshall the data into the temporary parse_struct. - */ - - 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")); - prs_mem_free(&auth_info); - return NT_STATUS_NO_MEMORY; - } - saved_hdr_offset = prs_offset(&auth_info); - } - - if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + /* We may change the pad length before marshalling. */ + init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1); - NTSTATUS nt_status; - DATA_BLOB null_blob = data_blob(NULL, 0); - DATA_BLOB request; + DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n")); + nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, + null_blob, + &request); - DEBUG(5, ("Processing NTLMSSP Negotiate\n")); - nt_status = ntlmssp_update(cli->ntlmssp_pipe_state, - null_blob, - &request); + if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + data_blob_free(&request); + prs_mem_free(auth_data); + return nt_status; + } - if (!NT_STATUS_EQUAL(nt_status, - NT_STATUS_MORE_PROCESSING_REQUIRED)) { - prs_mem_free(&auth_info); - return nt_status; - } + /* Auth len in the rpc header doesn't include auth_header. */ + if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) { + data_blob_free(&request); + prs_mem_free(auth_data); + return NT_STATUS_NO_MEMORY; + } - /* Auth len in the rpc header doesn't include auth_header. */ - auth_len = request.length; - prs_copy_data_in(&auth_info, (char *)request.data, request.length); + DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n")); + dump_data(5, (const char *)request.data, request.length); - DEBUG(5, ("NTLMSSP Negotiate:\n")); - dump_data(5, (const char *)request.data, request.length); + data_blob_free(&request); + return NT_STATUS_OK; +} - data_blob_free(&request); +/******************************************************************* + Creates schannel auth bind. + ********************************************************************/ - } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - RPC_AUTH_NETSEC_NEG netsec_neg; +static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli, + enum pipe_auth_level auth_level, + RPC_HDR_AUTH *pauth_out, + prs_struct *auth_data) +{ + RPC_AUTH_SCHANNEL_NEG schannel_neg; - /* Use lp_workgroup() if domain not specified */ + /* We may change the pad length before marshalling. */ + init_rpc_hdr_auth(pauth_out, RPC_SCHANNEL_AUTH_TYPE, (int)auth_level, 0, 1); - if (!domain || !domain[0]) { - DEBUG(10,("create_rpc_bind_req: no domain; assuming my own\n")); - domain = lp_workgroup(); - } + /* Use lp_workgroup() if domain not specified */ - init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name); + if (!cli->domain || !cli->domain[0]) { + cli->domain = lp_workgroup(); + } - /* - * Now marshall the data into the temporary parse_struct. - */ + init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname()); - if(!smb_io_rpc_auth_netsec_neg("netsec_neg", - &netsec_neg, &auth_info, 0)) { - DEBUG(0,("Failed to marshall RPC_AUTH_NETSEC_NEG.\n")); - prs_mem_free(&auth_info); - return NT_STATUS_NO_MEMORY; - } + /* + * Now marshall the data into the auth parse_struct. + */ - /* Auth len in the rpc header doesn't include auth_header. */ - auth_len = prs_offset(&auth_info) - saved_hdr_offset; + if(!smb_io_rpc_auth_schannel_neg("schannel_neg", + &schannel_neg, auth_data, 0)) { + DEBUG(0,("Failed to marshall RPC_AUTH_SCHANNEL_NEG.\n")); + prs_mem_free(auth_data); + return NT_STATUS_NO_MEMORY; } + return NT_STATUS_OK; +} + +/******************************************************************* + Creates the internals of a DCE/RPC bind request or alter context PDU. + ********************************************************************/ + +static NTSTATUS create_bind_or_alt_ctx_internal(uint8 pkt_type, + prs_struct *rpc_out, + uint32 rpc_call_id, + RPC_IFACE *abstract, + RPC_IFACE *transfer, + RPC_HDR_AUTH *phdr_auth, + prs_struct *pauth_info) +{ + RPC_HDR hdr; + RPC_HDR_RB hdr_rb; + RPC_CONTEXT rpc_ctx; + uint16 auth_len = prs_offset(pauth_info); + uint8 ss_padding_len = 0; + uint16 frag_len = 0; + /* create the RPC context. */ - init_rpc_context(&rpc_ctx, 0 /* context id */, - abstract, transfer); + init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer); /* create the bind request RPC_HDR_RB */ - init_rpc_hdr_rb(&hdr_rb, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx); + init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx); + + /* Start building the frag length. */ + frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb); + + /* Do we need to pad ? */ + if (auth_len) { + uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb); + if (data_len % 8) { + ss_padding_len = 8 - (data_len % 8); + phdr_auth->auth_pad_len = ss_padding_len; + } + frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len; + } /* Create the request RPC_HDR */ - init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id, - RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb) + prs_offset(&auth_info), - auth_len); + init_rpc_hdr(&hdr, pkt_type, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, frag_len, auth_len); /* Marshall the RPC header */ if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) { - DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n")); - prs_mem_free(&auth_info); + DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n")); return NT_STATUS_NO_MEMORY; } /* 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")); - prs_mem_free(&auth_info); + DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n")); return NT_STATUS_NO_MEMORY; } @@ -773,363 +1142,453 @@ static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli, */ if(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")); - prs_mem_free(&auth_info); + if (ss_padding_len) { + unsigned char pad[8]; + memset(pad, '\0', 8); + if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) { + DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n")); + return NT_STATUS_NO_MEMORY; + } + } + + if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) { + DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n")); + return NT_STATUS_NO_MEMORY; + } + + + if(!prs_append_prs_data( rpc_out, pauth_info)) { + DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n")); return NT_STATUS_NO_MEMORY; } } - prs_mem_free(&auth_info); + return NT_STATUS_OK; } /******************************************************************* - 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. + Creates a DCE/RPC bind request. ********************************************************************/ -static NTSTATUS create_rpc_bind_resp(struct rpc_pipe_client *cli, - uint32 rpc_call_id, - prs_struct *rpc_out) +static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli, + prs_struct *rpc_out, + uint32 rpc_call_id, + RPC_IFACE *abstract, RPC_IFACE *transfer, + enum pipe_auth_type auth_type, + enum pipe_auth_level auth_level) { - NTSTATUS nt_status; - RPC_HDR hdr; RPC_HDR_AUTH hdr_auth; - RPC_HDR_AUTHA hdr_autha; - DATA_BLOB ntlmssp_null_response = data_blob(NULL, 0); - DATA_BLOB ntlmssp_reply; - int auth_type, auth_level; - - /* The response is picked up from the internal cache, - where it was placed by the rpc_auth_pipe() code */ - nt_status = ntlmssp_update(cli->ntlmssp_pipe_state, - ntlmssp_null_response, - &ntlmssp_reply); - - if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - return nt_status; - } + prs_struct auth_info; + NTSTATUS ret = NT_STATUS_OK; - /* Create the request RPC_HDR */ - init_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id, - RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN + ntlmssp_reply.length, - ntlmssp_reply.length ); - - /* Marshall it. */ - if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) { - DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR.\n")); - data_blob_free(&ntlmssp_reply); - return NT_STATUS_NO_MEMORY; - } + ZERO_STRUCT(hdr_auth); + prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL); - get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); - - /* Create the request RPC_HDR_AUTHA */ - init_rpc_hdr_auth(&hdr_auth, auth_type, auth_level, 0, 0x0014a0c0); - init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, &hdr_auth); + switch (auth_type) { + case PIPE_AUTH_TYPE_SCHANNEL: + ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info); + if (!NT_STATUS_IS_OK(ret)) { + prs_mem_free(&auth_info); + return ret; + } + break; - 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")); - data_blob_free(&ntlmssp_reply); - return NT_STATUS_NO_MEMORY; - } + case PIPE_AUTH_TYPE_NTLMSSP: + ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info); + if (!NT_STATUS_IS_OK(ret)) { + prs_mem_free(&auth_info); + return ret; + } + break; - /* - * Append the auth data to the outgoing buffer. - */ + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info); + if (!NT_STATUS_IS_OK(ret)) { + prs_mem_free(&auth_info); + return ret; + } + break; - if(!prs_copy_data_in(rpc_out, (char *)ntlmssp_reply.data, ntlmssp_reply.length)) { - DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n")); - data_blob_free(&ntlmssp_reply); - return NT_STATUS_NO_MEMORY; + case PIPE_AUTH_TYPE_KRB5: + ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info); + if (!NT_STATUS_IS_OK(ret)) { + prs_mem_free(&auth_info); + return ret; + } + break; + + case PIPE_AUTH_TYPE_NONE: + break; + + default: + /* "Can't" happen. */ + return NT_STATUS_INVALID_INFO_CLASS; } - data_blob_free(&ntlmssp_reply); - return NT_STATUS_OK; -} + ret = create_bind_or_alt_ctx_internal(RPC_BIND, + rpc_out, + rpc_call_id, + abstract, + transfer, + &hdr_auth, + &auth_info); + prs_mem_free(&auth_info); + return ret; +} /******************************************************************* - Creates a DCE/RPC request. + Create and add the NTLMSSP sign/seal auth header and data. ********************************************************************/ -static uint32 create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, int auth_len, uint8 flags, uint32 oldid, uint32 data_left) +static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli, + RPC_HDR *phdr, + uint32 ss_padding_len, + prs_struct *outgoing_pdu) { - uint32 alloc_hint; - RPC_HDR hdr; - RPC_HDR_REQ hdr_req; - uint32 callid = oldid ? oldid : get_rpc_call_id(); + RPC_HDR_AUTH auth_info; + NTSTATUS status; + DATA_BLOB auth_blob = data_blob(NULL, 0); + uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; - DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n", op_num, data_len)); + if (!cli->auth.a_u.ntlmssp_state) { + return NT_STATUS_INVALID_PARAMETER; + } - /* create the rpc header RPC_HDR */ - init_rpc_hdr(&hdr, RPC_REQUEST, flags, - callid, data_len, auth_len); + /* Init and marshall the auth header. */ + init_rpc_hdr_auth(&auth_info, + map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type), + cli->auth.auth_level, + ss_padding_len, + 1 /* context id. */); - /* - * The alloc hint should be the amount of data, not including - * RPC headers & footers. - */ + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) { + DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n")); + data_blob_free(&auth_blob); + return NT_STATUS_NO_MEMORY; + } + + switch (cli->auth.auth_level) { + case PIPE_AUTH_LEVEL_PRIVACY: + /* Data portion is encrypted. */ + status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state, + prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, + data_and_pad_len, + prs_data_p(outgoing_pdu), + (size_t)prs_offset(outgoing_pdu), + &auth_blob); + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&auth_blob); + return status; + } + break; + + case PIPE_AUTH_LEVEL_INTEGRITY: + /* Data is signed. */ + status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state, + prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, + data_and_pad_len, + prs_data_p(outgoing_pdu), + (size_t)prs_offset(outgoing_pdu), + &auth_blob); + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&auth_blob); + return status; + } + break; + + default: + /* Can't happen. */ + smb_panic("bad auth level"); + /* Notreached. */ + return NT_STATUS_INVALID_PARAMETER; + } - if (auth_len != 0) - alloc_hint = data_len - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len; - else - alloc_hint = data_len - RPC_HEADER_LEN; + /* Finally marshall the blob. */ + + if (!prs_copy_data_in(outgoing_pdu, auth_blob.data, NTLMSSP_SIG_SIZE)) { + DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n", + (unsigned int)NTLMSSP_SIG_SIZE)); + data_blob_free(&auth_blob); + return NT_STATUS_NO_MEMORY; + } + + data_blob_free(&auth_blob); + return NT_STATUS_OK; +} - DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n", - data_len, auth_len, alloc_hint)); +/******************************************************************* + Create and add the schannel sign/seal auth header and data. + ********************************************************************/ - /* Create the rpc request RPC_HDR_REQ */ - init_rpc_hdr_req(&hdr_req, alloc_hint, op_num); +static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli, + RPC_HDR *phdr, + uint32 ss_padding_len, + prs_struct *outgoing_pdu) +{ + RPC_HDR_AUTH auth_info; + RPC_AUTH_SCHANNEL_CHK verf; + struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth; + char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN; + size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; + + if (!sas) { + return NT_STATUS_INVALID_PARAMETER; + } - /* stream-time... */ - if(!smb_io_rpc_hdr("hdr ", &hdr, rpc_out, 0)) - return 0; + /* Init and marshall the auth header. */ + init_rpc_hdr_auth(&auth_info, + map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type), + cli->auth.auth_level, + ss_padding_len, + 1 /* context id. */); - if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, rpc_out, 0)) - return 0; + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) { + DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n")); + return NT_STATUS_NO_MEMORY; + } - if (prs_offset(rpc_out) != RPC_HEADER_LEN + RPC_HDR_REQ_LEN) - return 0; + switch (cli->auth.auth_level) { + case PIPE_AUTH_LEVEL_PRIVACY: + case PIPE_AUTH_LEVEL_INTEGRITY: + DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n", + sas->seq_num)); + + schannel_encode(sas, + cli->auth.auth_level, + SENDER_IS_INITIATOR, + &verf, + data_p, + data_and_pad_len); + + sas->seq_num++; + break; + + default: + /* Can't happen. */ + smb_panic("bad auth level"); + /* Notreached. */ + return NT_STATUS_INVALID_PARAMETER; + } - return callid; + /* Finally marshall the blob. */ + smb_io_rpc_auth_schannel_chk("", + RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN, + &verf, + outgoing_pdu, + 0); + + return NT_STATUS_OK; } /******************************************************************* - Puts an auth header into an rpc request. + Calculate how much data we're going to send in this packet, also + work out any sign/seal padding length. ********************************************************************/ -static BOOL create_auth_hdr(prs_struct *outgoing_packet, - int auth_type, - int auth_level, int padding) +static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, + uint32 data_left, + uint16 *p_frag_len, + uint16 *p_auth_len, + uint32 *p_ss_padding) { - RPC_HDR_AUTH hdr_auth; + uint32 data_space, data_len; + + switch (cli->auth.auth_level) { + case PIPE_AUTH_LEVEL_NONE: + case PIPE_AUTH_LEVEL_CONNECT: + data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN; + data_len = MIN(data_space, data_left); + *p_ss_padding = 0; + *p_auth_len = 0; + *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len; + return data_len; + + case PIPE_AUTH_LEVEL_INTEGRITY: + case PIPE_AUTH_LEVEL_PRIVACY: + /* Treat the same for all authenticated rpc requests. */ + switch(cli->auth.auth_type) { + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + case PIPE_AUTH_TYPE_NTLMSSP: + *p_auth_len = NTLMSSP_SIG_SIZE; + break; + case PIPE_AUTH_TYPE_SCHANNEL: + *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN; + break; + default: + smb_panic("bad auth type"); + break; + } - init_rpc_hdr_auth(&hdr_auth, auth_type, 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; + data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - + RPC_HDR_AUTH_LEN - *p_auth_len; + + data_len = MIN(data_space, data_left); + if (data_len % 8) { + *p_ss_padding = 8 - (data_len % 8); + } + *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */ + data_len + *p_ss_padding + /* data plus padding. */ + RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */ + return data_len; + + default: + smb_panic("bad auth level"); + /* Notreached. */ + return 0; } - return True; } -/** - * Send a request on an RPC pipe and get a response. - * - * @param data NDR contents of the request to be sent. - * @param rdata Unparsed NDR response data. -**/ +/******************************************************************* + External interface. + Does an rpc request on a pipe. Incoming data is NDR encoded in in_data. + Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's + and deals with signing/sealing details. + ********************************************************************/ -BOOL rpc_api_pipe_req_int(struct rpc_pipe_client *cli, uint8 op_num, - prs_struct *data, prs_struct *rdata) +NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, + uint8 op_num, + prs_struct *in_data, + prs_struct *out_data) { - uint32 auth_len, real_auth_len, auth_hdr_len, max_data, data_left, data_sent; - NTSTATUS nt_status; - BOOL ret = False; - uint32 callid = 0; - fstring dump_name; - - auth_len = 0; - real_auth_len = 0; - auth_hdr_len = 0; + NTSTATUS ret; + uint32 data_left = prs_offset(in_data); + uint32 alloc_hint = prs_offset(in_data); + uint32 data_sent_thistime = 0; + uint32 current_data_offset = 0; + uint32 call_id = get_rpc_call_id(); + char pad[8]; + prs_struct outgoing_pdu; + + memset(pad, '\0', 8); + + if (cli->max_xmit_frag < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) { + /* Server is screwed up ! */ + return NT_STATUS_INVALID_PARAMETER; + } - if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; - } - if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; - } - auth_hdr_len = RPC_HDR_AUTH_LEN; + if (data_left == 0) { + /* Caller is screwed up ! */ + return NT_STATUS_INVALID_PARAMETER; } - /* - * 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_hdr_len - auth_len - 8; - - for (data_left = prs_offset(data), data_sent = 0; data_left > 0;) { - prs_struct outgoing_packet; - prs_struct sec_blob; - uint32 data_len, send_size; + prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL); + + while (1) { + RPC_HDR hdr; + RPC_HDR_REQ hdr_req; + uint16 auth_len = 0; + uint16 frag_len = 0; uint8 flags = 0; - uint32 auth_padding = 0; - DATA_BLOB sign_blob; + uint32 ss_padding = 0; - /* - * how much will we send this time - */ - send_size = MIN(data_left, max_data); + data_sent_thistime = calculate_data_len_tosend(cli, data_left, + &frag_len, &auth_len, &ss_padding); - if (!prs_init(&sec_blob, send_size, /* will need at least this much */ - cli->cli->mem_ctx, MARSHALL)) { - DEBUG(0,("Could not malloc %u bytes", - send_size+auth_padding)); - return False; + if (current_data_offset == 0) { + flags = RPC_FLG_FIRST; } - if(!prs_append_some_prs_data(&sec_blob, data, - data_sent, send_size)) { - DEBUG(0,("Failed to append data to netsec blob\n")); - prs_mem_free(&sec_blob); - return False; + if (data_sent_thistime == data_left) { + flags |= RPC_FLG_LAST; } - /* - * 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. - */ + /* Create and marshall the header and request header. */ + init_rpc_hdr(&hdr, RPC_REQUEST, flags, call_id, frag_len, auth_len); - if (cli->pipe_auth_flags) { - size_t data_and_padding_size; - int auth_type; - int auth_level; - prs_align_uint64(&sec_blob); + if(!smb_io_rpc_hdr("hdr ", &hdr, &outgoing_pdu, 0)) { + prs_mem_free(&outgoing_pdu); + return NT_STATUS_NO_MEMORY; + } - get_auth_type_level(cli->pipe_auth_flags, &auth_type, &auth_level); + /* Create the rpc request RPC_HDR_REQ */ + init_rpc_hdr_req(&hdr_req, alloc_hint, op_num); + + if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, &outgoing_pdu, 0)) { + prs_mem_free(&outgoing_pdu); + return NT_STATUS_NO_MEMORY; + } - data_and_padding_size = prs_offset(&sec_blob); - auth_padding = data_and_padding_size - send_size; + /* Copy in the data, plus any ss padding. */ + if (!prs_append_some_prs_data(&outgoing_pdu, in_data, current_data_offset, data_sent_thistime)) { + prs_mem_free(&outgoing_pdu); + return NT_STATUS_NO_MEMORY; + } - /* insert the auth header */ - - if(!create_auth_hdr(&sec_blob, auth_type, auth_level, auth_padding)) { - prs_mem_free(&sec_blob); - return False; + /* Copy the sign/seal padding data. */ + if (ss_padding) { + if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding)) { + prs_mem_free(&outgoing_pdu); + return NT_STATUS_NO_MEMORY; } - - /* create an NTLMSSP signature */ - if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - /* - * Seal the outgoing data if requested. - */ - if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { - - nt_status = ntlmssp_seal_packet(cli->ntlmssp_pipe_state, - (unsigned char*)prs_data_p(&sec_blob), - data_and_padding_size, - &sign_blob); - if (!NT_STATUS_IS_OK(nt_status)) { - prs_mem_free(&sec_blob); - return False; + } + + /* Generate any auth sign/seal and add the auth footer. */ + if (auth_len) { + switch (cli->auth.auth_type) { + case PIPE_AUTH_TYPE_NONE: + break; + case PIPE_AUTH_TYPE_NTLMSSP: + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu); + if (!NT_STATUS_IS_OK(ret)) { + prs_mem_free(&outgoing_pdu); + return ret; } - } - else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - - nt_status = ntlmssp_sign_packet(cli->ntlmssp_pipe_state, - (unsigned char*)prs_data_p(&sec_blob), - data_and_padding_size, &sign_blob); - if (!NT_STATUS_IS_OK(nt_status)) { - prs_mem_free(&sec_blob); - return False; + break; + case PIPE_AUTH_TYPE_SCHANNEL: + ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu); + if (!NT_STATUS_IS_OK(ret)) { + prs_mem_free(&outgoing_pdu); + return ret; } - } - - - /* write auth footer onto the packet */ - real_auth_len = sign_blob.length; - - prs_copy_data_in(&sec_blob, (char *)sign_blob.data, sign_blob.length); - data_blob_free(&sign_blob); - - } - else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - size_t parse_offset_marker; - RPC_AUTH_NETSEC_CHK verf; - DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num)); - - netsec_encode(&cli->auth_info, - cli->pipe_auth_flags, - SENDER_IS_INITIATOR, - &verf, - prs_data_p(&sec_blob), - data_and_padding_size); - - cli->auth_info.seq_num++; - - /* write auth footer onto the packet */ - - parse_offset_marker = prs_offset(&sec_blob); - if (!smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, - &verf, &sec_blob, 0)) - { - prs_mem_free(&sec_blob); - return False; - } - real_auth_len = prs_offset(&sec_blob) - parse_offset_marker; + break; + default: + smb_panic("bad auth type"); + break; /* notreached */ } } - data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(&sec_blob); + /* Actually send the packet. */ + if (flags & RPC_FLG_LAST) { + /* Last packet - send the data, get the reply and return. */ + ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE); + prs_mem_free(&outgoing_pdu); - /* - * Malloc parse struct to hold it (and enough for alignments). - */ - if(!prs_init(&outgoing_packet, data_len + 8, - cli->cli->mem_ctx, MARSHALL)) { - DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len )); - return False; - } - - if (data_left == prs_offset(data)) - flags |= RPC_FLG_FIRST; + + if (DEBUGLEVEL >= 50) { + pstring dump_name; + /* Also capture received data */ + slprintf(dump_name, sizeof(dump_name) - 1, "%s/reply_%s_%d", + dyn_LOGFILEBASE, cli->pipe_name, op_num); + prs_dump(dump_name, op_num, out_data); + } - if (data_left <= max_data) - flags |= RPC_FLG_LAST; - /* - * Write out the RPC header and the request header. - */ - if(!(callid = create_rpc_request(&outgoing_packet, op_num, - data_len, real_auth_len, flags, - callid, data_left))) { - DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n")); - prs_mem_free(&outgoing_packet); - prs_mem_free(&sec_blob); - return False; + return ret; + } else { + /* More packets to come - write and continue. */ + ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */ + prs_data_p(&outgoing_pdu), + (off_t)0, + (size_t)hdr.frag_len); + + if (num_written != hdr.frag_len) { + prs_mem_free(&outgoing_pdu); + return cli_get_nt_error(cli->cli); + } } - prs_append_prs_data(&outgoing_packet, &sec_blob); - prs_mem_free(&sec_blob); - - DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, - prs_offset(&outgoing_packet))); - - if (flags & RPC_FLG_LAST) - ret = rpc_api_pipe(cli, &outgoing_packet, - rdata, RPC_RESPONSE); - else { - cli_write(cli->cli, cli->fnum, 0x0008, - prs_data_p(&outgoing_packet), - data_sent, data_len); + current_data_offset += data_sent_thistime; + data_left -= data_sent_thistime; + + /* Reset the marshalling position back to zero. */ + if (!prs_set_offset(&outgoing_pdu, 0)) { + prs_mem_free(&outgoing_pdu); + return NT_STATUS_NO_MEMORY; } - prs_mem_free(&outgoing_packet); - data_sent += send_size; - data_left -= send_size; } - /* Also capture received data */ - slprintf(dump_name, sizeof(dump_name) - 1, "reply_%s", - cli_pipe_get_name(cli->cli)); - prs_dump(dump_name, op_num, rdata); - - return ret; -} - -BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num, - prs_struct *data, prs_struct *rdata) -{ - return rpc_api_pipe_req_int(&cli->pipes[pipe_idx], op_num, - data, rdata); } - - +#if 0 /**************************************************************************** Set the handle state. ****************************************************************************/ @@ -1174,56 +1633,10 @@ static BOOL rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli, return state_set; } +#endif /**************************************************************************** - check the rpc bind acknowledge response -****************************************************************************/ - -int get_pipe_index( const char *pipe_name ) -{ - int pipe_idx = 0; - - while (pipe_names[pipe_idx].client_pipe != NULL) { - if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) - return pipe_idx; - pipe_idx++; - }; - - return -1; -} - - -/**************************************************************************** - check the rpc bind acknowledge response -****************************************************************************/ - -const char* get_pipe_name_from_index( const int pipe_index ) -{ - - if ( (pipe_index < 0) || (pipe_index >= PI_MAX_PIPES) ) - return NULL; - - return pipe_names[pipe_index].client_pipe; -} - -/**************************************************************************** - Check to see if this pipe index points to one of - the pipes only supported by Win2k - ****************************************************************************/ - -BOOL is_win2k_pipe( const int pipe_idx ) -{ - switch ( pipe_idx ) - { - case PI_LSARPC_DS: - return True; - } - - return False; -} - -/**************************************************************************** - check the rpc bind acknowledge response + Check the rpc bind acknowledge response. ****************************************************************************/ static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer) @@ -1235,10 +1648,10 @@ static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE * } DEBUG(5,("Bind Abstract Syntax: ")); - dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax), + dump_data(5, (char*)&pipe_names[pipe_idx].abstr_syntax, sizeof(pipe_names[pipe_idx].abstr_syntax)); DEBUG(5,("Bind Transfer Syntax: ")); - dump_data(5, (char*)&(pipe_names[pipe_idx].trans_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 */ @@ -1250,7 +1663,7 @@ static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE * } /**************************************************************************** - check the rpc bind acknowledge response + Check the rpc bind acknowledge response. ****************************************************************************/ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer) @@ -1259,7 +1672,6 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)")); } - # if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */ if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) && !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) ) @@ -1284,396 +1696,500 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC return False; } - /* lkclXXXX only accept one result: check the result(s) */ 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)); } - DEBUG(5,("bind_rpc_pipe: accepted!\n")); + DEBUG(5,("check_bind_response: accepted!\n")); return True; } -/**************************************************************************** - Create and send the third packet in an RPC auth. -****************************************************************************/ +/******************************************************************* + 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. + ********************************************************************/ -static BOOL rpc_send_auth_reply(struct rpc_pipe_client *cli, - prs_struct *rdata, uint32 rpc_call_id) +static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli, + uint32 rpc_call_id, + enum pipe_auth_type auth_type, + enum pipe_auth_level auth_level, + DATA_BLOB *pauth_blob, + prs_struct *rpc_out) { - prs_struct rpc_out; - ssize_t ret; + RPC_HDR hdr; + RPC_HDR_AUTH hdr_auth; + uint32 pad = 0; + + /* Create the request RPC_HDR */ + init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, + RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length, + pauth_blob->length ); + + /* Marshall it. */ + if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) { + DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n")); + return NT_STATUS_NO_MEMORY; + } - prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */ - cli->cli->mem_ctx, MARSHALL); + /* + I'm puzzled about this - seems to violate the DCE RPC auth rules, + about padding - shouldn't this pad to length 8 ? JRA. + */ - if (!NT_STATUS_IS_OK(create_rpc_bind_resp(cli, rpc_call_id, - &rpc_out))) { - return False; + /* 4 bytes padding. */ + if (!prs_uint32("pad", rpc_out, 0, &pad)) { + DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n")); + return NT_STATUS_NO_MEMORY; } - if ((ret = cli_write(cli->cli, cli->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)); - prs_mem_free(&rpc_out); - return False; + /* Create the request RPC_HDR_AUTHA */ + init_rpc_hdr_auth(&hdr_auth, + map_pipe_auth_type_to_rpc_auth_type(auth_type), + auth_level, 0, 1); + + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) { + DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n")); + return NT_STATUS_NO_MEMORY; } - prs_mem_free(&rpc_out); - return True; + /* + * Append the auth data to the outgoing buffer. + */ + + if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) { + DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n")); + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; } /**************************************************************************** - Do an rpc bind. + Create and send the third packet in an RPC auth. ****************************************************************************/ -static BOOL rpc_pipe_bind(struct rpc_pipe_client *cli) +static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, + RPC_HDR *phdr, + prs_struct *rbuf, + uint32 rpc_call_id, + enum pipe_auth_type auth_type, + enum pipe_auth_level auth_level) { - RPC_IFACE abstract; - RPC_IFACE transfer; + DATA_BLOB server_response = data_blob(NULL,0); + DATA_BLOB client_reply = data_blob(NULL,0); + RPC_HDR_AUTH hdr_auth; + NTSTATUS nt_status; prs_struct rpc_out; - prs_struct rdata; - uint32 rpc_call_id; - char buffer[MAX_PDU_FRAG_LEN]; + ssize_t ret; - if ( (cli->pipe_idx < 0) || (cli->pipe_idx >= PI_MAX_PIPES) ) - return False; + if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) { + return NT_STATUS_INVALID_PARAMETER; + } - DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->fnum, - pipe_names[cli->pipe_idx].client_pipe)); + /* Process the returned NTLMSSP blob first. */ + if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) { + return NT_STATUS_INVALID_PARAMETER; + } - if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) - return False; + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) { + return NT_STATUS_INVALID_PARAMETER; + } - prs_init(&rpc_out, 0, cli->cli->mem_ctx, MARSHALL); + /* TODO - check auth_type/auth_level match. */ - /* - * Use the MAX_PDU_FRAG_LEN buffer to store the bind request. - */ + server_response = data_blob(NULL, phdr->auth_len); + prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len); + + nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, + server_response, + &client_reply); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n")); + return nt_status; + } - prs_give_memory( &rpc_out, buffer, sizeof(buffer), False); + prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL); - rpc_call_id = get_rpc_call_id(); + nt_status = create_rpc_bind_auth3(cli, rpc_call_id, + auth_type, auth_level, + &client_reply, &rpc_out); - if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - NTSTATUS nt_status; - fstring password; + if (!NT_STATUS_IS_OK(nt_status)) { + prs_mem_free(&rpc_out); + data_blob_free(&client_reply); + data_blob_free(&server_response); + return nt_status; + } - DEBUG(5, ("NTLMSSP authenticated pipe selected\n")); + /* 8 here is named pipe message mode. */ + ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0, + (size_t)prs_offset(&rpc_out)); - nt_status = ntlmssp_client_start(&cli->ntlmssp_pipe_state); - - if (!NT_STATUS_IS_OK(nt_status)) - return False; + if (ret != (ssize_t)prs_offset(&rpc_out)) { + DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret)); + prs_mem_free(&rpc_out); + data_blob_free(&client_reply); + data_blob_free(&server_response); + return cli_get_nt_error(cli->cli); + } - /* Currently the NTLMSSP code does not implement NTLM2 correctly for signing or sealing */ + DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s " + "fnum 0x%x sent auth3 response ok.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum)); - cli->ntlmssp_pipe_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + prs_mem_free(&rpc_out); + data_blob_free(&client_reply); + data_blob_free(&server_response); + return NT_STATUS_OK; +} - nt_status = ntlmssp_set_username(cli->ntlmssp_pipe_state, - cli->user_name); - if (!NT_STATUS_IS_OK(nt_status)) - return False; +/******************************************************************* + Creates a DCE/RPC bind alter context authentication request which + may contain a spnego auth blobl + ********************************************************************/ - nt_status = ntlmssp_set_domain(cli->ntlmssp_pipe_state, - cli->domain); - if (!NT_STATUS_IS_OK(nt_status)) - return False; +static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id, + RPC_IFACE *abstract, + RPC_IFACE *transfer, + enum pipe_auth_level auth_level, + const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */ + prs_struct *rpc_out) +{ + RPC_HDR_AUTH hdr_auth; + prs_struct auth_info; + NTSTATUS ret = NT_STATUS_OK; - if (cli->pwd.null_pwd) { - nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, - NULL); - if (!NT_STATUS_IS_OK(nt_status)) - return False; - } else { - pwd_get_cleartext(&cli->pwd, password); - nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, - password); - if (!NT_STATUS_IS_OK(nt_status)) - return False; - } + ZERO_STRUCT(hdr_auth); + prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL); - if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { - cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } + /* We may change the pad length before marshalling. */ + init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1); - if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) { - cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + if (pauth_blob->length) { + if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) { + prs_mem_free(&auth_info); + return NT_STATUS_NO_MEMORY; } - } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - cli->auth_info.seq_num = 0; } - /* Marshall the outgoing data. */ - create_rpc_bind_req(cli, &rpc_out, rpc_call_id, - &abstract, &transfer, - global_myname(), cli->domain); - - /* Initialize the incoming data struct. */ - prs_init(&rdata, 0, cli->cli->mem_ctx, UNMARSHALL); - - /* send data on \PIPE\. receive a response */ - if (rpc_api_pipe(cli, &rpc_out, &rdata, RPC_BINDACK)) { - RPC_HDR_BA hdr_ba; - - DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n")); - - 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; - } + ret = create_bind_or_alt_ctx_internal(RPC_ALTCONT, + rpc_out, + rpc_call_id, + abstract, + transfer, + &hdr_auth, + &auth_info); + prs_mem_free(&auth_info); + return ret; +} - if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) { - DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n")); - prs_mem_free(&rdata); - return False; - } +/******************************************************************* + Third leg of the SPNEGO bind mechanism - sends alter context PDU + and gets a response. + ********************************************************************/ - cli->max_xmit_frag = hdr_ba.bba.max_tsize; - cli->max_recv_frag = hdr_ba.bba.max_rsize; +static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, + RPC_HDR *phdr, + prs_struct *rbuf, + uint32 rpc_call_id, + RPC_IFACE *abstract, + RPC_IFACE *transfer, + enum pipe_auth_type auth_type, + enum pipe_auth_level auth_level) +{ + DATA_BLOB server_spnego_response = data_blob(NULL,0); + DATA_BLOB server_ntlm_response = data_blob(NULL,0); + DATA_BLOB client_reply = data_blob(NULL,0); + DATA_BLOB tmp_blob = data_blob(NULL, 0); + RPC_HDR_AUTH hdr_auth; + NTSTATUS nt_status; + prs_struct rpc_out; - /* - * If we're doing NTLMSSP auth we need to send a reply to - * the bind-ack to complete the 3-way challenge response - * handshake. - */ + if (!phdr->auth_len || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) { + return NT_STATUS_INVALID_PARAMETER; + } - if ((cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) - && !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(&rdata); - return True; + /* Process the returned NTLMSSP blob first. */ + if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) { + return NT_STATUS_INVALID_PARAMETER; } - return False; -} + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) { + return NT_STATUS_INVALID_PARAMETER; + } -/**************************************************************************** - Open a session. - ****************************************************************************/ + server_spnego_response = data_blob(NULL, phdr->auth_len); + prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len); + + /* The server might give us back two challenges - tmp_blob is for the second. */ + if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) { + data_blob_free(&server_spnego_response); + data_blob_free(&server_ntlm_response); + data_blob_free(&tmp_blob); + return NT_STATUS_INVALID_PARAMETER; + } -BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx) -{ - int fnum; - struct rpc_pipe_client *cli_pipe; + /* We're finished with the server spnego response and the tmp_blob. */ + data_blob_free(&server_spnego_response); + data_blob_free(&tmp_blob); - SMB_ASSERT(cli->pipes[pipe_idx].fnum == 0); + nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, + server_ntlm_response, + &client_reply); - /* The pipe index must fall within our array */ + /* Finished with the server_ntlm response */ + data_blob_free(&server_ntlm_response); - SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update using server blob failed.\n")); + data_blob_free(&client_reply); + return nt_status; + } - if (cli->capabilities & CAP_NT_SMBS) { - if ((fnum = cli_nt_create(cli, &pipe_names[pipe_idx].client_pipe[5], DESIRED_ACCESS_PIPE)) == -1) { - DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n", - &pipe_names[pipe_idx].client_pipe[5], cli->desthost, cli_errstr(cli))); - return False; - } + /* SPNEGO wrap the client reply. */ + tmp_blob = spnego_gen_auth(client_reply); + data_blob_free(&client_reply); + client_reply = tmp_blob; + tmp_blob = data_blob(NULL,0); /* Ensure it's safe to free this just in case. */ - cli->pipes[pipe_idx].fnum = (uint16)fnum; - } else { - if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, O_CREAT|O_RDWR, DENY_NONE)) == -1) { - DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n", - pipe_names[pipe_idx].client_pipe, cli->desthost, cli_errstr(cli))); - return False; - } + /* Now prepare the alter context pdu. */ + prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL); - cli->pipes[pipe_idx].fnum = (uint16)fnum; + nt_status = create_rpc_alter_context(rpc_call_id, + abstract, + transfer, + auth_level, + &client_reply, + &rpc_out); - /**************** Set Named Pipe State ***************/ - if (!rpc_pipe_set_hnd_state(&cli->pipes[pipe_idx], pipe_names[pipe_idx].client_pipe, 0x4300)) { - DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n", - cli_errstr(cli))); - cli_close(cli, cli->pipes[pipe_idx].fnum); - cli->pipes[pipe_idx].fnum = 0; - return False; - } + data_blob_free(&client_reply); + + if (!NT_STATUS_IS_OK(nt_status)) { + prs_mem_free(&rpc_out); + return nt_status; } - cli_pipe = &cli->pipes[pipe_idx]; - cli_pipe->pipe_idx = pipe_idx; - cli_pipe->cli = cli; - cli_pipe->pipe_auth_flags = cli->pipe_auth_flags; - memcpy(&cli_pipe->auth_info.sess_key, - cli->sess_key, sizeof(cli->sess_key)); + /* Initialize the returning data struct. */ + prs_mem_free(rbuf); + prs_init(rbuf, 0, cli->cli->mem_ctx, UNMARSHALL); - /******************* bind request on pipe *****************/ + nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP); + if (!NT_STATUS_IS_OK(nt_status)) { + prs_mem_free(&rpc_out); + return nt_status; + } - if (!rpc_pipe_bind(&cli->pipes[pipe_idx])) { - DEBUG(2,("cli_nt_session_open: rpc bind to %s failed\n", - get_pipe_name_from_index(pipe_idx))); - cli_close(cli, cli->pipes[pipe_idx].fnum); - cli->pipes[pipe_idx].fnum = 0; - return False; + prs_mem_free(&rpc_out); + + /* Get the auth blob from the reply. */ + if(!smb_io_rpc_hdr("rpc_hdr ", phdr, rbuf, 0)) { + DEBUG(0,("rpc_finish_spnego_ntlmssp_bind: Failed to unmarshall RPC_HDR.\n")); + return NT_STATUS_BUFFER_TOO_SMALL; } - cli->pipe_idx = pipe_idx; + if (!prs_set_offset(rbuf, phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) { + return NT_STATUS_INVALID_PARAMETER; + } - /* - * Setup the remote server name prefixed by \ and the machine account name. - */ + if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rbuf, 0)) { + return NT_STATUS_INVALID_PARAMETER; + } - fstrcpy(cli->srv_name_slash, "\\\\"); - fstrcat(cli->srv_name_slash, cli->desthost); - strupper_m(cli->srv_name_slash); + server_spnego_response = data_blob(NULL, phdr->auth_len); + prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len); - fstrcpy(cli->clnt_name_slash, "\\\\"); - fstrcat(cli->clnt_name_slash, global_myname()); - strupper_m(cli->clnt_name_slash); + /* Check we got a valid auth response. */ + if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, &tmp_blob)) { + data_blob_free(&server_spnego_response); + data_blob_free(&tmp_blob); + return NT_STATUS_INVALID_PARAMETER; + } - fstrcpy(cli->mach_acct, global_myname()); - fstrcat(cli->mach_acct, "$"); - strupper_m(cli->mach_acct); + data_blob_free(&server_spnego_response); + data_blob_free(&tmp_blob); - /* Remember which pipe we're talking to */ - fstrcpy(cli->pipe_name, pipe_names[pipe_idx].client_pipe); + DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to " + "remote machine %s pipe %s fnum 0x%x.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum)); - return True; + return NT_STATUS_OK; } - /**************************************************************************** - Open a session to the NETLOGON pipe using schannel. - - (Assumes that the netlogon pipe is already open) - ****************************************************************************/ + Do an rpc bind. +****************************************************************************/ -NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan, - const uchar trust_password[16]) +static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, + enum pipe_auth_type auth_type, + enum pipe_auth_level auth_level) { - NTSTATUS result; - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; - - cli_nt_netlogon_netsec_session_close(cli); - - if (lp_client_schannel() != False) - neg_flags |= NETLOGON_NEG_SCHANNEL; + RPC_HDR hdr; + RPC_HDR_BA hdr_ba; + RPC_IFACE abstract; + RPC_IFACE transfer; + prs_struct rpc_out; + prs_struct rbuf; + uint32 rpc_call_id; + NTSTATUS status; - result = cli_nt_setup_creds(cli, sec_chan, trust_password, - &neg_flags, 2); + DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n", + (unsigned int)cli->fnum, + cli->pipe_name, + (unsigned int)auth_type, + (unsigned int)auth_level )); - if (!NT_STATUS_IS_OK(result)) { - cli_nt_session_close(cli); - return result; + if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) { + return NT_STATUS_INVALID_PARAMETER; } - if ((lp_client_schannel() == True) && - ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { + prs_init(&rpc_out, 0, cli->cli->mem_ctx, MARSHALL); - DEBUG(3, ("Server did not offer schannel\n")); - cli_nt_session_close(cli); - return NT_STATUS_UNSUCCESSFUL; - } + rpc_call_id = get_rpc_call_id(); - if ((lp_client_schannel() == False) || - ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { - return NT_STATUS_OK; - - /* keep the existing connection to NETLOGON open */ + /* Marshall the outgoing data. */ + status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id, + &abstract, &transfer, + auth_type, + auth_level); + if (!NT_STATUS_IS_OK(status)) { + prs_mem_free(&rpc_out); + return status; } - cli->netlogon_pipe = cli->pipes[PI_NETLOGON]; - ZERO_STRUCT(cli->pipes[PI_NETLOGON]); + /* Initialize the incoming data struct. */ + prs_init(&rbuf, 0, cli->cli->mem_ctx, UNMARSHALL); - /* Server offered schannel, so try it. */ + /* send data on \PIPE\. receive a response */ + status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK); + if (!NT_STATUS_IS_OK(status)) { + prs_mem_free(&rpc_out); + return status; + } - memcpy(cli->pipes[PI_NETLOGON].auth_info.sess_key, cli->sess_key, - sizeof(cli->pipes[PI_NETLOGON].auth_info.sess_key)); + prs_mem_free(&rpc_out); - cli->pipe_auth_flags = AUTH_PIPE_NETSEC; - cli->pipe_auth_flags |= AUTH_PIPE_SIGN; - cli->pipe_auth_flags |= AUTH_PIPE_SEAL; + DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s " + "fnum 0x%x bind request returned ok.\n", + cli->cli->desthost, + cli->pipe_name, + (unsigned int)cli->fnum)); + + /* Unmarshall the RPC header */ + if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) { + DEBUG(0,("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n")); + prs_mem_free(&rbuf); + return NT_STATUS_BUFFER_TOO_SMALL; + } - return cli_nt_session_open(cli, PI_NETLOGON) ? - NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; -} + if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rbuf, 0)) { + DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n")); + prs_mem_free(&rbuf); + return NT_STATUS_BUFFER_TOO_SMALL; + } + if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) { + DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n")); + prs_mem_free(&rbuf); + return NT_STATUS_BUFFER_TOO_SMALL; + } -NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, int auth_flags, - const uchar trust_password[16]) -{ - NTSTATUS result; - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; - cli->pipe_auth_flags = 0; + cli->max_xmit_frag = hdr_ba.bba.max_tsize; + cli->max_recv_frag = hdr_ba.bba.max_rsize; - if (lp_client_schannel() == False) { - return NT_STATUS_OK; - } + /* For authenticated binds we may need to do 3 or 4 leg binds. */ + switch(auth_type) { - if (!cli_nt_session_open(cli, PI_NETLOGON)) { - DEBUG(0, ("Could not initialise %s\n", - get_pipe_name_from_index(PI_NETLOGON))); - return NT_STATUS_UNSUCCESSFUL; - } + case PIPE_AUTH_TYPE_NONE: + case PIPE_AUTH_TYPE_SCHANNEL: + /* Bind complete. */ + break; - neg_flags |= NETLOGON_NEG_SCHANNEL; + case PIPE_AUTH_TYPE_NTLMSSP: + /* Need to send AUTH3 packet - no reply. */ + status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id, + auth_type, auth_level); + if (!NT_STATUS_IS_OK(status)) { + prs_mem_free(&rbuf); + return status; + } + break; + + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + /* Need to send alter context request and reply. */ + status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id, + &abstract, &transfer, + auth_type, auth_level); + if (!NT_STATUS_IS_OK(status)) { + prs_mem_free(&rbuf); + return status; + } + break; - result = cli_nt_setup_creds(cli, sec_chan, trust_password, - &neg_flags, 2); + case PIPE_AUTH_TYPE_KRB5: + /* */ - if (!(neg_flags & NETLOGON_NEG_SCHANNEL) - && lp_client_schannel() == True) { - DEBUG(1, ("Could not negotiate SCHANNEL with the DC!\n")); - result = NT_STATUS_UNSUCCESSFUL; + default: + DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n", + (unsigned int)auth_type )); + prs_mem_free(&rbuf); + return NT_STATUS_INVALID_INFO_CLASS; } - if (!NT_STATUS_IS_OK(result)) { - ZERO_STRUCT(cli->pipes[cli->pipe_idx].auth_info.sess_key); - ZERO_STRUCT(cli->sess_key); - cli->pipe_auth_flags = 0; - cli_nt_session_close(cli); - return result; - } + /* Pipe is bound - set up auth_type and auth_level data. */ - memcpy(cli->pipes[PI_NETLOGON].auth_info.sess_key, cli->sess_key, - sizeof(cli->pipes[PI_NETLOGON].auth_info.sess_key)); - - cli_close(cli, cli->pipes[PI_NETLOGON].fnum); - cli->pipes[PI_NETLOGON].fnum = 0; - cli->pipe_idx = -1; - - /* doing schannel, not per-user auth */ - cli->pipe_auth_flags = auth_flags; + cli->auth.auth_type = auth_type; + cli->auth.auth_level = auth_level; + prs_mem_free(&rbuf); return NT_STATUS_OK; } -const char *cli_pipe_get_name(struct cli_state *cli) -{ - return cli->pipe_name; -} +/**************************************************************************** + Open a named pipe over SMB to a remote server. + ****************************************************************************/ -static struct rpc_pipe_client *cli_rpc_open(struct cli_state *cli, - int pipe_idx) +static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) { TALLOC_CTX *mem_ctx; struct rpc_pipe_client *result; int fnum; - /* The pipe index must fall within our array */ + *perr = NT_STATUS_NO_MEMORY; + + /* The pipe name index must fall within our array */ SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); mem_ctx = talloc_init("struct rpc_pipe_client"); - if (mem_ctx == NULL) return NULL; + if (mem_ctx == NULL) { + return NULL; + } - result = TALLOC_P(mem_ctx, struct rpc_pipe_client); - if (result == NULL) return NULL; + result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client); + if (result == NULL) { + return NULL; + } result->mem_ctx = mem_ctx; - fnum = cli_nt_create(cli, &pipe_names[pipe_idx].client_pipe[5], - DESIRED_ACCESS_PIPE); + result->pipe_name = cli_get_pipe_name(pipe_idx); + + fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE); if (fnum == -1) { - DEBUG(0,("cli_rpc_open failed on pipe %s " + DEBUG(0,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s " "to machine %s. Error was %s\n", - &pipe_names[pipe_idx].client_pipe[5], cli->desthost, + result->pipe_name, cli->desthost, cli_errstr(cli))); + *perr = cli_get_nt_error(cli); talloc_destroy(result->mem_ctx); return NULL; } @@ -1681,91 +2197,440 @@ static struct rpc_pipe_client *cli_rpc_open(struct cli_state *cli, result->fnum = fnum; result->cli = cli; result->pipe_idx = pipe_idx; + result->auth.auth_type = PIPE_AUTH_TYPE_NONE; + result->auth.auth_level = PIPE_AUTH_LEVEL_NONE; + + if (pipe_idx == PI_NETLOGON) { + /* Set up a netlogon credential chain for a netlogon pipe. */ + result->dc = TALLOC_ZERO_P(mem_ctx, struct dcinfo); + if (result->dc == NULL) { + talloc_destroy(result->mem_ctx); + return NULL; + } + } + + DLIST_ADD(cli->pipe_list, result); + *perr = NT_STATUS_OK; return result; } -struct rpc_pipe_client *cli_rpc_open_noauth(struct cli_state *cli, - int pipe_idx) +/**************************************************************************** + Open a named pipe to an SMB server and bind anonymously. + ****************************************************************************/ + +struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) { struct rpc_pipe_client *result; - result = cli_rpc_open(cli, pipe_idx); - if (result == NULL) return NULL; - - result->max_xmit_frag = 0; - result->pipe_auth_flags = 0; + result = cli_rpc_pipe_open(cli, pipe_idx, perr); + if (result == NULL) { + return NULL; + } - if (!rpc_pipe_bind(result)) { - DEBUG(0, ("rpc_pipe_bind failed\n")); - talloc_destroy(result->mem_ctx); + *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE); + if (!NT_STATUS_IS_OK(*perr)) { + DEBUG(0, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n", + cli_get_pipe_name(pipe_idx), nt_errstr(*perr) )); + cli_rpc_pipe_close(result); return NULL; } + DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n", + result->pipe_name, cli->desthost )); + return result; } -struct rpc_pipe_client *cli_rpc_open_ntlmssp(struct cli_state *cli, - int pipe_idx, - const char *domain, - const char *username, - const char *password) +/**************************************************************************** + Free function for NTLMSSP auth. + ****************************************************************************/ + +static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth) +{ + if (auth->a_u.ntlmssp_state) { + ntlmssp_end(&auth->a_u.ntlmssp_state); + auth->a_u.ntlmssp_state = NULL; + } +} + +/**************************************************************************** + Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP + ****************************************************************************/ + +static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli, + int pipe_idx, + enum pipe_auth_type auth_type, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + NTSTATUS *perr) { struct rpc_pipe_client *result; + NTLMSSP_STATE *ntlmssp_state = NULL; - result = cli_rpc_open(cli, pipe_idx); - if (result == NULL) return NULL; + result = cli_rpc_pipe_open(cli, pipe_idx, perr); + if (result == NULL) { + return NULL; + } - result->max_xmit_frag = 0; - result->pipe_auth_flags = - AUTH_PIPE_NTLMSSP|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL; + result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free; + result->domain = domain; result->user_name = username; pwd_set_cleartext(&result->pwd, password); - if (!rpc_pipe_bind(result)) { - DEBUG(0, ("cli_rpc_pipe_bind failed\n")); - talloc_destroy(result->mem_ctx); - return NULL; + *perr = ntlmssp_client_start(&ntlmssp_state); + if (!NT_STATUS_IS_OK(*perr)) { + goto err; + } + + result->auth.a_u.ntlmssp_state = ntlmssp_state; + + *perr = ntlmssp_set_username(ntlmssp_state, cli->user_name); + if (!NT_STATUS_IS_OK(*perr)) { + goto err; + } + + *perr = ntlmssp_set_domain(ntlmssp_state, cli->domain); + if (!NT_STATUS_IS_OK(*perr)) { + goto err; } + if (cli->pwd.null_pwd) { + *perr = ntlmssp_set_password(ntlmssp_state, NULL); + if (!NT_STATUS_IS_OK(*perr)) { + goto err; + } + } else { + *perr = ntlmssp_set_password(ntlmssp_state, password); + if (!NT_STATUS_IS_OK(*perr)) { + goto err; + } + } + + /* Turn off sign+seal to allow selected auth level to turn it back on. */ + ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL); + + if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN; + } + + *perr = rpc_pipe_bind(result, auth_type, auth_level); + if (!NT_STATUS_IS_OK(*perr)) { + DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n", + nt_errstr(*perr) )); + goto err; + } + + DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to machine %s and" + "bound NTLMSSP as user %s\\%s.\n", + result->pipe_name, cli->desthost, + domain, username )); + return result; + + err: + + cli_rpc_pipe_close(result); + return NULL; } -struct rpc_pipe_client *cli_rpc_open_schannel(struct cli_state *cli, - int pipe_idx, - const uchar session_key[16], - const char *domain) +/**************************************************************************** + External interface. + Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10) + ****************************************************************************/ + +struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli, + int pipe_idx, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + NTSTATUS *perr) +{ + return cli_rpc_pipe_open_ntlmssp_internal(cli, + pipe_idx, + PIPE_AUTH_TYPE_NTLMSSP, + auth_level, + domain, + username, + password, + perr); +} + +/**************************************************************************** + External interface. + Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9) + ****************************************************************************/ + +struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, + int pipe_idx, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + NTSTATUS *perr) +{ + return cli_rpc_pipe_open_ntlmssp_internal(cli, + pipe_idx, + PIPE_AUTH_TYPE_SPNEGO_NTLMSSP, + auth_level, + domain, + username, + password, + perr); +} + +/**************************************************************************** + Open a netlogon pipe and get the schannel session key. + ****************************************************************************/ + +static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, + const char *domain, + NTSTATUS *perr) +{ + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + struct rpc_pipe_client *netlogon_pipe = NULL; + uint32 sec_chan_type = 0; + char machine_pwd[16]; + fstring machine_account; + + netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr); + if (!netlogon_pipe) { + return NULL; + } + + /* Get the machine account credentials from secrets.tdb. */ + if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) { + DEBUG(0, ("get_schannel_session_key: could not fetch " + "trust account password for domain '%s'\n", + domain)); + cli_rpc_pipe_close(netlogon_pipe); + *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + return NULL; + } + + if ( IS_DC ) { + fstrcpy( machine_account, lp_workgroup() ); + } else { + /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */ + if (strequal(domain, lp_workgroup())) { + fstrcpy(machine_account, global_myname()); + } else { + fstrcpy(machine_account, domain); + } + } + + *perr = rpccli_netlogon_setup_creds(netlogon_pipe, + cli->desthost, + domain, + machine_account, + machine_pwd, + sec_chan_type, + &neg_flags); + + if (!NT_STATUS_IS_OK(*perr)) { + DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds " + "failed with result %s\n", + nt_errstr(*perr) )); + cli_rpc_pipe_close(netlogon_pipe); + return NULL; + } + + if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) { + DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n", + cli->desthost)); + cli_rpc_pipe_close(netlogon_pipe); + *perr = NT_STATUS_INVALID_NETWORK_RESPONSE; + return NULL; + } + + return netlogon_pipe; +} + +/**************************************************************************** + External interface. + Open a named pipe to an SMB server and bind using schannel (bind type 68) + using session_key. sign and seal. + ****************************************************************************/ + +struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli, + int pipe_idx, + enum pipe_auth_level auth_level, + const char *domain, + const struct dcinfo *pdc, + NTSTATUS *perr) { struct rpc_pipe_client *result; - result = cli_rpc_open(cli, pipe_idx); - if (result == NULL) return NULL; - - result->max_xmit_frag = 0; - result->pipe_auth_flags = - AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL; + result = cli_rpc_pipe_open(cli, pipe_idx, perr); + if (result == NULL) { + return NULL; + } + + result->auth.a_u.schannel_auth = TALLOC_ZERO_P(result->mem_ctx, struct schannel_auth_struct); + if (!result->auth.a_u.schannel_auth) { + cli_rpc_pipe_close(result); + *perr = NT_STATUS_NO_MEMORY; + return NULL; + } + result->domain = domain; - memcpy(result->auth_info.sess_key, session_key, 16); + memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16); - if (!rpc_pipe_bind(result)) { - DEBUG(0, ("cli_rpc_pipe_bind failed\n")); - talloc_destroy(result->mem_ctx); + *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level); + if (!NT_STATUS_IS_OK(*perr)) { + DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n", + nt_errstr(*perr) )); + cli_rpc_pipe_close(result); return NULL; } + /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */ + if (result->dc) { + *result->dc = *pdc; + } + + DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s " + "for domain %s " + "and bound using schannel.\n", + result->pipe_name, cli->desthost, domain )); + return result; } -void cli_rpc_close(struct rpc_pipe_client *cli_pipe) +/**************************************************************************** + Open a named pipe to an SMB server and bind using schannel (bind type 68). + Fetch the session key ourselves using a temporary netlogon pipe. + ****************************************************************************/ + +struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, + int pipe_idx, + enum pipe_auth_level auth_level, + const char *domain, + NTSTATUS *perr) { - if (!cli_close(cli_pipe->cli, cli_pipe->fnum)) - DEBUG(0,("cli_rpc_open failed on pipe %s " - "to machine %s. Error was %s\n", - &pipe_names[cli_pipe->pipe_idx].client_pipe[5], - cli_pipe->cli->desthost, - cli_errstr(cli_pipe->cli))); + struct rpc_pipe_client *netlogon_pipe = NULL; + struct rpc_pipe_client *result = NULL; + + netlogon_pipe = get_schannel_session_key(cli, domain, perr); + if (!netlogon_pipe) { + DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session " + "key from server %s for domain %s.\n", + cli->desthost, domain )); + return NULL; + } + + result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx, + auth_level, + domain, netlogon_pipe->dc, perr); + + /* Now we've bound using the session key we can close the netlog pipe. */ + cli_rpc_pipe_close(netlogon_pipe); + + return result; +} + +/**************************************************************************** + Free function for the kerberos spcific data. + ****************************************************************************/ + +static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a) +{ + data_blob_free(&a->a_u.kerberos_auth->session_key); +} - talloc_destroy(cli_pipe->mem_ctx); +/**************************************************************************** + Open a named pipe to an SMB server and bind using krb5 (bind type 16). + ****************************************************************************/ + +struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, + int pipe_idx, + enum pipe_auth_level auth_level, + const char *service_princ, + const char *username, + const char *password, + NTSTATUS *perr) +{ +#ifdef HAVE_KRB5 + struct rpc_pipe_client *result; + + result = cli_rpc_pipe_open(cli, pipe_idx, perr); + if (result == NULL) { + return NULL; + } + + /* Default service principal is "host/server@realm" */ + if (!service_princ) { + service_princ = talloc_asprintf(result->mem_ctx, "host/%s@%s", + cli->desthost, lp_realm() ); + if (!service_princ) { + cli_rpc_pipe_close(result); + return NULL; + } + } + + /* Only get a new TGT if username/password are given. */ + if (username && password) { + int ret = kerberos_kinit_password(username, password, 0, NULL, NULL); + if (ret) { + cli_rpc_pipe_close(result); + return NULL; + } + } + + result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(cli->mem_ctx, struct kerberos_auth_struct); + if (!result->auth.a_u.kerberos_auth) { + cli_rpc_pipe_close(result); + *perr = NT_STATUS_NO_MEMORY; + return NULL; + } + + result->auth.a_u.kerberos_auth->service_principal = service_princ; + result->auth.cli_auth_data_free_func = kerberos_auth_struct_free; + + *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level); + if (!NT_STATUS_IS_OK(*perr)) { + DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n", + nt_errstr(*perr) )); + cli_rpc_pipe_close(result); + return NULL; + } + + return result; +#else + DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n")); + return NULL; +#endif } +#if 0 /* Moved to libsmb/clientgen.c */ +/**************************************************************************** + External interface. + Close an open named pipe over SMB. Free any authentication data. + ****************************************************************************/ + +void cli_rpc_pipe_close(struct rpc_pipe_client *cli) +{ + if (!cli_close(cli->cli, cli->fnum)) { + DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s " + "to machine %s. Error was %s\n", + cli->pipe_name), + cli->cli->desthost, + cli_errstr(cli->cli))); + } + + if (cli->auth.cli_auth_data_free_func) { + (*cli->auth.cli_auth_data_free_func)(&cli->auth); + } + DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n", + cli->pipe_name, cli->cli->desthost )); + + DLIST_REMOVE(cli->cli->pipe_list, cli); + talloc_destroy(cli->mem_ctx); +} +#endif -- cgit From 515be57030e5675581e86fec17546569e9f12ac9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Oct 2005 23:02:59 +0000 Subject: r10745: Fix artificial 1k restriction. Jeremy. (This used to be commit bb1ba9a9089b38bf400d48b992f7977ce926aeaf) --- source3/rpc_client/cli_pipe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index df34b1c3d9..c29ee0c067 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -748,7 +748,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, uint32 data_len = data ? prs_offset(data) : 0; char *prdata = NULL; uint32 rdata_len = 0; - uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : 1024; + uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN; uint32 current_rbuf_offset = 0; prs_struct current_pdu; @@ -2546,6 +2546,8 @@ static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a) /**************************************************************************** Open a named pipe to an SMB server and bind using krb5 (bind type 16). + The idea is this can be called with service_princ, username and password all + NULL so long as the caller has a TGT. ****************************************************************************/ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, -- cgit From 7fe605c97e8f90beedd891429752ff9fd902b1c8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 5 Oct 2005 23:11:34 +0000 Subject: r10747: Remove overparanoid check that broke RPC function calls with no [in] parameters. (This used to be commit 03a3caaddd5bf28a059d4edb5e55031f7e5de94a) --- source3/rpc_client/cli_pipe.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c29ee0c067..01f9a86c87 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1467,11 +1467,6 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, return NT_STATUS_INVALID_PARAMETER; } - if (data_left == 0) { - /* Caller is screwed up ! */ - return NT_STATUS_INVALID_PARAMETER; - } - prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL); while (1) { -- cgit From 20d36c1c8d84731d0e78fdcb723c3330095ed5de Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Oct 2005 16:51:10 +0000 Subject: r10778: Allow schannel setup over NTLMSSP authenticated pipes. Jeremy. (This used to be commit ed62720f897ebf10f5ae50a3e9cf7788c9570183) --- source3/rpc_client/cli_pipe.c | 106 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 01f9a86c87..0a2e664489 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2498,6 +2498,112 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl return result; } +/**************************************************************************** + Open a named pipe to an SMB server and bind using schannel (bind type 68). + Fetch the session key ourselves using a temporary netlogon pipe. This + version uses an ntlmssp auth bound netlogon pipe to get the key. + ****************************************************************************/ + +static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli, + const char *domain, + const char *username, + const char *password, + NTSTATUS *perr) +{ + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + struct rpc_pipe_client *netlogon_pipe = NULL; + uint32 sec_chan_type = 0; + char machine_pwd[16]; + fstring machine_account; + + netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr); + if (!netlogon_pipe) { + return NULL; + } + + /* Get the machine account credentials from secrets.tdb. */ + if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) { + DEBUG(0, ("get_schannel_session_key_auth_ntlmssp: could not fetch " + "trust account password for domain '%s'\n", + domain)); + cli_rpc_pipe_close(netlogon_pipe); + *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + return NULL; + } + + if ( IS_DC ) { + fstrcpy( machine_account, lp_workgroup() ); + } else { + /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */ + if (strequal(domain, lp_workgroup())) { + fstrcpy(machine_account, global_myname()); + } else { + fstrcpy(machine_account, domain); + } + } + + *perr = rpccli_netlogon_setup_creds(netlogon_pipe, + cli->desthost, + domain, + machine_account, + machine_pwd, + sec_chan_type, + &neg_flags); + + if (!NT_STATUS_IS_OK(*perr)) { + DEBUG(3,("get_schannel_session_key_auth_ntlmssp: rpccli_netlogon_setup_creds " + "failed with result %s\n", + nt_errstr(*perr) )); + cli_rpc_pipe_close(netlogon_pipe); + return NULL; + } + + if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) { + DEBUG(3, ("get_schannel_session_key_auth_ntlmssp: Server %s did not offer schannel\n", + cli->desthost)); + cli_rpc_pipe_close(netlogon_pipe); + *perr = NT_STATUS_INVALID_NETWORK_RESPONSE; + return NULL; + } + + return netlogon_pipe; +} + +/**************************************************************************** + Open a named pipe to an SMB server and bind using schannel (bind type 68). + Fetch the session key ourselves using a temporary netlogon pipe. This version + uses an ntlmssp bind to get the session key. + ****************************************************************************/ + +struct rpc_pipe_client *cli_rpc_pipe_open_ntlmttp_auth_schannel(struct cli_state *cli, + int pipe_idx, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + NTSTATUS *perr) +{ + struct rpc_pipe_client *netlogon_pipe = NULL; + struct rpc_pipe_client *result = NULL; + + netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username, password, perr); + if (!netlogon_pipe) { + DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session " + "key from server %s for domain %s.\n", + cli->desthost, domain )); + return NULL; + } + + result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx, + auth_level, + domain, netlogon_pipe->dc, perr); + + /* Now we've bound using the session key we can close the netlog pipe. */ + cli_rpc_pipe_close(netlogon_pipe); + + return result; +} + /**************************************************************************** Open a named pipe to an SMB server and bind using schannel (bind type 68). Fetch the session key ourselves using a temporary netlogon pipe. -- cgit From 6de37ee5f5d015904e650df3112cf725ab0f1cb8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Oct 2005 17:43:18 +0000 Subject: r10780: Fix typo noticed by Volker. Jeremy. (This used to be commit 76408ddd5bec22bbbee2236101bf65b407d2c664) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0a2e664489..2e6f42b0e6 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2575,7 +2575,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ uses an ntlmssp bind to get the session key. ****************************************************************************/ -struct rpc_pipe_client *cli_rpc_pipe_open_ntlmttp_auth_schannel(struct cli_state *cli, +struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli, int pipe_idx, enum pipe_auth_level auth_level, const char *domain, -- cgit From a23b680a087b3e7cc2c5bfd11b4f8814a089e858 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Oct 2005 04:53:30 +0000 Subject: r10801: Janitor for tpot - remember to keep 3.0 in sync. Jeremy. (This used to be commit 92fa541f6e92c03a49372ff73f9790afa2c0151c) --- source3/rpc_client/cli_pipe.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2e6f42b0e6..3b411272c3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2636,6 +2636,8 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, return result; } +#ifdef HAVE_KRB5 + /**************************************************************************** Free function for the kerberos spcific data. ****************************************************************************/ @@ -2645,6 +2647,8 @@ static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a) data_blob_free(&a->a_u.kerberos_auth->session_key); } +#endif + /**************************************************************************** Open a named pipe to an SMB server and bind using krb5 (bind type 16). The idea is this can be called with service_princ, username and password all -- cgit From 8d7c88667190fe286971ac4fffb64ee5bd9eeeb0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Oct 2005 03:24:00 +0000 Subject: r11137: Compile with only 2 warnings (I'm still working on that code) on a gcc4 x86_64 box. Jeremy. (This used to be commit d720867a788c735e56d53d63265255830ec21208) --- source3/rpc_client/cli_pipe.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3b411272c3..e1e502794c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -250,7 +250,7 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN); data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len); - full_packet_data = prs_data_p(current_pdu); + full_packet_data = (unsigned char *)prs_data_p(current_pdu); full_packet_data_len = prhdr->frag_len - auth_len; /* Pull the auth header and the following data into a blob. */ @@ -265,7 +265,7 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr return NT_STATUS_BUFFER_TOO_SMALL; } - auth_blob.data = prs_data_p(current_pdu) + prs_offset(current_pdu); + auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu); auth_blob.length = auth_len; switch (cli->auth.auth_level) { @@ -1143,7 +1143,7 @@ static NTSTATUS create_bind_or_alt_ctx_internal(uint8 pkt_type, if(auth_len != 0) { if (ss_padding_len) { - unsigned char pad[8]; + char pad[8]; memset(pad, '\0', 8); if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) { DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n")); @@ -1272,9 +1272,9 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli, case PIPE_AUTH_LEVEL_PRIVACY: /* Data portion is encrypted. */ status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state, - prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, + (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, data_and_pad_len, - prs_data_p(outgoing_pdu), + (unsigned char *)prs_data_p(outgoing_pdu), (size_t)prs_offset(outgoing_pdu), &auth_blob); if (!NT_STATUS_IS_OK(status)) { @@ -1286,9 +1286,9 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli, case PIPE_AUTH_LEVEL_INTEGRITY: /* Data is signed. */ status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state, - prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, + (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, data_and_pad_len, - prs_data_p(outgoing_pdu), + (unsigned char *)prs_data_p(outgoing_pdu), (size_t)prs_offset(outgoing_pdu), &auth_blob); if (!NT_STATUS_IS_OK(status)) { @@ -1306,7 +1306,7 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli, /* Finally marshall the blob. */ - if (!prs_copy_data_in(outgoing_pdu, auth_blob.data, NTLMSSP_SIG_SIZE)) { + if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) { DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n", (unsigned int)NTLMSSP_SIG_SIZE)); data_blob_free(&auth_blob); @@ -2391,7 +2391,7 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; - char machine_pwd[16]; + unsigned char machine_pwd[16]; fstring machine_account; netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr); @@ -2513,7 +2513,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; - char machine_pwd[16]; + unsigned char machine_pwd[16]; fstring machine_account; netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr); -- cgit From e12eb25793606e4dba7d0d24cd4959209f5d8a30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Nov 2005 20:26:24 +0000 Subject: r11491: If we get a reject ensure we're printing out the server/domain/machine a/c we were asking for. Jeremy. (This used to be commit 3ba5d02cff61d64dbab1fef28f74ea6509f4f8e9) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index e1e502794c..bed1ef843a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2430,8 +2430,8 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, if (!NT_STATUS_IS_OK(*perr)) { DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds " - "failed with result %s\n", - nt_errstr(*perr) )); + "failed with result %s to server %s, domain %s, machine account %s.\n", + nt_errstr(*perr), cli->desthost, domain, machine_account )); cli_rpc_pipe_close(netlogon_pipe); return NULL; } -- cgit From 5678e4abb04e546735bff4907854ca32094a5b71 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Nov 2005 00:03:55 +0000 Subject: r11492: Fix bug #3224 (I hope). Correctly use machine_account_name and client_name when doing netlogon credential setup. Jeremy. (This used to be commit 37e6ef9389041f58eada167239fd022f01c5fecb) --- source3/rpc_client/cli_pipe.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bed1ef843a..7965aee807 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2409,7 +2409,7 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, return NULL; } - if ( IS_DC ) { + if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) { fstrcpy( machine_account, lp_workgroup() ); } else { /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */ @@ -2421,9 +2421,10 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, } *perr = rpccli_netlogon_setup_creds(netlogon_pipe, - cli->desthost, - domain, - machine_account, + cli->desthost, /* server name */ + domain, /* domain */ + global_myname(), /* client name */ + machine_account, /* machine account name */ machine_pwd, sec_chan_type, &neg_flags); @@ -2531,7 +2532,10 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ return NULL; } - if ( IS_DC ) { + /* if we are a DC and this is a trusted domain, then we need to use our + domain name in the net_req_auth2() request */ + + if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) { fstrcpy( machine_account, lp_workgroup() ); } else { /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */ @@ -2543,9 +2547,10 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ } *perr = rpccli_netlogon_setup_creds(netlogon_pipe, - cli->desthost, - domain, - machine_account, + cli->desthost, /* server name */ + domain, /* domain */ + global_myname(), /* client name */ + machine_account, /* machine account name */ machine_pwd, sec_chan_type, &neg_flags); -- cgit From 765daab643c2957297e71b26de515c05b04d244d Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 14 Dec 2005 04:00:58 +0000 Subject: r12225: r11729@cabra: derrell | 2005-12-13 22:59:45 -0500 1. Fix a crash bug which should have reared its ugly head ages ago, but for some reason, remained dormant until recently. The bug pertained to libsmbclient doing a structure assignment of a cli after having opened a pipe. The pipe open code makes a copy of the cli pointer that was passed to it. If the cli is later copied (and that cli pointer that was saved is no longer valid), the pipe code will cause a crash during shutdown or when the copied cli is closed. 2. The 'type' field in enumerated shares was not being set correctly with the new RPC-based mechanism for enumerating shares. (This used to be commit 62a02b8f2a1fcb66881a9c9636e0b27e3049c5a1) --- source3/rpc_client/cli_pipe.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7965aee807..41266838a8 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2150,6 +2150,15 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, /**************************************************************************** Open a named pipe over SMB to a remote server. + * + * CAVEAT CALLER OF THIS FUNCTION: + * The returned rpc_pipe_client saves a copy of the cli_state cli pointer, + * so be sure that this function is called AFTER any structure (vs pointer) + * assignment of the cli. In particular, libsmbclient does structure + * assignments of cli, which invalidates the data in the returned + * rpc_pipe_client if this function is called before the structure assignment + * of cli. + * ****************************************************************************/ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) -- cgit From 0dc59604f72fc35b527a2dc4b49b8966b2a13980 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 14 Dec 2005 18:17:05 +0000 Subject: r12236: r11740@cabra: derrell | 2005-12-14 13:16:58 -0500 check in the DEBUG message referenced in the previous commit (This used to be commit 6c04a8f9adfcd40fb0f1e1fcd4e22056ee463046) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 41266838a8..e1143e6342 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2189,7 +2189,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE); if (fnum == -1) { - DEBUG(0,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s " + DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s " "to machine %s. Error was %s\n", result->pipe_name, cli->desthost, cli_errstr(cli))); -- cgit From 76796e212c0f1dc7587be138daac9c4ef093db4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Dec 2005 00:10:59 +0000 Subject: r12275: Fix memory leak found by Mikhail Kshevetskiy and followed up by derrell@samba.org. Jeremy. (This used to be commit 5cab88f1444177129bb5521ccc4afd8869e9bf25) --- source3/rpc_client/cli_pipe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index e1143e6342..23c66acf26 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -789,6 +789,8 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, (unsigned int)cli->fnum, cli_errstr(cli->cli))); ret = cli_get_nt_error(cli->cli); + SAFE_FREE(rparam); + SAFE_FREE(prdata); goto err; } -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/rpc_client/cli_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 23c66acf26..9cc350bef1 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -927,7 +927,7 @@ static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli, /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */ ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt, - &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED); + &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL); if (ret) { DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s " @@ -2699,7 +2699,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, /* Only get a new TGT if username/password are given. */ if (username && password) { - int ret = kerberos_kinit_password(username, password, 0, NULL, NULL); + int ret = kerberos_kinit_password(username, password, 0, NULL, NULL, NULL, False, 0); if (ret) { cli_rpc_pipe_close(result); return NULL; @@ -2737,7 +2737,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, Close an open named pipe over SMB. Free any authentication data. ****************************************************************************/ -void cli_rpc_pipe_close(struct rpc_pipe_client *cli) + void cli_rpc_pipe_close(struct rpc_pipe_client *cli) { if (!cli_close(cli->cli, cli->fnum)) { DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s " -- cgit From 202bc164ca11539a62a7e894330265df90319828 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Feb 2006 21:18:23 +0000 Subject: r13641: Finish fix for #3510. Don't use client schannel when told not to, cope with a server that doesn't offer schannel also. Jeremy (This used to be commit 68005f6bdb70883eace0d9067c76c3360a803023) --- source3/rpc_client/cli_pipe.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9cc350bef1..23cc6af114 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2393,13 +2393,14 @@ struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, /**************************************************************************** Open a netlogon pipe and get the schannel session key. + Now exposed to external callers. ****************************************************************************/ -static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, +struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, const char *domain, + uint32 *pneg_flags, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; @@ -2438,7 +2439,7 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, machine_account, /* machine account name */ machine_pwd, sec_chan_type, - &neg_flags); + pneg_flags); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds " @@ -2448,7 +2449,7 @@ static struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, return NULL; } - if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) { + if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n", cli->desthost)); cli_rpc_pipe_close(netlogon_pipe); @@ -2520,9 +2521,9 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ const char *domain, const char *username, const char *password, + uint32 *pneg_flags, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; @@ -2564,7 +2565,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ machine_account, /* machine account name */ machine_pwd, sec_chan_type, - &neg_flags); + pneg_flags); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(3,("get_schannel_session_key_auth_ntlmssp: rpccli_netlogon_setup_creds " @@ -2574,7 +2575,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ return NULL; } - if ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0) { + if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { DEBUG(3, ("get_schannel_session_key_auth_ntlmssp: Server %s did not offer schannel\n", cli->desthost)); cli_rpc_pipe_close(netlogon_pipe); @@ -2599,10 +2600,12 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state const char *password, NTSTATUS *perr) { + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; - netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username, password, perr); + netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username, + password, &neg_flags, perr); if (!netlogon_pipe) { DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session " "key from server %s for domain %s.\n", @@ -2631,10 +2634,11 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, const char *domain, NTSTATUS *perr) { + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; - netlogon_pipe = get_schannel_session_key(cli, domain, perr); + netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr); if (!netlogon_pipe) { DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session " "key from server %s for domain %s.\n", -- cgit From 7f59c7fcd627d8ca5ff801266967c165465b2611 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 27 Feb 2006 18:45:44 +0000 Subject: r13722: Ensure we use the correct enumerated type. Bug #3558 from jason@ncac.gwu.edu. Jeremy. (This used to be commit 00f8b4e1aa44904c91af8eb6ac4c3f196986c339) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 23cc6af114..d3db77b3cf 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1090,7 +1090,7 @@ static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli, Creates the internals of a DCE/RPC bind request or alter context PDU. ********************************************************************/ -static NTSTATUS create_bind_or_alt_ctx_internal(uint8 pkt_type, +static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type, prs_struct *rpc_out, uint32 rpc_call_id, RPC_IFACE *abstract, -- cgit From dc93156fe96c1861f3ad072496ad223513e915e0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Mar 2006 23:20:52 +0000 Subject: r14121: We never pass NULL to the rpc_api_pipe fn so don't trigger coverity checks by testing for NULL. Jeremy. (This used to be commit 6b4484159293d725613249adbfa01472dea1c722) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d3db77b3cf..45b2e96bac 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -744,8 +744,8 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, char *rparam = NULL; uint32 rparam_len = 0; uint16 setup[2]; - char *pdata = data ? prs_data_p(data) : NULL; - uint32 data_len = data ? prs_offset(data) : 0; + char *pdata = prs_data_p(data); + uint32 data_len = prs_offset(data); char *prdata = NULL; uint32 rdata_len = 0; uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN; -- cgit From 0f0ad2992eedeb9e75ddd2c122b5a5b291ba4efe Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Mar 2006 14:58:39 +0000 Subject: r14448: * protect against NULL cli_state* pointers in cli_rpc_pipe_open() * Fix inverted logic check for machine accounts in get_md4pw() (This used to be commit a36529535dcb5a262e7627b80fb62a31240dc8ad) --- source3/rpc_client/cli_pipe.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 45b2e96bac..a2e0dab990 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2171,6 +2171,12 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe *perr = NT_STATUS_NO_MEMORY; + /* sanity check to protect against crashes */ + + if ( !cli ) { + return NT_STATUS_INVALID_HANDLE; + } + /* The pipe name index must fall within our array */ SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); -- cgit From a19949821399543a9d0924333d5efb4a8695f06f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Mar 2006 15:11:44 +0000 Subject: r14449: fix the build (sorry everyone) (This used to be commit e49ca3af8c2522aee670e6b807d7b3df31be47f6) --- source3/rpc_client/cli_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a2e0dab990..c809ac1ac7 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2174,7 +2174,8 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe /* sanity check to protect against crashes */ if ( !cli ) { - return NT_STATUS_INVALID_HANDLE; + *perr = NT_STATUS_INVALID_HANDLE; + return NULL; } /* The pipe name index must fall within our array */ -- cgit From 485a286a65d3b37f424f5701179f73c99eb9b5b9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 20 Mar 2006 19:05:44 +0000 Subject: r14585: Tighten argument list of kerberos_kinit_password again, kerberos_kinit_password_ext provides access to more options. Guenther (This used to be commit afc519530f94b420b305fc28f83c16db671d0d7f) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c809ac1ac7..afdf6f3d67 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2710,7 +2710,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, /* Only get a new TGT if username/password are given. */ if (username && password) { - int ret = kerberos_kinit_password(username, password, 0, NULL, NULL, NULL, False, 0); + int ret = kerberos_kinit_password(username, password, 0, NULL); if (ret) { cli_rpc_pipe_close(result); return NULL; -- cgit From 6e17934ee614f5f129b69898be7eceb09486a48f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 22 Mar 2006 14:41:07 +0000 Subject: r14643: Merge dcerpc_errstr from Samba 4. Might need to rework prs_dcerpc_status(). Guenther (This used to be commit 38b18f428ba941f4d9a14fa2de45cb0cd793a754) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index afdf6f3d67..37b1b2a671 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -619,7 +619,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s " "pipe %s fnum 0x%x!\n", - nt_errstr(fault_resp.status), + dcerpc_errstr(NT_STATUS_V(fault_resp.status)), cli->cli->desthost, cli->pipe_name, (unsigned int)cli->fnum)); -- cgit From 0498f3b8890ec62eeb9275a6bf685a6c3d81fce5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Apr 2006 18:00:57 +0000 Subject: r15129: Separate out mechanism and policy for NTLMSSP auth/sign/seal. With this change (and setting lanman auth = no in smb.conf) we have *identical* NTLMSSP flags to W2K3 in SPNEGO auth. Jeremy (This used to be commit 93ca3eee55297eb7fdd38fca38103ce129987e2a) --- source3/rpc_client/cli_pipe.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 37b1b2a671..11eb21df44 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2141,6 +2141,24 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return NT_STATUS_INVALID_INFO_CLASS; } + /* For NTLMSSP ensure the server gave us the auth_level we wanted. */ + if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { + if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { + if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { + DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n")); + prs_mem_free(&rbuf); + return NT_STATUS_INVALID_PARAMETER; + } + } + if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { + if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { + DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n")); + prs_mem_free(&rbuf); + return NT_STATUS_INVALID_PARAMETER; + } + } + } + /* Pipe is bound - set up auth_type and auth_level data. */ cli->auth.auth_type = auth_type; -- cgit From a6e662f5565bbdee8fcee36882a59f421ec54732 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 Jun 2006 11:58:13 +0000 Subject: r16253: Fix another host/ UPN case in (the currently unused) cli_rpc_pipe_open_krb5. Guenther (This used to be commit fa19099112490daa085bb310f2f4ed877bb22b40) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 11eb21df44..d41c1ef12a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2716,9 +2716,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, return NULL; } - /* Default service principal is "host/server@realm" */ + /* Default service principal is "desthost$@realm" */ if (!service_princ) { - service_princ = talloc_asprintf(result->mem_ctx, "host/%s@%s", + service_princ = talloc_asprintf(result->mem_ctx, "%s$@%s", cli->desthost, lp_realm() ); if (!service_princ) { cli_rpc_pipe_close(result); -- cgit From 22b52b818b9a137c0dcc86d170736b22ceddf7b7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Jun 2006 12:37:05 +0000 Subject: r16255: Fix 'net ads join' when the workgroup is set incorrectly in smb.conf. This did work before the join rewrite. Samba will have problems if you try to run any of the daemons with an incorrect workgroup but it should not fail to join. The summary is that a member server should always use it's own machine name when setting up schannel since that is the only account it has. Thanks to Volker for the discussion. (This used to be commit 95763b94f709fe1ad9e381dbc6b364c2f3759024) --- source3/rpc_client/cli_pipe.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d41c1ef12a..467e652ca9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2446,15 +2446,18 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, return NULL; } + /* A DC should use DOMAIN$ as its account name. + A member server can only use it's machine name since it + does not have an account in a trusted domain. + + We don't check the domain against lp_workgroup() here since + 'net ads join' has to continue to work with only the realm + specified in smb.conf. -- jerry */ + if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) { fstrcpy( machine_account, lp_workgroup() ); } else { - /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */ - if (strequal(domain, lp_workgroup())) { - fstrcpy(machine_account, global_myname()); - } else { - fstrcpy(machine_account, domain); - } + fstrcpy(machine_account, global_myname()); } *perr = rpccli_netlogon_setup_creds(netlogon_pipe, -- cgit From 69cee2a3ec4f39aab83a8cbf55307df182bf3065 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 Feb 2007 17:02:39 +0000 Subject: r21240: Fix longstanding Bug #4009. For the winbind cached ADS LDAP connection handling (ads_cached_connection()) we were (incorrectly) assuming that the service ticket lifetime equaled the tgt lifetime. For setups where the service ticket just lives 10 minutes, we were leaving hundreds of LDAP connections in CLOSE_WAIT state, until we fail to service entirely with "Too many open files". Also sequence_number() in winbindd_ads.c needs to delete the cached LDAP connection after the ads_do_search_retry() has failed to submit the search request (although the bind succeeded (returning an expired service ticket that we cannot delete from the memory cred cache - this will get fixed later)). Guenther (This used to be commit 7e1a84b7226fb8dcd5d34c64a3478a6d886a9a91) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 467e652ca9..547f300f3a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -927,7 +927,7 @@ static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli, /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */ ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt, - &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL); + &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL); if (ret) { DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s " -- cgit From ca072a99985eaa3036be8116027ea951abc6a759 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 16 Feb 2007 13:30:19 +0000 Subject: r21382: Important fix for winbind when using non-AD domains. Jeremy, I'm afraid you removed the "domain->initialized" from the set_dc_types_and_flags() call when the connect to PI_LSARPC_DS failed (with rev. 19148). This causes now that init_dc_connection_network is called again and again which in turn rescans the DC each time (which of course fails each time with NT_STATUS_BUFFER_TOO_SMALL). Just continue with the non-PI_LSARPC_DS scan so that the domain is initialized properly. Guenther (This used to be commit c6f63a08f55a4121cbe5aac537d2ef983dc25a97) --- source3/rpc_client/cli_pipe.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 547f300f3a..61f5ee51bd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2261,7 +2261,13 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE); if (!NT_STATUS_IS_OK(*perr)) { - DEBUG(0, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n", + int lvl = 0; + if (pipe_idx == PI_LSARPC_DS) { + /* non AD domains just don't have this pipe, avoid + * level 0 statement in that case - gd */ + lvl = 3; + } + DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n", cli_get_pipe_name(pipe_idx), nt_errstr(*perr) )); cli_rpc_pipe_close(result); return NULL; -- cgit From 56ba44766854ed7cda265bdaf85913f2a1008282 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Mar 2007 13:34:59 +0000 Subject: r22001: change prototype of dump_data(), so that it takes unsigned char * now, which matches what samba4 has. also fix all the callers to prevent compiler warnings metze (This used to be commit fa322f0cc9c26a9537ba3f0a7d4e4a25941317e7) --- source3/rpc_client/cli_pipe.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 61f5ee51bd..c7c1b7fe69 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -953,7 +953,7 @@ static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli, } DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n")); - dump_data(5, (const char *)tkt_wrapped.data, tkt_wrapped.length); + dump_data(5, tkt_wrapped.data, tkt_wrapped.length); data_blob_free(&tkt_wrapped); return NT_STATUS_OK; @@ -1003,7 +1003,7 @@ static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client } DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n")); - dump_data(5, (const char *)spnego_msg.data, spnego_msg.length); + dump_data(5, spnego_msg.data, spnego_msg.length); data_blob_free(&spnego_msg); return NT_STATUS_OK; @@ -1044,7 +1044,7 @@ static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli, } DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n")); - dump_data(5, (const char *)request.data, request.length); + dump_data(5, request.data, request.length); data_blob_free(&request); return NT_STATUS_OK; @@ -1645,10 +1645,10 @@ static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE * } DEBUG(5,("Bind Abstract Syntax: ")); - dump_data(5, (char*)&pipe_names[pipe_idx].abstr_syntax, + dump_data(5, (uint8 *)&pipe_names[pipe_idx].abstr_syntax, sizeof(pipe_names[pipe_idx].abstr_syntax)); DEBUG(5,("Bind Transfer Syntax: ")); - dump_data(5, (char*)&pipe_names[pipe_idx].trans_syntax, + dump_data(5, (uint8 *)&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 */ -- cgit From eceb926df94063e91c5abc96f52a1bc7b45ce290 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Apr 2007 12:30:23 +0000 Subject: r22092: - make spnego_parse_auth_response() more generic and not specific for NTLMSSP - it's possible that the server sends a mechOID and authdata if negResult != SPNEGO_NEG_RESULT_INCOMPLETE, but we still force the mechOID to be present if negResult == SPNEGO_NEG_RESULT_INCOMPLETE metze (This used to be commit e9f2aa22f90208a5e530ef3b68664151960a0a22) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c7c1b7fe69..ab7f0b9b47 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2002,7 +2002,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len); /* Check we got a valid auth response. */ - if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, &tmp_blob)) { + if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK, OID_NTLMSSP, &tmp_blob)) { data_blob_free(&server_spnego_response); data_blob_free(&tmp_blob); return NT_STATUS_INVALID_PARAMETER; -- cgit From b4a7b7a8889737e2891fc1176feabd4ce47f2737 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 12:16:20 +0000 Subject: r22844: Introduce const DATA_BLOB data_blob_null = { NULL, 0, NULL }; and replace all data_blob(NULL, 0) calls. (This used to be commit 3d3d61687ef00181f4f04e001d42181d93ac931e) --- source3/rpc_client/cli_pipe.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ab7f0b9b47..5f21caeccf 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -915,8 +915,8 @@ static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli, #ifdef HAVE_KRB5 int ret; struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth; - DATA_BLOB tkt = data_blob(NULL, 0); - DATA_BLOB tkt_wrapped = data_blob(NULL, 0); + DATA_BLOB tkt = data_blob_null; + DATA_BLOB tkt_wrapped = data_blob_null; /* We may change the pad length before marshalling. */ init_rpc_hdr_auth(pauth_out, RPC_KRB5_AUTH_TYPE, (int)auth_level, 0, 1); @@ -972,9 +972,9 @@ static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client prs_struct *auth_data) { NTSTATUS nt_status; - DATA_BLOB null_blob = data_blob(NULL, 0); - DATA_BLOB request = data_blob(NULL, 0); - DATA_BLOB spnego_msg = data_blob(NULL, 0); + DATA_BLOB null_blob = data_blob_null; + DATA_BLOB request = data_blob_null; + DATA_BLOB spnego_msg = data_blob_null; /* We may change the pad length before marshalling. */ init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1); @@ -1019,8 +1019,8 @@ static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli, prs_struct *auth_data) { NTSTATUS nt_status; - DATA_BLOB null_blob = data_blob(NULL, 0); - DATA_BLOB request = data_blob(NULL, 0); + DATA_BLOB null_blob = data_blob_null; + DATA_BLOB request = data_blob_null; /* We may change the pad length before marshalling. */ init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1); @@ -1250,7 +1250,7 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli, { RPC_HDR_AUTH auth_info; NTSTATUS status; - DATA_BLOB auth_blob = data_blob(NULL, 0); + DATA_BLOB auth_blob = data_blob_null; uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; if (!cli->auth.a_u.ntlmssp_state) { @@ -1775,8 +1775,8 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level) { - DATA_BLOB server_response = data_blob(NULL,0); - DATA_BLOB client_reply = data_blob(NULL,0); + DATA_BLOB server_response = data_blob_null; + DATA_BLOB client_reply = data_blob_null; RPC_HDR_AUTH hdr_auth; NTSTATUS nt_status; prs_struct rpc_out; @@ -1900,10 +1900,10 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level) { - DATA_BLOB server_spnego_response = data_blob(NULL,0); - DATA_BLOB server_ntlm_response = data_blob(NULL,0); - DATA_BLOB client_reply = data_blob(NULL,0); - DATA_BLOB tmp_blob = data_blob(NULL, 0); + DATA_BLOB server_spnego_response = data_blob_null; + DATA_BLOB server_ntlm_response = data_blob_null; + DATA_BLOB client_reply = data_blob_null; + DATA_BLOB tmp_blob = data_blob_null; RPC_HDR_AUTH hdr_auth; NTSTATUS nt_status; prs_struct rpc_out; @@ -1953,7 +1953,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, tmp_blob = spnego_gen_auth(client_reply); data_blob_free(&client_reply); client_reply = tmp_blob; - tmp_blob = data_blob(NULL,0); /* Ensure it's safe to free this just in case. */ + tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */ /* Now prepare the alter context pdu. */ prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL); -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5f21caeccf..a659785896 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -5,7 +5,7 @@ * * 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 - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, -- cgit From 153cfb9c83534b09f15cc16205d7adb19b394928 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 05:23:25 +0000 Subject: r23801: The FSF has moved around a lot. This fixes their Mass Ave address. (This used to be commit 87c91e4362c51819032bfbebbb273c52e203b227) --- source3/rpc_client/cli_pipe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a659785896..c4ad43e6a4 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program; if not, see . */ #include "includes.h" -- cgit From 451224166dd8f0e91907f541d15febb385360c09 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 12 Jul 2007 09:36:52 +0000 Subject: r23850: Fix whitespacing in DEBUG output. (This used to be commit 918aad0d8b4b0c2caa8830726a17d3ad4d19f72a) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c4ad43e6a4..db696edae5 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -781,7 +781,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, &rparam, &rparam_len, /* return params, len */ &prdata, &rdata_len)) /* return data, len */ { - DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x" + DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x " "returned critical error. Error was %s\n", cli->cli->desthost, cli->pipe_name, -- cgit From 3529156971e17c7ec13f6a6243f7b613e4666cdd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 03:54:42 +0000 Subject: r25400: Windows 2008 (Longhorn) Interop fixes for AD specific auth2 flags, and client fixes. Patch from Todd Stetcher . (This used to be commit 8304ccba7346597425307e260e88647e49081f68) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index db696edae5..314a694369 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2633,7 +2633,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state const char *password, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; @@ -2667,7 +2667,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, const char *domain, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; -- cgit From 5221ebb299081da6a806362212c6a8ceb9cc70a8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 18:15:34 +0000 Subject: r25407: Revert Longhorn join patch as it is not correct for the 3.2 tree. The translate_name() used by cli_session_setup_spnego() cann rely Winbindd since it is needed by the join process (and hence before Winbind can be run). (This used to be commit 00a93ed336c5f36643e6e33bd277608eaf05677c) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 314a694369..db696edae5 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2633,7 +2633,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state const char *password, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; @@ -2667,7 +2667,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, const char *domain, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/rpc_client/cli_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index db696edae5..1e5e04448f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1589,10 +1589,10 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, Set the handle state. ****************************************************************************/ -static BOOL rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli, +static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli, const char *pipe_name, uint16 device_state) { - BOOL state_set = False; + bool state_set = False; char param[2]; uint16 setup[2]; /* only need 2 uint16 setup parameters */ char *rparam = NULL; @@ -1635,7 +1635,7 @@ static BOOL rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli, Check the rpc bind acknowledge response. ****************************************************************************/ -static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer) +static bool valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer) { if ( pipe_idx >= PI_MAX_PIPES ) { DEBUG(0,("valid_pipe_name: Programmer error! Invalid pipe index [%d]\n", @@ -1662,7 +1662,7 @@ static BOOL valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE * Check the rpc bind acknowledge response. ****************************************************************************/ -static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer) +static bool check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer) { if ( hdr_ba->addr.len == 0) { DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)")); -- cgit From 66298d808034bb606478ff66aa156bda4e7e3f2a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Nov 2007 17:18:16 -0800 Subject: More pstring elimination. Jeremy. (This used to be commit 15074de938539e7a9c527d9a6d81792adc2ac3d0) --- source3/rpc_client/cli_pipe.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1e5e04448f..c93e26ccbc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1551,13 +1551,15 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE); prs_mem_free(&outgoing_pdu); - if (DEBUGLEVEL >= 50) { - pstring dump_name; + char *dump_name = NULL; /* Also capture received data */ - slprintf(dump_name, sizeof(dump_name) - 1, "%s/reply_%s_%d", - dyn_LOGFILEBASE, cli->pipe_name, op_num); - prs_dump(dump_name, op_num, out_data); + if (asprintf(&dump_name, "%s/reply_%s_%d", + dyn_LOGFILEBASE, cli->pipe_name, + op_num) > 0) { + prs_dump(dump_name, op_num, out_data); + SAFE_FREE(dump_name); + } } return ret; -- cgit From d2cf97aeba14a4d336fb57b01f19bd5a08dcb003 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Nov 2007 13:24:54 -0800 Subject: Remove the explicit TALLOC_CTX * from cli_struct. Make us very explicit about how long a talloc ctx should last. Jeremy. (This used to be commit ba9e2be2b5a59684e854609f9d82ea1633448c62) --- source3/rpc_client/cli_pipe.c | 35 ++++------------------------------- 1 file changed, 4 insertions(+), 31 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c93e26ccbc..05ef2ad151 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1975,7 +1975,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, /* Initialize the returning data struct. */ prs_mem_free(rbuf); - prs_init(rbuf, 0, cli->cli->mem_ctx, UNMARSHALL); + prs_init(rbuf, 0, cli->mem_ctx, UNMARSHALL); nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP); if (!NT_STATUS_IS_OK(nt_status)) { @@ -2048,7 +2048,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return NT_STATUS_INVALID_PARAMETER; } - prs_init(&rpc_out, 0, cli->cli->mem_ctx, MARSHALL); + prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL); rpc_call_id = get_rpc_call_id(); @@ -2064,7 +2064,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, } /* Initialize the incoming data struct. */ - prs_init(&rbuf, 0, cli->cli->mem_ctx, UNMARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* send data on \PIPE\. receive a response */ status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK); @@ -2745,7 +2745,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, } } - result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(cli->mem_ctx, struct kerberos_auth_struct); + result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(result->mem_ctx, struct kerberos_auth_struct); if (!result->auth.a_u.kerberos_auth) { cli_rpc_pipe_close(result); *perr = NT_STATUS_NO_MEMORY; @@ -2769,30 +2769,3 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, return NULL; #endif } - -#if 0 /* Moved to libsmb/clientgen.c */ -/**************************************************************************** - External interface. - Close an open named pipe over SMB. Free any authentication data. - ****************************************************************************/ - - void cli_rpc_pipe_close(struct rpc_pipe_client *cli) -{ - if (!cli_close(cli->cli, cli->fnum)) { - DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s " - "to machine %s. Error was %s\n", - cli->pipe_name), - cli->cli->desthost, - cli_errstr(cli->cli))); - } - - if (cli->auth.cli_auth_data_free_func) { - (*cli->auth.cli_auth_data_free_func)(&cli->auth); - } - DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n", - cli->pipe_name, cli->cli->desthost )); - - DLIST_REMOVE(cli->cli->pipe_list, cli); - talloc_destroy(cli->mem_ctx); -} -#endif -- cgit From 7faee02d0d351c5c039e8f1be7e82ce3a93cbe96 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Dec 2007 11:30:37 -0800 Subject: Remove the char[1024] strings from dynconfig. Replace them with malloc'ing accessor functions. Should save a lot of static space :-). Jeremy. (This used to be commit 52dc5eaef2106015b3a8b659e818bdb15ad94b05) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 05ef2ad151..37558a7ff0 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1555,7 +1555,7 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, char *dump_name = NULL; /* Also capture received data */ if (asprintf(&dump_name, "%s/reply_%s_%d", - dyn_LOGFILEBASE, cli->pipe_name, + get_dyn_LOGFILEBASE(), cli->pipe_name, op_num) > 0) { prs_dump(dump_name, op_num, out_data); SAFE_FREE(dump_name); -- cgit From f793c99ca54d62cb8142607e8449f5b5b3a5e79d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 11 Dec 2007 13:05:44 +0100 Subject: Let get_trust_pw() determine the machine_account_name to use. Up to now each caller used its own logic. This eliminates code paths where there was a special treatment of the following situation: the domain given is not our workgroup (i.e. our own domain) and we are not a DC (i.e. it is not a typical trusted domain situation). In situation the given domain name was previously used as the machine account name, resulting in an account name of DOMAIN\\DOMAIN$, which does not seem very reasonable to me. get_trust_pw would not have obtained a password in this situation anyways. I hope I have not missed an important point here! Michael (This used to be commit 6ced4a7f88798dc449a667d63bc29bf6c569291f) --- source3/rpc_client/cli_pipe.c | 38 ++++++-------------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 37558a7ff0..bf019c89a1 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2436,7 +2436,7 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; - fstring machine_account; + const char *machine_account; netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr); if (!netlogon_pipe) { @@ -2444,7 +2444,8 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, } /* Get the machine account credentials from secrets.tdb. */ - if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) { + if (!get_trust_pw(domain, machine_pwd, &machine_account, &sec_chan_type)) + { DEBUG(0, ("get_schannel_session_key: could not fetch " "trust account password for domain '%s'\n", domain)); @@ -2453,20 +2454,6 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, return NULL; } - /* A DC should use DOMAIN$ as its account name. - A member server can only use it's machine name since it - does not have an account in a trusted domain. - - We don't check the domain against lp_workgroup() here since - 'net ads join' has to continue to work with only the realm - specified in smb.conf. -- jerry */ - - if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) { - fstrcpy( machine_account, lp_workgroup() ); - } else { - fstrcpy(machine_account, global_myname()); - } - *perr = rpccli_netlogon_setup_creds(netlogon_pipe, cli->desthost, /* server name */ domain, /* domain */ @@ -2562,7 +2549,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; - fstring machine_account; + const char *machine_account; netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr); if (!netlogon_pipe) { @@ -2570,7 +2557,8 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ } /* Get the machine account credentials from secrets.tdb. */ - if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) { + if (!get_trust_pw(domain, machine_pwd, &machine_account, &sec_chan_type)) + { DEBUG(0, ("get_schannel_session_key_auth_ntlmssp: could not fetch " "trust account password for domain '%s'\n", domain)); @@ -2579,20 +2567,6 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ return NULL; } - /* if we are a DC and this is a trusted domain, then we need to use our - domain name in the net_req_auth2() request */ - - if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) { - fstrcpy( machine_account, lp_workgroup() ); - } else { - /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */ - if (strequal(domain, lp_workgroup())) { - fstrcpy(machine_account, global_myname()); - } else { - fstrcpy(machine_account, domain); - } - } - *perr = rpccli_netlogon_setup_creds(netlogon_pipe, cli->desthost, /* server name */ domain, /* domain */ -- cgit From 31f221ed9316c8dc2f4911d7b8ddcdf8b74367db Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 11 Dec 2007 14:07:32 +0100 Subject: Rename get_trust_pw() to get_trust_pw_hash(). Michael (This used to be commit 0cde7ac9cb39a0026a38ccf66dbecefc12931074) --- source3/rpc_client/cli_pipe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bf019c89a1..9f1d9c6e3e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2444,7 +2444,8 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, } /* Get the machine account credentials from secrets.tdb. */ - if (!get_trust_pw(domain, machine_pwd, &machine_account, &sec_chan_type)) + if (!get_trust_pw_hash(domain, machine_pwd, &machine_account, + &sec_chan_type)) { DEBUG(0, ("get_schannel_session_key: could not fetch " "trust account password for domain '%s'\n", @@ -2557,7 +2558,8 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ } /* Get the machine account credentials from secrets.tdb. */ - if (!get_trust_pw(domain, machine_pwd, &machine_account, &sec_chan_type)) + if (!get_trust_pw_hash(domain, machine_pwd, &machine_account, + &sec_chan_type)) { DEBUG(0, ("get_schannel_session_key_auth_ntlmssp: could not fetch " "trust account password for domain '%s'\n", -- cgit From 7cf5c17f12328d100fca7979a292ea22165bf80b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 11 Dec 2007 14:36:11 +0100 Subject: Refactoring out get_schannel_session_key logic. Refactor the actual retrieval of the session key through the established netlogon pipe out of get_schannel_session_key() and get_schannel_session_key_auth_ntlmssp() into a new function get_schannel_session_key_common(). (To avoid code duplication.) Michael (This used to be commit e77c4022cfbb868e608edcb06b676658b0e201ad) --- source3/rpc_client/cli_pipe.c | 92 ++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 53 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9f1d9c6e3e..f61ea95d04 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2424,25 +2424,18 @@ struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, } /**************************************************************************** - Open a netlogon pipe and get the schannel session key. - Now exposed to external callers. + Get a the schannel session key out of an already opened netlogon pipe. ****************************************************************************/ - -struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, - const char *domain, - uint32 *pneg_flags, - NTSTATUS *perr) +static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe, + struct cli_state *cli, + const char *domain, + uint32 *pneg_flags, + NTSTATUS *perr) { - struct rpc_pipe_client *netlogon_pipe = NULL; uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; const char *machine_account; - netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr); - if (!netlogon_pipe) { - return NULL; - } - /* Get the machine account credentials from secrets.tdb. */ if (!get_trust_pw_hash(domain, machine_pwd, &machine_account, &sec_chan_type)) @@ -2450,9 +2443,8 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, DEBUG(0, ("get_schannel_session_key: could not fetch " "trust account password for domain '%s'\n", domain)); - cli_rpc_pipe_close(netlogon_pipe); *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - return NULL; + return false; } *perr = rpccli_netlogon_setup_creds(netlogon_pipe, @@ -2465,11 +2457,10 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, pneg_flags); if (!NT_STATUS_IS_OK(*perr)) { - DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds " + DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds " "failed with result %s to server %s, domain %s, machine account %s.\n", nt_errstr(*perr), cli->desthost, domain, machine_account )); - cli_rpc_pipe_close(netlogon_pipe); - return NULL; + return false; } if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { @@ -2477,6 +2468,34 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, cli->desthost)); cli_rpc_pipe_close(netlogon_pipe); *perr = NT_STATUS_INVALID_NETWORK_RESPONSE; + return false; + } + + return true; +} + +/**************************************************************************** + Open a netlogon pipe and get the schannel session key. + Now exposed to external callers. + ****************************************************************************/ + + +struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, + const char *domain, + uint32 *pneg_flags, + NTSTATUS *perr) +{ + struct rpc_pipe_client *netlogon_pipe = NULL; + + netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr); + if (!netlogon_pipe) { + return NULL; + } + + if (!get_schannel_session_key_common(netlogon_pipe, cli, domain, + pneg_flags, perr)) + { + cli_rpc_pipe_close(netlogon_pipe); return NULL; } @@ -2548,49 +2567,16 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ NTSTATUS *perr) { struct rpc_pipe_client *netlogon_pipe = NULL; - uint32 sec_chan_type = 0; - unsigned char machine_pwd[16]; - const char *machine_account; netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr); if (!netlogon_pipe) { return NULL; } - /* Get the machine account credentials from secrets.tdb. */ - if (!get_trust_pw_hash(domain, machine_pwd, &machine_account, - &sec_chan_type)) + if (!get_schannel_session_key_common(netlogon_pipe, cli, domain, + pneg_flags, perr)) { - DEBUG(0, ("get_schannel_session_key_auth_ntlmssp: could not fetch " - "trust account password for domain '%s'\n", - domain)); - cli_rpc_pipe_close(netlogon_pipe); - *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - return NULL; - } - - *perr = rpccli_netlogon_setup_creds(netlogon_pipe, - cli->desthost, /* server name */ - domain, /* domain */ - global_myname(), /* client name */ - machine_account, /* machine account name */ - machine_pwd, - sec_chan_type, - pneg_flags); - - if (!NT_STATUS_IS_OK(*perr)) { - DEBUG(3,("get_schannel_session_key_auth_ntlmssp: rpccli_netlogon_setup_creds " - "failed with result %s\n", - nt_errstr(*perr) )); - cli_rpc_pipe_close(netlogon_pipe); - return NULL; - } - - if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { - DEBUG(3, ("get_schannel_session_key_auth_ntlmssp: Server %s did not offer schannel\n", - cli->desthost)); cli_rpc_pipe_close(netlogon_pipe); - *perr = NT_STATUS_INVALID_NETWORK_RESPONSE; return NULL; } -- cgit From d9682dfb5918c20516d45de20c4f3d5824572e20 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 17 Dec 2007 23:02:39 +0100 Subject: Do not close netlogon pipe in get_schannel_session_key_common(). This removes one forgotten call of cli_rpc_pipe_close(netlogon_pipe). Correction of e77c4022cfbb868e608edcb06b676658b0e201ad. Michael (This used to be commit 7f6593cddef048dd05140b05d306c708d8134f0e) --- source3/rpc_client/cli_pipe.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f61ea95d04..5a4ccf4f02 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2466,7 +2466,6 @@ static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pip if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n", cli->desthost)); - cli_rpc_pipe_close(netlogon_pipe); *perr = NT_STATUS_INVALID_NETWORK_RESPONSE; return false; } -- cgit From 68e65b29815f1f9bbe7384e07fc341f6c8f2f605 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 18 Dec 2007 07:58:22 +0100 Subject: Fix a debug message: add missing space. Michael (This used to be commit 6a7f2a59fc370e226ddacb195059155f28c6c157) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5a4ccf4f02..f4cb424527 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2364,8 +2364,8 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta goto err; } - DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to machine %s and" - "bound NTLMSSP as user %s\\%s.\n", + DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to " + "machine %s and bound NTLMSSP as user %s\\%s.\n", result->pipe_name, cli->desthost, domain, username )); -- cgit From 691c4b1a4175e3d4a073c396a2a7d8d315cd42bd Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 17 Jan 2008 10:11:11 +0100 Subject: Windows 2008 (Longhorn) auth2 flag fixes. Interop fixes for AD specific flags. Original patch from Todd Stetcher. (This used to be commit 5aadfcdaacd6f136eab9e107a88b8544e6d2105f) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index f4cb424527..81b2ea5d68 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2596,7 +2596,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state const char *password, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; @@ -2630,7 +2630,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, const char *domain, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; -- cgit From 05ff7fd46e19d9c1aab8524495c9b926290927c7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 25 Jan 2008 13:26:10 +0100 Subject: Use generated DSSETUP client & server rpc functions and remove the hand-written ones. Guenther (This used to be commit d5ebfccebb1f1b56b45673a506fcdb414103c43b) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 81b2ea5d68..40d0ac5da9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2263,7 +2263,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE); if (!NT_STATUS_IS_OK(*perr)) { int lvl = 0; - if (pipe_idx == PI_LSARPC_DS) { + if (pipe_idx == PI_DSSETUP) { /* non AD domains just don't have this pipe, avoid * level 0 statement in that case - gd */ lvl = 3; -- cgit From 6fb37ae6725acda88876d92061a4db39f53cbf0a Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Tue, 26 Feb 2008 20:14:04 -0800 Subject: Closed memory leak on error path. (This used to be commit 376de8a0e4194e186b460911e3319b0f4448203e) --- source3/rpc_client/cli_pipe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 40d0ac5da9..c89c5531d7 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1807,6 +1807,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n")); + data_blob_free(&server_response); return nt_status; } -- cgit From e06aa46b9fab1e107fea8f6453fb13deffa91e96 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Fri, 14 Mar 2008 14:26:28 -0800 Subject: Coverity fixes (This used to be commit 3fc85d22590550f0539215d020e4411bf5b14363) --- source3/rpc_client/cli_pipe.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c89c5531d7..1fd06f868e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -683,7 +683,7 @@ static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR /* Common case. */ if (current_pdu_len == (uint32)prhdr->frag_len) { prs_mem_free(current_pdu); - prs_init(current_pdu, 0, prs_get_mem_context(current_pdu), UNMARSHALL); + prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL); /* Make current_pdu dynamic with no memory. */ prs_give_memory(current_pdu, 0, 0, True); return NT_STATUS_OK; @@ -757,7 +757,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, #endif /* Set up the current pdu parse struct. */ - prs_init(¤t_pdu, 0, prs_get_mem_context(rbuf), UNMARSHALL); + prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL); /* Create setup parameters - must be in native byte order. */ setup[0] = TRANSACT_DCERPCCMD; @@ -1183,7 +1183,8 @@ static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli, NTSTATUS ret = NT_STATUS_OK; ZERO_STRUCT(hdr_auth); - prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL); + if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL)) + return NT_STATUS_NO_MEMORY; switch (auth_type) { case PIPE_AUTH_TYPE_SCHANNEL: @@ -1468,7 +1469,8 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, return NT_STATUS_INVALID_PARAMETER; } - prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL); + if (!prs_init(&outgoing_pdu, cli->max_xmit_frag, prs_get_mem_context(in_data), MARSHALL)) + return NT_STATUS_NO_MEMORY; while (1) { RPC_HDR hdr; @@ -1811,7 +1813,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, return nt_status; } - prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL); + prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL); nt_status = create_rpc_bind_auth3(cli, rpc_call_id, auth_type, auth_level, @@ -1865,7 +1867,8 @@ static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id, NTSTATUS ret = NT_STATUS_OK; ZERO_STRUCT(hdr_auth); - prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL); + if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL)) + return NT_STATUS_NO_MEMORY; /* We may change the pad length before marshalling. */ init_rpc_hdr_auth(&hdr_auth, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1); @@ -1958,7 +1961,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, tmp_blob = data_blob_null; /* Ensure it's safe to free this just in case. */ /* Now prepare the alter context pdu. */ - prs_init(&rpc_out, 0, prs_get_mem_context(rbuf), MARSHALL); + prs_init_empty(&rpc_out, prs_get_mem_context(rbuf), MARSHALL); nt_status = create_rpc_alter_context(rpc_call_id, abstract, @@ -1976,7 +1979,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, /* Initialize the returning data struct. */ prs_mem_free(rbuf); - prs_init(rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init_empty(rbuf, cli->mem_ctx, UNMARSHALL); nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP); if (!NT_STATUS_IS_OK(nt_status)) { @@ -2049,7 +2052,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return NT_STATUS_INVALID_PARAMETER; } - prs_init(&rpc_out, 0, cli->mem_ctx, MARSHALL); + prs_init_empty(&rpc_out, cli->mem_ctx, MARSHALL); rpc_call_id = get_rpc_call_id(); @@ -2065,7 +2068,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, } /* Initialize the incoming data struct. */ - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init_empty(&rbuf, cli->mem_ctx, UNMARSHALL); /* send data on \PIPE\. receive a response */ status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK); -- cgit From 99d35904552b01ef9f2adc40e16887da9eb4de69 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 2 Apr 2008 02:29:48 +0200 Subject: Fix NETLOGON credential chain with Windows 2008 all over the place. In order to avoid receiving NT_STATUS_DOWNGRADE_DETECTED from a w2k8 netr_ServerAuthenticate2 reply, we need to start with the AD netlogon negotiate flags everywhere (not only when running in security=ads). Only for NT4 we need to do a downgrade to the returned negotiate flags. Tested with w2k8, w2ksp4, w2k3r2 and nt4sp6. Guenther (This used to be commit 0970369ca0cb9ae465cff40e5c75739824daf1d0) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1fd06f868e..71422cd9ad 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2600,7 +2600,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state const char *password, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; @@ -2634,7 +2634,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, const char *domain, NTSTATUS *perr) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; -- cgit From 28fd4f6fcb101fc0274c43611a59d22072fb7891 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 20:26:52 +0200 Subject: Reconcile ndr_syntax_id used by pidl-generated code and Samba3's RFC_IFACE. (This used to be commit 7bea00dca1ee08ef731dfa73110ef9c190a29919) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 71422cd9ad..ba59a41793 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1690,7 +1690,7 @@ static bool check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC #endif /* JERRY */ /* check the transfer syntax */ - if ((hdr_ba->transfer.version != transfer->version) || + if ((hdr_ba->transfer.if_version != transfer->if_version) || (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) { DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n")); return False; -- cgit From a4c60b2696962c7f83e033e00d97e4b1dacc05c9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 17:44:40 +0200 Subject: rpc_parse: Use UUIDs from librpc/gen_ndr/ when possible to reduce duplication. (This used to be commit 428654b473ba44b2f5340eefef0d4fcd51aff558) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ba59a41793..2a2b547b5e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1656,8 +1656,8 @@ static bool valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE * /* copy the required syntaxes out so we can do the right bind */ - *transfer = pipe_names[pipe_idx].trans_syntax; - *abstract = pipe_names[pipe_idx].abstr_syntax; + *transfer = *pipe_names[pipe_idx].trans_syntax; + *abstract = *pipe_names[pipe_idx].abstr_syntax; return True; } -- cgit From fb73de3b927e02fbc056565714ecbe83c7645dc2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 23:50:58 +0200 Subject: Set the right domain\user in cli_rpc_pipe_open_ntlmssp_internal This probably does not matter in current code, but without this it's not possible to do the bind as a different user than the underlying smb user. Jeremy, please check! Thanks, Volker (This used to be commit b90062e33cbde7de4961414fd35a3a588760d002) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2a2b547b5e..bc49e24df1 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2330,12 +2330,12 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta result->auth.a_u.ntlmssp_state = ntlmssp_state; - *perr = ntlmssp_set_username(ntlmssp_state, cli->user_name); + *perr = ntlmssp_set_username(ntlmssp_state, username); if (!NT_STATUS_IS_OK(*perr)) { goto err; } - *perr = ntlmssp_set_domain(ntlmssp_state, cli->domain); + *perr = ntlmssp_set_domain(ntlmssp_state, domain); if (!NT_STATUS_IS_OK(*perr)) { goto err; } -- cgit From b46d340fd5d7e88684ac77000e17c1899ff608b2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 18:17:13 +0200 Subject: Refactoring: Make struct rpc_pipe_client its own talloc parent (This used to be commit a6d74a5a562b54f0b36934965f545fdeb1e8b34a) --- source3/rpc_client/cli_pipe.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bc49e24df1..a94da8b79b 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1979,7 +1979,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, /* Initialize the returning data struct. */ prs_mem_free(rbuf); - prs_init_empty(rbuf, cli->mem_ctx, UNMARSHALL); + prs_init_empty(rbuf, talloc_tos(), UNMARSHALL); nt_status = rpc_api_pipe(cli, &rpc_out, rbuf, RPC_ALTCONTRESP); if (!NT_STATUS_IS_OK(nt_status)) { @@ -2052,7 +2052,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return NT_STATUS_INVALID_PARAMETER; } - prs_init_empty(&rpc_out, cli->mem_ctx, MARSHALL); + prs_init_empty(&rpc_out, talloc_tos(), MARSHALL); rpc_call_id = get_rpc_call_id(); @@ -2068,7 +2068,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, } /* Initialize the incoming data struct. */ - prs_init_empty(&rbuf, cli->mem_ctx, UNMARSHALL); + prs_init_empty(&rbuf, talloc_tos(), UNMARSHALL); /* send data on \PIPE\. receive a response */ status = rpc_api_pipe(cli, &rpc_out, &rbuf, RPC_BINDACK); @@ -2188,7 +2188,6 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) { - TALLOC_CTX *mem_ctx; struct rpc_pipe_client *result; int fnum; @@ -2204,18 +2203,11 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe /* The pipe name index must fall within our array */ SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); - mem_ctx = talloc_init("struct rpc_pipe_client"); - if (mem_ctx == NULL) { - return NULL; - } - - result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client); + result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client); if (result == NULL) { return NULL; } - result->mem_ctx = mem_ctx; - result->pipe_name = cli_get_pipe_name(pipe_idx); fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE); @@ -2226,7 +2218,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe result->pipe_name, cli->desthost, cli_errstr(cli))); *perr = cli_get_nt_error(cli); - talloc_destroy(result->mem_ctx); + talloc_destroy(result); return NULL; } @@ -2238,9 +2230,9 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe if (pipe_idx == PI_NETLOGON) { /* Set up a netlogon credential chain for a netlogon pipe. */ - result->dc = TALLOC_ZERO_P(mem_ctx, struct dcinfo); + result->dc = TALLOC_ZERO_P(result, struct dcinfo); if (result->dc == NULL) { - talloc_destroy(result->mem_ctx); + talloc_destroy(result); return NULL; } } @@ -2525,7 +2517,8 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl return NULL; } - result->auth.a_u.schannel_auth = TALLOC_ZERO_P(result->mem_ctx, struct schannel_auth_struct); + result->auth.a_u.schannel_auth = TALLOC_ZERO_P( + result, struct schannel_auth_struct); if (!result->auth.a_u.schannel_auth) { cli_rpc_pipe_close(result); *perr = NT_STATUS_NO_MEMORY; @@ -2693,8 +2686,8 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, /* Default service principal is "desthost$@realm" */ if (!service_princ) { - service_princ = talloc_asprintf(result->mem_ctx, "%s$@%s", - cli->desthost, lp_realm() ); + service_princ = talloc_asprintf(result, "%s$@%s", + cli->desthost, lp_realm() ); if (!service_princ) { cli_rpc_pipe_close(result); return NULL; @@ -2710,7 +2703,8 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, } } - result->auth.a_u.kerberos_auth = TALLOC_ZERO_P(result->mem_ctx, struct kerberos_auth_struct); + result->auth.a_u.kerberos_auth = TALLOC_ZERO_P( + result, struct kerberos_auth_struct); if (!result->auth.a_u.kerberos_auth) { cli_rpc_pipe_close(result); *perr = NT_STATUS_NO_MEMORY; -- cgit From 2a2188591b5ed922d09dc723adcf10f8b8f5e5a0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 21:56:43 +0200 Subject: Add "desthost" to rpc_pipe_client This reduces the dependency on cli_state (This used to be commit 783afab9c891dd7bcb78895b2a639b6f3a0edf5b) --- source3/rpc_client/cli_pipe.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a94da8b79b..6465228f18 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -279,7 +279,7 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal " "packet from remote machine %s on pipe %s " "fnum 0x%x. Error was %s.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum, nt_errstr(status) )); @@ -297,7 +297,7 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on " "packet from remote machine %s on pipe %s " "fnum 0x%x. Error was %s.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum, nt_errstr(status) )); @@ -400,7 +400,7 @@ static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *p DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU " "Connection to remote machine %s " "pipe %s fnum 0x%x.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum )); return NT_STATUS_INVALID_PARAMETER; @@ -461,7 +461,7 @@ static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_ if (prhdr->auth_len) { DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s " "pipe %s fnum 0x%x - got non-zero auth len %u.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum, (unsigned int)prhdr->auth_len )); @@ -489,7 +489,7 @@ static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_ default: DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s " "pipe %s fnum %x - unknown internal auth type %u.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum, cli->auth.auth_type )); @@ -595,7 +595,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H case RPC_BINDNACK: DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s " "pipe %s fnum 0x%x!\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum)); /* Use this for now... */ @@ -619,7 +619,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s " "pipe %s fnum 0x%x!\n", dcerpc_errstr(NT_STATUS_V(fault_resp.status)), - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum)); if (NT_STATUS_IS_OK(fault_resp.status)) { @@ -634,7 +634,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received " "from remote machine %s pipe %s fnum 0x%x!\n", (unsigned int)prhdr->pkt_type, - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum)); return NT_STATUS_INVALID_INFO_CLASS; @@ -644,7 +644,7 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s " "pipe %s fnum %x got an unexpected RPC packet " "type - %u, not %u\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum, prhdr->pkt_type, @@ -764,7 +764,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, setup[1] = cli->fnum; /* Pipe file handle. */ DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum )); @@ -783,7 +783,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, { DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x " "returned critical error. Error was %s\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum, cli_errstr(cli->cli))); @@ -800,7 +800,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, if (prdata == NULL) { DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s " "fnum 0x%x failed to return data.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum)); /* Yes - some calls can truely return no data... */ @@ -850,7 +850,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, /* Set the data type correctly for big-endian data on the first packet. */ DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x " "PDU data format is big-endian.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum)); @@ -887,7 +887,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, } DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum, (unsigned int)prs_data_size(rbuf) )); @@ -1840,7 +1840,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s " "fnum 0x%x sent auth3 response ok.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum)); @@ -2018,7 +2018,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to " "remote machine %s pipe %s fnum 0x%x.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum)); @@ -2081,7 +2081,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s " "fnum 0x%x bind request returned ok.\n", - cli->cli->desthost, + cli->desthost, cli->pipe_name, (unsigned int)cli->fnum)); @@ -2228,6 +2228,12 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe result->auth.auth_type = PIPE_AUTH_TYPE_NONE; result->auth.auth_level = PIPE_AUTH_LEVEL_NONE; + result->desthost = talloc_strdup(result, cli->desthost); + if (result->desthost == NULL) { + TALLOC_FREE(result); + return NULL; + } + if (pipe_idx == PI_NETLOGON) { /* Set up a netlogon credential chain for a netlogon pipe. */ result->dc = TALLOC_ZERO_P(result, struct dcinfo); -- cgit From 9048cafbeaf82d1916de6538024fd660612dd25f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 23:03:16 +0200 Subject: Move srv_name_slash from cli_state to rpc_pipe_client (This used to be commit a9061e52e1ff8e31aa480f4a30cda64c9d93214e) --- source3/rpc_client/cli_pipe.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6465228f18..3ef3f05cc6 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2234,6 +2234,13 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe return NULL; } + result->srv_name_slash = talloc_asprintf_strupper_m( + result, "\\\\%s", result->desthost); + if (result->srv_name_slash == NULL) { + TALLOC_FREE(result); + return NULL; + } + if (pipe_idx == PI_NETLOGON) { /* Set up a netlogon credential chain for a netlogon pipe. */ result->dc = TALLOC_ZERO_P(result, struct dcinfo); -- cgit From e1102b8f48aeebe7d4e730d2b432a1503b425210 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 23:27:35 +0200 Subject: Introduce rpccli_set_timeout() Reduce dependency on "cli" member of rpc_pipe_client struct (This used to be commit 2e4c1ba38963cffe4c3f25ab24bc28975f2fc291) --- source3/rpc_client/cli_pipe.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3ef3f05cc6..64fcc16bde 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2173,6 +2173,12 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return NT_STATUS_OK; } +unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, + unsigned int timeout) +{ + return cli_set_timeout(cli->cli, timeout); +} + /**************************************************************************** Open a named pipe over SMB to a remote server. * -- cgit From cf2442bdcb68d75582da98ba15da8928c37fb058 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 00:01:52 +0200 Subject: Use rpc_pipe_client->user_name instead of rpc_pipe_client->cli->user_name Also make sure that rpc_pipe_client->user_name is always talloced. (This used to be commit 3f6c5b99664a75a6f490ee3b6980b89cacf7f579) --- source3/rpc_client/cli_pipe.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 64fcc16bde..bc9a4268d0 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2275,6 +2275,15 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe return NULL; } + result->domain = talloc_strdup(result, cli->domain); + result->user_name = talloc_strdup(result, cli->user_name); + + if ((result->domain == NULL) || (result->user_name == NULL)) { + *perr = NT_STATUS_NO_MEMORY; + cli_rpc_pipe_close(result); + return NULL; + } + *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE); if (!NT_STATUS_IS_OK(*perr)) { int lvl = 0; @@ -2330,8 +2339,14 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free; - result->domain = domain; - result->user_name = username; + result->domain = talloc_strdup(result, domain); + result->user_name = talloc_strdup(result, username); + + if ((result->domain == NULL) || (result->user_name == NULL)) { + *perr = NT_STATUS_NO_MEMORY; + goto err; + } + pwd_set_cleartext(&result->pwd, password); *perr = ntlmssp_client_start(&ntlmssp_state); -- cgit From ff8aa642f34f95cb85d4b9a65e01b4fe0efe5384 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 11:27:24 +0200 Subject: Remove some unused code referencing pipe_names[] (This used to be commit d8a04b798c44c26a91a37fa7090dd071a1909166) --- source3/rpc_client/cli_pipe.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bc9a4268d0..b9d184f023 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1672,23 +1672,6 @@ static bool check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)")); } -# if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */ - if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) && - !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) ) - { - DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n", - pipe_names[i].server_pipe ,hdr_ba->addr.str)); - return False; - } - - DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n", pipe_names[i].server_pipe )); - - if (pipe_names[pipe_idx].server_pipe == NULL) { - DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str)); - return False; - } -#endif /* JERRY */ - /* check the transfer syntax */ if ((hdr_ba->transfer.if_version != transfer->if_version) || (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) { -- cgit From f56eedb95c64593ceff0ef91b99729c5071aa7ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 11:45:41 +0200 Subject: Remove the pipe_idx variable from rpc_pipe_client (This used to be commit 4840febcd481563c3d9b2fabc1fe1b2ae5a76cf6) --- source3/rpc_client/cli_pipe.c | 73 +++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 45 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b9d184f023..2979d168c5 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1092,8 +1092,8 @@ static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli, static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type, prs_struct *rpc_out, uint32 rpc_call_id, - RPC_IFACE *abstract, - RPC_IFACE *transfer, + const RPC_IFACE *abstract, + const RPC_IFACE *transfer, RPC_HDR_AUTH *phdr_auth, prs_struct *pauth_info) { @@ -1174,7 +1174,8 @@ static NTSTATUS create_bind_or_alt_ctx_internal(enum RPC_PKT_TYPE pkt_type, static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli, prs_struct *rpc_out, uint32 rpc_call_id, - RPC_IFACE *abstract, RPC_IFACE *transfer, + const RPC_IFACE *abstract, + const RPC_IFACE *transfer, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level) { @@ -1639,34 +1640,7 @@ static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli, Check the rpc bind acknowledge response. ****************************************************************************/ -static bool valid_pipe_name(const int pipe_idx, RPC_IFACE *abstract, RPC_IFACE *transfer) -{ - if ( pipe_idx >= PI_MAX_PIPES ) { - DEBUG(0,("valid_pipe_name: Programmer error! Invalid pipe index [%d]\n", - pipe_idx)); - return False; - } - - DEBUG(5,("Bind Abstract Syntax: ")); - dump_data(5, (uint8 *)&pipe_names[pipe_idx].abstr_syntax, - sizeof(pipe_names[pipe_idx].abstr_syntax)); - DEBUG(5,("Bind Transfer Syntax: ")); - dump_data(5, (uint8 *)&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 */ - - *transfer = *pipe_names[pipe_idx].trans_syntax; - *abstract = *pipe_names[pipe_idx].abstr_syntax; - - return True; -} - -/**************************************************************************** - Check the rpc bind acknowledge response. -****************************************************************************/ - -static bool check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFACE *transfer) +static bool check_bind_response(RPC_HDR_BA *hdr_ba, const RPC_IFACE *transfer) { if ( hdr_ba->addr.len == 0) { DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)")); @@ -1839,8 +1813,8 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, ********************************************************************/ static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id, - RPC_IFACE *abstract, - RPC_IFACE *transfer, + const RPC_IFACE *abstract, + const RPC_IFACE *transfer, enum pipe_auth_level auth_level, const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */ prs_struct *rpc_out) @@ -1883,8 +1857,8 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, RPC_HDR *phdr, prs_struct *rbuf, uint32 rpc_call_id, - RPC_IFACE *abstract, - RPC_IFACE *transfer, + const RPC_IFACE *abstract, + const RPC_IFACE *transfer, enum pipe_auth_type auth_type, enum pipe_auth_level auth_level) { @@ -2018,8 +1992,6 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, { RPC_HDR hdr; RPC_HDR_BA hdr_ba; - RPC_IFACE abstract; - RPC_IFACE transfer; prs_struct rpc_out; prs_struct rbuf; uint32 rpc_call_id; @@ -2031,17 +2003,14 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, (unsigned int)auth_type, (unsigned int)auth_level )); - if (!valid_pipe_name(cli->pipe_idx, &abstract, &transfer)) { - return NT_STATUS_INVALID_PARAMETER; - } - prs_init_empty(&rpc_out, talloc_tos(), MARSHALL); rpc_call_id = get_rpc_call_id(); /* Marshall the outgoing data. */ status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id, - &abstract, &transfer, + cli->abstract_syntax, + cli->transfer_syntax, auth_type, auth_level); @@ -2081,7 +2050,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return NT_STATUS_BUFFER_TOO_SMALL; } - if(!check_bind_response(&hdr_ba, cli->pipe_idx, &transfer)) { + if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) { DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n")); prs_mem_free(&rbuf); return NT_STATUS_BUFFER_TOO_SMALL; @@ -2111,7 +2080,8 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: /* Need to send alter context request and reply. */ status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id, - &abstract, &transfer, + cli->abstract_syntax, + cli->transfer_syntax, auth_type, auth_level); if (!NT_STATUS_IS_OK(status)) { prs_mem_free(&rbuf); @@ -2162,6 +2132,11 @@ unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, return cli_set_timeout(cli->cli, timeout); } +bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx) +{ + return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax); +} + /**************************************************************************** Open a named pipe over SMB to a remote server. * @@ -2189,6 +2164,13 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe return NULL; } + if ( pipe_idx >= PI_MAX_PIPES ) { + DEBUG(0, ("cli_rpc_pipe_open: Programmer error! Invalid pipe " + "index [%d]\n", pipe_idx)); + *perr = NT_STATUS_INVALID_PARAMETER; + return NULL; + } + /* The pipe name index must fall within our array */ SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); @@ -2213,7 +2195,8 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe result->fnum = fnum; result->cli = cli; - result->pipe_idx = pipe_idx; + result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax; + result->transfer_syntax = pipe_names[pipe_idx].trans_syntax; result->auth.auth_type = PIPE_AUTH_TYPE_NONE; result->auth.auth_level = PIPE_AUTH_LEVEL_NONE; -- cgit From 33592bdcb97c05a85a9c5a8e11b351d63c326f0e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 12:19:27 +0200 Subject: Refactoring: Move stuff around for creating a pipe (This used to be commit 45be749ed69f8c1ad3ebe8ea1f35c806db2ed5d0) --- source3/rpc_client/cli_pipe.c | 74 +++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 38 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2979d168c5..3e03887bfd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2164,51 +2164,34 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe return NULL; } - if ( pipe_idx >= PI_MAX_PIPES ) { - DEBUG(0, ("cli_rpc_pipe_open: Programmer error! Invalid pipe " - "index [%d]\n", pipe_idx)); - *perr = NT_STATUS_INVALID_PARAMETER; - return NULL; - } - /* The pipe name index must fall within our array */ SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client); if (result == NULL) { + *perr = NT_STATUS_NO_MEMORY; return NULL; } result->pipe_name = cli_get_pipe_name(pipe_idx); - fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE); - - if (fnum == -1) { - DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s " - "to machine %s. Error was %s\n", - result->pipe_name, cli->desthost, - cli_errstr(cli))); - *perr = cli_get_nt_error(cli); - talloc_destroy(result); - return NULL; - } - - result->fnum = fnum; result->cli = cli; result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax; result->transfer_syntax = pipe_names[pipe_idx].trans_syntax; result->auth.auth_type = PIPE_AUTH_TYPE_NONE; result->auth.auth_level = PIPE_AUTH_LEVEL_NONE; + result->domain = talloc_strdup(result, cli->domain); + result->user_name = talloc_strdup(result, cli->user_name); result->desthost = talloc_strdup(result, cli->desthost); - if (result->desthost == NULL) { - TALLOC_FREE(result); - return NULL; - } - result->srv_name_slash = talloc_asprintf_strupper_m( result, "\\\\%s", result->desthost); - if (result->srv_name_slash == NULL) { + + if ((result->domain == NULL) + || (result->user_name == NULL) + || (result->desthost == NULL) + || (result->srv_name_slash == NULL)) { + *perr = NT_STATUS_NO_MEMORY; TALLOC_FREE(result); return NULL; } @@ -2217,11 +2200,25 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe /* Set up a netlogon credential chain for a netlogon pipe. */ result->dc = TALLOC_ZERO_P(result, struct dcinfo); if (result->dc == NULL) { - talloc_destroy(result); + *perr = NT_STATUS_NO_MEMORY; + TALLOC_FREE(result); return NULL; } } + fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE); + if (fnum == -1) { + DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s " + "to machine %s. Error was %s\n", + result->pipe_name, cli->desthost, + cli_errstr(cli))); + *perr = cli_get_nt_error(cli); + talloc_destroy(result); + return NULL; + } + + result->fnum = fnum; + DLIST_ADD(cli->pipe_list, result); *perr = NT_STATUS_OK; @@ -2241,19 +2238,10 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe return NULL; } - result->domain = talloc_strdup(result, cli->domain); - result->user_name = talloc_strdup(result, cli->user_name); - - if ((result->domain == NULL) || (result->user_name == NULL)) { - *perr = NT_STATUS_NO_MEMORY; - cli_rpc_pipe_close(result); - return NULL; - } - *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE); if (!NT_STATUS_IS_OK(*perr)) { int lvl = 0; - if (pipe_idx == PI_DSSETUP) { + if (rpccli_is_pipe_idx(result, PI_DSSETUP)) { /* non AD domains just don't have this pipe, avoid * level 0 statement in that case - gd */ lvl = 3; @@ -2305,6 +2293,9 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free; + TALLOC_FREE(result->domain); + TALLOC_FREE(result->user_name); + result->domain = talloc_strdup(result, domain); result->user_name = talloc_strdup(result, username); @@ -2525,7 +2516,14 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl return NULL; } - result->domain = domain; + TALLOC_FREE(result->domain); + result->domain = talloc_strdup(result, domain); + if (result->domain == NULL) { + cli_rpc_pipe_close(result); + *perr = NT_STATUS_NO_MEMORY; + return NULL; + } + memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16); *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level); -- cgit From e73e8297f5484b6c7f525917679414c09a145cf0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 13:51:46 +0200 Subject: Replace cli_rpc_pipe_close by a talloc destructor on rpc_pipe_struct (This used to be commit 99fc3283c4ecc791f5a242bd1983b4352ce3e6cf) --- source3/rpc_client/cli_pipe.c | 57 ++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3e03887bfd..b0d6f8eafd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1066,7 +1066,10 @@ static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli, /* Use lp_workgroup() if domain not specified */ if (!cli->domain || !cli->domain[0]) { - cli->domain = lp_workgroup(); + cli->domain = talloc_strdup(cli, lp_workgroup()); + if (cli->domain == NULL) { + return NT_STATUS_NO_MEMORY; + } } init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname()); @@ -2137,6 +2140,30 @@ bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx) return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax); } +static int rpc_pipe_destructor(struct rpc_pipe_client *p) +{ + bool ret; + + ret = cli_close(p->cli, p->fnum); + if (!ret) { + DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s, " + "fnum 0x%x to machine %s. Error was %s\n", + p->pipe_name, (int) p->fnum, + p->desthost, cli_errstr(p->cli))); + } + + if (p->auth.cli_auth_data_free_func) { + (*p->auth.cli_auth_data_free_func)(&p->auth); + } + + DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n", + p->pipe_name, p->desthost )); + + DLIST_REMOVE(p->cli->pipe_list, p); + + return ret ? -1 : 0; +} + /**************************************************************************** Open a named pipe over SMB to a remote server. * @@ -2220,6 +2247,8 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe result->fnum = fnum; DLIST_ADD(cli->pipe_list, result); + talloc_set_destructor(result, rpc_pipe_destructor); + *perr = NT_STATUS_OK; return result; @@ -2248,7 +2277,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe } DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n", cli_get_pipe_name(pipe_idx), nt_errstr(*perr) )); - cli_rpc_pipe_close(result); + TALLOC_FREE(result); return NULL; } @@ -2360,7 +2389,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta err: - cli_rpc_pipe_close(result); + TALLOC_FREE(result); return NULL; } @@ -2481,7 +2510,7 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, if (!get_schannel_session_key_common(netlogon_pipe, cli, domain, pneg_flags, perr)) { - cli_rpc_pipe_close(netlogon_pipe); + TALLOC_FREE(netlogon_pipe); return NULL; } @@ -2511,7 +2540,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl result->auth.a_u.schannel_auth = TALLOC_ZERO_P( result, struct schannel_auth_struct); if (!result->auth.a_u.schannel_auth) { - cli_rpc_pipe_close(result); + TALLOC_FREE(result); *perr = NT_STATUS_NO_MEMORY; return NULL; } @@ -2519,7 +2548,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl TALLOC_FREE(result->domain); result->domain = talloc_strdup(result, domain); if (result->domain == NULL) { - cli_rpc_pipe_close(result); + TALLOC_FREE(result); *perr = NT_STATUS_NO_MEMORY; return NULL; } @@ -2530,7 +2559,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl if (!NT_STATUS_IS_OK(*perr)) { DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n", nt_errstr(*perr) )); - cli_rpc_pipe_close(result); + TALLOC_FREE(result); return NULL; } @@ -2570,7 +2599,7 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ if (!get_schannel_session_key_common(netlogon_pipe, cli, domain, pneg_flags, perr)) { - cli_rpc_pipe_close(netlogon_pipe); + TALLOC_FREE(netlogon_pipe); return NULL; } @@ -2609,7 +2638,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state domain, netlogon_pipe->dc, perr); /* Now we've bound using the session key we can close the netlog pipe. */ - cli_rpc_pipe_close(netlogon_pipe); + TALLOC_FREE(netlogon_pipe); return result; } @@ -2642,7 +2671,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, domain, netlogon_pipe->dc, perr); /* Now we've bound using the session key we can close the netlog pipe. */ - cli_rpc_pipe_close(netlogon_pipe); + TALLOC_FREE(netlogon_pipe); return result; } @@ -2687,7 +2716,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, service_princ = talloc_asprintf(result, "%s$@%s", cli->desthost, lp_realm() ); if (!service_princ) { - cli_rpc_pipe_close(result); + TALLOC_FREE(result); return NULL; } } @@ -2696,7 +2725,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, if (username && password) { int ret = kerberos_kinit_password(username, password, 0, NULL); if (ret) { - cli_rpc_pipe_close(result); + TALLOC_FREE(result); return NULL; } } @@ -2704,7 +2733,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, result->auth.a_u.kerberos_auth = TALLOC_ZERO_P( result, struct kerberos_auth_struct); if (!result->auth.a_u.kerberos_auth) { - cli_rpc_pipe_close(result); + TALLOC_FREE(result); *perr = NT_STATUS_NO_MEMORY; return NULL; } @@ -2716,7 +2745,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, if (!NT_STATUS_IS_OK(*perr)) { DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n", nt_errstr(*perr) )); - cli_rpc_pipe_close(result); + TALLOC_FREE(result); return NULL; } -- cgit From b9cc05506273e5ce3398a5912b9c9e5989717480 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 14:05:25 +0200 Subject: Introduce rpc_pipe_np_smb_conn() This abstracts away all references to rpc_pipe_client->cli, the only reference is now in cli_pipe.c. (This used to be commit c56e1c08cef107ff33a34346ceeca3475a102b19) --- source3/rpc_client/cli_pipe.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b0d6f8eafd..1ea01c94f0 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2140,6 +2140,11 @@ bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx) return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax); } +struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p) +{ + return p->cli; +} + static int rpc_pipe_destructor(struct rpc_pipe_client *p) { bool ret; -- cgit From 712e40dad291f9a54dd41d7ac912d173628dbed6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 16:23:48 +0200 Subject: Fix some empty lines with just spaces (This used to be commit f8fb9b7e3759bec7fbcf93b27438ca6b03202ddb) --- source3/rpc_client/cli_pipe.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1ea01c94f0..d4ce45446b 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -373,7 +373,7 @@ static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *p (unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len )); return NT_STATUS_BUFFER_TOO_SMALL; } - + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) { DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n")); return NT_STATUS_BUFFER_TOO_SMALL; @@ -627,7 +627,6 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H } else { return fault_resp.status; } - } default: @@ -750,7 +749,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, uint32 max_data = cli->max_xmit_frag ? cli->max_xmit_frag : RPC_MAX_PDU_FRAG_LEN; uint32 current_rbuf_offset = 0; prs_struct current_pdu; - + #ifdef DEVELOPER /* Ensure we're not sending too much. */ SMB_ASSERT(data_len <= max_data); @@ -1311,14 +1310,14 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli, } /* Finally marshall the blob. */ - + if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) { DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n", (unsigned int)NTLMSSP_SIG_SIZE)); data_blob_free(&auth_blob); return NT_STATUS_NO_MEMORY; } - + data_blob_free(&auth_blob); return NT_STATUS_OK; } @@ -1383,7 +1382,7 @@ static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli, &verf, outgoing_pdu, 0); - + return NT_STATUS_OK; } @@ -1687,7 +1686,7 @@ static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli, init_rpc_hdr(&hdr, RPC_AUTH3, RPC_FLG_FIRST|RPC_FLG_LAST, rpc_call_id, RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length, pauth_blob->length ); - + /* Marshall it. */ if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) { DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n")); @@ -1762,11 +1761,11 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, server_response = data_blob(NULL, phdr->auth_len); prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len); - + nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, server_response, &client_reply); - + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n")); data_blob_free(&server_response); @@ -1888,7 +1887,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, server_spnego_response = data_blob(NULL, phdr->auth_len); prs_copy_data_out((char *)server_spnego_response.data, rbuf, phdr->auth_len); - + /* The server might give us back two challenges - tmp_blob is for the second. */ if (!spnego_parse_challenge(server_spnego_response, &server_ntlm_response, &tmp_blob)) { data_blob_free(&server_spnego_response); @@ -1904,7 +1903,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, server_ntlm_response, &client_reply); - + /* Finished with the server_ntlm response */ data_blob_free(&server_ntlm_response); @@ -2324,7 +2323,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta if (result == NULL) { return NULL; } - + result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free; TALLOC_FREE(result->domain); @@ -2377,7 +2376,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN; } - + *perr = rpc_pipe_bind(result, auth_type, auth_level); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n", -- cgit From b78453326bf41cf3af239a5415dfef80a842d555 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Apr 2008 08:01:51 +0200 Subject: Remove the "pwd" struct from rpc_pipe_client The only user of this was decrypt_trustdom_secret, and this only needs the NT hash anyway. (This used to be commit 3d8c2a47e677a4c4aacf4abf148b1bd8163c3351) --- source3/rpc_client/cli_pipe.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d4ce45446b..828307cace 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2139,6 +2139,18 @@ bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx) return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax); } +bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]) +{ + if (!((cli->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) + || (cli->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { + E_md4hash(cli->cli->pwd.password, nt_hash); + return true; + } + + memcpy(nt_hash, cli->auth.a_u.ntlmssp_state->nt_hash, 16); + return true; +} + struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p) { return p->cli; @@ -2337,8 +2349,6 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta goto err; } - pwd_set_cleartext(&result->pwd, password); - *perr = ntlmssp_client_start(&ntlmssp_state); if (!NT_STATUS_IS_OK(*perr)) { goto err; -- cgit From 9e9d40d0977add05ac65d35251c1a5986c721e48 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Apr 2008 10:39:37 +0200 Subject: Refactoring: Make cli_pipe_auth_data a pointer off rpc_pipe_client (This used to be commit f665afaaa3eff9ef54112e08ed034a6e1bb30edc) --- source3/rpc_client/cli_pipe.c | 119 +++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 54 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 828307cace..8c540ee6fd 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -215,7 +215,7 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr RPC_HDR_AUTH auth_info; uint32 save_offset = prs_offset(current_pdu); uint32 auth_len = prhdr->auth_len; - NTLMSSP_STATE *ntlmssp_state = cli->auth.a_u.ntlmssp_state; + NTLMSSP_STATE *ntlmssp_state = cli->auth->a_u.ntlmssp_state; unsigned char *data = NULL; size_t data_len; unsigned char *full_packet_data = NULL; @@ -223,7 +223,8 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr DATA_BLOB auth_blob; NTSTATUS status; - if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) { + if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE + || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) { return NT_STATUS_OK; } @@ -267,7 +268,7 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu); auth_blob.length = auth_len; - switch (cli->auth.auth_level) { + switch (cli->auth->auth_level) { case PIPE_AUTH_LEVEL_PRIVACY: /* Data is encrypted. */ status = ntlmssp_unseal_packet(ntlmssp_state, @@ -305,8 +306,8 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr } break; default: - DEBUG(0,("cli_pipe_verify_ntlmssp: unknown internal auth level %d\n", - cli->auth.auth_level )); + DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal " + "auth level %d\n", cli->auth->auth_level)); return NT_STATUS_INVALID_INFO_CLASS; } @@ -342,10 +343,12 @@ static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *p RPC_AUTH_SCHANNEL_CHK schannel_chk; uint32 auth_len = prhdr->auth_len; uint32 save_offset = prs_offset(current_pdu); - struct schannel_auth_struct *schannel_auth = cli->auth.a_u.schannel_auth; + struct schannel_auth_struct *schannel_auth = + cli->auth->a_u.schannel_auth; uint32 data_len; - if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) { + if (cli->auth->auth_level == PIPE_AUTH_LEVEL_NONE + || cli->auth->auth_level == PIPE_AUTH_LEVEL_CONNECT) { return NT_STATUS_OK; } @@ -392,7 +395,7 @@ static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *p } if (!schannel_decode(schannel_auth, - cli->auth.auth_level, + cli->auth->auth_level, SENDER_IS_ACCEPTOR, &schannel_chk, prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN, @@ -456,7 +459,7 @@ static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_ * Now we have a complete RPC request PDU fragment, try and verify any auth data. */ - switch(cli->auth.auth_type) { + switch(cli->auth->auth_type) { case PIPE_AUTH_TYPE_NONE: if (prhdr->auth_len) { DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s " @@ -487,12 +490,12 @@ static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_ case PIPE_AUTH_TYPE_KRB5: case PIPE_AUTH_TYPE_SPNEGO_KRB5: default: - DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s " - "pipe %s fnum %x - unknown internal auth type %u.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum, - cli->auth.auth_type )); + DEBUG(3, ("cli_pipe_validate_rpc_response: Connection " + "to remote machine %s pipe %s fnum %x - " + "unknown internal auth type %u.\n", + cli->desthost, cli->pipe_name, + (unsigned int)cli->fnum, + cli->auth->auth_type )); return NT_STATUS_INVALID_INFO_CLASS; } @@ -912,7 +915,7 @@ static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli, { #ifdef HAVE_KRB5 int ret; - struct kerberos_auth_struct *a = cli->auth.a_u.kerberos_auth; + struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth; DATA_BLOB tkt = data_blob_null; DATA_BLOB tkt_wrapped = data_blob_null; @@ -978,7 +981,7 @@ static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client init_rpc_hdr_auth(pauth_out, RPC_SPNEGO_AUTH_TYPE, (int)auth_level, 0, 1); DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n")); - nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, + nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state, null_blob, &request); @@ -1024,7 +1027,7 @@ static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli, init_rpc_hdr_auth(pauth_out, RPC_NTLMSSP_AUTH_TYPE, (int)auth_level, 0, 1); DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n")); - nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, + nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state, null_blob, &request); @@ -1256,14 +1259,15 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli, DATA_BLOB auth_blob = data_blob_null; uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; - if (!cli->auth.a_u.ntlmssp_state) { + if (!cli->auth->a_u.ntlmssp_state) { return NT_STATUS_INVALID_PARAMETER; } /* Init and marshall the auth header. */ init_rpc_hdr_auth(&auth_info, - map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type), - cli->auth.auth_level, + map_pipe_auth_type_to_rpc_auth_type( + cli->auth->auth_type), + cli->auth->auth_level, ss_padding_len, 1 /* context id. */); @@ -1273,10 +1277,10 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli, return NT_STATUS_NO_MEMORY; } - switch (cli->auth.auth_level) { + switch (cli->auth->auth_level) { case PIPE_AUTH_LEVEL_PRIVACY: /* Data portion is encrypted. */ - status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state, + status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state, (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, data_and_pad_len, (unsigned char *)prs_data_p(outgoing_pdu), @@ -1290,7 +1294,7 @@ static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli, case PIPE_AUTH_LEVEL_INTEGRITY: /* Data is signed. */ - status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state, + status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state, (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, data_and_pad_len, (unsigned char *)prs_data_p(outgoing_pdu), @@ -1333,7 +1337,7 @@ static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli, { RPC_HDR_AUTH auth_info; RPC_AUTH_SCHANNEL_CHK verf; - struct schannel_auth_struct *sas = cli->auth.a_u.schannel_auth; + struct schannel_auth_struct *sas = cli->auth->a_u.schannel_auth; char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN; size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; @@ -1343,8 +1347,8 @@ static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli, /* Init and marshall the auth header. */ init_rpc_hdr_auth(&auth_info, - map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type), - cli->auth.auth_level, + map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type), + cli->auth->auth_level, ss_padding_len, 1 /* context id. */); @@ -1353,14 +1357,14 @@ static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli, return NT_STATUS_NO_MEMORY; } - switch (cli->auth.auth_level) { + switch (cli->auth->auth_level) { case PIPE_AUTH_LEVEL_PRIVACY: case PIPE_AUTH_LEVEL_INTEGRITY: DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n", sas->seq_num)); schannel_encode(sas, - cli->auth.auth_level, + cli->auth->auth_level, SENDER_IS_INITIATOR, &verf, data_p, @@ -1399,7 +1403,7 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, { uint32 data_space, data_len; - switch (cli->auth.auth_level) { + switch (cli->auth->auth_level) { case PIPE_AUTH_LEVEL_NONE: case PIPE_AUTH_LEVEL_CONNECT: data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN; @@ -1412,7 +1416,7 @@ static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli, case PIPE_AUTH_LEVEL_INTEGRITY: case PIPE_AUTH_LEVEL_PRIVACY: /* Treat the same for all authenticated rpc requests. */ - switch(cli->auth.auth_type) { + switch(cli->auth->auth_type) { case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: case PIPE_AUTH_TYPE_NTLMSSP: *p_auth_len = NTLMSSP_SIG_SIZE; @@ -1526,7 +1530,7 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, /* Generate any auth sign/seal and add the auth footer. */ if (auth_len) { - switch (cli->auth.auth_type) { + switch (cli->auth->auth_type) { case PIPE_AUTH_TYPE_NONE: break; case PIPE_AUTH_TYPE_NTLMSSP: @@ -1762,7 +1766,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, server_response = data_blob(NULL, phdr->auth_len); prs_copy_data_out((char *)server_response.data, rbuf, phdr->auth_len); - nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, + nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state, server_response, &client_reply); @@ -1900,7 +1904,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, data_blob_free(&server_spnego_response); data_blob_free(&tmp_blob); - nt_status = ntlmssp_update(cli->auth.a_u.ntlmssp_state, + nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state, server_ntlm_response, &client_reply); @@ -2104,14 +2108,14 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, /* For NTLMSSP ensure the server gave us the auth_level we wanted. */ if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { - if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { + if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n")); prs_mem_free(&rbuf); return NT_STATUS_INVALID_PARAMETER; } } if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { - if (!(cli->auth.a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { + if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n")); prs_mem_free(&rbuf); return NT_STATUS_INVALID_PARAMETER; @@ -2121,8 +2125,8 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, /* Pipe is bound - set up auth_type and auth_level data. */ - cli->auth.auth_type = auth_type; - cli->auth.auth_level = auth_level; + cli->auth->auth_type = auth_type; + cli->auth->auth_level = auth_level; prs_mem_free(&rbuf); return NT_STATUS_OK; @@ -2141,13 +2145,13 @@ bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx) bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]) { - if (!((cli->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) - || (cli->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { + if (!((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP) + || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { E_md4hash(cli->cli->pwd.password, nt_hash); return true; } - memcpy(nt_hash, cli->auth.a_u.ntlmssp_state->nt_hash, 16); + memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16); return true; } @@ -2168,8 +2172,8 @@ static int rpc_pipe_destructor(struct rpc_pipe_client *p) p->desthost, cli_errstr(p->cli))); } - if (p->auth.cli_auth_data_free_func) { - (*p->auth.cli_auth_data_free_func)(&p->auth); + if (p->auth->cli_auth_data_free_func) { + (*p->auth->cli_auth_data_free_func)(p->auth); } DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n", @@ -2216,13 +2220,20 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe return NULL; } + result->auth = TALLOC_ZERO_P(result, struct cli_pipe_auth_data); + if (result->auth == NULL) { + *perr = NT_STATUS_NO_MEMORY; + TALLOC_FREE(result); + return NULL; + } + result->pipe_name = cli_get_pipe_name(pipe_idx); result->cli = cli; result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax; result->transfer_syntax = pipe_names[pipe_idx].trans_syntax; - result->auth.auth_type = PIPE_AUTH_TYPE_NONE; - result->auth.auth_level = PIPE_AUTH_LEVEL_NONE; + result->auth->auth_type = PIPE_AUTH_TYPE_NONE; + result->auth->auth_level = PIPE_AUTH_LEVEL_NONE; result->domain = talloc_strdup(result, cli->domain); result->user_name = talloc_strdup(result, cli->user_name); @@ -2336,7 +2347,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta return NULL; } - result->auth.cli_auth_data_free_func = cli_ntlmssp_auth_free; + result->auth->cli_auth_data_free_func = cli_ntlmssp_auth_free; TALLOC_FREE(result->domain); TALLOC_FREE(result->user_name); @@ -2354,7 +2365,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta goto err; } - result->auth.a_u.ntlmssp_state = ntlmssp_state; + result->auth->a_u.ntlmssp_state = ntlmssp_state; *perr = ntlmssp_set_username(ntlmssp_state, username); if (!NT_STATUS_IS_OK(*perr)) { @@ -2551,9 +2562,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl return NULL; } - result->auth.a_u.schannel_auth = TALLOC_ZERO_P( + result->auth->a_u.schannel_auth = TALLOC_ZERO_P( result, struct schannel_auth_struct); - if (!result->auth.a_u.schannel_auth) { + if (!result->auth->a_u.schannel_auth) { TALLOC_FREE(result); *perr = NT_STATUS_NO_MEMORY; return NULL; @@ -2567,7 +2578,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl return NULL; } - memcpy(result->auth.a_u.schannel_auth->sess_key, pdc->sess_key, 16); + memcpy(result->auth->a_u.schannel_auth->sess_key, pdc->sess_key, 16); *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level); if (!NT_STATUS_IS_OK(*perr)) { @@ -2744,16 +2755,16 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, } } - result->auth.a_u.kerberos_auth = TALLOC_ZERO_P( + result->auth->a_u.kerberos_auth = TALLOC_ZERO_P( result, struct kerberos_auth_struct); - if (!result->auth.a_u.kerberos_auth) { + if (!result->auth->a_u.kerberos_auth) { TALLOC_FREE(result); *perr = NT_STATUS_NO_MEMORY; return NULL; } - result->auth.a_u.kerberos_auth->service_principal = service_princ; - result->auth.cli_auth_data_free_func = kerberos_auth_struct_free; + result->auth->a_u.kerberos_auth->service_principal = service_princ; + result->auth->cli_auth_data_free_func = kerberos_auth_struct_free; *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level); if (!NT_STATUS_IS_OK(*perr)) { -- cgit From 862d7e32b90f7020d46e025de918f6338f40441b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Apr 2008 22:27:29 +0200 Subject: Move user/domain from rpc_pipe_client to cli_pipe_auth_data (This used to be commit 42de50d2cd43e760d776694f7b5f003ba51d7f84) --- source3/rpc_client/cli_pipe.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8c540ee6fd..14ee78202a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1067,14 +1067,15 @@ static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli, /* Use lp_workgroup() if domain not specified */ - if (!cli->domain || !cli->domain[0]) { - cli->domain = talloc_strdup(cli, lp_workgroup()); - if (cli->domain == NULL) { + if (!cli->auth->domain || !cli->auth->domain[0]) { + cli->auth->domain = talloc_strdup(cli, lp_workgroup()); + if (cli->auth->domain == NULL) { return NT_STATUS_NO_MEMORY; } } - init_rpc_auth_schannel_neg(&schannel_neg, cli->domain, global_myname()); + init_rpc_auth_schannel_neg(&schannel_neg, cli->auth->domain, + global_myname()); /* * Now marshall the data into the auth parse_struct. @@ -2235,14 +2236,14 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe result->auth->auth_type = PIPE_AUTH_TYPE_NONE; result->auth->auth_level = PIPE_AUTH_LEVEL_NONE; - result->domain = talloc_strdup(result, cli->domain); - result->user_name = talloc_strdup(result, cli->user_name); + result->auth->domain = talloc_strdup(result, cli->domain); + result->auth->user_name = talloc_strdup(result, cli->user_name); result->desthost = talloc_strdup(result, cli->desthost); result->srv_name_slash = talloc_asprintf_strupper_m( result, "\\\\%s", result->desthost); - if ((result->domain == NULL) - || (result->user_name == NULL) + if ((result->auth->domain == NULL) + || (result->auth->user_name == NULL) || (result->desthost == NULL) || (result->srv_name_slash == NULL)) { *perr = NT_STATUS_NO_MEMORY; @@ -2349,13 +2350,14 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta result->auth->cli_auth_data_free_func = cli_ntlmssp_auth_free; - TALLOC_FREE(result->domain); - TALLOC_FREE(result->user_name); + TALLOC_FREE(result->auth->domain); + TALLOC_FREE(result->auth->user_name); - result->domain = talloc_strdup(result, domain); - result->user_name = talloc_strdup(result, username); + result->auth->domain = talloc_strdup(result, domain); + result->auth->user_name = talloc_strdup(result, username); - if ((result->domain == NULL) || (result->user_name == NULL)) { + if ((result->auth->domain == NULL) + || (result->auth->user_name == NULL)) { *perr = NT_STATUS_NO_MEMORY; goto err; } @@ -2570,9 +2572,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl return NULL; } - TALLOC_FREE(result->domain); - result->domain = talloc_strdup(result, domain); - if (result->domain == NULL) { + TALLOC_FREE(result->auth->domain); + result->auth->domain = talloc_strdup(result, domain); + if (result->auth->domain == NULL) { TALLOC_FREE(result); *perr = NT_STATUS_NO_MEMORY; return NULL; -- cgit From 253b0b88687d4f72f1a4f1e7a9e46e438d56bd0d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 22 Apr 2008 13:03:06 +0200 Subject: Create rpccli_xxx_bind_data functions These functions create the auth data for the later bind (This used to be commit 630b9c241cb6db758f8290420a38af452569e903) --- source3/rpc_client/cli_pipe.c | 198 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 14ee78202a..991029d203 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2185,6 +2185,204 @@ static int rpc_pipe_destructor(struct rpc_pipe_client *p) return ret ? -1 : 0; } +NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, + struct cli_pipe_auth_data **presult) +{ + struct cli_pipe_auth_data *result; + + result = talloc(mem_ctx, struct cli_pipe_auth_data); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->auth_type = PIPE_AUTH_TYPE_NONE; + result->auth_level = PIPE_AUTH_LEVEL_NONE; + + result->user_name = talloc_strdup(result, ""); + result->domain = talloc_strdup(result, ""); + if ((result->user_name == NULL) || (result->domain == NULL)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + *presult = result; + return NT_STATUS_OK; +} + +static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth) +{ + ntlmssp_end(&auth->a_u.ntlmssp_state); + return 0; +} + +NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx, + enum pipe_auth_type auth_type, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + struct cli_pipe_auth_data **presult) +{ + struct cli_pipe_auth_data *result; + NTSTATUS status; + + result = talloc(mem_ctx, struct cli_pipe_auth_data); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->auth_type = auth_type; + result->auth_level = auth_level; + + result->user_name = talloc_strdup(result, username); + result->domain = talloc_strdup(result, domain); + if ((result->user_name == NULL) || (result->domain == NULL)) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + status = ntlmssp_client_start(&result->a_u.ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor); + + status = ntlmssp_set_username(result->a_u.ntlmssp_state, username); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + status = ntlmssp_set_password(result->a_u.ntlmssp_state, password); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + /* + * Turn off sign+seal to allow selected auth level to turn it back on. + */ + result->a_u.ntlmssp_state->neg_flags &= + ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL); + + if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { + result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { + result->a_u.ntlmssp_state->neg_flags + |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN; + } + + *presult = result; + return NT_STATUS_OK; + + fail: + TALLOC_FREE(result); + return status; +} + +NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain, + enum pipe_auth_level auth_level, + const struct dcinfo *pdc, + struct cli_pipe_auth_data **presult) +{ + struct cli_pipe_auth_data *result; + + result = talloc(mem_ctx, struct cli_pipe_auth_data); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->auth_type = PIPE_AUTH_TYPE_SCHANNEL; + result->auth_level = auth_level; + + result->user_name = talloc_strdup(result, ""); + result->domain = talloc_strdup(result, domain); + if ((result->user_name == NULL) || (result->domain == NULL)) { + goto fail; + } + + result->a_u.schannel_auth = talloc(result, + struct schannel_auth_struct); + if (result->a_u.schannel_auth == NULL) { + goto fail; + } + + memcpy(result->a_u.schannel_auth->sess_key, pdc->sess_key, 16); + result->a_u.schannel_auth->seq_num = 0; + + *presult = result; + return NT_STATUS_OK; + + fail: + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; +} + +static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth) +{ + data_blob_free(&auth->session_key); + return 0; +} + +NTSTATUS rpccli_krb5_bind_data(TALLOC_CTX *mem_ctx, + enum pipe_auth_level auth_level, + const char *service_princ, + const char *username, + const char *password, + struct cli_pipe_auth_data **presult) +{ + struct cli_pipe_auth_data *result; + + if ((username != NULL) && (password != NULL)) { + int ret = kerberos_kinit_password(username, password, 0, NULL); + if (ret != 0) { + return NT_STATUS_ACCESS_DENIED; + } + } + + result = talloc(mem_ctx, struct cli_pipe_auth_data); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->auth_type = PIPE_AUTH_TYPE_KRB5; + result->auth_level = auth_level; + + /* + * Username / domain need fixing! + */ + result->user_name = talloc_strdup(result, ""); + result->domain = talloc_strdup(result, ""); + if ((result->user_name == NULL) || (result->domain == NULL)) { + goto fail; + } + + result->a_u.kerberos_auth = TALLOC_ZERO_P( + result, struct kerberos_auth_struct); + if (result->a_u.kerberos_auth == NULL) { + goto fail; + } + talloc_set_destructor(result->a_u.kerberos_auth, + cli_auth_kerberos_data_destructor); + + result->a_u.kerberos_auth->service_principal = talloc_strdup( + result, service_princ); + if (result->a_u.kerberos_auth->service_principal == NULL) { + goto fail; + } + + *presult = result; + return NT_STATUS_OK; + + fail: + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; +} + /**************************************************************************** Open a named pipe over SMB to a remote server. * -- cgit From 324e92ea670d7bd6b1630b04fb5fb51324abda7b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 22 Apr 2008 14:31:35 +0200 Subject: Make use of rpccli_xxx_bind_data (This used to be commit f9bc336affd2ce21a3c62880ecea2622f35653d1) --- source3/rpc_client/cli_pipe.c | 230 ++++++++++++------------------------------ 1 file changed, 62 insertions(+), 168 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 991029d203..1897cff18e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1994,8 +1994,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, ****************************************************************************/ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, - enum pipe_auth_type auth_type, - enum pipe_auth_level auth_level) + struct cli_pipe_auth_data *auth) { RPC_HDR hdr; RPC_HDR_BA hdr_ba; @@ -2007,8 +2006,10 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n", (unsigned int)cli->fnum, cli->pipe_name, - (unsigned int)auth_type, - (unsigned int)auth_level )); + (unsigned int)auth->auth_type, + (unsigned int)auth->auth_level )); + + cli->auth = talloc_move(cli, &auth); prs_init_empty(&rpc_out, talloc_tos(), MARSHALL); @@ -2018,8 +2019,8 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id, cli->abstract_syntax, cli->transfer_syntax, - auth_type, - auth_level); + cli->auth->auth_type, + cli->auth->auth_level); if (!NT_STATUS_IS_OK(status)) { prs_mem_free(&rpc_out); @@ -2067,7 +2068,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, cli->max_recv_frag = hdr_ba.bba.max_rsize; /* For authenticated binds we may need to do 3 or 4 leg binds. */ - switch(auth_type) { + switch(cli->auth->auth_type) { case PIPE_AUTH_TYPE_NONE: case PIPE_AUTH_TYPE_SCHANNEL: @@ -2076,8 +2077,10 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, case PIPE_AUTH_TYPE_NTLMSSP: /* Need to send AUTH3 packet - no reply. */ - status = rpc_finish_auth3_bind(cli, &hdr, &rbuf, rpc_call_id, - auth_type, auth_level); + status = rpc_finish_auth3_bind( + cli, &hdr, &rbuf, rpc_call_id, + cli->auth->auth_type, + cli->auth->auth_level); if (!NT_STATUS_IS_OK(status)) { prs_mem_free(&rbuf); return status; @@ -2086,10 +2089,10 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: /* Need to send alter context request and reply. */ - status = rpc_finish_spnego_ntlmssp_bind(cli, &hdr, &rbuf, rpc_call_id, - cli->abstract_syntax, - cli->transfer_syntax, - auth_type, auth_level); + status = rpc_finish_spnego_ntlmssp_bind( + cli, &hdr, &rbuf, rpc_call_id, + cli->abstract_syntax, cli->transfer_syntax, + cli->auth->auth_type, cli->auth->auth_level); if (!NT_STATUS_IS_OK(status)) { prs_mem_free(&rbuf); return status; @@ -2100,22 +2103,23 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, /* */ default: - DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n", - (unsigned int)auth_type )); + DEBUG(0,("cli_finish_bind_auth: unknown auth type " + "%u\n", (unsigned int)cli->auth->auth_type)); prs_mem_free(&rbuf); return NT_STATUS_INVALID_INFO_CLASS; } /* For NTLMSSP ensure the server gave us the auth_level we wanted. */ - if (auth_type == PIPE_AUTH_TYPE_NTLMSSP || auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { - if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { + if (cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP + || cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) { + if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP signing and server refused.\n")); prs_mem_free(&rbuf); return NT_STATUS_INVALID_PARAMETER; } } - if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { + if (cli->auth->auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { if (!(cli->auth->a_u.ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { DEBUG(0,("cli_finish_bind_auth: requested NTLMSSSP sealing and server refused.\n")); prs_mem_free(&rbuf); @@ -2124,11 +2128,6 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, } } - /* Pipe is bound - set up auth_type and auth_level data. */ - - cli->auth->auth_type = auth_type; - cli->auth->auth_level = auth_level; - prs_mem_free(&rbuf); return NT_STATUS_OK; } @@ -2173,10 +2172,6 @@ static int rpc_pipe_destructor(struct rpc_pipe_client *p) p->desthost, cli_errstr(p->cli))); } - if (p->auth->cli_auth_data_free_func) { - (*p->auth->cli_auth_data_free_func)(p->auth); - } - DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n", p->pipe_name, p->desthost )); @@ -2328,12 +2323,12 @@ static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth) return 0; } -NTSTATUS rpccli_krb5_bind_data(TALLOC_CTX *mem_ctx, - enum pipe_auth_level auth_level, - const char *service_princ, - const char *username, - const char *password, - struct cli_pipe_auth_data **presult) +NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, + enum pipe_auth_level auth_level, + const char *service_princ, + const char *username, + const char *password, + struct cli_pipe_auth_data **presult) { struct cli_pipe_auth_data *result; @@ -2419,31 +2414,16 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe return NULL; } - result->auth = TALLOC_ZERO_P(result, struct cli_pipe_auth_data); - if (result->auth == NULL) { - *perr = NT_STATUS_NO_MEMORY; - TALLOC_FREE(result); - return NULL; - } - result->pipe_name = cli_get_pipe_name(pipe_idx); result->cli = cli; result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax; result->transfer_syntax = pipe_names[pipe_idx].trans_syntax; - result->auth->auth_type = PIPE_AUTH_TYPE_NONE; - result->auth->auth_level = PIPE_AUTH_LEVEL_NONE; - - result->auth->domain = talloc_strdup(result, cli->domain); - result->auth->user_name = talloc_strdup(result, cli->user_name); result->desthost = talloc_strdup(result, cli->desthost); result->srv_name_slash = talloc_asprintf_strupper_m( result, "\\\\%s", result->desthost); - if ((result->auth->domain == NULL) - || (result->auth->user_name == NULL) - || (result->desthost == NULL) - || (result->srv_name_slash == NULL)) { + if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) { *perr = NT_STATUS_NO_MEMORY; TALLOC_FREE(result); return NULL; @@ -2487,13 +2467,22 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) { struct rpc_pipe_client *result; + struct cli_pipe_auth_data *auth; result = cli_rpc_pipe_open(cli, pipe_idx, perr); if (result == NULL) { return NULL; } - *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_NONE, PIPE_AUTH_LEVEL_NONE); + *perr = rpccli_anon_bind_data(result, &auth); + if (!NT_STATUS_IS_OK(*perr)) { + DEBUG(0, ("rpccli_anon_bind_data returned %s\n", + nt_errstr(*perr))); + TALLOC_FREE(result); + return NULL; + } + + *perr = rpc_pipe_bind(result, auth); if (!NT_STATUS_IS_OK(*perr)) { int lvl = 0; if (rpccli_is_pipe_idx(result, PI_DSSETUP)) { @@ -2513,18 +2502,6 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe return result; } -/**************************************************************************** - Free function for NTLMSSP auth. - ****************************************************************************/ - -static void cli_ntlmssp_auth_free(struct cli_pipe_auth_data *auth) -{ - if (auth->a_u.ntlmssp_state) { - ntlmssp_end(&auth->a_u.ntlmssp_state); - auth->a_u.ntlmssp_state = NULL; - } -} - /**************************************************************************** Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP ****************************************************************************/ @@ -2539,66 +2516,24 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta NTSTATUS *perr) { struct rpc_pipe_client *result; - NTLMSSP_STATE *ntlmssp_state = NULL; + struct cli_pipe_auth_data *auth; result = cli_rpc_pipe_open(cli, pipe_idx, perr); if (result == NULL) { return NULL; } - result->auth->cli_auth_data_free_func = cli_ntlmssp_auth_free; - - TALLOC_FREE(result->auth->domain); - TALLOC_FREE(result->auth->user_name); - - result->auth->domain = talloc_strdup(result, domain); - result->auth->user_name = talloc_strdup(result, username); - - if ((result->auth->domain == NULL) - || (result->auth->user_name == NULL)) { - *perr = NT_STATUS_NO_MEMORY; - goto err; - } - - *perr = ntlmssp_client_start(&ntlmssp_state); + *perr = rpccli_ntlmssp_bind_data( + result, auth_type, auth_level, domain, username, + cli->pwd.null_pwd ? NULL : password, &auth); if (!NT_STATUS_IS_OK(*perr)) { - goto err; - } - - result->auth->a_u.ntlmssp_state = ntlmssp_state; - - *perr = ntlmssp_set_username(ntlmssp_state, username); - if (!NT_STATUS_IS_OK(*perr)) { - goto err; - } - - *perr = ntlmssp_set_domain(ntlmssp_state, domain); - if (!NT_STATUS_IS_OK(*perr)) { - goto err; - } - - if (cli->pwd.null_pwd) { - *perr = ntlmssp_set_password(ntlmssp_state, NULL); - if (!NT_STATUS_IS_OK(*perr)) { - goto err; - } - } else { - *perr = ntlmssp_set_password(ntlmssp_state, password); - if (!NT_STATUS_IS_OK(*perr)) { - goto err; - } - } - - /* Turn off sign+seal to allow selected auth level to turn it back on. */ - ntlmssp_state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL); - - if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN; + DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n", + nt_errstr(*perr))); + TALLOC_FREE(result); + return NULL; } - *perr = rpc_pipe_bind(result, auth_type, auth_level); + *perr = rpc_pipe_bind(result, auth); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n", nt_errstr(*perr) )); @@ -2756,31 +2691,23 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl NTSTATUS *perr) { struct rpc_pipe_client *result; + struct cli_pipe_auth_data *auth; result = cli_rpc_pipe_open(cli, pipe_idx, perr); if (result == NULL) { return NULL; } - result->auth->a_u.schannel_auth = TALLOC_ZERO_P( - result, struct schannel_auth_struct); - if (!result->auth->a_u.schannel_auth) { + *perr = rpccli_schannel_bind_data(result, domain, auth_level, + pdc, &auth); + if (!NT_STATUS_IS_OK(*perr)) { + DEBUG(0, ("rpccli_schannel_bind_data returned %s\n", + nt_errstr(*perr))); TALLOC_FREE(result); - *perr = NT_STATUS_NO_MEMORY; return NULL; } - TALLOC_FREE(result->auth->domain); - result->auth->domain = talloc_strdup(result, domain); - if (result->auth->domain == NULL) { - TALLOC_FREE(result); - *perr = NT_STATUS_NO_MEMORY; - return NULL; - } - - memcpy(result->auth->a_u.schannel_auth->sess_key, pdc->sess_key, 16); - - *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_SCHANNEL, auth_level); + *perr = rpc_pipe_bind(result, auth); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n", nt_errstr(*perr) )); @@ -2901,19 +2828,6 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, return result; } -#ifdef HAVE_KRB5 - -/**************************************************************************** - Free function for the kerberos spcific data. - ****************************************************************************/ - -static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a) -{ - data_blob_free(&a->a_u.kerberos_auth->session_key); -} - -#endif - /**************************************************************************** Open a named pipe to an SMB server and bind using krb5 (bind type 16). The idea is this can be called with service_princ, username and password all @@ -2930,43 +2844,23 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, { #ifdef HAVE_KRB5 struct rpc_pipe_client *result; + struct cli_pipe_auth_data *auth; result = cli_rpc_pipe_open(cli, pipe_idx, perr); if (result == NULL) { return NULL; } - /* Default service principal is "desthost$@realm" */ - if (!service_princ) { - service_princ = talloc_asprintf(result, "%s$@%s", - cli->desthost, lp_realm() ); - if (!service_princ) { - TALLOC_FREE(result); - return NULL; - } - } - - /* Only get a new TGT if username/password are given. */ - if (username && password) { - int ret = kerberos_kinit_password(username, password, 0, NULL); - if (ret) { - TALLOC_FREE(result); - return NULL; - } - } - - result->auth->a_u.kerberos_auth = TALLOC_ZERO_P( - result, struct kerberos_auth_struct); - if (!result->auth->a_u.kerberos_auth) { + *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ, + username, password, &auth); + if (!NT_STATUS_IS_OK(*perr)) { + DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n", + nt_errstr(*perr))); TALLOC_FREE(result); - *perr = NT_STATUS_NO_MEMORY; return NULL; } - result->auth->a_u.kerberos_auth->service_principal = service_princ; - result->auth->cli_auth_data_free_func = kerberos_auth_struct_free; - - *perr = rpc_pipe_bind(result, PIPE_AUTH_TYPE_KRB5, auth_level); + *perr = rpc_pipe_bind(result, auth); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n", nt_errstr(*perr) )); -- cgit From eb5582d28ae486f97427cd9015e717466879e4ab Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 22 Apr 2008 18:17:01 +0200 Subject: cli_rpc_pipe_open_noauth must take the user/domain from the smb session (This used to be commit 6f08128cf2722618e74b603e180e7e2a83d7d07a) --- source3/rpc_client/cli_pipe.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1897cff18e..748a000b47 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2482,6 +2482,24 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe return NULL; } + /* + * This is a bit of an abstraction violation due to the fact that an + * anonymous bind on an authenticated SMB inherits the user/domain + * from the enclosing SMB creds + */ + + TALLOC_FREE(auth->user_name); + TALLOC_FREE(auth->domain); + + auth->user_name = talloc_strdup(auth, cli->user_name); + auth->domain = talloc_strdup(auth, cli->domain); + + if ((auth->user_name == NULL) || (auth->domain == NULL)) { + *perr = NT_STATUS_NO_MEMORY; + TALLOC_FREE(result); + return NULL; + } + *perr = rpc_pipe_bind(result, auth); if (!NT_STATUS_IS_OK(*perr)) { int lvl = 0; -- cgit From cf182c0a7685dc962d67e16212ea0fc535c17683 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Apr 2008 20:24:37 +0200 Subject: Introduce rpccli_pipe_txt(), describing a pipe for debug messages (This used to be commit 83892d51de0dcdaeae18bc34d03eefefc95ff601) --- source3/rpc_client/cli_pipe.c | 155 +++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 93 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 748a000b47..642784c765 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -57,6 +57,19 @@ static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type) return -1; } +/******************************************************************** + Pipe description for a DEBUG + ********************************************************************/ +static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli) +{ + char *result; + result = talloc_asprintf(mem_ctx, "host %s, pipe %s, fnum 0x%x", + cli->desthost, cli->pipe_name, + (unsigned int)(cli->fnum)); + SMB_ASSERT(result != NULL); + return result; +} + /******************************************************************** Rpc pipe call id. ********************************************************************/ @@ -123,7 +136,7 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n", eclass, (unsigned int)ecode, cli_errstr(cli->cli), - cli->pipe_name )); + rpccli_pipe_txt(debug_ctx(), cli))); return dos_to_ntstatus(eclass, ecode); } } @@ -135,14 +148,14 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) { DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n", nt_errstr(cli_nt_error(cli->cli)), - cli->pipe_name )); + rpccli_pipe_txt(debug_ctx(), cli))); return cli_nt_error(cli->cli); } } if (num_read == -1) { DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n", - cli->pipe_name )); + rpccli_pipe_txt(debug_ctx(), cli))); return cli_get_nt_error(cli->cli); } @@ -278,11 +291,8 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr &auth_blob); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal " - "packet from remote machine %s on pipe %s " - "fnum 0x%x. Error was %s.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum, + "packet from %s. Error was %s.\n", + rpccli_pipe_txt(debug_ctx(), cli), nt_errstr(status) )); return status; } @@ -296,11 +306,8 @@ static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *pr &auth_blob); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on " - "packet from remote machine %s on pipe %s " - "fnum 0x%x. Error was %s.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum, + "packet from %s. Error was %s.\n", + rpccli_pipe_txt(debug_ctx(), cli), nt_errstr(status) )); return status; } @@ -401,11 +408,8 @@ static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *p prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN, data_len)) { DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU " - "Connection to remote machine %s " - "pipe %s fnum 0x%x.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum )); + "Connection to %s.\n", + rpccli_pipe_txt(debug_ctx(), cli))); return NT_STATUS_INVALID_PARAMETER; } @@ -462,11 +466,10 @@ static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_ switch(cli->auth->auth_type) { case PIPE_AUTH_TYPE_NONE: if (prhdr->auth_len) { - DEBUG(3, ("cli_pipe_validate_rpc_response: Connection to remote machine %s " - "pipe %s fnum 0x%x - got non-zero auth len %u.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum, + DEBUG(3, ("cli_pipe_validate_rpc_response: " + "Connection to %s - got non-zero " + "auth len %u.\n", + rpccli_pipe_txt(debug_ctx(), cli), (unsigned int)prhdr->auth_len )); return NT_STATUS_INVALID_PARAMETER; } @@ -491,10 +494,8 @@ static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_ case PIPE_AUTH_TYPE_SPNEGO_KRB5: default: DEBUG(3, ("cli_pipe_validate_rpc_response: Connection " - "to remote machine %s pipe %s fnum %x - " - "unknown internal auth type %u.\n", - cli->desthost, cli->pipe_name, - (unsigned int)cli->fnum, + "to %s - unknown internal auth type %u.\n", + rpccli_pipe_txt(debug_ctx(), cli), cli->auth->auth_type )); return NT_STATUS_INVALID_INFO_CLASS; } @@ -596,11 +597,9 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H } case RPC_BINDNACK: - DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK received from remote machine %s " - "pipe %s fnum 0x%x!\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum)); + DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK " + "received from %s!\n", + rpccli_pipe_txt(debug_ctx(), cli))); /* Use this for now... */ return NT_STATUS_NETWORK_ACCESS_DENIED; @@ -619,12 +618,10 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H return NT_STATUS_BUFFER_TOO_SMALL; } - DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault code %s received from remote machine %s " - "pipe %s fnum 0x%x!\n", + DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault " + "code %s received from %s!\n", dcerpc_errstr(NT_STATUS_V(fault_resp.status)), - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum)); + rpccli_pipe_txt(debug_ctx(), cli))); if (NT_STATUS_IS_OK(fault_resp.status)) { return NT_STATUS_UNSUCCESSFUL; } else { @@ -634,21 +631,16 @@ static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_H default: DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received " - "from remote machine %s pipe %s fnum 0x%x!\n", + "from %s!\n", (unsigned int)prhdr->pkt_type, - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum)); + rpccli_pipe_txt(debug_ctx(), cli))); return NT_STATUS_INVALID_INFO_CLASS; } if (prhdr->pkt_type != expected_pkt_type) { - DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to remote machine %s " - "pipe %s fnum %x got an unexpected RPC packet " - "type - %u, not %u\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum, + DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s " + "got an unexpected RPC packet type - %u, not %u\n", + rpccli_pipe_txt(debug_ctx(), cli), prhdr->pkt_type, expected_pkt_type)); return NT_STATUS_INVALID_INFO_CLASS; @@ -765,10 +757,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, setup[0] = TRANSACT_DCERPCCMD; setup[1] = cli->fnum; /* Pipe file handle. */ - DEBUG(5,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum )); + DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli))); /* * Send the last (or only) fragment of an RPC request. For small @@ -783,12 +772,9 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, &rparam, &rparam_len, /* return params, len */ &prdata, &rdata_len)) /* return data, len */ { - DEBUG(0, ("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x " - "returned critical error. Error was %s\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum, - cli_errstr(cli->cli))); + DEBUG(0, ("rpc_api_pipe: %s returned critical error. Error " + "was %s\n", rpccli_pipe_txt(debug_ctx(), cli), + cli_errstr(cli->cli))); ret = cli_get_nt_error(cli->cli); SAFE_FREE(rparam); SAFE_FREE(prdata); @@ -800,11 +786,8 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, SAFE_FREE(rparam); if (prdata == NULL) { - DEBUG(3,("rpc_api_pipe: Remote machine %s pipe %s " - "fnum 0x%x failed to return data.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum)); + DEBUG(3,("rpc_api_pipe: %s failed to return data.\n", + rpccli_pipe_txt(debug_ctx(), cli))); /* Yes - some calls can truely return no data... */ prs_mem_free(¤t_pdu); return NT_STATUS_OK; @@ -850,11 +833,9 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, if ((rhdr.flags & RPC_FLG_FIRST)) { if (rhdr.pack_type[0] == 0) { /* Set the data type correctly for big-endian data on the first packet. */ - DEBUG(10,("rpc_api_pipe: On machine %s pipe %s fnum 0x%x " + DEBUG(10,("rpc_api_pipe: On %s " "PDU data format is big-endian.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum)); + rpccli_pipe_txt(debug_ctx(), cli))); prs_set_endian_data(rbuf, RPC_BIG_ENDIAN); } else { @@ -888,10 +869,8 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, } } - DEBUG(10,("rpc_api_pipe: Remote machine %s pipe %s fnum 0x%x returned %u bytes.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum, + DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n", + rpccli_pipe_txt(debug_ctx(), cli), (unsigned int)prs_data_size(rbuf) )); prs_mem_free(¤t_pdu); @@ -1802,11 +1781,8 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, return cli_get_nt_error(cli->cli); } - DEBUG(5,("rpc_send_auth_auth3: Remote machine %s pipe %s " - "fnum 0x%x sent auth3 response ok.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum)); + DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n", + rpccli_pipe_txt(debug_ctx(), cli))); prs_mem_free(&rpc_out); data_blob_free(&client_reply); @@ -1981,10 +1957,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, data_blob_free(&tmp_blob); DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to " - "remote machine %s pipe %s fnum 0x%x.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum)); + "%s.\n", rpccli_pipe_txt(debug_ctx(), cli))); return NT_STATUS_OK; } @@ -2003,9 +1976,8 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, uint32 rpc_call_id; NTSTATUS status; - DEBUG(5,("Bind RPC Pipe[%x]: %s auth_type %u, auth_level %u\n", - (unsigned int)cli->fnum, - cli->pipe_name, + DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n", + rpccli_pipe_txt(debug_ctx(), cli), (unsigned int)auth->auth_type, (unsigned int)auth->auth_level )); @@ -2039,11 +2011,8 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, prs_mem_free(&rpc_out); - DEBUG(3,("rpc_pipe_bind: Remote machine %s pipe %s " - "fnum 0x%x bind request returned ok.\n", - cli->desthost, - cli->pipe_name, - (unsigned int)cli->fnum)); + DEBUG(3,("rpc_pipe_bind: %s bind request returned ok.\n", + rpccli_pipe_txt(debug_ctx(), cli))); /* Unmarshall the RPC header */ if(!smb_io_rpc_hdr("hdr" , &hdr, &rbuf, 0)) { @@ -2166,14 +2135,14 @@ static int rpc_pipe_destructor(struct rpc_pipe_client *p) ret = cli_close(p->cli, p->fnum); if (!ret) { - DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s, " - "fnum 0x%x to machine %s. Error was %s\n", - p->pipe_name, (int) p->fnum, - p->desthost, cli_errstr(p->cli))); + DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s. " + "Error was %s\n", + rpccli_pipe_txt(debug_ctx(), p), + cli_errstr(p->cli))); } - DEBUG(10, ("rpc_pipe_destructor: closed pipe %s to machine %s\n", - p->pipe_name, p->desthost )); + DEBUG(10, ("rpc_pipe_destructor: closed %s\n", + rpccli_pipe_txt(debug_ctx(), p))); DLIST_REMOVE(p->cli->pipe_list, p); -- cgit From 63e0884df518b497d8dfee6ebdf916b73b8d9645 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Apr 2008 20:42:32 +0200 Subject: Introduce a redirection for ncacn_np and ncacn_ip_tcp in rpc_pipe_client Should be no functional change, just a change in the data structure (This used to be commit 3433f430b0c1f7d350a40eac783385a2d30d905c) --- source3/rpc_client/cli_pipe.c | 123 ++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 52 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 642784c765..af12999995 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -64,8 +64,9 @@ static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli) { char *result; result = talloc_asprintf(mem_ctx, "host %s, pipe %s, fnum 0x%x", - cli->desthost, cli->pipe_name, - (unsigned int)(cli->fnum)); + cli->desthost, + cli->trans.np.pipe_name, + (unsigned int)(cli->trans.np.fnum)); SMB_ASSERT(result != NULL); return result; } @@ -119,8 +120,8 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, size = (size_t)data_to_read; } - num_read = cli_read(cli->cli, cli->fnum, pdata, - (off_t)stream_offset, size); + num_read = cli_read(cli->trans.np.cli, cli->trans.np.fnum, + pdata, (off_t)stream_offset, size); DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n", (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read)); @@ -128,14 +129,14 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, /* * A dos error of ERRDOS/ERRmoredata is not an error. */ - if (cli_is_dos_error(cli->cli)) { + if (cli_is_dos_error(cli->trans.np.cli)) { uint32 ecode; uint8 eclass; - cli_dos_error(cli->cli, &eclass, &ecode); + cli_dos_error(cli->trans.np.cli, &eclass, &ecode); if (eclass != ERRDOS && ecode != ERRmoredata) { DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n", eclass, (unsigned int)ecode, - cli_errstr(cli->cli), + cli_errstr(cli->trans.np.cli), rpccli_pipe_txt(debug_ctx(), cli))); return dos_to_ntstatus(eclass, ecode); } @@ -144,19 +145,20 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, /* * Likewise for NT_STATUS_BUFFER_TOO_SMALL */ - if (cli_is_nt_error(cli->cli)) { - if (!NT_STATUS_EQUAL(cli_nt_error(cli->cli), NT_STATUS_BUFFER_TOO_SMALL)) { + if (cli_is_nt_error(cli->trans.np.cli)) { + if (!NT_STATUS_EQUAL(cli_nt_error(cli->trans.np.cli), + NT_STATUS_BUFFER_TOO_SMALL)) { DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n", - nt_errstr(cli_nt_error(cli->cli)), + nt_errstr(cli_nt_error(cli->trans.np.cli)), rpccli_pipe_txt(debug_ctx(), cli))); - return cli_nt_error(cli->cli); + return cli_nt_error(cli->trans.np.cli); } } if (num_read == -1) { DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n", rpccli_pipe_txt(debug_ctx(), cli))); - return cli_get_nt_error(cli->cli); + return cli_get_nt_error(cli->trans.np.cli); } data_to_read -= num_read; @@ -755,7 +757,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, /* Create setup parameters - must be in native byte order. */ setup[0] = TRANSACT_DCERPCCMD; - setup[1] = cli->fnum; /* Pipe file handle. */ + setup[1] = cli->trans.np.fnum; /* Pipe file handle. */ DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli))); @@ -765,7 +767,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, * appears in a SMBtrans request and response. */ - if (!cli_api_pipe(cli->cli, "\\PIPE\\", + if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ pdata, data_len, max_data, /* data, length, max */ @@ -774,8 +776,8 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, { DEBUG(0, ("rpc_api_pipe: %s returned critical error. Error " "was %s\n", rpccli_pipe_txt(debug_ctx(), cli), - cli_errstr(cli->cli))); - ret = cli_get_nt_error(cli->cli); + cli_errstr(cli->trans.np.cli))); + ret = cli_get_nt_error(cli->trans.np.cli); SAFE_FREE(rparam); SAFE_FREE(prdata); goto err; @@ -1540,12 +1542,13 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, ret = rpc_api_pipe(cli, &outgoing_pdu, out_data, RPC_RESPONSE); prs_mem_free(&outgoing_pdu); - if (DEBUGLEVEL >= 50) { + if ((DEBUGLEVEL >= 50) + && (cli->transport_type == NCACN_NP)) { char *dump_name = NULL; /* Also capture received data */ if (asprintf(&dump_name, "%s/reply_%s_%d", - get_dyn_LOGFILEBASE(), cli->pipe_name, - op_num) > 0) { + get_dyn_LOGFILEBASE(), + cli->trans.np.pipe_name, op_num) > 0) { prs_dump(dump_name, op_num, out_data); SAFE_FREE(dump_name); } @@ -1554,14 +1557,16 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, return ret; } else { /* More packets to come - write and continue. */ - ssize_t num_written = cli_write(cli->cli, cli->fnum, 8, /* 8 means message mode. */ + ssize_t num_written = cli_write(cli->trans.np.cli, + cli->trans.np.fnum, + 8, /* 8 means message mode. */ prs_data_p(&outgoing_pdu), (off_t)0, (size_t)hdr.frag_len); if (num_written != hdr.frag_len) { prs_mem_free(&outgoing_pdu); - return cli_get_nt_error(cli->cli); + return cli_get_nt_error(cli->trans.np.cli); } } @@ -1770,7 +1775,8 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, } /* 8 here is named pipe message mode. */ - ret = cli_write(cli->cli, cli->fnum, 0x8, prs_data_p(&rpc_out), 0, + ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum, + 0x8, prs_data_p(&rpc_out), 0, (size_t)prs_offset(&rpc_out)); if (ret != (ssize_t)prs_offset(&rpc_out)) { @@ -1778,7 +1784,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, prs_mem_free(&rpc_out); data_blob_free(&client_reply); data_blob_free(&server_response); - return cli_get_nt_error(cli->cli); + return cli_get_nt_error(cli->trans.np.cli); } DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n", @@ -2104,7 +2110,7 @@ static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, unsigned int timeout) { - return cli_set_timeout(cli->cli, timeout); + return cli_set_timeout(cli->trans.np.cli, timeout); } bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx) @@ -2114,39 +2120,48 @@ bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx) bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]) { - if (!((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP) - || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { - E_md4hash(cli->cli->pwd.password, nt_hash); + if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP) + || (cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) { + memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16); return true; } - memcpy(nt_hash, cli->auth->a_u.ntlmssp_state->nt_hash, 16); - return true; + if (cli->transport_type == NCACN_NP) { + E_md4hash(cli->trans.np.cli->pwd.password, nt_hash); + return true; + } + + return false; } struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p) { - return p->cli; + if (p->transport_type == NCACN_NP) { + return p->trans.np.cli; + } + return NULL; } static int rpc_pipe_destructor(struct rpc_pipe_client *p) { - bool ret; - - ret = cli_close(p->cli, p->fnum); - if (!ret) { - DEBUG(1, ("rpc_pipe_destructor: cli_close failed on pipe %s. " - "Error was %s\n", - rpccli_pipe_txt(debug_ctx(), p), - cli_errstr(p->cli))); - } + if (p->transport_type == NCACN_NP) { + bool ret; + ret = cli_close(p->trans.np.cli, p->trans.np.fnum); + if (!ret) { + DEBUG(1, ("rpc_pipe_destructor: cli_close failed on " + "pipe %s. Error was %s\n", + rpccli_pipe_txt(debug_ctx(), p), + cli_errstr(p->trans.np.cli))); + } - DEBUG(10, ("rpc_pipe_destructor: closed %s\n", - rpccli_pipe_txt(debug_ctx(), p))); + DEBUG(10, ("rpc_pipe_destructor: closed %s\n", + rpccli_pipe_txt(debug_ctx(), p))); - DLIST_REMOVE(p->cli->pipe_list, p); + DLIST_REMOVE(p->trans.np.cli->pipe_list, p); + return ret ? -1 : 0; + } - return ret ? -1 : 0; + return -1; } NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, @@ -2383,9 +2398,11 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe return NULL; } - result->pipe_name = cli_get_pipe_name(pipe_idx); + result->transport_type = NCACN_NP; + + result->trans.np.pipe_name = cli_get_pipe_name(pipe_idx); - result->cli = cli; + result->trans.np.cli = cli; result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax; result->transfer_syntax = pipe_names[pipe_idx].trans_syntax; result->desthost = talloc_strdup(result, cli->desthost); @@ -2408,18 +2425,19 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe } } - fnum = cli_nt_create(cli, result->pipe_name, DESIRED_ACCESS_PIPE); + fnum = cli_nt_create(cli, result->trans.np.pipe_name, + DESIRED_ACCESS_PIPE); if (fnum == -1) { DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s " "to machine %s. Error was %s\n", - result->pipe_name, cli->desthost, + result->trans.np.pipe_name, cli->desthost, cli_errstr(cli))); *perr = cli_get_nt_error(cli); talloc_destroy(result); return NULL; } - result->fnum = fnum; + result->trans.np.fnum = fnum; DLIST_ADD(cli->pipe_list, result); talloc_set_destructor(result, rpc_pipe_destructor); @@ -2483,8 +2501,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe return NULL; } - DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine %s and bound anonymously.\n", - result->pipe_name, cli->desthost )); + DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine " + "%s and bound anonymously.\n", result->trans.np.pipe_name, + cli->desthost )); return result; } @@ -2529,7 +2548,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to " "machine %s and bound NTLMSSP as user %s\\%s.\n", - result->pipe_name, cli->desthost, + result->trans.np.pipe_name, cli->desthost, domain, username )); return result; @@ -2710,7 +2729,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s " "for domain %s " "and bound using schannel.\n", - result->pipe_name, cli->desthost, domain )); + result->trans.np.pipe_name, cli->desthost, domain )); return result; } -- cgit From 79fae5082a786417ab2dfa5e270b957f20929bbe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Apr 2008 22:24:20 +0200 Subject: Add basic ncacn_ip_tcp client infrastructure (This used to be commit 11072ccc7aeb6e087e78cea83959a2f6e0b2f837) --- source3/rpc_client/cli_pipe.c | 312 ++++++++++++++++++++++++++++++++---------- 1 file changed, 241 insertions(+), 71 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index af12999995..a3ad774ee3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -81,6 +81,58 @@ static uint32 get_rpc_call_id(void) return ++call_id; } +/******************************************************************* + Read from a RPC named pipe + ********************************************************************/ +static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name, + int fnum, char *buf, off_t offset, size_t size, + ssize_t *pnum_read) +{ + ssize_t num_read; + + num_read = cli_read(cli, fnum, buf, offset, size); + + DEBUG(5,("rpc_read_np: num_read = %d, read offset: %u, to read: %u\n", + (int)num_read, (unsigned int)offset, (unsigned int)size)); + + /* + * A dos error of ERRDOS/ERRmoredata is not an error. + */ + if (cli_is_dos_error(cli)) { + uint32 ecode; + uint8 eclass; + cli_dos_error(cli, &eclass, &ecode); + if (eclass != ERRDOS && ecode != ERRmoredata) { + DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read " + "on fnum 0x%x\n", eclass, (unsigned int)ecode, + cli_errstr(cli), fnum)); + return dos_to_ntstatus(eclass, ecode); + } + } + + /* + * Likewise for NT_STATUS_BUFFER_TOO_SMALL + */ + if (cli_is_nt_error(cli)) { + if (!NT_STATUS_EQUAL(cli_nt_error(cli), + NT_STATUS_BUFFER_TOO_SMALL)) { + DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum " + "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum)); + return cli_nt_error(cli); + } + } + + if (num_read == -1) { + DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned " + "-1\n", fnum)); + return cli_get_nt_error(cli); + } + + *pnum_read = num_read; + return NT_STATUS_OK; +} + + /******************************************************************* Use SMBreadX to get rest of one fragment's worth of rpc data. Will expand the current_pdu struct to the correct size. @@ -115,50 +167,35 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, pdata = prs_data_p(current_pdu) + *current_pdu_offset; do { + NTSTATUS status; + /* read data using SMBreadX */ if (size > (size_t)data_to_read) { size = (size_t)data_to_read; } - num_read = cli_read(cli->trans.np.cli, cli->trans.np.fnum, - pdata, (off_t)stream_offset, size); - - DEBUG(5,("rpc_read: num_read = %d, read offset: %u, to read: %u\n", - (int)num_read, (unsigned int)stream_offset, (unsigned int)data_to_read)); - - /* - * A dos error of ERRDOS/ERRmoredata is not an error. - */ - if (cli_is_dos_error(cli->trans.np.cli)) { - uint32 ecode; - uint8 eclass; - cli_dos_error(cli->trans.np.cli, &eclass, &ecode); - if (eclass != ERRDOS && ecode != ERRmoredata) { - DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read on pipe %s\n", - eclass, (unsigned int)ecode, - cli_errstr(cli->trans.np.cli), - rpccli_pipe_txt(debug_ctx(), cli))); - return dos_to_ntstatus(eclass, ecode); + switch (cli->transport_type) { + case NCACN_NP: + status = rpc_read_np(cli->trans.np.cli, + cli->trans.np.pipe_name, + cli->trans.np.fnum, pdata, + (off_t)stream_offset, size, + &num_read); + break; + case NCACN_IP_TCP: + status = NT_STATUS_OK; + num_read = sys_read(cli->trans.tcp.sock, pdata, size); + if (num_read == -1) { + status = map_nt_error_from_unix(errno); } - } - - /* - * Likewise for NT_STATUS_BUFFER_TOO_SMALL - */ - if (cli_is_nt_error(cli->trans.np.cli)) { - if (!NT_STATUS_EQUAL(cli_nt_error(cli->trans.np.cli), - NT_STATUS_BUFFER_TOO_SMALL)) { - DEBUG(0,("rpc_read: Error (%s) in cli_read on pipe %s\n", - nt_errstr(cli_nt_error(cli->trans.np.cli)), - rpccli_pipe_txt(debug_ctx(), cli))); - return cli_nt_error(cli->trans.np.cli); + if (num_read == 0) { + status = NT_STATUS_END_OF_FILE; } - } - - if (num_read == -1) { - DEBUG(0,("rpc_read: Error - cli_read on pipe %s returned -1\n", - rpccli_pipe_txt(debug_ctx(), cli))); - return cli_get_nt_error(cli->trans.np.cli); + break; + default: + DEBUG(0, ("unknown transport type %d\n", + cli->transport_type)); + return NT_STATUS_INTERNAL_ERROR; } data_to_read -= num_read; @@ -738,7 +775,6 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; char *rparam = NULL; uint32 rparam_len = 0; - uint16 setup[2]; char *pdata = prs_data_p(data); uint32 data_len = prs_offset(data); char *prdata = NULL; @@ -755,32 +791,71 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, /* Set up the current pdu parse struct. */ prs_init_empty(¤t_pdu, prs_get_mem_context(rbuf), UNMARSHALL); - /* Create setup parameters - must be in native byte order. */ - setup[0] = TRANSACT_DCERPCCMD; - setup[1] = cli->trans.np.fnum; /* Pipe file handle. */ - DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(debug_ctx(), cli))); - /* - * Send the last (or only) fragment of an RPC request. For small - * amounts of data (about 1024 bytes or so) the RPC request and response - * appears in a SMBtrans request and response. - */ + switch (cli->transport_type) { + case NCACN_NP: { + uint16 setup[2]; + /* Create setup parameters - must be in native byte order. */ + setup[0] = TRANSACT_DCERPCCMD; + setup[1] = cli->trans.np.fnum; /* Pipe file handle. */ + + /* + * Send the last (or only) fragment of an RPC request. For + * small amounts of data (about 1024 bytes or so) the RPC + * request and response appears in a SMBtrans request and + * response. + */ - if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\", - setup, 2, 0, /* Setup, length, max */ - NULL, 0, 0, /* Params, length, max */ - pdata, data_len, max_data, /* data, length, max */ - &rparam, &rparam_len, /* return params, len */ - &prdata, &rdata_len)) /* return data, len */ + if (!cli_api_pipe(cli->trans.np.cli, "\\PIPE\\", + setup, 2, 0, /* Setup, length, max */ + NULL, 0, 0, /* Params, length, max */ + pdata, data_len, max_data, /* data, length, + * max */ + &rparam, &rparam_len, /* return params, + * len */ + &prdata, &rdata_len)) /* return data, len */ + { + DEBUG(0, ("rpc_api_pipe: %s returned critical error. " + "Error was %s\n", + rpccli_pipe_txt(debug_ctx(), cli), + cli_errstr(cli->trans.np.cli))); + ret = cli_get_nt_error(cli->trans.np.cli); + SAFE_FREE(rparam); + SAFE_FREE(prdata); + goto err; + } + break; + } + case NCACN_IP_TCP: { - DEBUG(0, ("rpc_api_pipe: %s returned critical error. Error " - "was %s\n", rpccli_pipe_txt(debug_ctx(), cli), - cli_errstr(cli->trans.np.cli))); - ret = cli_get_nt_error(cli->trans.np.cli); - SAFE_FREE(rparam); - SAFE_FREE(prdata); - goto err; + ssize_t nwritten, nread; + nwritten = write_data(cli->trans.tcp.sock, pdata, data_len); + if (nwritten == -1) { + ret = map_nt_error_from_unix(errno); + DEBUG(0, ("rpc_api_pipe: write_data returned %s\n", + strerror(errno))); + goto err; + } + rparam = NULL; + prdata = SMB_MALLOC_ARRAY(char, 1); + if (prdata != NULL) { + nread = sys_read(cli->trans.tcp.sock, prdata, 1); + } + if (nread == 0) { + SAFE_FREE(prdata); + } + if (nread == -1) { + ret = NT_STATUS_END_OF_FILE; + goto err; + } + rdata_len = nread; + break; + } + default: + DEBUG(0, ("unknown transport type %d\n", + cli->transport_type)); + return NT_STATUS_INTERNAL_ERROR; } /* Throw away returned params - we know we won't use them. */ @@ -1557,16 +1632,39 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, return ret; } else { /* More packets to come - write and continue. */ - ssize_t num_written = cli_write(cli->trans.np.cli, + ssize_t num_written; + + switch (cli->transport_type) { + case NCACN_NP: + num_written = cli_write(cli->trans.np.cli, cli->trans.np.fnum, 8, /* 8 means message mode. */ prs_data_p(&outgoing_pdu), (off_t)0, (size_t)hdr.frag_len); - if (num_written != hdr.frag_len) { - prs_mem_free(&outgoing_pdu); - return cli_get_nt_error(cli->trans.np.cli); + if (num_written != hdr.frag_len) { + prs_mem_free(&outgoing_pdu); + return cli_get_nt_error( + cli->trans.np.cli); + } + break; + case NCACN_IP_TCP: + num_written = write_data( + cli->trans.tcp.sock, + prs_data_p(&outgoing_pdu), + (size_t)hdr.frag_len); + if (num_written != hdr.frag_len) { + NTSTATUS status; + status = map_nt_error_from_unix(errno); + prs_mem_free(&outgoing_pdu); + return status; + } + break; + default: + DEBUG(0, ("unknown transport type %d\n", + cli->transport_type)); + return NT_STATUS_INTERNAL_ERROR; } } @@ -1774,17 +1872,36 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, return nt_status; } - /* 8 here is named pipe message mode. */ - ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum, - 0x8, prs_data_p(&rpc_out), 0, + switch (cli->transport_type) { + case NCACN_NP: + /* 8 here is named pipe message mode. */ + ret = cli_write(cli->trans.np.cli, cli->trans.np.fnum, + 0x8, prs_data_p(&rpc_out), 0, (size_t)prs_offset(&rpc_out)); + break; + + if (ret != (ssize_t)prs_offset(&rpc_out)) { + nt_status = cli_get_nt_error(cli->trans.np.cli); + } + case NCACN_IP_TCP: + ret = write_data(cli->trans.tcp.sock, prs_data_p(&rpc_out), + (size_t)prs_offset(&rpc_out)); + if (ret != (ssize_t)prs_offset(&rpc_out)) { + nt_status = map_nt_error_from_unix(errno); + } + break; + default: + DEBUG(0, ("unknown transport type %d\n", cli->transport_type)); + return NT_STATUS_INTERNAL_ERROR; + } if (ret != (ssize_t)prs_offset(&rpc_out)) { - DEBUG(0,("rpc_send_auth_auth3: cli_write failed. Return was %d\n", (int)ret)); + DEBUG(0,("rpc_send_auth_auth3: write failed. Return was %s\n", + nt_errstr(nt_status))); prs_mem_free(&rpc_out); data_blob_free(&client_reply); data_blob_free(&server_response); - return cli_get_nt_error(cli->trans.np.cli); + return nt_status; } DEBUG(5,("rpc_send_auth_auth3: %s sent auth3 response ok.\n", @@ -1972,8 +2089,8 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind(struct rpc_pipe_client *cli, Do an rpc bind. ****************************************************************************/ -static NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, - struct cli_pipe_auth_data *auth) +NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, + struct cli_pipe_auth_data *auth) { RPC_HDR hdr; RPC_HDR_BA hdr_ba; @@ -2362,6 +2479,59 @@ NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } +/******************************************************************** + Create a named pipe struct, connecting to a tcp port + ********************************************************************/ +NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, + uint16_t port, + const struct ndr_syntax_id *abstract_syntax, + struct rpc_pipe_client **presult) +{ + struct rpc_pipe_client *result; + struct sockaddr_storage addr; + NTSTATUS status; + + result = talloc(mem_ctx, struct rpc_pipe_client); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->transport_type = NCACN_IP_TCP; + + result->abstract_syntax = abstract_syntax; + result->transfer_syntax = &ndr_transfer_syntax; + + result->desthost = talloc_strdup(result, host); + result->srv_name_slash = talloc_asprintf_strupper_m( + result, "\\\\%s", result->desthost); + if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; + result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN; + + if (!resolve_name(host, &addr, 0)) { + status = NT_STATUS_NOT_FOUND; + goto fail; + } + + result->trans.tcp.sock = open_socket_out(SOCK_STREAM, &addr, port, 60); + if (result->trans.tcp.sock == -1) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + *presult = result; + return NT_STATUS_OK; + + fail: + TALLOC_FREE(result); + return status; +} + + /**************************************************************************** Open a named pipe over SMB to a remote server. * -- cgit From 9de291e671a72b0871ed86cd6675bb774c0e2114 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Apr 2008 12:36:39 +0200 Subject: Attempt to fix the non-krb build (This used to be commit 31d80a476701c89bf236997f2ab68bd2765579bd) --- source3/rpc_client/cli_pipe.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a3ad774ee3..7e381f24c9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2431,6 +2431,7 @@ NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, const char *password, struct cli_pipe_auth_data **presult) { +#ifdef HAVE_KRB5 struct cli_pipe_auth_data *result; if ((username != NULL) && (password != NULL)) { @@ -2477,6 +2478,9 @@ NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, fail: TALLOC_FREE(result); return NT_STATUS_NO_MEMORY; +#else + return NT_STATUS_NOT_SUPPORTED; +#endif } /******************************************************************** -- cgit From 2c00ff5407d5b126c8d38ceb2bcc8626ee7c0c5d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 May 2008 11:15:59 +0200 Subject: Fix two uninitialized variable warnings (This used to be commit 48fd7b3635137e2fe77c0b0413965869194421ff) --- source3/rpc_client/cli_pipe.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7e381f24c9..8c801e5f6b 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -145,7 +145,7 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, { size_t size = (size_t)cli->max_recv_frag; uint32 stream_offset = 0; - ssize_t num_read; + ssize_t num_read = 0; char *pdata; ssize_t extra_data_size = ((ssize_t)*current_pdu_offset) + ((ssize_t)data_to_read) - (ssize_t)prs_data_size(current_pdu); @@ -839,9 +839,10 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, } rparam = NULL; prdata = SMB_MALLOC_ARRAY(char, 1); - if (prdata != NULL) { - nread = sys_read(cli->trans.tcp.sock, prdata, 1); + if (prdata == NULL) { + return NT_STATUS_NO_MEMORY; } + nread = sys_read(cli->trans.tcp.sock, prdata, 1); if (nread == 0) { SAFE_FREE(prdata); } -- cgit From 9a6b1f4b5f54c9d14be03c11252f1348d27131f8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 May 2008 17:05:42 +0200 Subject: Fix a comment (This used to be commit 8ae39c1339758795a91c6a168e210357e7f29eae) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8c801e5f6b..7eaeb53025 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2485,7 +2485,7 @@ NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, } /******************************************************************** - Create a named pipe struct, connecting to a tcp port + Create a rpc pipe client struct, connecting to a tcp port ********************************************************************/ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, uint16_t port, -- cgit From ec70996fc71768eabdc92076a60a9fa04ae717ab Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 May 2008 17:07:37 +0200 Subject: Rename rpc_pipe_client.tcp.sock to rpc_pipe_client.sock.fd (This used to be commit 2ff908a902ec857856518eaddb5246dd5067063d) --- source3/rpc_client/cli_pipe.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7eaeb53025..b415a39a51 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -184,7 +184,7 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, break; case NCACN_IP_TCP: status = NT_STATUS_OK; - num_read = sys_read(cli->trans.tcp.sock, pdata, size); + num_read = sys_read(cli->trans.sock.fd, pdata, size); if (num_read == -1) { status = map_nt_error_from_unix(errno); } @@ -830,7 +830,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, case NCACN_IP_TCP: { ssize_t nwritten, nread; - nwritten = write_data(cli->trans.tcp.sock, pdata, data_len); + nwritten = write_data(cli->trans.sock.fd, pdata, data_len); if (nwritten == -1) { ret = map_nt_error_from_unix(errno); DEBUG(0, ("rpc_api_pipe: write_data returned %s\n", @@ -842,7 +842,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, if (prdata == NULL) { return NT_STATUS_NO_MEMORY; } - nread = sys_read(cli->trans.tcp.sock, prdata, 1); + nread = sys_read(cli->trans.sock.fd, prdata, 1); if (nread == 0) { SAFE_FREE(prdata); } @@ -1652,7 +1652,7 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, break; case NCACN_IP_TCP: num_written = write_data( - cli->trans.tcp.sock, + cli->trans.sock.fd, prs_data_p(&outgoing_pdu), (size_t)hdr.frag_len); if (num_written != hdr.frag_len) { @@ -1885,7 +1885,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, nt_status = cli_get_nt_error(cli->trans.np.cli); } case NCACN_IP_TCP: - ret = write_data(cli->trans.tcp.sock, prs_data_p(&rpc_out), + ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out), (size_t)prs_offset(&rpc_out)); if (ret != (ssize_t)prs_offset(&rpc_out)) { nt_status = map_nt_error_from_unix(errno); @@ -2522,8 +2522,8 @@ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, goto fail; } - result->trans.tcp.sock = open_socket_out(SOCK_STREAM, &addr, port, 60); - if (result->trans.tcp.sock == -1) { + result->trans.sock.fd = open_socket_out(SOCK_STREAM, &addr, port, 60); + if (result->trans.sock.fd == -1) { status = map_nt_error_from_unix(errno); goto fail; } -- cgit From 78022953e7911a9ca7e71788b0b033b4d858126f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 May 2008 23:35:27 +0200 Subject: rpccli_schannel_bind_data only needs the schannel key (This used to be commit be5d54a363a57113e494202a2d22dd9bbcf13b41) --- source3/rpc_client/cli_pipe.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b415a39a51..03deaf60c7 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2383,7 +2383,7 @@ NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx, NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain, enum pipe_auth_level auth_level, - const struct dcinfo *pdc, + const uint8_t sess_key[16], struct cli_pipe_auth_data **presult) { struct cli_pipe_auth_data *result; @@ -2408,7 +2408,8 @@ NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain, goto fail; } - memcpy(result->a_u.schannel_auth->sess_key, pdc->sess_key, 16); + memcpy(result->a_u.schannel_auth->sess_key, sess_key, + sizeof(result->a_u.schannel_auth->sess_key)); result->a_u.schannel_auth->seq_num = 0; *presult = result; @@ -2880,7 +2881,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl } *perr = rpccli_schannel_bind_data(result, domain, auth_level, - pdc, &auth); + pdc->sess_key, &auth); if (!NT_STATUS_IS_OK(*perr)) { DEBUG(0, ("rpccli_schannel_bind_data returned %s\n", nt_errstr(*perr))); -- cgit From e8d25443c17c7c52627e7addd3a35f0646d60d38 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 May 2008 23:37:07 +0200 Subject: Add client support for NCACN_UNIX_STREAM (This used to be commit 24ac40518f79fd480baaedc1d42f3b6fe8ea1c94) --- source3/rpc_client/cli_pipe.c | 90 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 03deaf60c7..6bd240dd81 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -63,10 +63,24 @@ static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type) static char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli) { char *result; - result = talloc_asprintf(mem_ctx, "host %s, pipe %s, fnum 0x%x", - cli->desthost, - cli->trans.np.pipe_name, - (unsigned int)(cli->trans.np.fnum)); + + switch (cli->transport_type) { + case NCACN_NP: + result = talloc_asprintf(mem_ctx, "host %s, pipe %s, " + "fnum 0x%x", + cli->desthost, + cli->trans.np.pipe_name, + (unsigned int)(cli->trans.np.fnum)); + break; + case NCACN_IP_TCP: + case NCACN_UNIX_STREAM: + result = talloc_asprintf(mem_ctx, "host %s, fd %d", + cli->desthost, cli->trans.sock.fd); + break; + default: + result = talloc_asprintf(mem_ctx, "host %s", cli->desthost); + break; + } SMB_ASSERT(result != NULL); return result; } @@ -183,6 +197,7 @@ static NTSTATUS rpc_read(struct rpc_pipe_client *cli, &num_read); break; case NCACN_IP_TCP: + case NCACN_UNIX_STREAM: status = NT_STATUS_OK; num_read = sys_read(cli->trans.sock.fd, pdata, size); if (num_read == -1) { @@ -828,6 +843,7 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, break; } case NCACN_IP_TCP: + case NCACN_UNIX_STREAM: { ssize_t nwritten, nread; nwritten = write_data(cli->trans.sock.fd, pdata, data_len); @@ -1651,6 +1667,7 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, } break; case NCACN_IP_TCP: + case NCACN_UNIX_STREAM: num_written = write_data( cli->trans.sock.fd, prs_data_p(&outgoing_pdu), @@ -1885,6 +1902,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, nt_status = cli_get_nt_error(cli->trans.np.cli); } case NCACN_IP_TCP: + case NCACN_UNIX_STREAM: ret = write_data(cli->trans.sock.fd, prs_data_p(&rpc_out), (size_t)prs_offset(&rpc_out)); if (ret != (ssize_t)prs_offset(&rpc_out)) { @@ -2537,6 +2555,70 @@ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, return status; } +/******************************************************************** + Create a rpc pipe client struct, connecting to a unix domain socket + ********************************************************************/ +NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, + const struct ndr_syntax_id *abstract_syntax, + struct rpc_pipe_client **presult) +{ + struct rpc_pipe_client *result; + struct sockaddr_un addr; + NTSTATUS status; + + result = talloc(mem_ctx, struct rpc_pipe_client); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->transport_type = NCACN_UNIX_STREAM; + + result->abstract_syntax = abstract_syntax; + result->transfer_syntax = &ndr_transfer_syntax; + + result->desthost = get_myname(result); + result->srv_name_slash = talloc_asprintf_strupper_m( + result, "\\\\%s", result->desthost); + if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; + result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN; + + result->trans.sock.fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (result->trans.sock.fd == -1) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + result->dc = TALLOC_ZERO_P(result, struct dcinfo); + if (result->dc == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + ZERO_STRUCT(addr); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)); + + if (sys_connect(result->trans.sock.fd, + (struct sockaddr *)&addr) == -1) { + DEBUG(0, ("connect(%s) failed: %s\n", socket_path, + strerror(errno))); + close(result->trans.sock.fd); + return map_nt_error_from_unix(errno); + } + + *presult = result; + return NT_STATUS_OK; + + fail: + TALLOC_FREE(result); + return status; +} + /**************************************************************************** Open a named pipe over SMB to a remote server. -- cgit From 36e94197d0653fe98518ce5813bfe3f9f13d13f0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 20 May 2008 18:25:42 +0200 Subject: rpc_client: add a destructor to close the socket for pipes over tcp. used in rpc_pipe_open_tcp() and rpc_pipe_open_ncalrpc(). (This used to be commit a0bdd56c75ca6f6c6068995647c0dc1ba89aef12) --- source3/rpc_client/cli_pipe.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6bd240dd81..9908c69674 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2503,6 +2503,12 @@ NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, #endif } +static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p) +{ + close(p->trans.sock.fd); + return 0; +} + /******************************************************************** Create a rpc pipe client struct, connecting to a tcp port ********************************************************************/ @@ -2547,6 +2553,8 @@ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, goto fail; } + talloc_set_destructor(result, rpc_pipe_sock_destructor); + *presult = result; return NT_STATUS_OK; @@ -2593,6 +2601,8 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, goto fail; } + talloc_set_destructor(result, rpc_pipe_sock_destructor); + result->dc = TALLOC_ZERO_P(result, struct dcinfo); if (result->dc == NULL) { status = NT_STATUS_NO_MEMORY; -- cgit From b398a96b09af5268e71bd3108f6c1e97568736f8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 20 May 2008 18:08:41 +0200 Subject: rpc_client: use endpoint mapper to get the port for rpc_pipe_open_tcp(). Michael (This used to be commit f7db445c828c0eef2c08b538bd07d485dc248689) --- source3/rpc_client/cli_pipe.c | 167 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 160 insertions(+), 7 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 9908c69674..7a5a62f2d9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "librpc/gen_ndr/cli_epmapper.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI @@ -2509,13 +2510,13 @@ static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p) return 0; } -/******************************************************************** - Create a rpc pipe client struct, connecting to a tcp port - ********************************************************************/ -NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, - uint16_t port, - const struct ndr_syntax_id *abstract_syntax, - struct rpc_pipe_client **presult) +/** + * Create an rpc pipe client struct, connecting to a tcp port. + */ +NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host, + uint16_t port, + const struct ndr_syntax_id *abstract_syntax, + struct rpc_pipe_client **presult) { struct rpc_pipe_client *result; struct sockaddr_storage addr; @@ -2563,6 +2564,158 @@ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, return status; } +/** + * Determine the tcp port on which a dcerpc interface is listening + * for the ncacn_ip_tcp transport via the endpoint mapper of the + * target host. + */ +NTSTATUS rpc_pipe_get_tcp_port(const char *host, + const struct ndr_syntax_id *abstract_syntax, + uint16_t *pport) +{ + NTSTATUS status; + struct rpc_pipe_client *epm_pipe = NULL; + struct cli_pipe_auth_data *auth = NULL; + struct dcerpc_binding *map_binding = NULL; + struct dcerpc_binding *res_binding = NULL; + struct epm_twr_t *map_tower = NULL; + struct epm_twr_t *res_towers = NULL; + struct policy_handle *entry_handle = NULL; + uint32_t num_towers = 0; + uint32_t max_towers = 1; + struct epm_twr_p_t towers; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + + if (pport == NULL) { + status = NT_STATUS_INVALID_PARAMETER; + goto done; + } + + /* open the connection to the endpoint mapper */ + status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135, + &ndr_table_epmapper.syntax_id, + &epm_pipe); + + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpccli_anon_bind_data(tmp_ctx, &auth); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_pipe_bind(epm_pipe, auth); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + /* create tower for asking the epmapper */ + + map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding); + if (map_binding == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + map_binding->transport = NCACN_IP_TCP; + map_binding->object = *abstract_syntax; + map_binding->host = host; /* needed? */ + map_binding->endpoint = "0"; /* correct? needed? */ + + map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t); + if (map_tower == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + status = dcerpc_binding_build_tower(tmp_ctx, map_binding, + &(map_tower->tower)); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + /* allocate further parameters for the epm_Map call */ + + res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers); + if (res_towers == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + towers.twr = res_towers; + + entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle); + if (entry_handle == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + /* ask the endpoint mapper for the port */ + + status = rpccli_epm_Map(epm_pipe, + tmp_ctx, + &(abstract_syntax->uuid), + map_tower, + entry_handle, + max_towers, + &num_towers, + &towers); + + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + if (num_towers != 1) { + status = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* extract the port from the answer */ + + status = dcerpc_binding_from_tower(tmp_ctx, + &(towers.twr->tower), + &res_binding); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + /* are further checks here necessary? */ + if (res_binding->transport != NCACN_IP_TCP) { + status = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + *pport = (uint16_t)atoi(res_binding->endpoint); + +done: + TALLOC_FREE(tmp_ctx); + return status; +} + +/** + * Create a rpc pipe client struct, connecting to a host via tcp. + * The port is determined by asking the endpoint mapper on the given + * host. + */ +NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, + const struct ndr_syntax_id *abstract_syntax, + struct rpc_pipe_client **presult) +{ + NTSTATUS status; + uint16_t port; + + status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + status = rpc_pipe_open_tcp_port(mem_ctx, host, port, + abstract_syntax, presult); + +done: + return status; +} + /******************************************************************** Create a rpc pipe client struct, connecting to a unix domain socket ********************************************************************/ -- cgit From a8045b1339153175ec294acaa59d0496e90d9e03 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 22 May 2008 11:16:57 +0200 Subject: rpc_client: make rpc_pipe_open_tcp_port and rpc_pipe_get_tcp_port static. Slim the interface... Michael (This used to be commit 9971118c23900d81e885a013e738a67df790c90c) --- source3/rpc_client/cli_pipe.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7a5a62f2d9..2705fd8e4e 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2513,10 +2513,10 @@ static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p) /** * Create an rpc pipe client struct, connecting to a tcp port. */ -NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host, - uint16_t port, - const struct ndr_syntax_id *abstract_syntax, - struct rpc_pipe_client **presult) +static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host, + uint16_t port, + const struct ndr_syntax_id *abstract_syntax, + struct rpc_pipe_client **presult) { struct rpc_pipe_client *result; struct sockaddr_storage addr; @@ -2569,9 +2569,9 @@ NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host, * for the ncacn_ip_tcp transport via the endpoint mapper of the * target host. */ -NTSTATUS rpc_pipe_get_tcp_port(const char *host, - const struct ndr_syntax_id *abstract_syntax, - uint16_t *pport) +static NTSTATUS rpc_pipe_get_tcp_port(const char *host, + const struct ndr_syntax_id *abstract_syntax, + uint16_t *pport) { NTSTATUS status; struct rpc_pipe_client *epm_pipe = NULL; -- cgit From 34104dfc21e85dd37f96ca7d381d5b033b62936e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 23 May 2008 15:09:21 +0200 Subject: Fix a (bogus) uninitialized variable warning (This used to be commit 6106d48a5c94e7c1f3a7234807e43aca0a51fa62) --- source3/rpc_client/cli_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2705fd8e4e..8f410379ab 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2702,7 +2702,7 @@ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, struct rpc_pipe_client **presult) { NTSTATUS status; - uint16_t port; + uint16_t port = 0; status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port); if (!NT_STATUS_IS_OK(status)) { -- cgit From 1a16a2cf9707866c4f6d4dfe64f6c1d18d5f2075 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 24 May 2008 01:29:13 +0200 Subject: drsuapi: always use tcp for drsuapi. cli_rpc_pipe_open() now uses tcp transport for drsuapi and named pipe transport for all other pipes. This finally allows rpcclient to call dscracknames on windows (don't forget to call "seal" in advance). Guenther (This used to be commit b243a036026e79b8d3fb75bf7f7d59a27cb813af) --- source3/rpc_client/cli_pipe.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8f410379ab..cec2797a73 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2796,7 +2796,7 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, * ****************************************************************************/ -static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) +static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) { struct rpc_pipe_client *result; int fnum; @@ -2849,7 +2849,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe fnum = cli_nt_create(cli, result->trans.np.pipe_name, DESIRED_ACCESS_PIPE); if (fnum == -1) { - DEBUG(1,("cli_rpc_pipe_open: cli_nt_create failed on pipe %s " + DEBUG(1,("rpc_pipe_open_np: cli_nt_create failed on pipe %s " "to machine %s. Error was %s\n", result->trans.np.pipe_name, cli->desthost, cli_errstr(cli))); @@ -2868,6 +2868,40 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe return result; } +/**************************************************************************** + Open a pipe to a remote server. + ****************************************************************************/ + +static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, + int pipe_idx, + NTSTATUS *perr) +{ + struct rpc_pipe_client *result; + + *perr = NT_STATUS_PIPE_NOT_AVAILABLE; + + switch (pipe_idx) { + case PI_DRSUAPI: + *perr = rpc_pipe_open_tcp(NULL, cli->desthost, + &ndr_table_drsuapi.syntax_id, + &result); + if (!NT_STATUS_IS_OK(*perr)) { + return NULL; + } + break; + default: + result = rpc_pipe_open_np(cli, pipe_idx, perr); + if (result == NULL) { + return NULL; + } + break; + } + + *perr = NT_STATUS_OK; + + return result; +} + /**************************************************************************** Open a named pipe to an SMB server and bind anonymously. ****************************************************************************/ -- cgit From f1d160f33302519cfc1406579d2236063d827a27 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 25 May 2008 13:44:35 +0200 Subject: Fix a const warning Jelmer, would it be possible to make the rpc client functions take const pointers for pure [in] arguments? (This used to be commit d893b2ea13d2e64f1c13aa3984f77baa91a2c658) --- source3/rpc_client/cli_pipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index cec2797a73..8ba79d3c6d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2654,7 +2654,8 @@ static NTSTATUS rpc_pipe_get_tcp_port(const char *host, status = rpccli_epm_Map(epm_pipe, tmp_ctx, - &(abstract_syntax->uuid), + CONST_DISCARD(struct GUID *, + &(abstract_syntax->uuid)), map_tower, entry_handle, max_towers, -- cgit From 95a1f88d930808a7f1e63f47d78f349b4967b8a4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Jun 2008 10:44:47 +0200 Subject: rpc_client: fix some valgrind warnings. Guenther (This used to be commit 0352682a355b42ced7628a720a6889d8453e7946) --- source3/rpc_client/cli_pipe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8ba79d3c6d..ba6fbddf7f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2522,7 +2522,7 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host, struct sockaddr_storage addr; NTSTATUS status; - result = talloc(mem_ctx, struct rpc_pipe_client); + result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client); if (result == NULL) { return NT_STATUS_NO_MEMORY; } @@ -2705,6 +2705,8 @@ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, NTSTATUS status; uint16_t port = 0; + *presult = NULL; + status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port); if (!NT_STATUS_IS_OK(status)) { goto done; @@ -2877,7 +2879,7 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) { - struct rpc_pipe_client *result; + struct rpc_pipe_client *result = NULL; *perr = NT_STATUS_PIPE_NOT_AVAILABLE; -- cgit From 1178287eebe25d98cbd130e16d7c9c61331f83f8 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Tue, 24 Jun 2008 15:53:23 +0200 Subject: rpc_client: Avoid warning in builds without krb5 headers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit warning: ‘cli_auth_kerberos_data_destructor’ defined but not used Karolin (This used to be commit b5f9176b6ca8c137d5c065abed943fa437b5531f) --- source3/rpc_client/cli_pipe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ba6fbddf7f..2fd0a6e7eb 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2439,11 +2439,13 @@ NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain, return NT_STATUS_NO_MEMORY; } +#ifdef HAVE_KRB5 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth) { data_blob_free(&auth->session_key); return 0; } +#endif NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx, enum pipe_auth_level auth_level, -- cgit From 07f06eec2155268eb6b00e6edba0c17c13b723b9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 10 Jun 2008 21:35:34 +0200 Subject: rpc_client: add cli_get_session_key(). Guenther (This used to be commit 93b56755f739889da3a67b18a6430b14306d84f7) --- source3/rpc_client/cli_pipe.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2fd0a6e7eb..469142d146 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3340,3 +3340,34 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, return NULL; #endif } + +NTSTATUS cli_get_session_key(struct rpc_pipe_client *cli, + DATA_BLOB *session_key) +{ + if (!session_key || !cli) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!cli->auth) { + return NT_STATUS_INVALID_PARAMETER; + } + + switch (cli->auth->auth_type) { + case PIPE_AUTH_TYPE_SCHANNEL: + *session_key = data_blob(cli->auth->a_u.schannel_auth->sess_key, 16); + break; + case PIPE_AUTH_TYPE_NTLMSSP: + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + *session_key = cli->auth->a_u.ntlmssp_state->session_key; + break; + case PIPE_AUTH_TYPE_KRB5: + case PIPE_AUTH_TYPE_SPNEGO_KRB5: + *session_key = cli->auth->a_u.kerberos_auth->session_key; + break; + case PIPE_AUTH_TYPE_NONE: + default: + return NT_STATUS_NO_USER_SESSION_KEY; + } + + return NT_STATUS_OK; +} -- cgit From 92bd665aea68ee8d198f72c95af5da487efcfc36 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Jun 2008 00:21:37 +0200 Subject: rpc_client: let cli_get_session_key() return talloced session key. Thanks, Volker, for pointing this out. Guenther (This used to be commit b47899195e0c190445953243fe80da4e92994dd1) --- source3/rpc_client/cli_pipe.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 469142d146..da81417220 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3341,7 +3341,8 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, #endif } -NTSTATUS cli_get_session_key(struct rpc_pipe_client *cli, +NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, + struct rpc_pipe_client *cli, DATA_BLOB *session_key) { if (!session_key || !cli) { @@ -3354,15 +3355,20 @@ NTSTATUS cli_get_session_key(struct rpc_pipe_client *cli, switch (cli->auth->auth_type) { case PIPE_AUTH_TYPE_SCHANNEL: - *session_key = data_blob(cli->auth->a_u.schannel_auth->sess_key, 16); + *session_key = data_blob_talloc(mem_ctx, + cli->auth->a_u.schannel_auth->sess_key, 16); break; case PIPE_AUTH_TYPE_NTLMSSP: case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: - *session_key = cli->auth->a_u.ntlmssp_state->session_key; + *session_key = data_blob_talloc(mem_ctx, + cli->auth->a_u.ntlmssp_state->session_key.data, + cli->auth->a_u.ntlmssp_state->session_key.length); break; case PIPE_AUTH_TYPE_KRB5: case PIPE_AUTH_TYPE_SPNEGO_KRB5: - *session_key = cli->auth->a_u.kerberos_auth->session_key; + *session_key = data_blob_talloc(mem_ctx, + cli->auth->a_u.kerberos_auth->session_key.data, + cli->auth->a_u.kerberos_auth->session_key.length); break; case PIPE_AUTH_TYPE_NONE: default: -- cgit From 799252f635a4cf1790a24f9ba8765dba9fb7df86 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Jun 2008 19:46:18 -0700 Subject: Fix the non-LDAP, non-krb5 build, fix gcc -O3 warnings. Jeremy. (This used to be commit 9e2ab30d3cf6950fc79152b2169e7aeae8d6a366) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index da81417220..5e8bff3116 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -507,8 +507,8 @@ static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_ return NT_STATUS_INVALID_PARAMETER; } - if (prhdr->auth_len + RPC_HDR_AUTH_LEN < prhdr->auth_len || - prhdr->auth_len + RPC_HDR_AUTH_LEN < RPC_HDR_AUTH_LEN) { + if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len || + prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) { /* Integer wrap attempt. */ return NT_STATUS_INVALID_PARAMETER; } -- cgit From bf6c11fea3e28532bd8ebc503e9d4d8dfb68e0e0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jul 2008 20:40:27 +0200 Subject: Make the pipe_names[] array static to cli_pipe.c (This used to be commit ab7ab350591bf16717744a0c252d3a9d185bcb77) --- source3/rpc_client/cli_pipe.c | 79 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5e8bff3116..169fe79406 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -23,7 +23,84 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI -extern struct pipe_id_info pipe_names[]; +/******************************************************************* +interface/version dce/rpc pipe identification +********************************************************************/ + +static const struct ndr_syntax_id syntax_spoolss = { + { + 0x12345678, 0x1234, 0xabcd, + { 0xef, 0x00 }, + { 0x01, 0x23, + 0x45, 0x67, 0x89, 0xab } + }, 0x01 +}; + +/* + * IMPORTANT!! If you update this structure, make sure to + * update the index #defines in smb.h. + */ + +static const struct pipe_id_info pipe_names [] = +{ + { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id, + PIPE_LSASS, &ndr_transfer_syntax }, + { PIPE_LSARPC, &ndr_table_dssetup.syntax_id, + PIPE_LSASS, &ndr_transfer_syntax }, + { PIPE_SAMR, &ndr_table_samr.syntax_id, + PIPE_LSASS, &ndr_transfer_syntax }, + { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id, + PIPE_LSASS, &ndr_transfer_syntax }, + { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id, + PIPE_NTSVCS, &ndr_transfer_syntax }, + { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id, + PIPE_NTSVCS, &ndr_transfer_syntax }, + { PIPE_WINREG, &ndr_table_winreg.syntax_id, + PIPE_WINREG, &ndr_transfer_syntax }, + { PIPE_SPOOLSS, &syntax_spoolss, + PIPE_SPOOLSS, &ndr_transfer_syntax }, + { PIPE_NETDFS, &ndr_table_netdfs.syntax_id, + PIPE_NETDFS, &ndr_transfer_syntax }, + { PIPE_ECHO, &ndr_table_rpcecho.syntax_id, + PIPE_ECHO, &ndr_transfer_syntax }, + { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id, + PIPE_SHUTDOWN, &ndr_transfer_syntax }, + { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id, + PIPE_NTSVCS, &ndr_transfer_syntax }, + { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id, + PIPE_EVENTLOG, &ndr_transfer_syntax }, + { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id, + PIPE_NTSVCS, &ndr_transfer_syntax }, + { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id, + PIPE_EPMAPPER, &ndr_transfer_syntax }, + { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id, + PIPE_DRSUAPI, &ndr_transfer_syntax }, + { NULL, NULL, NULL, NULL } +}; + +/**************************************************************************** + Return the pipe name from the index. + ****************************************************************************/ + +const char *cli_get_pipe_name(int pipe_idx) +{ + return &pipe_names[pipe_idx].client_pipe[5]; +} + +/**************************************************************************** + Return the pipe idx from the syntax. + ****************************************************************************/ +int cli_get_pipe_idx(const RPC_IFACE *syntax) +{ + int i; + for (i = 0; pipe_names[i].client_pipe; i++) { + if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax, syntax)) { + return i; + } + } + + return -1; +} /******************************************************************** Map internal value to wire value. -- cgit From 867b61d0a12cfec0803efb66e0aee68e64ffc26b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jul 2008 21:07:14 +0200 Subject: The PIPE_ pipename macros are only used in cli_pipe.c (This used to be commit 03f7af26f255476d84a375a95fbccfce24db9de8) --- source3/rpc_client/cli_pipe.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 169fe79406..dc130a1d9f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -36,6 +36,25 @@ static const struct ndr_syntax_id syntax_spoolss = { }, 0x01 }; +#define PIPE_SRVSVC "\\PIPE\\srvsvc" +#define PIPE_SAMR "\\PIPE\\samr" +#define PIPE_WINREG "\\PIPE\\winreg" +#define PIPE_WKSSVC "\\PIPE\\wkssvc" +#define PIPE_NETLOGON "\\PIPE\\NETLOGON" +#define PIPE_NTLSA "\\PIPE\\ntlsa" +#define PIPE_NTSVCS "\\PIPE\\ntsvcs" +#define PIPE_LSASS "\\PIPE\\lsass" +#define PIPE_LSARPC "\\PIPE\\lsarpc" +#define PIPE_SPOOLSS "\\PIPE\\spoolss" +#define PIPE_NETDFS "\\PIPE\\netdfs" +#define PIPE_ECHO "\\PIPE\\rpcecho" +#define PIPE_SHUTDOWN "\\PIPE\\initshutdown" +#define PIPE_EPM "\\PIPE\\epmapper" +#define PIPE_SVCCTL "\\PIPE\\svcctl" +#define PIPE_EVENTLOG "\\PIPE\\eventlog" +#define PIPE_EPMAPPER "\\PIPE\\epmapper" +#define PIPE_DRSUAPI "\\PIPE\\drsuapi" + /* * IMPORTANT!! If you update this structure, make sure to * update the index #defines in smb.h. -- cgit From 66669bad4384086c91c833db78d70b8aac7a4f04 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 10:00:46 +0200 Subject: Simplify pipe_names: we only do ndr_transfer_syntax anyway (This used to be commit b808403af55a37f2ec0e87e60450505ddfc2edda) --- source3/rpc_client/cli_pipe.c | 59 ++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index dc130a1d9f..cfb3091feb 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -60,41 +60,30 @@ static const struct ndr_syntax_id syntax_spoolss = { * update the index #defines in smb.h. */ -static const struct pipe_id_info pipe_names [] = +static const struct pipe_id_info { + /* the names appear not to matter: the syntaxes _do_ matter */ + + const char *client_pipe; + const RPC_IFACE *abstr_syntax; /* this one is the abstract syntax id */ +} pipe_names [] = { - { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id, - PIPE_LSASS, &ndr_transfer_syntax }, - { PIPE_LSARPC, &ndr_table_dssetup.syntax_id, - PIPE_LSASS, &ndr_transfer_syntax }, - { PIPE_SAMR, &ndr_table_samr.syntax_id, - PIPE_LSASS, &ndr_transfer_syntax }, - { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id, - PIPE_LSASS, &ndr_transfer_syntax }, - { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id, - PIPE_NTSVCS, &ndr_transfer_syntax }, - { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id, - PIPE_NTSVCS, &ndr_transfer_syntax }, - { PIPE_WINREG, &ndr_table_winreg.syntax_id, - PIPE_WINREG, &ndr_transfer_syntax }, - { PIPE_SPOOLSS, &syntax_spoolss, - PIPE_SPOOLSS, &ndr_transfer_syntax }, - { PIPE_NETDFS, &ndr_table_netdfs.syntax_id, - PIPE_NETDFS, &ndr_transfer_syntax }, - { PIPE_ECHO, &ndr_table_rpcecho.syntax_id, - PIPE_ECHO, &ndr_transfer_syntax }, - { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id, - PIPE_SHUTDOWN, &ndr_transfer_syntax }, - { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id, - PIPE_NTSVCS, &ndr_transfer_syntax }, - { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id, - PIPE_EVENTLOG, &ndr_transfer_syntax }, - { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id, - PIPE_NTSVCS, &ndr_transfer_syntax }, - { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id, - PIPE_EPMAPPER, &ndr_transfer_syntax }, - { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id, - PIPE_DRSUAPI, &ndr_transfer_syntax }, - { NULL, NULL, NULL, NULL } + { PIPE_LSARPC, &ndr_table_lsarpc.syntax_id }, + { PIPE_LSARPC, &ndr_table_dssetup.syntax_id }, + { PIPE_SAMR, &ndr_table_samr.syntax_id }, + { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id }, + { PIPE_SRVSVC, &ndr_table_srvsvc.syntax_id }, + { PIPE_WKSSVC, &ndr_table_wkssvc.syntax_id }, + { PIPE_WINREG, &ndr_table_winreg.syntax_id }, + { PIPE_SPOOLSS, &syntax_spoolss }, + { PIPE_NETDFS, &ndr_table_netdfs.syntax_id }, + { PIPE_ECHO, &ndr_table_rpcecho.syntax_id }, + { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id }, + { PIPE_SVCCTL, &ndr_table_svcctl.syntax_id }, + { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id }, + { PIPE_NTSVCS, &ndr_table_ntsvcs.syntax_id }, + { PIPE_EPMAPPER, &ndr_table_epmapper.syntax_id }, + { PIPE_DRSUAPI, &ndr_table_drsuapi.syntax_id }, + { NULL, NULL } }; /**************************************************************************** @@ -2926,7 +2915,7 @@ static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_ result->trans.np.cli = cli; result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax; - result->transfer_syntax = pipe_names[pipe_idx].trans_syntax; + result->transfer_syntax = &ndr_transfer_syntax; result->desthost = talloc_strdup(result, cli->desthost); result->srv_name_slash = talloc_asprintf_strupper_m( result, "\\\\%s", result->desthost); -- cgit From 65dfc40a4adc41fc45e48d96631238817cef8394 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 10:21:14 +0200 Subject: Store copies of the syntax ids in rpc_pipe_client (This used to be commit 848a3497e385090b4b21837c8d0e0313f5c062e5) --- source3/rpc_client/cli_pipe.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index cfb3091feb..af4c28195d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2217,8 +2217,8 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, /* Marshall the outgoing data. */ status = create_rpc_bind_req(cli, &rpc_out, rpc_call_id, - cli->abstract_syntax, - cli->transfer_syntax, + &cli->abstract_syntax, + &cli->transfer_syntax, cli->auth->auth_type, cli->auth->auth_level); @@ -2255,7 +2255,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, return NT_STATUS_BUFFER_TOO_SMALL; } - if(!check_bind_response(&hdr_ba, cli->transfer_syntax)) { + if(!check_bind_response(&hdr_ba, &cli->transfer_syntax)) { DEBUG(2,("rpc_pipe_bind: check_bind_response failed.\n")); prs_mem_free(&rbuf); return NT_STATUS_BUFFER_TOO_SMALL; @@ -2288,7 +2288,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, /* Need to send alter context request and reply. */ status = rpc_finish_spnego_ntlmssp_bind( cli, &hdr, &rbuf, rpc_call_id, - cli->abstract_syntax, cli->transfer_syntax, + &cli->abstract_syntax, &cli->transfer_syntax, cli->auth->auth_type, cli->auth->auth_level); if (!NT_STATUS_IS_OK(status)) { prs_mem_free(&rbuf); @@ -2337,7 +2337,8 @@ unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx) { - return (cli->abstract_syntax == pipe_names[pipe_idx].abstr_syntax); + return ndr_syntax_id_equal(&cli->abstract_syntax, + pipe_names[pipe_idx].abstr_syntax); } bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]) @@ -2616,8 +2617,8 @@ static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host, result->transport_type = NCACN_IP_TCP; - result->abstract_syntax = abstract_syntax; - result->transfer_syntax = &ndr_transfer_syntax; + result->abstract_syntax = *abstract_syntax; + result->transfer_syntax = ndr_transfer_syntax; result->desthost = talloc_strdup(result, host); result->srv_name_slash = talloc_asprintf_strupper_m( @@ -2824,8 +2825,8 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, result->transport_type = NCACN_UNIX_STREAM; - result->abstract_syntax = abstract_syntax; - result->transfer_syntax = &ndr_transfer_syntax; + result->abstract_syntax = *abstract_syntax; + result->transfer_syntax = ndr_transfer_syntax; result->desthost = get_myname(result); result->srv_name_slash = talloc_asprintf_strupper_m( @@ -2914,8 +2915,8 @@ static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_ result->trans.np.pipe_name = cli_get_pipe_name(pipe_idx); result->trans.np.cli = cli; - result->abstract_syntax = pipe_names[pipe_idx].abstr_syntax; - result->transfer_syntax = &ndr_transfer_syntax; + result->abstract_syntax = *pipe_names[pipe_idx].abstr_syntax; + result->transfer_syntax = ndr_transfer_syntax; result->desthost = talloc_strdup(result, cli->desthost); result->srv_name_slash = talloc_asprintf_strupper_m( result, "\\\\%s", result->desthost); -- cgit From 2e905d2cd14b96af4ed8a912cc1f46c661e31756 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 10:40:43 +0200 Subject: Allocate rpc_cli->dc in rpccli_netlogon_setup_creds() The general cli_pipe routines should not have to know about this NETLOGON speciality. (This used to be commit d30237598d0c55b73e202c1de3a020194b67a7e6) --- source3/rpc_client/cli_pipe.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index af4c28195d..2aa96ab414 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2818,7 +2818,7 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, struct sockaddr_un addr; NTSTATUS status; - result = talloc(mem_ctx, struct rpc_pipe_client); + result = talloc_zero(mem_ctx, struct rpc_pipe_client); if (result == NULL) { return NT_STATUS_NO_MEMORY; } @@ -2847,12 +2847,6 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, talloc_set_destructor(result, rpc_pipe_sock_destructor); - result->dc = TALLOC_ZERO_P(result, struct dcinfo); - if (result->dc == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - ZERO_STRUCT(addr); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)); @@ -2927,16 +2921,6 @@ static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_ return NULL; } - if (pipe_idx == PI_NETLOGON) { - /* Set up a netlogon credential chain for a netlogon pipe. */ - result->dc = TALLOC_ZERO_P(result, struct dcinfo); - if (result->dc == NULL) { - *perr = NT_STATUS_NO_MEMORY; - TALLOC_FREE(result); - return NULL; - } - } - fnum = cli_nt_create(cli, result->trans.np.pipe_name, DESIRED_ACCESS_PIPE); if (fnum == -1) { @@ -3267,9 +3251,15 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl return NULL; } - /* The credentials on a new netlogon pipe are the ones we are passed in - copy them over. */ - if (result->dc) { - *result->dc = *pdc; + /* + * The credentials on a new netlogon pipe are the ones we are passed + * in - copy them over. + */ + result->dc = (struct dcinfo *)talloc_memdup(result, pdc, sizeof(*pdc)); + if (result->dc == NULL) { + DEBUG(0, ("talloc failed\n")); + TALLOC_FREE(result); + return NULL; } DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s " -- cgit From eb68e95d9a20ab844ea6487ba44997aebc57c47b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 10:56:36 +0200 Subject: Refactoring: Change calling conventions for rpc_pipe_open_np Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit 9249fe9e917982c8b9ca25933b716e8ac0aa40cd) --- source3/rpc_client/cli_pipe.c | 62 ++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 21 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 2aa96ab414..b0bbeda3ae 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -95,6 +95,26 @@ const char *cli_get_pipe_name(int pipe_idx) return &pipe_names[pipe_idx].client_pipe[5]; } +static const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx, + struct cli_state *cli, + const struct ndr_syntax_id *interface) +{ + int i; + for (i = 0; pipe_names[i].client_pipe; i++) { + if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax, + interface)) { + return cli_get_pipe_name(i); + } + } + + /* + * Here we should ask \\epmapper, but for now our code is only + * interested in the known pipes mentioned in pipe_names[] + */ + + return NULL; +} + /**************************************************************************** Return the pipe idx from the syntax. ****************************************************************************/ @@ -2881,44 +2901,44 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, * ****************************************************************************/ -static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) +static NTSTATUS rpc_pipe_open_np(struct cli_state *cli, + const struct ndr_syntax_id *abstract_syntax, + struct rpc_pipe_client **presult) { struct rpc_pipe_client *result; int fnum; - *perr = NT_STATUS_NO_MEMORY; - /* sanity check to protect against crashes */ if ( !cli ) { - *perr = NT_STATUS_INVALID_HANDLE; - return NULL; + return NT_STATUS_INVALID_HANDLE; } - /* The pipe name index must fall within our array */ - SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); - result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client); if (result == NULL) { - *perr = NT_STATUS_NO_MEMORY; - return NULL; + return NT_STATUS_NO_MEMORY; } result->transport_type = NCACN_NP; - result->trans.np.pipe_name = cli_get_pipe_name(pipe_idx); + result->trans.np.pipe_name = cli_get_pipe_name_from_iface( + result, cli, abstract_syntax); + if (result->trans.np.pipe_name == NULL) { + DEBUG(1, ("Could not find pipe for interface\n")); + TALLOC_FREE(result); + return NT_STATUS_INVALID_PARAMETER; + } result->trans.np.cli = cli; - result->abstract_syntax = *pipe_names[pipe_idx].abstr_syntax; + result->abstract_syntax = *abstract_syntax; result->transfer_syntax = ndr_transfer_syntax; result->desthost = talloc_strdup(result, cli->desthost); result->srv_name_slash = talloc_asprintf_strupper_m( result, "\\\\%s", result->desthost); if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) { - *perr = NT_STATUS_NO_MEMORY; TALLOC_FREE(result); - return NULL; + return NT_STATUS_NO_MEMORY; } fnum = cli_nt_create(cli, result->trans.np.pipe_name, @@ -2928,9 +2948,8 @@ static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_ "to machine %s. Error was %s\n", result->trans.np.pipe_name, cli->desthost, cli_errstr(cli))); - *perr = cli_get_nt_error(cli); - talloc_destroy(result); - return NULL; + TALLOC_FREE(result); + return cli_get_nt_error(cli); } result->trans.np.fnum = fnum; @@ -2938,9 +2957,8 @@ static struct rpc_pipe_client *rpc_pipe_open_np(struct cli_state *cli, int pipe_ DLIST_ADD(cli->pipe_list, result); talloc_set_destructor(result, rpc_pipe_destructor); - *perr = NT_STATUS_OK; - - return result; + *presult = result; + return NT_STATUS_OK; } /**************************************************************************** @@ -2965,7 +2983,9 @@ static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, } break; default: - result = rpc_pipe_open_np(cli, pipe_idx, perr); + *perr = rpc_pipe_open_np( + cli, pipe_names[pipe_idx].abstr_syntax, + &result); if (result == NULL) { return NULL; } -- cgit From 18fb7e09776e26dacfa2329607f8a20699ad2969 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 11:04:31 +0200 Subject: Refactoring: Change calling conventions for cli_rpc_pipe_open Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit 6c122457ff3f22e20dbb595dc6d5fb49689f4d61) --- source3/rpc_client/cli_pipe.c | 58 +++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 35 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b0bbeda3ae..1a55bc20da 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2965,36 +2965,20 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli, Open a pipe to a remote server. ****************************************************************************/ -static struct rpc_pipe_client *cli_rpc_pipe_open(struct cli_state *cli, - int pipe_idx, - NTSTATUS *perr) +static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli, + const struct ndr_syntax_id *interface, + struct rpc_pipe_client **presult) { - struct rpc_pipe_client *result = NULL; - - *perr = NT_STATUS_PIPE_NOT_AVAILABLE; - - switch (pipe_idx) { - case PI_DRSUAPI: - *perr = rpc_pipe_open_tcp(NULL, cli->desthost, - &ndr_table_drsuapi.syntax_id, - &result); - if (!NT_STATUS_IS_OK(*perr)) { - return NULL; - } - break; - default: - *perr = rpc_pipe_open_np( - cli, pipe_names[pipe_idx].abstr_syntax, - &result); - if (result == NULL) { - return NULL; - } - break; + if (ndr_syntax_id_equal(interface, &ndr_table_drsuapi.syntax_id)) { + /* + * We should have a better way to figure out this drsuapi + * speciality... + */ + return rpc_pipe_open_tcp(NULL, cli->desthost, interface, + presult); } - *perr = NT_STATUS_OK; - - return result; + return rpc_pipe_open_np(cli, interface, presult); } /**************************************************************************** @@ -3006,8 +2990,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe struct rpc_pipe_client *result; struct cli_pipe_auth_data *auth; - result = cli_rpc_pipe_open(cli, pipe_idx, perr); - if (result == NULL) { + *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax, + &result); + if (!NT_STATUS_IS_OK(*perr)) { return NULL; } @@ -3074,8 +3059,9 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta struct rpc_pipe_client *result; struct cli_pipe_auth_data *auth; - result = cli_rpc_pipe_open(cli, pipe_idx, perr); - if (result == NULL) { + *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax, + &result); + if (!NT_STATUS_IS_OK(*perr)) { return NULL; } @@ -3249,8 +3235,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl struct rpc_pipe_client *result; struct cli_pipe_auth_data *auth; - result = cli_rpc_pipe_open(cli, pipe_idx, perr); - if (result == NULL) { + *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax, + &result); + if (!NT_STATUS_IS_OK(*perr)) { return NULL; } @@ -3408,8 +3395,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, struct rpc_pipe_client *result; struct cli_pipe_auth_data *auth; - result = cli_rpc_pipe_open(cli, pipe_idx, perr); - if (result == NULL) { + *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax, + &result); + if (!NT_STATUS_IS_OK(*perr)) { return NULL; } -- cgit From 1335da2a7cc639310e5d389e8e8dbe67c4e7ca25 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 11:04:31 +0200 Subject: Refactoring: Change calling conventions for cli_rpc_pipe_open_noauth Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit 9abc9dc4dc13bd3e42f98eff64eacf24b51f5779) --- source3/rpc_client/cli_pipe.c | 65 ++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 29 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1a55bc20da..6fe3a0831a 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -27,15 +27,6 @@ interface/version dce/rpc pipe identification ********************************************************************/ -static const struct ndr_syntax_id syntax_spoolss = { - { - 0x12345678, 0x1234, 0xabcd, - { 0xef, 0x00 }, - { 0x01, 0x23, - 0x45, 0x67, 0x89, 0xab } - }, 0x01 -}; - #define PIPE_SRVSVC "\\PIPE\\srvsvc" #define PIPE_SAMR "\\PIPE\\samr" #define PIPE_WINREG "\\PIPE\\winreg" @@ -130,6 +121,15 @@ int cli_get_pipe_idx(const RPC_IFACE *syntax) return -1; } +/******************************************************************** + LEGACY function to ease transition from pipe_idx to interface + ********************************************************************/ +const struct ndr_syntax_id *cli_get_iface(int pipe_idx) +{ + SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); + return pipe_names[pipe_idx].abstr_syntax; +} + /******************************************************************** Map internal value to wire value. ********************************************************************/ @@ -2985,23 +2985,25 @@ static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli, Open a named pipe to an SMB server and bind anonymously. ****************************************************************************/ -struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr) +NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli, + const struct ndr_syntax_id *interface, + struct rpc_pipe_client **presult) { struct rpc_pipe_client *result; struct cli_pipe_auth_data *auth; + NTSTATUS status; - *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax, - &result); - if (!NT_STATUS_IS_OK(*perr)) { - return NULL; + status = cli_rpc_pipe_open(cli, interface, &result); + if (!NT_STATUS_IS_OK(status)) { + return status; } - *perr = rpccli_anon_bind_data(result, &auth); - if (!NT_STATUS_IS_OK(*perr)) { + status = rpccli_anon_bind_data(result, &auth); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("rpccli_anon_bind_data returned %s\n", - nt_errstr(*perr))); + nt_errstr(status))); TALLOC_FREE(result); - return NULL; + return status; } /* @@ -3017,30 +3019,34 @@ struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe auth->domain = talloc_strdup(auth, cli->domain); if ((auth->user_name == NULL) || (auth->domain == NULL)) { - *perr = NT_STATUS_NO_MEMORY; TALLOC_FREE(result); - return NULL; + return NT_STATUS_NO_MEMORY; } - *perr = rpc_pipe_bind(result, auth); - if (!NT_STATUS_IS_OK(*perr)) { + status = rpc_pipe_bind(result, auth); + if (!NT_STATUS_IS_OK(status)) { int lvl = 0; - if (rpccli_is_pipe_idx(result, PI_DSSETUP)) { + if (ndr_syntax_id_equal(interface, + &ndr_table_dssetup.syntax_id)) { /* non AD domains just don't have this pipe, avoid * level 0 statement in that case - gd */ lvl = 3; } - DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe %s failed with error %s\n", - cli_get_pipe_name(pipe_idx), nt_errstr(*perr) )); + DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe " + "%s failed with error %s\n", + cli_get_pipe_name_from_iface(debug_ctx(), cli, + interface), + nt_errstr(status) )); TALLOC_FREE(result); - return NULL; + return status; } DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine " "%s and bound anonymously.\n", result->trans.np.pipe_name, cli->desthost )); - return result; + *presult = result; + return NT_STATUS_OK; } /**************************************************************************** @@ -3204,8 +3210,9 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, { struct rpc_pipe_client *netlogon_pipe = NULL; - netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr); - if (!netlogon_pipe) { + *perr = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id, + &netlogon_pipe); + if (!NT_STATUS_IS_OK(*perr)) { return NULL; } -- cgit From e0be03d8d5006f92ed479b84cd30ebfe510fa68a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 11:04:31 +0200 Subject: Refactoring: Change calling conventions for cli_rpc_pipe_open_ntlmssp Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit a13f0599551609394904b99e4014d580ec65c506) --- source3/rpc_client/cli_pipe.c | 86 ++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 41 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6fe3a0831a..b93e8181e9 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3053,38 +3053,37 @@ NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli, Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP ****************************************************************************/ -static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli, - int pipe_idx, - enum pipe_auth_type auth_type, - enum pipe_auth_level auth_level, - const char *domain, - const char *username, - const char *password, - NTSTATUS *perr) +static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli, + const struct ndr_syntax_id *interface, + enum pipe_auth_type auth_type, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + struct rpc_pipe_client **presult) { struct rpc_pipe_client *result; struct cli_pipe_auth_data *auth; + NTSTATUS status; - *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax, - &result); - if (!NT_STATUS_IS_OK(*perr)) { - return NULL; + status = cli_rpc_pipe_open(cli, interface, &result); + if (!NT_STATUS_IS_OK(status)) { + return status; } - *perr = rpccli_ntlmssp_bind_data( + status = rpccli_ntlmssp_bind_data( result, auth_type, auth_level, domain, username, cli->pwd.null_pwd ? NULL : password, &auth); - if (!NT_STATUS_IS_OK(*perr)) { + if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n", - nt_errstr(*perr))); - TALLOC_FREE(result); - return NULL; + nt_errstr(status))); + goto err; } - *perr = rpc_pipe_bind(result, auth); - if (!NT_STATUS_IS_OK(*perr)) { + status = rpc_pipe_bind(result, auth); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n", - nt_errstr(*perr) )); + nt_errstr(status) )); goto err; } @@ -3093,12 +3092,13 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta result->trans.np.pipe_name, cli->desthost, domain, username )); - return result; + *presult = result; + return NT_STATUS_OK; err: TALLOC_FREE(result); - return NULL; + return status; } /**************************************************************************** @@ -3106,22 +3106,22 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10) ****************************************************************************/ -struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli, - int pipe_idx, - enum pipe_auth_level auth_level, - const char *domain, - const char *username, - const char *password, - NTSTATUS *perr) +NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli, + const struct ndr_syntax_id *interface, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + struct rpc_pipe_client **presult) { return cli_rpc_pipe_open_ntlmssp_internal(cli, - pipe_idx, + interface, PIPE_AUTH_TYPE_NTLMSSP, auth_level, domain, username, password, - perr); + presult); } /**************************************************************************** @@ -3129,22 +3129,22 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp(struct cli_state *cli, Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9) ****************************************************************************/ -struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, - int pipe_idx, - enum pipe_auth_level auth_level, - const char *domain, - const char *username, - const char *password, - NTSTATUS *perr) +NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, + const struct ndr_syntax_id *interface, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + struct rpc_pipe_client **presult) { return cli_rpc_pipe_open_ntlmssp_internal(cli, - pipe_idx, + interface, PIPE_AUTH_TYPE_SPNEGO_NTLMSSP, auth_level, domain, username, password, - perr); + presult); } /**************************************************************************** @@ -3299,7 +3299,11 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ { struct rpc_pipe_client *netlogon_pipe = NULL; - netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr); + *perr = cli_rpc_pipe_open_spnego_ntlmssp(cli, + &ndr_table_netlogon.syntax_id, + PIPE_AUTH_LEVEL_PRIVACY, + domain, username, password, + &netlogon_pipe); if (!netlogon_pipe) { return NULL; } -- cgit From 1f854d1db709ea0eeac9f5469fda053bd38e72c4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 16:27:45 +0200 Subject: Refactoring: Make get_schannel_session_key_common return NTSTATUS (This used to be commit 513e69507676fc2227424362d24d8ea9615ea758) --- source3/rpc_client/cli_pipe.c | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b93e8181e9..0ba94ea292 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3150,15 +3150,15 @@ NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli, /**************************************************************************** Get a the schannel session key out of an already opened netlogon pipe. ****************************************************************************/ -static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe, - struct cli_state *cli, - const char *domain, - uint32 *pneg_flags, - NTSTATUS *perr) +static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe, + struct cli_state *cli, + const char *domain, + uint32 *pneg_flags) { uint32 sec_chan_type = 0; unsigned char machine_pwd[16]; const char *machine_account; + NTSTATUS status; /* Get the machine account credentials from secrets.tdb. */ if (!get_trust_pw_hash(domain, machine_pwd, &machine_account, @@ -3167,11 +3167,10 @@ static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pip DEBUG(0, ("get_schannel_session_key: could not fetch " "trust account password for domain '%s'\n", domain)); - *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - return false; + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - *perr = rpccli_netlogon_setup_creds(netlogon_pipe, + status = rpccli_netlogon_setup_creds(netlogon_pipe, cli->desthost, /* server name */ domain, /* domain */ global_myname(), /* client name */ @@ -3180,21 +3179,22 @@ static bool get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pip sec_chan_type, pneg_flags); - if (!NT_STATUS_IS_OK(*perr)) { - DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds " - "failed with result %s to server %s, domain %s, machine account %s.\n", - nt_errstr(*perr), cli->desthost, domain, machine_account )); - return false; + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("get_schannel_session_key_common: " + "rpccli_netlogon_setup_creds failed with result %s " + "to server %s, domain %s, machine account %s.\n", + nt_errstr(status), cli->desthost, domain, + machine_account )); + return status; } if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) { DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n", cli->desthost)); - *perr = NT_STATUS_INVALID_NETWORK_RESPONSE; - return false; + return NT_STATUS_INVALID_NETWORK_RESPONSE; } - return true; + return NT_STATUS_OK;; } /**************************************************************************** @@ -3216,9 +3216,9 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, return NULL; } - if (!get_schannel_session_key_common(netlogon_pipe, cli, domain, - pneg_flags, perr)) - { + *perr = get_schannel_session_key_common(netlogon_pipe, cli, domain, + pneg_flags); + if (!NT_STATUS_IS_OK(*perr)) { TALLOC_FREE(netlogon_pipe); return NULL; } @@ -3308,9 +3308,9 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_ return NULL; } - if (!get_schannel_session_key_common(netlogon_pipe, cli, domain, - pneg_flags, perr)) - { + *perr = get_schannel_session_key_common(netlogon_pipe, cli, domain, + pneg_flags); + if (!NT_STATUS_IS_OK(*perr)) { TALLOC_FREE(netlogon_pipe); return NULL; } -- cgit From b8fc15be950072846d23e3836d4d0289c10156f2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 16:33:26 +0200 Subject: Refactoring: Make get_schannel_session_key return NTSTATUS (This used to be commit a0793cc853d3bd43df2fc49df193a5fead6b01ab) --- source3/rpc_client/cli_pipe.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0ba94ea292..6d15771d73 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3203,27 +3203,29 @@ static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon ****************************************************************************/ -struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli, - const char *domain, - uint32 *pneg_flags, - NTSTATUS *perr) +NTSTATUS get_schannel_session_key(struct cli_state *cli, + const char *domain, + uint32 *pneg_flags, + struct rpc_pipe_client **presult) { struct rpc_pipe_client *netlogon_pipe = NULL; + NTSTATUS status; - *perr = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id, - &netlogon_pipe); - if (!NT_STATUS_IS_OK(*perr)) { - return NULL; + status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id, + &netlogon_pipe); + if (!NT_STATUS_IS_OK(status)) { + return status; } - *perr = get_schannel_session_key_common(netlogon_pipe, cli, domain, - pneg_flags); - if (!NT_STATUS_IS_OK(*perr)) { + status = get_schannel_session_key_common(netlogon_pipe, cli, domain, + pneg_flags); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(netlogon_pipe); - return NULL; + return status; } - return netlogon_pipe; + *presult = netlogon_pipe; + return NT_STATUS_OK; } /**************************************************************************** @@ -3370,8 +3372,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; - netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, perr); - if (!netlogon_pipe) { + *perr = get_schannel_session_key(cli, domain, &neg_flags, + &netlogon_pipe); + if (!NT_STATUS_IS_OK(*perr)) { DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session " "key from server %s for domain %s.\n", cli->desthost, domain )); -- cgit From 44bdc98823bd85597803f1ca8f5d0282f2d724b3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 16:36:55 +0200 Subject: Refactoring: Make get_schannel_session_key_auth_ntlmssp return NTSTATUS (This used to be commit ab3d80d476d8264030fa71d974324c6dcf6fe6e1) --- source3/rpc_client/cli_pipe.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6d15771d73..1825174803 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3292,32 +3292,32 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl version uses an ntlmssp auth bound netlogon pipe to get the key. ****************************************************************************/ -static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_state *cli, - const char *domain, - const char *username, - const char *password, - uint32 *pneg_flags, - NTSTATUS *perr) +static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli, + const char *domain, + const char *username, + const char *password, + uint32 *pneg_flags, + struct rpc_pipe_client **presult) { struct rpc_pipe_client *netlogon_pipe = NULL; + NTSTATUS status; - *perr = cli_rpc_pipe_open_spnego_ntlmssp(cli, - &ndr_table_netlogon.syntax_id, - PIPE_AUTH_LEVEL_PRIVACY, - domain, username, password, - &netlogon_pipe); - if (!netlogon_pipe) { - return NULL; + status = cli_rpc_pipe_open_spnego_ntlmssp( + cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY, + domain, username, password, &netlogon_pipe); + if (!NT_STATUS_IS_OK(status)) { + return status; } - *perr = get_schannel_session_key_common(netlogon_pipe, cli, domain, - pneg_flags); - if (!NT_STATUS_IS_OK(*perr)) { + status = get_schannel_session_key_common(netlogon_pipe, cli, domain, + pneg_flags); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(netlogon_pipe); - return NULL; + return status; } - return netlogon_pipe; + *presult = netlogon_pipe; + return NT_STATUS_OK; } /**************************************************************************** @@ -3338,9 +3338,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; - netlogon_pipe = get_schannel_session_key_auth_ntlmssp(cli, domain, username, - password, &neg_flags, perr); - if (!netlogon_pipe) { + *perr = get_schannel_session_key_auth_ntlmssp( + cli, domain, username, password, &neg_flags, &netlogon_pipe); + if (!NT_STATUS_IS_OK(*perr)) { DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session " "key from server %s for domain %s.\n", cli->desthost, domain )); -- cgit From ba2cb35ca5b335a8f33e012255b43b9cf9a04ecf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 11:04:31 +0200 Subject: Refactoring: Change calling conventions for cli_rpc_pipe_open_schannel_with_key Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit 78e9c937ff2d2e1b70cfed4121e17feb6efafda1) --- source3/rpc_client/cli_pipe.c | 58 ++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 28 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1825174803..abafa0ff26 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3234,37 +3234,38 @@ NTSTATUS get_schannel_session_key(struct cli_state *cli, using session_key. sign and seal. ****************************************************************************/ -struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli, - int pipe_idx, - enum pipe_auth_level auth_level, - const char *domain, - const struct dcinfo *pdc, - NTSTATUS *perr) +NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli, + const struct ndr_syntax_id *interface, + enum pipe_auth_level auth_level, + const char *domain, + const struct dcinfo *pdc, + struct rpc_pipe_client **presult) { struct rpc_pipe_client *result; struct cli_pipe_auth_data *auth; + NTSTATUS status; - *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax, - &result); - if (!NT_STATUS_IS_OK(*perr)) { - return NULL; + status = cli_rpc_pipe_open(cli, interface, &result); + if (!NT_STATUS_IS_OK(status)) { + return status; } - *perr = rpccli_schannel_bind_data(result, domain, auth_level, - pdc->sess_key, &auth); - if (!NT_STATUS_IS_OK(*perr)) { + status = rpccli_schannel_bind_data(result, domain, auth_level, + pdc->sess_key, &auth); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("rpccli_schannel_bind_data returned %s\n", - nt_errstr(*perr))); + nt_errstr(status))); TALLOC_FREE(result); - return NULL; + return status; } - *perr = rpc_pipe_bind(result, auth); - if (!NT_STATUS_IS_OK(*perr)) { - DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: cli_rpc_pipe_bind failed with error %s\n", - nt_errstr(*perr) )); + status = rpc_pipe_bind(result, auth); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: " + "cli_rpc_pipe_bind failed with error %s\n", + nt_errstr(status) )); TALLOC_FREE(result); - return NULL; + return status; } /* @@ -3275,7 +3276,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl if (result->dc == NULL) { DEBUG(0, ("talloc failed\n")); TALLOC_FREE(result); - return NULL; + return NT_STATUS_NO_MEMORY; } DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s " @@ -3283,7 +3284,8 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel_with_key(struct cli_state *cl "and bound using schannel.\n", result->trans.np.pipe_name, cli->desthost, domain )); - return result; + *presult = result; + return NT_STATUS_OK; } /**************************************************************************** @@ -3347,9 +3349,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state return NULL; } - result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx, - auth_level, - domain, netlogon_pipe->dc, perr); + *perr = cli_rpc_pipe_open_schannel_with_key( + cli, cli_get_iface(pipe_idx), auth_level, + domain, netlogon_pipe->dc, &result); /* Now we've bound using the session key we can close the netlog pipe. */ TALLOC_FREE(netlogon_pipe); @@ -3381,9 +3383,9 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, return NULL; } - result = cli_rpc_pipe_open_schannel_with_key(cli, pipe_idx, - auth_level, - domain, netlogon_pipe->dc, perr); + *perr = cli_rpc_pipe_open_schannel_with_key( + cli, cli_get_iface(pipe_idx), auth_level, + domain, netlogon_pipe->dc, &result); /* Now we've bound using the session key we can close the netlog pipe. */ TALLOC_FREE(netlogon_pipe); -- cgit From 52ff49600e6421828784a9e9aefbd1e94a290ed0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 11:04:31 +0200 Subject: Refactoring: Change calling conventions for cli_rpc_pipe_open_ntlmssp_auth_schannel Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit ff87127baf1d1bd62bb9c1be4a50c2ab2642b33d) --- source3/rpc_client/cli_pipe.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index abafa0ff26..5441ab8807 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3328,35 +3328,39 @@ static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli, uses an ntlmssp bind to get the session key. ****************************************************************************/ -struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli, - int pipe_idx, - enum pipe_auth_level auth_level, - const char *domain, - const char *username, - const char *password, - NTSTATUS *perr) +NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli, + const struct ndr_syntax_id *interface, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + struct rpc_pipe_client **presult) { uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; + NTSTATUS status; - *perr = get_schannel_session_key_auth_ntlmssp( + status = get_schannel_session_key_auth_ntlmssp( cli, domain, username, password, &neg_flags, &netlogon_pipe); - if (!NT_STATUS_IS_OK(*perr)) { + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session " "key from server %s for domain %s.\n", cli->desthost, domain )); - return NULL; + return status; } - *perr = cli_rpc_pipe_open_schannel_with_key( - cli, cli_get_iface(pipe_idx), auth_level, - domain, netlogon_pipe->dc, &result); + status = cli_rpc_pipe_open_schannel_with_key( + cli, interface, auth_level, domain, netlogon_pipe->dc, + &result); /* Now we've bound using the session key we can close the netlog pipe. */ TALLOC_FREE(netlogon_pipe); - return result; + if (NT_STATUS_IS_OK(status)) { + *presult = result; + } + return status; } /**************************************************************************** -- cgit From 99526d391dc274eb87cfd0b393363d8ceafccda9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 11:04:31 +0200 Subject: Refactoring: Change calling conventions for cli_rpc_pipe_open_schannel Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit 1fcfca007f33a2c4e979abf30c2ea0db65bac718) --- source3/rpc_client/cli_pipe.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5441ab8807..e9a9480e35 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3368,33 +3368,38 @@ NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli, Fetch the session key ourselves using a temporary netlogon pipe. ****************************************************************************/ -struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, - int pipe_idx, - enum pipe_auth_level auth_level, - const char *domain, - NTSTATUS *perr) +NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli, + const struct ndr_syntax_id *interface, + enum pipe_auth_level auth_level, + const char *domain, + struct rpc_pipe_client **presult) { uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; struct rpc_pipe_client *netlogon_pipe = NULL; struct rpc_pipe_client *result = NULL; + NTSTATUS status; - *perr = get_schannel_session_key(cli, domain, &neg_flags, - &netlogon_pipe); - if (!NT_STATUS_IS_OK(*perr)) { + status = get_schannel_session_key(cli, domain, &neg_flags, + &netlogon_pipe); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session " "key from server %s for domain %s.\n", cli->desthost, domain )); - return NULL; + return status; } - *perr = cli_rpc_pipe_open_schannel_with_key( - cli, cli_get_iface(pipe_idx), auth_level, - domain, netlogon_pipe->dc, &result); + status = cli_rpc_pipe_open_schannel_with_key( + cli, interface, auth_level, domain, netlogon_pipe->dc, + &result); /* Now we've bound using the session key we can close the netlog pipe. */ TALLOC_FREE(netlogon_pipe); - return result; + if (NT_STATUS_IS_OK(status)) { + *presult = result; + } + + return NT_STATUS_OK; } /**************************************************************************** -- cgit From 55f84c05bdb33f9c97bb71240e02a8f5a77b3355 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 11:04:31 +0200 Subject: Refactoring: Change calling conventions for cli_rpc_pipe_open_krb5 Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit f2656e5c2e700523ead7a62734d203ad0caaff0c) --- source3/rpc_client/cli_pipe.c | 47 ++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index e9a9480e35..b5a188ed76 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3408,45 +3408,46 @@ NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli, NULL so long as the caller has a TGT. ****************************************************************************/ -struct rpc_pipe_client *cli_rpc_pipe_open_krb5(struct cli_state *cli, - int pipe_idx, - enum pipe_auth_level auth_level, - const char *service_princ, - const char *username, - const char *password, - NTSTATUS *perr) +NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli, + const struct ndr_syntax_id *interface, + enum pipe_auth_level auth_level, + const char *service_princ, + const char *username, + const char *password, + struct rpc_pipe_client **presult) { #ifdef HAVE_KRB5 struct rpc_pipe_client *result; struct cli_pipe_auth_data *auth; + NTSTATUS status; - *perr = cli_rpc_pipe_open(cli, pipe_names[pipe_idx].abstr_syntax, - &result); - if (!NT_STATUS_IS_OK(*perr)) { - return NULL; + status = cli_rpc_pipe_open(cli, interface, &result); + if (!NT_STATUS_IS_OK(status)) { + return status; } - *perr = rpccli_kerberos_bind_data(result, auth_level, service_princ, - username, password, &auth); - if (!NT_STATUS_IS_OK(*perr)) { + status = rpccli_kerberos_bind_data(result, auth_level, service_princ, + username, password, &auth); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n", - nt_errstr(*perr))); + nt_errstr(status))); TALLOC_FREE(result); - return NULL; + return status; } - *perr = rpc_pipe_bind(result, auth); - if (!NT_STATUS_IS_OK(*perr)) { - DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed with error %s\n", - nt_errstr(*perr) )); + status = rpc_pipe_bind(result, auth); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed " + "with error %s\n", nt_errstr(status))); TALLOC_FREE(result); - return NULL; + return status; } - return result; + *presult = result; + return NT_STATUS_OK; #else DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n")); - return NULL; + return NT_STATUS_NOT_IMPLEMENTED; #endif } -- cgit From 798b56edaec88206b0d61d2852af41777d53aef2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 17:59:30 +0200 Subject: Refactoring: libnetapi_open_pipe takes an interface instead of pipe_idx (This used to be commit 726e56c72fdb685ab5eddefd2fd8b043dc38d6ad) --- source3/rpc_client/cli_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b5a188ed76..6f132a6431 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -86,9 +86,9 @@ const char *cli_get_pipe_name(int pipe_idx) return &pipe_names[pipe_idx].client_pipe[5]; } -static const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx, - struct cli_state *cli, - const struct ndr_syntax_id *interface) +const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx, + struct cli_state *cli, + const struct ndr_syntax_id *interface) { int i; for (i = 0; pipe_names[i].client_pipe; i++) { -- cgit From 9664f24ecfcfe16b90e602bf7c9bc577a0b743d0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 18:45:39 +0200 Subject: Remove now unused cli_get_iface (This used to be commit 2e60701e8d41132f90e64a86bccd99cc188d38c9) --- source3/rpc_client/cli_pipe.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 6f132a6431..b969b83e4f 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -121,15 +121,6 @@ int cli_get_pipe_idx(const RPC_IFACE *syntax) return -1; } -/******************************************************************** - LEGACY function to ease transition from pipe_idx to interface - ********************************************************************/ -const struct ndr_syntax_id *cli_get_iface(int pipe_idx) -{ - SMB_ASSERT((pipe_idx >= 0) && (pipe_idx < PI_MAX_PIPES)); - return pipe_names[pipe_idx].abstr_syntax; -} - /******************************************************************** Map internal value to wire value. ********************************************************************/ -- cgit From 346a8d1bdcb5e69f608e9e6859e36798f3d43abe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 18:46:13 +0200 Subject: Remove now unused cli_get_pipe_idx (This used to be commit e02a550527307f7b300d3fe13631e2d29dbc5e06) --- source3/rpc_client/cli_pipe.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index b969b83e4f..3f27a89fc4 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -106,21 +106,6 @@ const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx, return NULL; } -/**************************************************************************** - Return the pipe idx from the syntax. - ****************************************************************************/ -int cli_get_pipe_idx(const RPC_IFACE *syntax) -{ - int i; - for (i = 0; pipe_names[i].client_pipe; i++) { - if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax, syntax)) { - return i; - } - } - - return -1; -} - /******************************************************************** Map internal value to wire value. ********************************************************************/ -- cgit From 303f98af2fdb39ea1362197baf8fd7d98cea7475 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 18:48:44 +0200 Subject: Remove now unused cli_get_pipe_name (This used to be commit ed4a447103cd9ada59222d79f5784818fe033209) --- source3/rpc_client/cli_pipe.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 3f27a89fc4..7781ea6921 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -78,14 +78,9 @@ static const struct pipe_id_info { }; /**************************************************************************** - Return the pipe name from the index. + Return the pipe name from the interface. ****************************************************************************/ -const char *cli_get_pipe_name(int pipe_idx) -{ - return &pipe_names[pipe_idx].client_pipe[5]; -} - const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx, struct cli_state *cli, const struct ndr_syntax_id *interface) @@ -94,7 +89,7 @@ const char *cli_get_pipe_name_from_iface(TALLOC_CTX *mem_ctx, for (i = 0; pipe_names[i].client_pipe; i++) { if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax, interface)) { - return cli_get_pipe_name(i); + return &pipe_names[i].client_pipe[5]; } } -- cgit From a20c49831013977385e5b7e7bcb307ce451aaaa9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Jul 2008 13:04:13 +0200 Subject: Remove unused function rpccli_is_pipe_idx (This used to be commit 287ffc17a072d5e1a5b0e1ecae089faf67b814b7) --- source3/rpc_client/cli_pipe.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 7781ea6921..ad2f512647 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2326,12 +2326,6 @@ unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, return cli_set_timeout(cli->trans.np.cli, timeout); } -bool rpccli_is_pipe_idx(struct rpc_pipe_client *cli, int pipe_idx) -{ - return ndr_syntax_id_equal(&cli->abstract_syntax, - pipe_names[pipe_idx].abstr_syntax); -} - bool rpccli_get_pwd_hash(struct rpc_pipe_client *cli, uint8_t nt_hash[16]) { if ((cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP) -- cgit From a77c9285b72a521dfffb22359dfcb5e4ba6a6b49 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 20 Aug 2008 20:24:45 +0200 Subject: fix another build warning. Guenther (This used to be commit 43693ce6c678b961fa516bbf502af92f87cd5346) --- source3/rpc_client/cli_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index ad2f512647..41dde87c42 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -979,8 +979,8 @@ static NTSTATUS rpc_api_pipe(struct rpc_pipe_client *cli, while(1) { RPC_HDR rhdr; - char *ret_data; - uint32 ret_data_len; + char *ret_data = NULL; + uint32 ret_data_len = 0; /* Ensure we have enough data for a pdu. */ ret = cli_pipe_get_current_pdu(cli, &rhdr, ¤t_pdu); -- cgit From 29dd253e696f9a2f94fc13f408996eca9ede8a7d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 3 Sep 2008 12:52:29 +0200 Subject: Tiny logic simplification: remove an else branch (This used to be commit 9c4905ed6703a38ff72be5990a036d0a79aebb9f) --- source3/rpc_client/cli_pipe.c | 69 +++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 36 deletions(-) (limited to 'source3/rpc_client/cli_pipe.c') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 41dde87c42..f32a33fdb6 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1637,6 +1637,7 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, uint16 frag_len = 0; uint8 flags = 0; uint32 ss_padding = 0; + ssize_t num_written; data_sent_thistime = calculate_data_len_tosend(cli, data_left, &frag_len, &auth_len, &ss_padding); @@ -1724,43 +1725,39 @@ NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli, } return ret; - } else { - /* More packets to come - write and continue. */ - ssize_t num_written; - - switch (cli->transport_type) { - case NCACN_NP: - num_written = cli_write(cli->trans.np.cli, - cli->trans.np.fnum, - 8, /* 8 means message mode. */ - prs_data_p(&outgoing_pdu), - (off_t)0, - (size_t)hdr.frag_len); - - if (num_written != hdr.frag_len) { - prs_mem_free(&outgoing_pdu); - return cli_get_nt_error( - cli->trans.np.cli); - } - break; - case NCACN_IP_TCP: - case NCACN_UNIX_STREAM: - num_written = write_data( - cli->trans.sock.fd, - prs_data_p(&outgoing_pdu), - (size_t)hdr.frag_len); - if (num_written != hdr.frag_len) { - NTSTATUS status; - status = map_nt_error_from_unix(errno); - prs_mem_free(&outgoing_pdu); - return status; - } - break; - default: - DEBUG(0, ("unknown transport type %d\n", - cli->transport_type)); - return NT_STATUS_INTERNAL_ERROR; + } + + switch (cli->transport_type) { + case NCACN_NP: + num_written = cli_write(cli->trans.np.cli, + cli->trans.np.fnum, + 8, /* 8 means message mode. */ + prs_data_p(&outgoing_pdu), + (off_t)0, + (size_t)hdr.frag_len); + + if (num_written != hdr.frag_len) { + prs_mem_free(&outgoing_pdu); + return cli_get_nt_error(cli->trans.np.cli); } + break; + case NCACN_IP_TCP: + case NCACN_UNIX_STREAM: + num_written = write_data( + cli->trans.sock.fd, + prs_data_p(&outgoing_pdu), + (size_t)hdr.frag_len); + if (num_written != hdr.frag_len) { + NTSTATUS status; + status = map_nt_error_from_unix(errno); + prs_mem_free(&outgoing_pdu); + return status; + } + break; + default: + DEBUG(0, ("unknown transport type %d\n", + cli->transport_type)); + return NT_STATUS_INTERNAL_ERROR; } current_data_offset += data_sent_thistime; -- cgit