diff options
author | Gerald Carter <jerry@samba.org> | 2006-04-08 17:25:31 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:15:55 -0500 |
commit | bbf666e447132a5f6b206ddf9ca918298b756392 (patch) | |
tree | 3cac70deddd159edbd7fb3aece639c48e9a5e67e | |
parent | c9c502442b40aba97de17456ba948effcdfa3d05 (diff) | |
download | samba-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.c | 17 | ||||
-rw-r--r-- | source3/lib/debug.c | 23 | ||||
-rw-r--r-- | source3/lib/messages.c | 18 | ||||
-rw-r--r-- | source3/lib/talloc.c | 10 | ||||
-rw-r--r-- | source3/lib/util.c | 25 | ||||
-rw-r--r-- | source3/lib/util_file.c | 20 | ||||
-rw-r--r-- | source3/lib/util_str.c | 12 | ||||
-rw-r--r-- | source3/lib/util_unistr.c | 39 | ||||
-rw-r--r-- | source3/nsswitch/pam_winbind.c | 10 | ||||
-rw-r--r-- | source3/param/loadparm.c | 50 |
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. |