summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/ntdomain.h90
-rw-r--r--source3/rpc_client/cli_pipe.c95
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c89
-rw-r--r--source3/smbd/ipc.c12
4 files changed, 167 insertions, 119 deletions
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index 67fe879f9b..329cb1e325 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -46,44 +46,46 @@
typedef struct
{
- struct mem_buf *data; /* memory buffer */
- uint32 offset; /* offset currently being accessed in memory buffer */
- uint8 align; /* data alignment */
- BOOL io; /* parsing in or out of data stream */
+ struct mem_buf *data; /* memory buffer */
+ uint32 offset; /* offset currently being accessed in memory buffer */
+ uint8 align; /* data alignment */
+ BOOL io; /* parsing in or out of data stream */
} prs_struct;
typedef struct
{
- int cnum;
- int uid;
- BOOL open; /* open connection */
- uint16 device_state;
- fstring name;
- fstring pipe_srv_name;
-
- prs_struct rhdr; /* output header */
- prs_struct rdata; /* output data */
- prs_struct rauth; /* output authentication verifier */
-
- RPC_HDR hdr;
- RPC_HDR_BA hdr_ba;
- RPC_HDR_RB hdr_rb;
- RPC_HDR_REQ hdr_req;
- RPC_HDR_RESP hdr_resp;
-
- RPC_AUTH_NTLMSSP_REQ ntlmssp_req;
- RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
-
- uint32 max_rdata_len;
- uint32 hdr_offsets;
+ int cnum;
+ int uid;
+ BOOL open; /* open connection */
+ uint16 device_state;
+ fstring name;
+ fstring pipe_srv_name;
+
+ prs_struct rhdr; /* output header */
+ prs_struct rdata; /* output data */
+ prs_struct rauth; /* output authentication verifier */
+
+ RPC_HDR hdr;
+ RPC_HDR_BA hdr_ba;
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR_REQ hdr_req;
+ RPC_HDR_RESP hdr_resp;
+
+ RPC_AUTH_NTLMSSP_REQ ntlmssp_req;
+ RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+
+ uint32 file_offset;
+ uint32 hdr_offsets;
+ uint32 frag_len_left;
+ uint32 next_frag_start;
} pipes_struct;
struct acct_info
{
- fstring acct_name; /* account name */
- uint32 smb_userid; /* domain-relative RID */
+ fstring acct_name; /* account name */
+ uint32 smb_userid; /* domain-relative RID */
};
struct api_struct
@@ -95,33 +97,33 @@ struct api_struct
struct mem_desc
{
- /* array memory offsets */
- uint32 start;
- uint32 end;
+ /* array memory offsets */
+ uint32 start;
+ uint32 end;
};
struct mem_buf
{
- BOOL dynamic; /* True iff data has been dynamically allocated
- (and therefore can be freed) */
- char *data;
- uint32 data_size;
- uint32 data_used;
+ BOOL dynamic; /* True iff data has been dynamically allocated
+ (and therefore can be freed) */
+ char *data;
+ uint32 data_size;
+ uint32 data_used;
- uint32 margin; /* safety margin when reallocing. */
- /* this can be abused quite nicely */
- uint8 align; /* alignment of data structures (smb, dce/rpc, udp etc) */
+ uint32 margin; /* safety margin when reallocing. */
+ /* this can be abused quite nicely */
+ uint8 align; /* alignment of data structures (smb, dce/rpc, udp etc) */
- struct mem_desc offset;
+ struct mem_desc offset;
- struct mem_buf *next;
+ struct mem_buf *next;
};
typedef struct
{
- uint32 rid;
- char *name;
-
+ uint32 rid;
+ char *name;
+
} rid_name;
#endif /* _NT_DOMAIN_H */
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"));
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index a371e48bfd..7ab2b3aec6 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -81,8 +81,10 @@ void init_rpc_pipe_hnd(void)
Pipes[i].rhdr.offset = 0;
Pipes[i].rdata.offset = 0;
- Pipes[i].max_rdata_len = 0;
- Pipes[i].hdr_offsets = 0;
+ Pipes[i].file_offset = 0;
+ Pipes[i].hdr_offsets = 0;
+ Pipes[i].frag_len_left = 0;
+ Pipes[i].next_frag_start = 0;
}
return;
@@ -110,8 +112,10 @@ int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid)
Pipes[i].rhdr.offset = 0;
Pipes[i].rdata.offset = 0;
- Pipes[i].max_rdata_len = 0;
- Pipes[i].hdr_offsets = 0;
+ Pipes[i].file_offset = 0;
+ Pipes[i].hdr_offsets = 0;
+ Pipes[i].frag_len_left = 0;
+ Pipes[i].next_frag_start = 0;
fstrcpy(Pipes[i].name, pipe_name);
@@ -134,7 +138,7 @@ int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid)
headers are interspersed with the data at regular intervals. by the time
this function is called, the start of the data could possibly have been
- read by an SMBtrans (max_rdata_len != 0).
+ read by an SMBtrans (file_offset != 0).
calling create_rpc_request() here is a fudge. the data should already
have been prepared into arrays of headers + data stream sections.
@@ -142,13 +146,14 @@ int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid)
****************************************************************************/
int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
{
- int data_pos = pos;
+ int data_hdr_pos;
+ int data_pos;
pipes_struct *p = &Pipes[pnum - PIPE_HANDLE_OFFSET];
DEBUG(6,("read_pipe: %x", pnum));
if (VALID_PNUM(pnum - PIPE_HANDLE_OFFSET))
{
- DEBUG(6,("name: %s cnum: %d open: %s data_pos: %lx len: %lx",
+ DEBUG(6,("name: %s cnum: %d open: %s data_pos: %d len: %d",
p->name,
p->cnum,
BOOLSTR(p->open),
@@ -160,7 +165,6 @@ int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
int num = 0;
int len = 0;
uint32 hdr_num = 0;
- uint32 rpc_frag_pos = 0;
DEBUG(6,("OK\n"));
@@ -170,29 +174,38 @@ int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
return 0;
}
- DEBUG(6,("read_pipe: p: %p max_rdata_len: %d data_pos: %d num: %d\n",
- p, p->max_rdata_len, data_pos, num));
+ DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
+ p, p->file_offset, n));
+ DEBUG(6,("read_pipe: frag_len_left: %d next_frag_start: %d\n",
+ p->frag_len_left, p->next_frag_start));
/* the read request starts from where the SMBtrans2 left off. */
- data_pos += p->max_rdata_len;
-
- rpc_frag_pos = data_pos % p->hdr.frag_len;
-
- /* headers accumulate an offset */
- data_pos -= p->hdr_offsets;
+ data_pos = p->file_offset - p->hdr_offsets;
+ data_hdr_pos = p->file_offset;
len = mem_buf_len(p->rhdr.data);
num = len - (int)data_pos;
+ DEBUG(6,("read_pipe: len: %d num: %d n: %d\n", len, num, n));
+
if (num > n) num = n;
+ if (num <= 0)
+ {
+ DEBUG(5,("read_pipe: 0 or -ve data length\n"));
+ return 0;
+ }
if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
{
- DEBUG(5,("read_pipe: hdr_offsets: %d rpc_frag_pos: %d frag_len: %d\n",
- p->hdr_offsets, rpc_frag_pos, p->hdr.frag_len));
+ /* intermediate fragment - possibility of another header */
+
+ DEBUG(5,("read_pipe: frag_len: %d data_pos: %d data_hdr_pos: %d\n",
+ p->hdr.frag_len, data_pos, data_hdr_pos));
- if (rpc_frag_pos == 0)
+ if (data_hdr_pos == p->next_frag_start)
{
+ DEBUG(6,("read_pipe: next fragment header\n"));
+
/* this is subtracted from the total data bytes, later */
hdr_num = 0x18;
@@ -200,24 +213,44 @@ int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
create_rpc_reply(p, data_pos, p->rdata.offset);
mem_buf_copy(data, p->rhdr.data, 0, 0x18);
- /* make room in data stream for header */
- p->hdr_offsets += 0x18;
data += 0x18;
+ p->frag_len_left = p->hdr.frag_len;
+ p->next_frag_start += p->hdr.frag_len;
+ p->hdr_offsets += 0x18;
- DEBUG(6,("read_pipe: hdr_offsets: %d\n", p->hdr_offsets));
+ /*DEBUG(6,("read_pipe: hdr_offsets: %d\n", p->hdr_offsets));*/
}
}
- if (num > 0)
+ if (num < hdr_num)
{
- DEBUG(6,("read_pipe: adjusted data_pos: %d num: %d\n",
- data_pos, num - hdr_num));
- mem_buf_copy(data, p->rhdr.data, data_pos, num - hdr_num);
+ DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
+ }
+
+ DEBUG(6,("read_pipe: adjusted data_pos: %d num-hdr_num: %d\n",
+ data_pos, num - hdr_num));
+ mem_buf_copy(data, p->rhdr.data, data_pos, num - hdr_num);
+
+ data_pos += num;
+ data_hdr_pos += num;
+
+ if (hdr_num == 0x18 && num == 0x18)
+ {
+ DEBUG(6,("read_pipe: just header read\n"));
- return num;
+ /* advance to the next fragment */
+ p->frag_len_left -= 0x18;
}
+ else if (data_hdr_pos == p->next_frag_start)
+ {
+ DEBUG(6,("read_pipe: next fragment expected\n"));
+
+ /* advance to the next fragment */
+ }
+
+ p->file_offset += num;
- return 0;
+ return num;
}
else
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 7cf4d6f5b8..74ae115217 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -3255,9 +3255,9 @@ static BOOL api_dce_rpc_command(char *outbuf,
if (reply)
{
/* now send the reply */
- send_trans_reply(outbuf, p->rhdr.data, NULL, NULL, 0, p->max_rdata_len);
+ send_trans_reply(outbuf, p->rhdr.data, NULL, NULL, 0, p->file_offset);
- if (mem_buf_len(p->rhdr.data) <= p->max_rdata_len)
+ if (mem_buf_len(p->rhdr.data) <= p->file_offset)
{
/* all of data was sent: no need to wait for SMBreadX calls */
mem_free_data(p->rhdr .data);
@@ -3283,7 +3283,7 @@ static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param)
if (set_rpc_pipe_hnd_state(p, id))
{
/* now send the reply */
- send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->max_rdata_len);
+ send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->file_offset);
return True;
}
@@ -3366,10 +3366,10 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid));
/* record maximum data length that can be transmitted in an SMBtrans */
- p->max_rdata_len = mdrcnt;
+ p->file_offset = mdrcnt;
- DEBUG(10,("api_fd_reply: p:%p max_rdata_len: %d\n",
- p, p->max_rdata_len));
+ DEBUG(10,("api_fd_reply: p:%p file_offset: %d\n",
+ p, p->file_offset));
switch (subcommand)
{