summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-04-08 17:25:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:15:55 -0500
commitbbf666e447132a5f6b206ddf9ca918298b756392 (patch)
tree3cac70deddd159edbd7fb3aece639c48e9a5e67e
parentc9c502442b40aba97de17456ba948effcdfa3d05 (diff)
downloadsamba-bbf666e447132a5f6b206ddf9ca918298b756392.tar.gz
samba-bbf666e447132a5f6b206ddf9ca918298b756392.tar.bz2
samba-bbf666e447132a5f6b206ddf9ca918298b756392.zip
r15003: patch based on code from Arkady Glabek <aglabek@centeris.com> to ensure that global memory is freed when unloading pam_winbind.so (needs more testing on non-linux platforms)
(This used to be commit 1e0b79e591d70352a96e0a0487d8f394dc7b36ba)
-rw-r--r--source3/lib/charcnv.c17
-rw-r--r--source3/lib/debug.c23
-rw-r--r--source3/lib/messages.c18
-rw-r--r--source3/lib/talloc.c10
-rw-r--r--source3/lib/util.c25
-rw-r--r--source3/lib/util_file.c20
-rw-r--r--source3/lib/util_str.c12
-rw-r--r--source3/lib/util_unistr.c39
-rw-r--r--source3/nsswitch/pam_winbind.c10
-rw-r--r--source3/param/loadparm.c50
10 files changed, 213 insertions, 11 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index ae04fd9ffb..097d746a63 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -102,6 +102,23 @@ void lazy_initialize_conv(void)
}
/**
+ * Destroy global objects allocated by init_iconv()
+ **/
+void gfree_charcnv(void)
+{
+ int c1, c2;
+
+ for (c1=0;c1<NUM_CHARSETS;c1++) {
+ for (c2=0;c2<NUM_CHARSETS;c2++) {
+ if ( conv_handles[c1][c2] ) {
+ smb_iconv_close( conv_handles[c1][c2] );
+ conv_handles[c1][c2] = 0;
+ }
+ }
+ }
+}
+
+/**
* Initialize iconv conversion descriptors.
*
* This is called the first time it is needed, and also called again
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index 97a147f17d..b8c42686cd 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -177,6 +177,27 @@ static char **classname_table = NULL;
* Functions...
*/
+/***************************************************************************
+ Free memory pointed to by global pointers.
+****************************************************************************/
+
+void gfree_debugsyms(void)
+{
+ int i;
+
+ if ( classname_table ) {
+ for ( i = 0; i < debug_num_classes; i++ ) {
+ SAFE_FREE( classname_table[i] );
+ }
+ SAFE_FREE( classname_table );
+ }
+
+ if ( DEBUGLEVEL_CLASS != &debug_all_class_hack )
+ SAFE_FREE( DEBUGLEVEL_CLASS );
+
+ if ( DEBUGLEVEL_CLASS_ISSET != &debug_all_class_isset_hack )
+ SAFE_FREE( DEBUGLEVEL_CLASS_ISSET );
+}
/****************************************************************************
utility lists registered debug class names's
@@ -510,7 +531,7 @@ void debug_init(void)
if (initialised)
return;
-
+
initialised = True;
message_register(MSG_DEBUG, debug_message);
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 2d6518aed6..cd2a3b36b6 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -70,6 +70,24 @@ static struct dispatch_fns {
} *dispatch_fns;
/****************************************************************************
+ Free global objects.
+****************************************************************************/
+
+void gfree_messsges(void)
+{
+ struct dispatch_fns *dfn, *next;
+
+ /* delete the dispatch_fns list */
+ dfn = dispatch_fns;
+ while( dfn ) {
+ next = dfn->next;
+ DLIST_REMOVE(dispatch_fns, dfn);
+ SAFE_FREE(dfn);
+ dfn = next;
+ }
+}
+
+/****************************************************************************
Notifications come in as signals.
****************************************************************************/
diff --git a/source3/lib/talloc.c b/source3/lib/talloc.c
index ba189199d7..c111615506 100644
--- a/source3/lib/talloc.c
+++ b/source3/lib/talloc.c
@@ -883,6 +883,16 @@ static void talloc_report_null_full(void)
}
/*
+ free allocated global memory
+*/
+
+void talloc_nc_free(void)
+{
+ if ( null_context )
+ talloc_free( (void*)null_context );
+}
+
+/*
enable tracking of the NULL context
*/
void talloc_enable_null_tracking(void)
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 0fbe4a13d3..bfc5eb2a8d 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -179,6 +179,31 @@ static BOOL set_my_netbios_names(const char *name, int i)
return True;
}
+/***********************************************************************
+ Free memory allocated to global objects
+***********************************************************************/
+
+void gfree_names(void)
+{
+ SAFE_FREE( smb_myname );
+ SAFE_FREE( smb_myworkgroup );
+ SAFE_FREE( smb_scope );
+ free_netbios_names_array();
+}
+
+void gfree_all( void )
+{
+ gfree_names();
+ gfree_loadparm();
+ gfree_case_tables();
+ gfree_debugsyms();
+ gfree_charcnv();
+ gfree_messsges();
+
+ /* release the talloc null_context memory last */
+ talloc_nc_free();
+}
+
const char *my_netbios_names(int i)
{
return smb_my_netbios_names[i];
diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c
index 06008886c0..fff564aeb0 100644
--- a/source3/lib/util_file.c
+++ b/source3/lib/util_file.c
@@ -441,6 +441,26 @@ char *file_load(const char *fname, size_t *size, size_t maxsize)
}
/*******************************************************************
+ unmap or free memory
+*******************************************************************/
+
+BOOL unmap_file(void* start, size_t size)
+{
+#ifdef HAVE_MMAP
+ if ( munmap( start, size ) != 0 ) {
+ DEBUG( 1, ("map_file: Failed to unmap address %X "
+ "of size %d - %s\n",
+ start, size, strerror(errno) ));
+ return False;
+ }
+ return True;
+#else
+ SAFE_FREE( start );
+ return True;
+#endif
+}
+
+/*******************************************************************
mmap (if possible) or read a file.
********************************************************************/
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 446a4a00a1..439cbea6d9 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -853,7 +853,7 @@ BOOL in_list(const char *s, const char *list, BOOL casesensitive)
}
/* this is used to prevent lots of mallocs of size 1 */
-static char *null_string = NULL;
+static const char *null_string = "";
/**
Set a string value, allocing the space for the string
@@ -862,20 +862,14 @@ static char *null_string = NULL;
static BOOL string_init(char **dest,const char *src)
{
size_t l;
+
if (!src)
src = "";
l = strlen(src);
if (l == 0) {
- if (!null_string) {
- if((null_string = (char *)SMB_MALLOC(1)) == NULL) {
- DEBUG(0,("string_init: malloc fail for null_string.\n"));
- return False;
- }
- *null_string = 0;
- }
- *dest = null_string;
+ *dest = CONST_DISCARD(char*, null_string);
} else {
(*dest) = SMB_STRDUP(src);
if ((*dest) == NULL) {
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c
index 9713c0ccb7..eef484148d 100644
--- a/source3/lib/util_unistr.c
+++ b/source3/lib/util_unistr.c
@@ -31,6 +31,9 @@
static smb_ucs2_t *upcase_table;
static smb_ucs2_t *lowcase_table;
static uint8 *valid_table;
+static BOOL upcase_table_use_unmap;
+static BOOL lowcase_table_use_unmap;
+static BOOL valid_table_use_unmap;
/**
* This table says which Unicode characters are valid dos
@@ -40,6 +43,32 @@ static uint8 *valid_table;
**/
static uint8 doschar_table[8192]; /* 65536 characters / 8 bits/byte */
+/**
+ * Destroy global objects allocated by load_case_tables()
+ **/
+void gfree_case_tables(void)
+{
+ if ( upcase_table ) {
+ if ( upcase_table_use_unmap )
+ unmap_file(upcase_table, 0x20000);
+ else
+ SAFE_FREE(upcase_table);
+ }
+
+ if ( lowcase_table ) {
+ if ( lowcase_table_use_unmap )
+ unmap_file(lowcase_table, 0x20000);
+ else
+ SAFE_FREE(lowcase_table);
+ }
+
+ if ( valid_table ) {
+ if ( valid_table_use_unmap )
+ unmap_file(valid_table, 0x10000);
+ else
+ SAFE_FREE(valid_table);
+ }
+}
/**
* Load or generate the case handling tables.
@@ -60,7 +89,10 @@ void load_case_tables(void)
initialised = 1;
upcase_table = map_file(lib_path("upcase.dat"), 0x20000);
+ upcase_table_use_unmap = ( upcase_table != NULL );
+
lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000);
+ lowcase_table_use_unmap = ( lowcase_table != NULL );
#ifdef HAVE_SETLOCALE
/* Get the name of the current locale. */
@@ -196,6 +228,7 @@ void init_valid_table(void)
if (valid_file) {
valid_table = valid_file;
mapped_file = 1;
+ valid_table_use_unmap = True;
return;
}
@@ -203,7 +236,11 @@ void init_valid_table(void)
* It might need to be regenerated if the code page changed.
* We know that we're not using a mapped file, so we can
* free() the old one. */
- if (valid_table) free(valid_table);
+ if (valid_table)
+ SAFE_FREE(valid_table);
+
+ /* use free rather than unmap */
+ valid_table_use_unmap = False;
DEBUG(2,("creating default valid table\n"));
valid_table = SMB_MALLOC(0x10000);
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index d78d65287e..2db10b69a8 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -17,6 +17,16 @@
#define MAX_PASSWD_TRIES 3
+/*******************************************************************
+ Need this destructor to free global memory when the shared library
+ is unloaded
+*******************************************************************/
+
+void __attribute__ ((destructor)) _fini_pam_winbind(void)
+{
+ gfree_all();
+}
+
/* some syslogging */
static void _pam_log(int err, const char *format, ...)
{
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index b7d6546fd9..e0c6c0686f 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -4865,6 +4865,56 @@ int load_usershare_shares(void)
return lp_numservices();
}
+/********************************************************
+ Destroy global resources allocated in this file
+********************************************************/
+
+void gfree_loadparm(void)
+{
+ struct file_lists *f;
+ struct file_lists *next;
+ int i;
+
+ lp_TALLOC_FREE();
+
+ /* Free the file lists */
+
+ f = file_lists;
+ while( f ) {
+ next = f->next;
+ SAFE_FREE( f->name );
+ SAFE_FREE( f->subfname );
+ SAFE_FREE( f );
+ f = next;
+ }
+
+ /* Free resources allocated to services */
+
+ for ( i = 0; i < iNumServices; i++ ) {
+ if ( VALID(i) ) {
+ free_service_byindex(i);
+ }
+ }
+
+ SAFE_FREE( ServicePtrs );
+ iNumServices = 0;
+
+ /* Now release all resources allocated to global
+ parameters and the default service */
+
+ for (i = 0; parm_table[i].label; i++)
+ {
+ if ( parm_table[i].type == P_STRING
+ || parm_table[i].type == P_USTRING )
+ {
+ string_free( (char**)parm_table[i].ptr );
+ }
+ else if (parm_table[i].type == P_LIST) {
+ str_list_free( (char***)parm_table[i].ptr );
+ }
+ }
+}
+
/***************************************************************************
Load the services array from the services file. Return True on success,
False on failure.