r15003: patch based on code from Arkady Glabek <aglabek@centeris.com> to ensure that...
authorGerald Carter <jerry@samba.org>
Sat, 8 Apr 2006 17:25:31 +0000 (17:25 +0000)
committerGerald Carter <jerry@samba.org>
Sat, 8 Apr 2006 17:25:31 +0000 (17:25 +0000)
source/lib/charcnv.c
source/lib/debug.c
source/lib/messages.c
source/lib/talloc.c
source/lib/util.c
source/lib/util_file.c
source/lib/util_str.c
source/lib/util_unistr.c
source/nsswitch/pam_winbind.c
source/param/loadparm.c

index ae04fd9ffb9bef4a8e49c1cd63e22839edda96ad..097d746a638817d5b012d9fb607089f59757e560 100644 (file)
@@ -101,6 +101,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.
  *
index 97a147f17d429a4a324c61c29268cae3925b53fd..b8c42686cdb0f5465e806a3099a093623553d11c 100644 (file)
@@ -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);
index 2d6518aed6a718a429962e487e61702f4a9b2836..cd2a3b36b6e2402d4bc48b244f80d82276e7036c 100644 (file)
@@ -69,6 +69,24 @@ static struct dispatch_fns {
        void (*fn)(int msg_type, struct process_id pid, void *buf, size_t len);
 } *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.
 ****************************************************************************/
index ba189199d71a0faf7196779365375b57c3111024..c11161550651e99073b2994436336d50d805bdf7 100644 (file)
@@ -882,6 +882,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
 */
index 0fbe4a13d3df45c3991e6fcc114c804accf8e5de..bfc5eb2a8da92ffb0847a584f8e0f749f67d58ba 100644 (file)
@@ -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];
index 06008886c056bce9da5aa89df32fce02270f5e92..fff564aeb01f6ba3020b8f0f6aac4cd12250d7c0 100644 (file)
@@ -440,6 +440,26 @@ char *file_load(const char *fname, size_t *size, size_t maxsize)
        return p;
 }
 
+/*******************************************************************
+ 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.
 ********************************************************************/
index 446a4a00a1916e3ac9ae1fea71a6061fa972bf6e..439cbea6d9317b3dd578c6f65c8d9b361c6a2f04 100644 (file)
@@ -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) {
index 9713c0ccb73fd77adf13677c2992c769df27a020..eef484148dbaf9c65d4934a8d89c2faa2a3edd41 100644 (file)
@@ -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);
index d78d65287ed221449436d7130641ee1e21c2d4cd..2db10b69a8b236441090dbde25a8de7f05dacf1e 100644 (file)
 
 #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, ...)
 {
index b7d6546fd9ae1886999316ef21e9245a22137669..e0c6c0686f1389342e4540342976be61a931dfa6 100644 (file)
@@ -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.