summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/rpc_parse/parse_prs.c29
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c7
3 files changed, 34 insertions, 3 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index cf3929f68d..45fd66cd09 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2064,6 +2064,7 @@ BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout);
void prs_mem_free(prs_struct *ps);
void prs_give_memory(prs_struct *ps, char *buf, uint32 size, BOOL is_dynamic);
char *prs_take_memory(prs_struct *ps, uint32 *psize);
+BOOL prs_set_buffer_size(prs_struct *ps, uint32 newsize);
BOOL prs_grow(prs_struct *ps, uint32 extra_space);
BOOL prs_force_grow(prs_struct *ps, uint32 extra_space);
char *prs_data_p(prs_struct *ps);
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 4260b1c8d5..dafff63ad9 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -154,6 +154,29 @@ char *prs_take_memory(prs_struct *ps, uint32 *psize)
}
/*******************************************************************
+ Set a prs_struct to exactly a given size. Will grow or tuncate if neccessary.
+ ********************************************************************/
+
+BOOL prs_set_buffer_size(prs_struct *ps, uint32 newsize)
+{
+ if (newsize > ps->buffer_size)
+ return prs_force_grow(ps, newsize - ps->buffer_size);
+
+ if (newsize < ps->buffer_size) {
+ char *new_data_p = Realloc(ps->data_p, newsize);
+ if (new_data_p == NULL) {
+ DEBUG(0,("prs_set_buffer_size: Realloc failure for size %u.\n",
+ (unsigned int)newsize));
+ return False;
+ }
+ ps->data_p = new_data_p;
+ ps->buffer_size = newsize;
+ }
+
+ return True;
+}
+
+/*******************************************************************
Attempt, if needed, to grow a data buffer.
Also depends on the data stream mode (io).
********************************************************************/
@@ -300,7 +323,7 @@ BOOL prs_set_offset(prs_struct *ps, uint32 offset)
BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src)
{
- if(!prs_force_grow(dst, prs_offset(src)))
+ if(!prs_grow(dst, prs_offset(src)))
return False;
memcpy(&dst->data_p[dst->data_offset], prs_data_p(src), (size_t)prs_offset(src));
@@ -315,7 +338,7 @@ BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src)
BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uint32 len)
{
- if(!prs_force_grow(dst, len))
+ if(!prs_grow(dst, len))
return False;
memcpy(&dst->data_p[dst->data_offset], prs_data_p(src)+start, (size_t)len);
@@ -330,7 +353,7 @@ BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uin
BOOL prs_append_data(prs_struct *dst, char *src, uint32 len)
{
- if(!prs_force_grow(dst, len))
+ if(!prs_grow(dst, len))
return False;
memcpy(&dst->data_p[dst->data_offset], src, (size_t)len);
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index f19aed1886..a349da839a 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -476,6 +476,13 @@ authentication failed. Denying the request.\n", p->name));
*/
/*
+ * Ensure the internal prs buffer size is *exactly* the same
+ * size as the current offset.
+ */
+
+ prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data));
+
+ /*
* Set the parse offset to the start of the data and set the
* prs_struct to UNMARSHALL.
*/