summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h16
-rw-r--r--source3/include/talloc.h1
-rw-r--r--source3/lib/talloc.c22
-rw-r--r--source3/rpc_parse/parse_lsa.c10
-rw-r--r--source3/rpc_parse/parse_misc.c103
-rw-r--r--source3/rpc_parse/parse_spoolss.c4
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c36
-rw-r--r--source3/smbd/process.c2
8 files changed, 134 insertions, 60 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index b525b039ff..bcde386362 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -367,6 +367,8 @@ TALLOC_CTX *talloc_init(void);
void *talloc(TALLOC_CTX *t, size_t size);
void talloc_destroy_pool(TALLOC_CTX *t);
void talloc_destroy(TALLOC_CTX *t);
+size_t talloc_pool_size(TALLOC_CTX *t);
+void *talloc_zero(TALLOC_CTX *t, size_t size);
/*The following definitions come from lib/time.c */
@@ -2398,7 +2400,11 @@ BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET *r_c, prs_struct *ps, in
/*The following definitions come from rpc_parse/parse_misc.c */
-void parse_talloc_free(void);
+TALLOC_CTX *get_current_rpc_talloc(void);
+void set_current_rpc_talloc( TALLOC_CTX *ctx);
+void main_loop_talloc_free(void);
+TALLOC_CTX *main_loop_talloc_get(void);
+TALLOC_CTX *get_talloc_ctx(void);
BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth);
BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth);
uint32 get_enum_hnd(ENUM_HND *enh);
@@ -3311,6 +3317,14 @@ BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int
BOOL api_netdfs_rpc(pipes_struct *p);
+/*The following definitions come from rpc_server/srv_dfs_nt.c */
+
+uint32 _dfs_exist(pipes_struct *p, DFS_Q_DFS_EXIST *q_u, DFS_R_DFS_EXIST *r_u);
+uint32 _dfs_add(pipes_struct *p, DFS_Q_DFS_ADD* q_u, DFS_R_DFS_ADD *r_u);
+uint32 _dfs_remove(pipes_struct *p, DFS_Q_DFS_REMOVE *q_u, DFS_R_DFS_REMOVE *r_u);
+uint32 _dfs_enum(pipes_struct *p, DFS_Q_DFS_ENUM *q_u, DFS_R_DFS_ENUM *r_u);
+uint32 _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u, DFS_R_DFS_GET_INFO *r_u);
+
/*The following definitions come from rpc_server/srv_lsa.c */
#if OLD_NTDOMAIN
diff --git a/source3/include/talloc.h b/source3/include/talloc.h
index 85a722d080..32b0f28ae6 100644
--- a/source3/include/talloc.h
+++ b/source3/include/talloc.h
@@ -36,6 +36,7 @@ struct talloc_chunk {
typedef struct {
struct talloc_chunk *list;
+ size_t total_alloc_size;
} TALLOC_CTX;
#endif
diff --git a/source3/lib/talloc.c b/source3/lib/talloc.c
index a04bd2561b..854a230a0e 100644
--- a/source3/lib/talloc.c
+++ b/source3/lib/talloc.c
@@ -47,6 +47,7 @@ TALLOC_CTX *talloc_init(void)
if (!t) return NULL;
t->list = NULL;
+ t->total_alloc_size = 0;
return t;
}
@@ -82,6 +83,7 @@ void *talloc(TALLOC_CTX *t, size_t size)
c->alloc_size = 0;
c->total_size = asize;
t->list = c;
+ t->total_alloc_size += asize;
}
p = ((char *)t->list->ptr) + t->list->alloc_size;
@@ -107,6 +109,7 @@ void talloc_destroy_pool(TALLOC_CTX *t)
}
t->list = NULL;
+ t->total_alloc_size = 0;
}
/* destroy a whole pool including the context */
@@ -117,3 +120,22 @@ void talloc_destroy(TALLOC_CTX *t)
talloc_destroy_pool(t);
free(t);
}
+
+/* return the current total size of the pool. */
+size_t talloc_pool_size(TALLOC_CTX *t)
+{
+ if (!t->list)
+ return 0;
+ return t->total_alloc_size;
+}
+
+/* talloc and zero memory. */
+void *talloc_zero(TALLOC_CTX *t, size_t size)
+{
+ void *p = talloc(t, size);
+
+ if (p)
+ memset(p, '\0', size);
+
+ return p;
+}
diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c
index a33c759473..d86df0ee11 100644
--- a/source3/rpc_parse/parse_lsa.c
+++ b/source3/rpc_parse/parse_lsa.c
@@ -708,7 +708,7 @@ static BOOL lsa_io_dom_query_2(char *desc, DOM_QUERY_2 *d_q, prs_struct *ps, int
return False;
if (UNMARSHALLING(ps)) {
- d_q->auditsettings = (uint32 *)talloc(ps->mem_ctx, d_q->count2 * sizeof(uint32));
+ d_q->auditsettings = (uint32 *)talloc_zero(ps->mem_ctx, d_q->count2 * sizeof(uint32));
}
if (d_q->auditsettings == NULL) {
@@ -829,13 +829,13 @@ void init_lsa_sid_enum(TALLOC_CTX *mem_ctx, LSA_SID_ENUM *sen,
if (num_entries == 0) return;
- if ((sen->ptr_sid = (uint32 *)talloc(mem_ctx, num_entries *
+ if ((sen->ptr_sid = (uint32 *)talloc_zero(mem_ctx, num_entries *
sizeof(uint32))) == NULL) {
DEBUG(3, ("init_lsa_sid_enum(): out of memory for ptr_sid\n"));
return;
}
- if ((sen->sid = (DOM_SID2 *)talloc(mem_ctx, num_entries *
+ if ((sen->sid = (DOM_SID2 *)talloc_zero(mem_ctx, num_entries *
sizeof(DOM_SID2))) == NULL) {
DEBUG(3, ("init_lsa_sid_enum(): out of memory for sids\n"));
return;
@@ -1070,13 +1070,13 @@ void init_q_lookup_names(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_NAMES *q_l,
q_l->num_entries2 = num_names;
q_l->lookup_level = 1;
- if ((q_l->uni_name = (UNISTR2 *)talloc(
+ if ((q_l->uni_name = (UNISTR2 *)talloc_zero(
mem_ctx, num_names * sizeof(UNISTR2))) == NULL) {
DEBUG(3, ("init_q_lookup_names(): out of memory\n"));
return;
}
- if ((q_l->hdr_name = (UNIHDR *)talloc(
+ if ((q_l->hdr_name = (UNIHDR *)talloc_zero(
mem_ctx, num_names * sizeof(UNIHDR))) == NULL) {
DEBUG(3, ("init_q_lookup_names(): out of memory\n"));
return;
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index 329683d23a..0a65c09493 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -26,18 +26,66 @@
extern int DEBUGLEVEL;
-static TALLOC_CTX *parse_misc_talloc = NULL;
+/****************************************************************************
+ A temporary TALLOC context for things like unistrs, that is valid for
+ the life of a complete RPC call.
+****************************************************************************/
-/******************************************************************* a
+static TALLOC_CTX *current_rpc_talloc = NULL;
+
+TALLOC_CTX *get_current_rpc_talloc(void)
+{
+ return current_rpc_talloc;
+}
+
+void set_current_rpc_talloc( TALLOC_CTX *ctx)
+{
+ current_rpc_talloc = ctx;
+}
+
+static TALLOC_CTX *main_loop_talloc = NULL;
+
+/*******************************************************************
free up temporary memory - called from the main loop
********************************************************************/
-void parse_talloc_free(void)
+void main_loop_talloc_free(void)
{
- if (!parse_misc_talloc)
+ if (!main_loop_talloc)
return;
- talloc_destroy(parse_misc_talloc);
- parse_misc_talloc = NULL;
+ talloc_destroy(main_loop_talloc);
+ main_loop_talloc = NULL;
+}
+
+/*******************************************************************
+ Get a talloc context that is freed in the main loop...
+********************************************************************/
+
+TALLOC_CTX *main_loop_talloc_get(void)
+{
+ if (!main_loop_talloc) {
+ main_loop_talloc = talloc_init();
+ if (!main_loop_talloc)
+ smb_panic("main_loop_talloc: malloc fail\n");
+ }
+
+ return main_loop_talloc;
+}
+
+/*******************************************************************
+ Try and get a talloc context. Get the rpc one if possible, else
+ get the main loop one. The main loop one is more dangerous as it
+ goes away between packets, the rpc one will stay around for as long
+ as a current RPC lasts.
+********************************************************************/
+
+TALLOC_CTX *get_talloc_ctx(void)
+{
+ TALLOC_CTX *tc = get_current_rpc_talloc();
+
+ if (tc)
+ return tc;
+ return main_loop_talloc_get();
}
/*******************************************************************
@@ -483,19 +531,14 @@ void init_unistr(UNISTR *str, const char *buf)
len = strlen(buf) + 1;
- if (!parse_misc_talloc)
- parse_misc_talloc = talloc_init();
-
if (len < MAX_UNISTRLEN)
len = MAX_UNISTRLEN;
len *= sizeof(uint16);
- str->buffer = (uint16 *)talloc(parse_misc_talloc, len);
+ str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
if (str->buffer == NULL)
smb_panic("init_unistr: malloc fail\n");
- memset(str->buffer, '\0', len);
-
/* store the string (null-terminated copy) */
dos_struni2((char *)str->buffer, buf, len);
}
@@ -527,15 +570,12 @@ BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
static void create_buffer3(BUFFER3 *str, size_t len)
{
- if (!parse_misc_talloc)
- parse_misc_talloc = talloc_init();
-
if (len < MAX_BUFFERLEN)
len = MAX_BUFFERLEN;
- str->buffer = talloc(parse_misc_talloc, len);
+ str->buffer = talloc_zero(get_talloc_ctx(), len);
if (str->buffer == NULL)
- smb_panic("create_buffer3: malloc fail\n");
+ smb_panic("create_buffer3: talloc fail\n");
}
@@ -673,14 +713,11 @@ void init_buffer2(BUFFER2 *str, uint8 *buf, int len)
str->buf_len = buf != NULL ? len : 0;
if (buf != NULL) {
- if (!parse_misc_talloc)
- parse_misc_talloc = talloc_init();
-
if (len < MAX_BUFFERLEN)
len = MAX_BUFFERLEN;
- str->buffer = talloc(parse_misc_talloc, len);
+ str->buffer = talloc_zero(get_talloc_ctx(), len);
if (str->buffer == NULL)
- smb_panic("init_buffer2: malloc fail\n");
+ smb_panic("init_buffer2: talloc fail\n");
memcpy(str->buffer, buf, MIN(str->buf_len, len));
}
}
@@ -767,17 +804,14 @@ void copy_unistr2(UNISTR2 *str, UNISTR2 *from)
if (str->buffer == NULL) {
size_t len = from->uni_max_len * sizeof(uint16);
- if (!parse_misc_talloc)
- parse_misc_talloc = talloc_init();
-
if (len < MAX_UNISTRLEN)
len = MAX_UNISTRLEN;
len *= sizeof(uint16);
- str->buffer = (uint16 *)talloc(parse_misc_talloc, len);
+ str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
if ((str->buffer == NULL) && (len > 0 ))
{
- smb_panic("copy_unistr2: malloc fail\n");
+ smb_panic("copy_unistr2: talloc fail\n");
return;
}
}
@@ -801,12 +835,9 @@ void init_string2(STRING2 *str, char *buf, int len)
/* store the string */
if(len != 0) {
- if (!parse_misc_talloc)
- parse_misc_talloc = talloc_init();
-
if (len < MAX_STRINGLEN)
alloc_len = MAX_STRINGLEN;
- str->buffer = talloc(parse_misc_talloc, alloc_len);
+ str->buffer = talloc_zero(get_talloc_ctx(), alloc_len);
if (str->buffer == NULL)
smb_panic("init_string2: malloc fail\n");
memcpy(str->buffer, buf, len);
@@ -869,14 +900,11 @@ void init_unistr2(UNISTR2 *str, const char *buf, size_t len)
str->undoc = 0;
str->uni_str_len = (uint32)len;
- if (!parse_misc_talloc)
- parse_misc_talloc = talloc_init();
-
if (len < MAX_UNISTRLEN)
len = MAX_UNISTRLEN;
len *= sizeof(uint16);
- str->buffer = (uint16 *)talloc(parse_misc_talloc, len);
+ str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
if ((str->buffer == NULL) && (len > 0))
{
smb_panic("init_unistr2: malloc fail\n");
@@ -917,11 +945,8 @@ void init_unistr2_from_unistr (UNISTR2 *to, UNISTR *from)
to->undoc = 0;
to->uni_str_len = i;
- if (!parse_misc_talloc)
- parse_misc_talloc = talloc_init();
-
/* allocate the space and copy the string buffer */
- to->buffer = (uint16 *)talloc(parse_misc_talloc, sizeof(uint16)*(to->uni_str_len));
+ to->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), sizeof(uint16)*(to->uni_str_len));
if (to->buffer == NULL)
smb_panic("init_unistr2_from_unistr: malloc fail\n");
memcpy(to->buffer, from->buffer, to->uni_max_len*sizeof(uint16));
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index 0961cda195..bb8c818421 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -401,10 +401,10 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
/* Tallocate memory for string */
- DEBUG(0, ("** tallocating memory\n"));
+ DEBUG(10, ("** tallocating memory\n"));
data->notify_data.data.string = (uint16 *)
- talloc(ps->mem_ctx, x * 2);
+ talloc_zero(ps->mem_ctx, x * 2);
if (!data->notify_data.data.string)
return False;
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index b8ee235185..3b60c78ade 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -485,14 +485,6 @@ static ssize_t process_complete_pdu(pipes_struct *p)
char *data_p = (char *)&p->in_data.current_in_pdu[0];
BOOL reply = False;
- if (p->mem_ctx) {
- talloc_destroy_pool(p->mem_ctx);
- } else {
- p->mem_ctx = talloc_init();
- if (p->mem_ctx == NULL)
- p->fault_state = True;
- }
-
if(p->fault_state) {
DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
p->name ));
@@ -713,7 +705,7 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
memcpy( data, &p->out_data.current_pdu[p->out_data.current_pdu_sent], (size_t)data_returned);
p->out_data.current_pdu_sent += (uint32)data_returned;
- return data_returned;
+ goto out;
}
/*
@@ -727,9 +719,10 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
/*
- * We have sent all possible data. Return 0.
+ * We have sent all possible data, return 0.
*/
- return 0;
+ data_returned = 0;
+ goto out;
}
/*
@@ -748,6 +741,26 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
memcpy( data, p->out_data.current_pdu, (size_t)data_returned);
p->out_data.current_pdu_sent += (uint32)data_returned;
+
+ out:
+
+ if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
+ /*
+ * We have copied all possible data into the current_pdu. This RPC is finished.
+ * Reset the talloc context to free any allocated data from this RPC.
+ */
+
+ if (p->mem_ctx) {
+ DEBUG(3,("read_from_pipe: destroying talloc pool of size %u\n", talloc_pool_size(p->mem_ctx) ));
+ talloc_destroy_pool(p->mem_ctx);
+ } else {
+ p->mem_ctx = talloc_init();
+ if (p->mem_ctx == NULL)
+ p->fault_state = True;
+ }
+
+ }
+
return data_returned;
}
@@ -872,5 +885,4 @@ pipes_struct *get_rpc_pipe(int pnum)
return NULL;
}
-
#undef OLD_NTDOMAIN
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 461fa99f39..f8fde41b77 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1209,7 +1209,7 @@ void smbd_process(void)
/* free up temporary memory */
lp_talloc_free();
- parse_talloc_free();
+ main_loop_talloc_free();
while (!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout)) {
if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))