Hello list,

While trying to figure out why openchangesim require so much memory I found that I had long lasting ldb objects and cli_credential.

But making profile to be talloced we can use profile as a talloc context for ldb requests and for cli_credential thus allowing desallocation of memory once the profile is not needed anymore.

I have also I patch to free the session in duplicate profile and another to have correctly initialized structures so that valgrind doesn't complain.


Any comments ?

Matthieu
>From ff51d200e17dc834bc31564443e75569c11efdf2 Mon Sep 17 00:00:00 2001
From: Matthieu Patou <[email protected]>
Date: Tue, 13 Mar 2012 11:54:55 -0700
Subject: [PATCH 1/4] Free the session in duplicateprofile

---
 libmapi/IProfAdmin.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/libmapi/IProfAdmin.c b/libmapi/IProfAdmin.c
index b651eba..75dfc6b 100644
--- a/libmapi/IProfAdmin.c
+++ b/libmapi/IProfAdmin.c
@@ -1139,6 +1139,8 @@ _PUBLIC_ enum MAPISTATUS DuplicateProfile(struct mapi_context *mapi_ctx,
 		set_profile_attribute(mapi_ctx, profile_dst, *SRowSet, index, PR_EMAIL_ADDRESS, "EmailAddress");
 		mapi_profile_delete_string_attr(mapi_ctx, profile_dst, "EmailAddress", oldEmailAddress);
 		MAPIFreeBuffer(SRowSet);
+		DLIST_REMOVE(mapi_ctx->session, session);
+		MAPIFreeBuffer(session);
 	}
 
 	/* Change ProxyAddress */
-- 
1.7.5.4

>From f8db2472f16b8f7b1fc37ec9ba1bf46d785598ea Mon Sep 17 00:00:00 2001
From: Matthieu Patou <[email protected]>
Date: Thu, 15 Mar 2012 16:38:48 -0700
Subject: [PATCH 2/4] Cleanly initialize structures for mapi_response

---
 libmapi/IUnknown.c |    2 ++
 ndr_mapi.c         |    4 +++-
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/libmapi/IUnknown.c b/libmapi/IUnknown.c
index 44c1eb6..85988b9 100644
--- a/libmapi/IUnknown.c
+++ b/libmapi/IUnknown.c
@@ -122,6 +122,8 @@ _PUBLIC_ enum MAPISTATUS Release(mapi_object_t *obj)
 	enum MAPISTATUS		retval;
 	uint8_t 		logon_id = 0;
 
+	mapi_response = 0;
+
 	/* Sanity checks */
 	session = mapi_object_get_session(obj);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
diff --git a/ndr_mapi.c b/ndr_mapi.c
index 2448178..d1e661d 100644
--- a/ndr_mapi.c
+++ b/ndr_mapi.c
@@ -633,7 +633,7 @@ enum ndr_err_code ndr_pull_mapi_response(struct ndr_pull *ndr, int ndr_flags, st
 	/* If length equals length field then skipping subcontext */
 	if (r->length > sizeof (uint16_t)) {
 		_mem_save_mapi_repl_0 = NDR_PULL_GET_MEM_CTX(ndr);
-		r->mapi_repl = talloc_array(_mem_save_mapi_repl_0, struct EcDoRpc_MAPI_REPL, 2);
+		r->mapi_repl = talloc_zero_array(_mem_save_mapi_repl_0, struct EcDoRpc_MAPI_REPL, 2);
 		NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_mapi_repl, 0, r->length - 2));
 		for (cntr_mapi_repl_0 = 0; _ndr_mapi_repl->offset < _ndr_mapi_repl->data_size - 2; cntr_mapi_repl_0++) {
 			NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL(_ndr_mapi_repl, NDR_SCALARS, &r->mapi_repl[cntr_mapi_repl_0]));
@@ -642,6 +642,8 @@ enum ndr_err_code ndr_pull_mapi_response(struct ndr_pull *ndr, int ndr_flags, st
 		r->mapi_repl[cntr_mapi_repl_0].opnum = 0;
 		NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_mapi_repl, 4, -1));
 		talloc_free(_ndr_mapi_repl);
+	} else {
+		r->mapi_repl = NULL;
 	}
 
 	_mem_save_handles_0 = NDR_PULL_GET_MEM_CTX(ndr);
-- 
1.7.5.4

>From 63ebb4a4573f51a3492b602a5a2301eba177573e Mon Sep 17 00:00:00 2001
From: Matthieu Patou <[email protected]>
Date: Fri, 16 Mar 2012 17:38:50 -0700
Subject: [PATCH 3/4] Move to talloced profile so that we can free ressources
 more easily

---
 libmapi/IProfAdmin.c |   54 ++++++++++++++++++++++++++++++-------------------
 utils/mapiprofile.c  |   30 ++++++++++++++-------------
 2 files changed, 49 insertions(+), 35 deletions(-)

diff --git a/libmapi/IProfAdmin.c b/libmapi/IProfAdmin.c
index 75dfc6b..35d8afe 100644
--- a/libmapi/IProfAdmin.c
+++ b/libmapi/IProfAdmin.c
@@ -57,30 +57,39 @@ static enum MAPISTATUS ldb_load_profile(TALLOC_CTX *mem_ctx,
 	if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND;
 
 	/* profile not found */
-	if (!res->count) return MAPI_E_NOT_FOUND;
+	if (!res->count) {
+		talloc_free(res);
+		return MAPI_E_NOT_FOUND;
+	}
+
 	/* more than one profile */
-	if (res->count > 1) return MAPI_E_COLLISION;
+	if (res->count > 1) {
+		talloc_free(res);
+		return MAPI_E_COLLISION;
+	}
 
 	/* fills in profile with query result */
 	msg = res->msgs[0];
 
-	profile->username = ldb_msg_find_attr_as_string(msg, "username", NULL);
-	profile->password = password ? password : ldb_msg_find_attr_as_string(msg, "password", NULL);
-	profile->workstation = ldb_msg_find_attr_as_string(msg, "workstation", NULL);
-	profile->realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);
-	profile->domain = ldb_msg_find_attr_as_string(msg, "domain", NULL);
-	profile->mailbox = ldb_msg_find_attr_as_string(msg, "EmailAddress", NULL);
-	profile->homemdb = ldb_msg_find_attr_as_string(msg, "HomeMDB", NULL);
-	profile->localaddr = ldb_msg_find_attr_as_string(msg, "localaddress", NULL);
-	profile->server = ldb_msg_find_attr_as_string(msg, "binding", NULL);
+	profile->username = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "username", NULL));
+	profile->password = password ? password : talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "password", NULL));
+	profile->workstation = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "workstation", NULL));
+	profile->realm = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "realm", NULL));
+	profile->domain = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "domain", NULL));
+	profile->mailbox = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "EmailAddress", NULL));
+	profile->homemdb = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "HomeMDB", NULL));
+	profile->localaddr = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "localaddress", NULL));
+	profile->server = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "binding", NULL));
 	profile->seal = ldb_msg_find_attr_as_bool(msg, "seal", false);
-	profile->org = ldb_msg_find_attr_as_string(msg, "Organization", NULL);
-	profile->ou = ldb_msg_find_attr_as_string(msg, "OrganizationUnit", NULL);
+	profile->org = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "Organization", NULL));
+	profile->ou = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "OrganizationUnit", NULL));
 	profile->codepage = ldb_msg_find_attr_as_int(msg, "codepage", 0);
 	profile->language = ldb_msg_find_attr_as_int(msg, "language", 0);
 	profile->method = ldb_msg_find_attr_as_int(msg, "method", 0);
 	profile->exchange_version = ldb_msg_find_attr_as_int(msg, "exchange_version", 0);
-	profile->kerberos = ldb_msg_find_attr_as_string(msg, "kerberos", NULL);
+	profile->kerberos = talloc_steal(profile, ldb_msg_find_attr_as_string(msg, "kerberos", NULL));
+
+	talloc_free(res);
 
 	return MAPI_E_SUCCESS;
 }
@@ -1022,7 +1031,7 @@ _PUBLIC_ enum MAPISTATUS DuplicateProfile(struct mapi_context *mapi_ctx,
 	char			*username_src = NULL;
 	char			*ProxyAddress = NULL;
 	char			*oldEmailAddress = NULL;
-	struct mapi_profile	profile;
+	struct mapi_profile	*profile;
 	char			**attr_tmp = NULL;
 	char			*tmp = NULL;
 	char			*attr;
@@ -1034,27 +1043,29 @@ _PUBLIC_ enum MAPISTATUS DuplicateProfile(struct mapi_context *mapi_ctx,
 	OPENCHANGE_RETVAL_IF(!profile_dst, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL);
 
+	mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "DuplicateProfile");
+	profile = talloc(mem_ctx, struct mapi_profile);
+
 	/* Step 1. Copy the profile */
 	retval = CopyProfile(mapi_ctx, profile_src, profile_dst);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 
 	/* retrieve username, EmailAddress and ProxyAddress */
-	retval = OpenProfile(mapi_ctx, &profile, profile_src, NULL);
+	retval = OpenProfile(mapi_ctx, profile, profile_src, NULL);
 	OPENCHANGE_RETVAL_IF(retval, MAPI_E_NOT_FOUND, NULL);
 
-	mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "DuplicateProfile");
 
-	retval = GetProfileAttr(&profile, "username", &count, &attr_tmp);
+	retval = GetProfileAttr(profile, "username", &count, &attr_tmp);
 	OPENCHANGE_RETVAL_IF(retval || !count, MAPI_E_NOT_FOUND, mem_ctx);
 	username_src = talloc_strdup(mem_ctx, attr_tmp[0]);
 	talloc_free(attr_tmp[0]);
 
-	retval = GetProfileAttr(&profile, "EmailAddress", &count, &attr_tmp);
+	retval = GetProfileAttr(profile, "EmailAddress", &count, &attr_tmp);
 	OPENCHANGE_RETVAL_IF(retval, MAPI_E_NOT_FOUND, mem_ctx);
 	oldEmailAddress = talloc_strdup(mem_ctx, attr_tmp[0]);
 	talloc_free(attr_tmp[0]);
 
-	retval = GetProfileAttr(&profile, "ProxyAddress", &count, &attr_tmp);
+	retval = GetProfileAttr(profile, "ProxyAddress", &count, &attr_tmp);
 	OPENCHANGE_RETVAL_IF(retval, MAPI_E_NOT_FOUND, mem_ctx);
 	ProxyAddress = talloc_strdup(mem_ctx, attr_tmp[0]);
 	talloc_free(attr_tmp[0]);
@@ -1072,7 +1083,7 @@ _PUBLIC_ enum MAPISTATUS DuplicateProfile(struct mapi_context *mapi_ctx,
 		char				*password;
 		struct mapi_session     *session = NULL;
 
-		retval = GetProfileAttr(&profile, "password", &count, &attr_tmp);
+		retval = GetProfileAttr(profile, "password", &count, &attr_tmp);
 		OPENCHANGE_RETVAL_IF(retval || !count, MAPI_E_NOT_FOUND, mem_ctx);
 		password = talloc_strdup(mem_ctx, attr_tmp[0]);
 		talloc_free(attr_tmp[0]);
@@ -1159,6 +1170,7 @@ _PUBLIC_ enum MAPISTATUS DuplicateProfile(struct mapi_context *mapi_ctx,
 	mapi_profile_modify_string_attr(mapi_ctx, profile_dst, "DisplayName", username);
 	mapi_profile_modify_string_attr(mapi_ctx, profile_dst, "Account", username);
 
+	talloc_free(profile);
 	talloc_free(mem_ctx);
 
 	return MAPI_E_SUCCESS;
diff --git a/utils/mapiprofile.c b/utils/mapiprofile.c
index b3331eb..b85aa4f 100644
--- a/utils/mapiprofile.c
+++ b/utils/mapiprofile.c
@@ -402,11 +402,12 @@ static void mapiprofile_dump(struct mapi_context *mapi_ctx, const char *profdb,
 {
 	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
-	struct mapi_profile	profile;
+	struct mapi_profile	*profile;
 	char			*profname;
 	char			*exchange_version = NULL;
 
 	mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapiprofile_dump");
+	profile = talloc(mem_ctx, struct mapi_profile);
 
 	if (!opt_profname) {
 		if ((retval = GetDefaultProfile(mapi_ctx, &profname)) != MAPI_E_SUCCESS) {
@@ -418,7 +419,7 @@ static void mapiprofile_dump(struct mapi_context *mapi_ctx, const char *profdb,
 		profname = talloc_strdup(mem_ctx, (const char *)opt_profname);
 	}
 
-	retval = OpenProfile(mapi_ctx, &profile, profname, NULL);
+	retval = OpenProfile(mapi_ctx, profile, profname, NULL);
 	talloc_free(profname);
 
 	if (retval && (retval != MAPI_E_INVALID_PARAMETER)) {
@@ -427,7 +428,7 @@ static void mapiprofile_dump(struct mapi_context *mapi_ctx, const char *profdb,
 		exit (1);
 	}
 
-	switch (profile.exchange_version) {
+	switch (profile->exchange_version) {
 	case 0x0:
 		exchange_version = talloc_strdup(mem_ctx, "exchange 2000");
 		break;
@@ -442,15 +443,15 @@ static void mapiprofile_dump(struct mapi_context *mapi_ctx, const char *profdb,
 		goto end;
 	}
 
-	printf("Profile: %s\n", profile.profname);
+	printf("Profile: %s\n", profile->profname);
 	printf("\texchange server == %s\n", exchange_version);
-	printf("\tencryption      == %s\n", (profile.seal == true) ? "yes" : "no");
-	printf("\tusername        == %s\n", profile.username);
-	printf("\tpassword        == %s\n", profile.password);
-	printf("\tmailbox         == %s\n", profile.mailbox);
-	printf("\tworkstation     == %s\n", profile.workstation);
-	printf("\tdomain          == %s\n", profile.domain);
-	printf("\tserver          == %s\n", profile.server);
+	printf("\tencryption      == %s\n", (profile->seal == true) ? "yes" : "no");
+	printf("\tusername        == %s\n", profile->username);
+	printf("\tpassword        == %s\n", profile->password);
+	printf("\tmailbox         == %s\n", profile->mailbox);
+	printf("\tworkstation     == %s\n", profile->workstation);
+	printf("\tdomain          == %s\n", profile->domain);
+	printf("\tserver          == %s\n", profile->server);
 
 end:
 	talloc_free(mem_ctx);
@@ -461,13 +462,14 @@ static void mapiprofile_attribute(struct mapi_context *mapi_ctx, const char *pro
 {
 	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
-	struct mapi_profile	profile;
+	struct mapi_profile	*profile;
 	char			*profname = NULL;
 	char			**value = NULL;
 	unsigned int		count = 0;
 	unsigned int		i;
 
 	mem_ctx = talloc_named(mapi_ctx->mem_ctx, 0, "mapiprofile_attribute");
+	profile = talloc(mem_ctx, struct mapi_profile);
 
 	if (!opt_profname) {
 		if ((retval = GetDefaultProfile(mapi_ctx, &profname)) != MAPI_E_SUCCESS) {
@@ -478,7 +480,7 @@ static void mapiprofile_attribute(struct mapi_context *mapi_ctx, const char *pro
 		profname = talloc_strdup(mem_ctx, (const char *)opt_profname);
 	}
 
-	retval = OpenProfile(mapi_ctx, &profile, profname, NULL);
+	retval = OpenProfile(mapi_ctx, profile, profname, NULL);
 	if (retval && (retval != MAPI_E_INVALID_PARAMETER)) {
 		mapi_errstr("OpenProfile", retval);
 		talloc_free(profname);
@@ -486,7 +488,7 @@ static void mapiprofile_attribute(struct mapi_context *mapi_ctx, const char *pro
 		exit (1);
 	}
 
-	if ((retval = GetProfileAttr(&profile, attribute, &count, &value))) {
+	if ((retval = GetProfileAttr(profile, attribute, &count, &value))) {
 		mapi_errstr("ProfileGetAttr", retval);
 		talloc_free(profname);
 		talloc_free(mem_ctx);
-- 
1.7.5.4

>From 6d0a674141ce1a713b1cc6aff269617e52defacb Mon Sep 17 00:00:00 2001
From: Matthieu Patou <[email protected]>
Date: Sun, 18 Mar 2012 19:25:06 -0700
Subject: [PATCH 4/4] Use the profile as a talloc context for credentials,
 allow ressources to be freed

---
 libmapi/IProfAdmin.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/libmapi/IProfAdmin.c b/libmapi/IProfAdmin.c
index 35d8afe..35967fd 100644
--- a/libmapi/IProfAdmin.c
+++ b/libmapi/IProfAdmin.c
@@ -761,7 +761,7 @@ _PUBLIC_ enum MAPISTATUS LoadProfile(struct mapi_context *mapi_ctx,
 
 	mem_ctx = mapi_ctx->mem_ctx;
 
-	profile->credentials = cli_credentials_init(mem_ctx);
+	profile->credentials = cli_credentials_init(profile);
 	OPENCHANGE_RETVAL_IF(!profile->credentials, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
 	cli_credentials_guess(profile->credentials, mapi_ctx->lp_ctx);
 	if (profile->workstation && *(profile->workstation)) {
-- 
1.7.5.4

_______________________________________________
devel mailing list
[email protected]
http://mailman.openchange.org/listinfo/devel

Reply via email to