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 */
/*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);
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
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) {
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;
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;
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();
}
/*******************************************************************
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);
}
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");
}
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));
}
}
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;
}
}
/* 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);
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");
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));
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 ));
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;
}
/*
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;
}
/*
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;
}
return NULL;
}
-
#undef OLD_NTDOMAIN