summaryrefslogtreecommitdiff
path: root/source3/rpc_server/srv_pipe_hnd.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-03-09 23:48:58 +0000
committerJeremy Allison <jra@samba.org>2001-03-09 23:48:58 +0000
commit00ab9021b0cc5fe2667d383eb9cc2973072cdaaa (patch)
treed6444c6041525e86a61c0aa70247dc332aeb1a80 /source3/rpc_server/srv_pipe_hnd.c
parent0bfc10011bd5cacecda8b59c36e80f676e5c7fa3 (diff)
downloadsamba-00ab9021b0cc5fe2667d383eb9cc2973072cdaaa.tar.gz
samba-00ab9021b0cc5fe2667d383eb9cc2973072cdaaa.tar.bz2
samba-00ab9021b0cc5fe2667d383eb9cc2973072cdaaa.zip
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)
Diffstat (limited to 'source3/rpc_server/srv_pipe_hnd.c')
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index eb369f22b4..5545071913 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -96,7 +96,7 @@ static BOOL pipe_init_outgoing_data(pipes_struct *p)
* Initialize the outgoing RPC data buffer.
* we will use this as the raw data area for replying to rpc requests.
*/
- if(!prs_init(&o_data->rdata, MAX_PDU_FRAG_LEN, 4, p->mem_ctx, MARSHALL)) {
+ if(!prs_init(&o_data->rdata, MAX_PDU_FRAG_LEN, p->mem_ctx, MARSHALL)) {
DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
return False;
}
@@ -159,7 +159,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
* change the type to UNMARSALLING before processing the stream.
*/
- if(!prs_init(&p->in_data.data, MAX_PDU_FRAG_LEN, 4, p->mem_ctx, MARSHALL)) {
+ if(!prs_init(&p->in_data.data, MAX_PDU_FRAG_LEN, p->mem_ctx, MARSHALL)) {
DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
return NULL;
}
@@ -185,6 +185,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
p->pipe_bound = False;
p->fault_state = False;
+ p->endian = RPC_LITTLE_ENDIAN;
/*
* Initialize the incoming RPC struct.
@@ -204,7 +205,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
/*
* Initialize the outgoing RPC data buffer with no memory.
*/
- prs_init(&p->out_data.rdata, 0, 4, p->mem_ctx, MARSHALL);
+ prs_init(&p->out_data.rdata, 0, p->mem_ctx, MARSHALL);
ZERO_STRUCT(p->pipe_user);
@@ -275,13 +276,16 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
return -1;
}
- prs_init( &rpc_in, 0, 4, p->mem_ctx, UNMARSHALL);
+ prs_init( &rpc_in, 0, p->mem_ctx, UNMARSHALL);
+ prs_set_endian_data( &rpc_in, p->endian);
+
prs_give_memory( &rpc_in, (char *)&p->in_data.current_in_pdu[0],
p->in_data.pdu_received_len, False);
/*
* Unmarshall the header as this will tell us how much
* data we need to read to get the complete pdu.
+ * This also sets the endian flag in rpc_in.
*/
if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
@@ -303,16 +307,45 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
}
/*
- * If there is no data in the incoming buffer and it's a requst pdu then
- * ensure that the FIRST flag is set. If not then we have
- * a stream missmatch.
+ * If there's not data in the incoming buffer and it's a
+ * request PDU this should be the start of a new RPC.
*/
- if((p->hdr.pkt_type == RPC_REQUEST) && (prs_offset(&p->in_data.data) == 0) && !(p->hdr.flags & RPC_FLG_FIRST)) {
- DEBUG(0,("unmarshall_rpc_header: FIRST flag not set in first PDU !\n"));
- set_incoming_fault(p);
- prs_mem_free(&rpc_in);
- return -1;
+ if((p->hdr.pkt_type == RPC_REQUEST) && (prs_offset(&p->in_data.data) == 0)) {
+
+ if (!(p->hdr.flags & RPC_FLG_FIRST)) {
+ /*
+ * Ensure that the FIRST flag is set. If not then we have
+ * a stream missmatch.
+ */
+
+ DEBUG(0,("unmarshall_rpc_header: FIRST flag not set in first PDU !\n"));
+ set_incoming_fault(p);
+ prs_mem_free(&rpc_in);
+ return -1;
+ }
+
+ /*
+ * If this is the first PDU then set the endianness
+ * flag in the pipe. We will need this when parsing all
+ * data in this RPC.
+ */
+
+ p->endian = rpc_in.bigendian_data;
+
+ } else {
+
+ /*
+ * If this is *NOT* the first PDU then check the endianness
+ * flag in the pipe is the same as that in the PDU.
+ */
+
+ if (p->endian != rpc_in.bigendian_data) {
+ DEBUG(0,("unmarshall_rpc_header: FIRST endianness flag different in next PDU !\n"));
+ set_incoming_fault(p);
+ prs_mem_free(&rpc_in);
+ return -1;
+ }
}
/*
@@ -493,7 +526,10 @@ static ssize_t process_complete_pdu(pipes_struct *p)
return (ssize_t)data_len;
}
- prs_init( &rpc_in, 0, 4, p->mem_ctx, UNMARSHALL);
+ prs_init( &rpc_in, 0, p->mem_ctx, UNMARSHALL);
+ /* Ensure we're using the corrent endianness. */
+ prs_set_endian_data( &rpc_in, p->endian);
+
prs_give_memory( &rpc_in, data_p, (uint32)data_len, False);
DEBUG(10,("process_complete_pdu: processing packet type %u\n",