summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/rpc_client/cli_pipe.c220
-rw-r--r--source3/rpc_client/cli_spoolss.c2
2 files changed, 128 insertions, 94 deletions
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);
}
diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c
index 78ec5f1d94..1875ae5400 100644
--- a/source3/rpc_client/cli_spoolss.c
+++ b/source3/rpc_client/cli_spoolss.c
@@ -56,7 +56,7 @@ BOOL spoolss_enum_printers(struct cli_state *cli, uint16 fnum,
DEBUG(5,("SPOOLSS Enum Printers (Server: %s level: %d)\n",
servername, level));
- make_spoolss_q_enumprinters(&q_o, flags, servername, level, 0x800);
+ make_spoolss_q_enumprinters(&q_o, flags, servername, level, 0x400);
/* turn parameters into data stream */
spoolss_io_q_enumprinters("", &q_o, &buf, 0);