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...
prs_struct rhdr; /* output header */
prs_struct rdata; /* output data */
+ prs_struct rdata_i; /* output data (intermediate, for fragments) */
prs_struct rauth; /* output authentication verifier */
prs_struct rverf; /* output verifier */
prs_struct rntlm; /* output ntlmssp */
/*The following definitions come from lib/membuffer.c */
void mem_init(struct mem_buf *buf, int margin);
-void mem_create(struct mem_buf *buf, char *data, int size, int margin, BOOL dynamic);
+void mem_create(struct mem_buf *buf, char *data, int offset, int size, int margin, BOOL dynamic);
BOOL mem_alloc_data(struct mem_buf *buf, int size);
BOOL mem_buf_copy(char *copy_into, struct mem_buf *buf,
uint32 offset, uint32 len);
dynamic indicates memory has been dynamically allocated.
if mem_free is called, the memory will be freed.
********************************************************************/
-void mem_create(struct mem_buf *buf, char *data, int size, int margin, BOOL dynamic)
+void mem_create(struct mem_buf *buf, char *data, int offset, int size, int margin, BOOL dynamic)
{
buf->dynamic = dynamic;
buf->data = data;
buf->next = NULL;
- buf->offset.start = 0;
- buf->offset.end = size;
+ buf->offset.start = offset;
+ buf->offset.end = offset + size;
}
/*******************************************************************
buf->data = malloc(buf->data_size);
- if (buf->data == NULL)
+ if (buf->data == NULL && size != 0)
{
DEBUG(3,("mem_alloc: could not malloc size %d\n",
buf->data_size));
{
ret = receive_smb(fd, buffer, timeout);
- if(ret == False)
+ if (!ret)
+ {
return ret;
+ }
/* Ignore session keepalive packets. */
if(CVAL(buffer,0) != 0x85)
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",
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)
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));
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;
}
/****************************************************************************
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Andrew Tridgell 1992-1998,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-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
dump_data(50, data, n);
/* fake up a data buffer from the write_pipe data parameters */
- mem_create(&data_buf, data, n, 0, False);
+ mem_create(&data_buf, data, 0, n, 0, False);
data_buf.offset.start = 0;
data_buf.offset.end = n;
this function is called, the start of the data could possibly have been
read by an SMBtrans (file_offset != 0).
- calling create_rpc_request() here is a fudge. the data should already
+ calling create_rpc_reply() here is a fudge. the data should already
have been prepared into arrays of headers + data stream sections.
****************************************************************************/
mem_buf_copy(data, p->rhdr.data, 0, 0x18);
data += 0x18;
- p->frag_len_left = p->hdr.frag_len;
- p->next_frag_start += p->hdr.frag_len;
p->hdr_offsets += 0x18;
}
}
BOOL create_rpc_reply(pipes_struct *p,
uint32 data_start, uint32 data_end)
{
+ char *data;
+ uint32 data_len;
+
DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
data_start, data_end, p->hdr_ba.bba.max_tsize));
p->hdr.frag_len = p->hdr_ba.bba.max_tsize;
}
+ data_len = p->hdr.frag_len;
+
p->rhdr.data->offset.start = 0;
p->rhdr.data->offset.end = 0x18;
smb_io_rpc_hdr ("hdr", &(p->hdr ), &(p->rhdr), 0);
smb_io_rpc_hdr_resp("resp", &(p->hdr_resp), &(p->rhdr), 0);
+ p->frag_len_left = p->hdr.frag_len - p->file_offset;
+ p->next_frag_start = p->hdr.frag_len;
+
+ /* don't use rdata: use rdata_i instead, which moves... */
+ /* make a pointer to the rdata data. NOT A COPY */
+
+ prs_init(&p->rdata_i, 0, p->rdata.align, p->rdata.data->margin, p->rdata.io);
+ data = mem_data(&(p->rdata.data), data_start);
+ mem_create(p->rdata_i.data, data, data_start, data_len, 0, False);
+
+ /* set up the data chain */
+ prs_link(NULL , &p->rhdr , &p->rdata_i);
+ prs_link(&p->rhdr, &p->rdata_i, NULL );
+
return p->rhdr.data != NULL && p->rhdr.offset == 0x18;
}
return False;
}
- p->frag_len_left = p->hdr.frag_len - p->file_offset;
- p->next_frag_start = p->hdr.frag_len;
-
- /* set up the data chain */
- p->rhdr.data->offset.start = 0;
- p->rhdr.data->offset.end = p->rhdr.offset;
- p->rhdr.data->next = p->rdata.data;
-
- p->rdata.data->offset.start = p->rhdr.data->offset.end;
- p->rdata.data->offset.end = p->rhdr.data->offset.end + p->rdata.offset;
- p->rdata.data->next = NULL;
-
return True;
}
/* all of data was sent: no need to wait for SMBreadX calls */
mem_free_data(p->rhdr .data);
mem_free_data(p->rdata.data);
+ mem_free_data(p->rdata_i.data);
}
}
int subcommand;
pipes_struct *p = NULL;
prs_struct pd;
- struct mem_buf data_buf;
DEBUG(5,("api_fd_reply\n"));
- /* fake up a data buffer from the api_fd_reply data parameters */
- mem_create(&data_buf, data, tdscnt, 0, False);
- data_buf.offset.start = 0;
- data_buf.offset.end = tdscnt;
-
- /* fake up a parsing structure */
- pd.data = &data_buf;
- pd.align = 4;
- pd.io = True;
- pd.offset = 0;
+ /* make a static data parsing structure from the api_fd_reply data */
+ prs_init(&pd, 0, 4, True, 0);
+ mem_create(pd.data, data, 0, tdscnt, 0, False);
/* First find out the name of this file. */
if (suwcnt != 2)
DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
}
+ mem_free_data(pd.data);
+
if (!reply)
{
return api_no_reply(outbuf, mdrcnt);
&rdata,&rparam,&rdata_len,&rparam_len);
- mem_create(&rdata_buf , rdata , rdata_len , 0, False);
- mem_create(&rparam_buf, rparam, rparam_len, 0, False);
-
- rdata_buf.offset.start = 0;
- rdata_buf.offset.end = rdata_len;
-
- rparam_buf.offset.start = 0;
- rparam_buf.offset.end = rparam_len;
+ mem_create(&rdata_buf , rdata , 0, rdata_len , 0, False);
+ mem_create(&rparam_buf, rparam, 0, rparam_len, 0, False);
/* now send the reply */
send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0);