예제 #1
0
static void delete_context(SMBCCTX *ctx) {
	//Trying to fix the error:  no talloc stackframe at ../source3/libsmb/cliconnect.c:2637, leaking memory
	//TALLOC_CTX *frame = talloc_stackframe();

	//First we need to purge the cache of servers the context has.
	//This should also free all the used memory allocations.
	smbc_getFunctionPurgeCachedServers(ctx)(ctx);

	//We're done with the frame, free it up now.
	//TALLOC_FREE(frame);

	//Next we need to free the context itself, and free all the 
	//memory it used.
	smbc_free_context(ctx, 1);
}
예제 #2
0
/*
 * Free a context
 *
 * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
 * and thus you'll be leaking memory if not handled properly.
 *
 */
int
smbc_free_context(SMBCCTX *context,
                  int shutdown_ctx)
{
        if (!context) {
                errno = EBADF;
                return 1;
        }
        
        if (shutdown_ctx) {
                SMBCFILE * f;
                DEBUG(1,("Performing aggressive shutdown.\n"));
                
                f = context->internal->files;
                while (f) {
                        smbc_getFunctionClose(context)(context, f);
                        f = f->next;
                }
                context->internal->files = NULL;
                
                /* First try to remove the servers the nice way. */
                if (smbc_getFunctionPurgeCachedServers(context)(context)) {
                        SMBCSRV * s;
                        SMBCSRV * next;
                        DEBUG(1, ("Could not purge all servers, "
                                  "Nice way shutdown failed.\n"));
                        s = context->internal->servers;
                        while (s) {
                                DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
                                          s, s->cli->fd));
                                cli_shutdown(s->cli);
                                smbc_getFunctionRemoveCachedServer(context)(context,
                                                                         s);
                                next = s->next;
                                DLIST_REMOVE(context->internal->servers, s);
                                SAFE_FREE(s);
                                s = next;
                        }
                        context->internal->servers = NULL;
                }
        }
        else {
                /* This is the polite way */
                if (smbc_getFunctionPurgeCachedServers(context)(context)) {
                        DEBUG(1, ("Could not purge all servers, "
                                  "free_context failed.\n"));
                        errno = EBUSY;
                        return 1;
                }
                if (context->internal->servers) {
                        DEBUG(1, ("Active servers in context, "
                                  "free_context failed.\n"));
                        errno = EBUSY;
                        return 1;
                }
                if (context->internal->files) {
                        DEBUG(1, ("Active files in context, "
                                  "free_context failed.\n"));
                        errno = EBUSY;
                        return 1;
                }
        }
        
        /* Things we have to clean up */
        free(smbc_getWorkgroup(context));
        smbc_setWorkgroup(context, NULL);

        free(smbc_getNetbiosName(context));
        smbc_setNetbiosName(context, NULL);

        free(smbc_getUser(context));
        smbc_setUser(context, NULL);
        
        DEBUG(3, ("Context %p successfully freed\n", context));

	/* Free any DFS auth context. */
	TALLOC_FREE(context->internal->auth_info);

	SAFE_FREE(context->internal);
        SAFE_FREE(context);

        /* Protect access to the count of contexts in use */
	if (SMB_THREAD_LOCK(initialized_ctx_count_mutex) != 0) {
                smb_panic("error locking 'initialized_ctx_count'");
	}

	if (initialized_ctx_count) {
		initialized_ctx_count--;
	}

	if (initialized_ctx_count == 0) {
            SMBC_module_terminate();
	}

        /* Unlock the mutex */
	if (SMB_THREAD_UNLOCK(initialized_ctx_count_mutex) != 0) {
                smb_panic("error unlocking 'initialized_ctx_count'");
	}
        
        return 0;
}
예제 #3
0
/*
 * Free a context
 *
 * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed
 * and thus you'll be leaking memory if not handled properly.
 *
 */
int
smbc_free_context(SMBCCTX *context,
                  int shutdown_ctx)
{
        if (!context) {
                errno = EBADF;
                return 1;
        }
        
        if (shutdown_ctx) {
                SMBCFILE * f;
                DEBUG(1,("Performing aggressive shutdown.\n"));
                
                f = context->internal->files;
                while (f) {
                        smbc_getFunctionClose(context)(context, f);
                        f = f->next;
                }
                context->internal->files = NULL;
                
                /* First try to remove the servers the nice way. */
                if (smbc_getFunctionPurgeCachedServers(context)(context)) {
                        SMBCSRV * s;
                        SMBCSRV * next;
                        DEBUG(1, ("Could not purge all servers, "
                                  "Nice way shutdown failed.\n"));
                        s = context->internal->servers;
                        while (s) {
                                DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
                                          s, s->cli->fd));
                                cli_shutdown(s->cli);
                                smbc_getFunctionRemoveCachedServer(context)(context,
                                                                         s);
                                next = s->next;
                                DLIST_REMOVE(context->internal->servers, s);
                                SAFE_FREE(s);
                                s = next;
                        }
                        context->internal->servers = NULL;
                }
        }
        else {
                /* This is the polite way */
                if (smbc_getFunctionPurgeCachedServers(context)(context)) {
                        DEBUG(1, ("Could not purge all servers, "
                                  "free_context failed.\n"));
                        errno = EBUSY;
                        return 1;
                }
                if (context->internal->servers) {
                        DEBUG(1, ("Active servers in context, "
                                  "free_context failed.\n"));
                        errno = EBUSY;
                        return 1;
                }
                if (context->internal->files) {
                        DEBUG(1, ("Active files in context, "
                                  "free_context failed.\n"));
                        errno = EBUSY;
                        return 1;
                }
        }
        
        /* Things we have to clean up */
        free(smbc_getWorkgroup(context));
        smbc_setWorkgroup(context, NULL);

        free(smbc_getNetbiosName(context));
        smbc_setNetbiosName(context, NULL);

        free(smbc_getUser(context));
        smbc_setUser(context, NULL);
        
        DEBUG(3, ("Context %p successfully freed\n", context));

	SAFE_FREE(context->internal);
        SAFE_FREE(context);

	if (initialized_ctx_count) {
		initialized_ctx_count--;
	}

	if (initialized_ctx_count == 0 && SMBC_initialized) {
		gencache_shutdown();
		secrets_shutdown();
		gfree_all();
		SMBC_initialized = false;
	}
        return 0;
}