svn commit: samba r19869 - in branches/SAMBA_4_0/source: dsdb/samdb/ldb_modules lib/ldb/common

idra at samba.org idra at samba.org
Thu Nov 23 22:06:08 GMT 2006


Author: idra
Date: 2006-11-23 22:06:07 +0000 (Thu, 23 Nov 2006)
New Revision: 19869

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=19869

Log:

fix memleaks


Modified:
   branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/partition.c
   branches/SAMBA_4_0/source/lib/ldb/common/ldb_dn.c


Changeset:
Modified: branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/partition.c
===================================================================
--- branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/partition.c	2006-11-23 20:59:09 UTC (rev 19868)
+++ branches/SAMBA_4_0/source/dsdb/samdb/ldb_modules/partition.c	2006-11-23 22:06:07 UTC (rev 19869)
@@ -109,8 +109,7 @@
 	/* Figure out which partition it is under */
 	/* Skip the lot if 'data' isn't here yet (initialistion) */
 	for (i=0; data && data->partitions && data->partitions[i]; i++) {
-		if (ldb_dn_compare_base(data->partitions[i]->dn, 
-					dn) == 0) {
+		if (ldb_dn_compare_base(data->partitions[i]->dn, dn) == 0) {
 			return make_module_for_next_request(req, module->ldb, data->partitions[i]->module);
 		}
 	}
@@ -318,8 +317,7 @@
 		}
 		for (i=0; data && data->partitions && data->partitions[i]; i++) {
 			/* Find all partitions under the search base */
-			if (ldb_dn_compare_base(req->op.search.base,
-						data->partitions[i]->dn) == 0) {
+			if (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0) {
 				ret = partition_send_request(ac, data->partitions[i]->module, data->partitions[i]->dn);
 				if (ret != LDB_SUCCESS) {
 					return ret;
@@ -767,8 +765,7 @@
 			}
 			
 			for (partition_idx = 0; data->partitions[partition_idx]; partition_idx++) {
-				if (ldb_dn_compare(data->partitions[partition_idx]->dn, 
-						   base_dn) == 0) {
+				if (ldb_dn_compare(data->partitions[partition_idx]->dn, base_dn) == 0) {
 					partition = data->partitions[partition_idx];
 					break;
 				}

Modified: branches/SAMBA_4_0/source/lib/ldb/common/ldb_dn.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/common/ldb_dn.c	2006-11-23 20:59:09 UTC (rev 19868)
+++ branches/SAMBA_4_0/source/lib/ldb/common/ldb_dn.c	2006-11-23 22:06:07 UTC (rev 19869)
@@ -203,6 +203,8 @@
 
 	ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
 
+	dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
+
 	return dst;
 }
 
@@ -243,6 +245,9 @@
 		return true;
 	}
 
+	/* make sure we free this if alloced previously before replacing */
+	talloc_free(dn->components);
+
 	/* in the common case we have 3 or more components */
 	/* make sure all components are zeroed, other functions depend on this */
 	dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
@@ -306,7 +311,12 @@
 				l = 0;
 
 				*d++ = '\0';
-				dn->components[dn->comp_num].name = dt;
+				dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
+				if ( ! dn->components[dn->comp_num].name) {
+					/* ouch */
+					goto failed;
+				}
+
 				dt = d;
 
 				p++;
@@ -385,8 +395,13 @@
 
 				p++;
 				*d++ = '\0';
-				dn->components[dn->comp_num].value.data = (uint8_t *)dt;
+				dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
 				dn->components[dn->comp_num].value.length = l;
+				if ( ! dn->components[dn->comp_num].value.data) {
+					/* ouch ! */
+					goto failed;
+				}
+
 				dt = d;
 
 				dn->comp_num++;
@@ -486,15 +501,23 @@
 	}
 
 	*d++ = '\0';
-	dn->components[dn->comp_num].value.data = (uint8_t *)dt;
+	dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
 	dn->components[dn->comp_num].value.length = l;
 
+	if ( ! dn->components[dn->comp_num].value.data) {
+		/* ouch */
+		goto failed;
+	}
+
 	dn->comp_num++;
 
 	dn->valid_comp = true;
+
+	talloc_free(data);
 	return true;
 
 failed:
+	dn->comp_num = 0;
 	talloc_free(dn->components);
 	return false;
 }
@@ -584,13 +607,11 @@
 	}
 
 	for (i = 0; i < dn->comp_num; i++) {
-		struct ldb_dn_component dc;
 		const struct ldb_attrib_handler *h;
 
-		memset(&dc, 0, sizeof(dc));
 		dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name);
 		if (!dn->components[i].cf_name) {
-			return false;
+			goto failed;
 		}
 
 		h = ldb_attrib_handler(dn->ldb, dn->components[i].cf_name);
@@ -598,11 +619,20 @@
 					 &(dn->components[i].value),
 					 &(dn->components[i].cf_value));
 		if (ret != 0) {
-			return false;
+			goto failed;
 		}
 	}
 
+	dn->valid_case = true;
+
 	return true;
+
+failed:
+	for (i = 0; i < dn->comp_num; i++) {
+		LDB_FREE(dn->components[i].cf_name);
+		LDB_FREE(dn->components[i].cf_value.data);
+	}
+	return false;
 }
 
 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
@@ -659,7 +689,8 @@
 	}
 	*(--d) = '\0';
 
-	dn->valid_case = true;
+	/* don't waste more memory than necessary */
+	dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
 
 	return dn->casefold;
 }
@@ -711,6 +742,10 @@
 	if (dn->comp_num == 0) {
 		if (dn->special && base->special) {
 			return strcmp(base->linearized, dn->linearized);
+		} else if (dn->special) {
+			return -1;
+		} else if (base->special) {
+			return 1;
 		} else {
 			return 0;
 		}
@@ -773,6 +808,10 @@
 	if (dn0->comp_num == 0) {
 		if (dn0->special && dn1->special) {
 			return strcmp(dn0->linearized, dn1->linearized);
+		} else if (dn0->special) {
+			return 1;
+		} else if (dn1->special) {
+			return -1;
 		} else {
 			return 0;
 		}
@@ -812,6 +851,7 @@
 	dst.name = talloc_strdup(mem_ctx, src->name);
 	if (dst.name == NULL) {
 		LDB_FREE(dst.value.data);
+		return dst;
 	}
 
 	if (src->cf_value.data) {
@@ -868,13 +908,13 @@
 				return NULL;
 			}
 		}
+	}
 
-		if (dn->casefold) {
-			new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
-			if ( ! new_dn->casefold) {
-				talloc_free(new_dn);
-				return NULL;
-			}
+	if (dn->casefold) {
+		new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
+		if ( ! new_dn->casefold) {
+			talloc_free(new_dn);
+			return NULL;
 		}
 	}
 
@@ -934,7 +974,7 @@
 			}
 		}
 
-		if (s) {
+		if (dn->casefold && s) {
 			t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
 			LDB_FREE(dn->casefold);
 			dn->casefold = t;
@@ -1046,7 +1086,7 @@
 
 		dn->comp_num = n;
 
-		if (s) {
+		if (dn->casefold && s) {
 			t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
 			LDB_FREE(dn->casefold);
 			dn->casefold = t;
@@ -1107,6 +1147,8 @@
 
 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
 {
+	int i;
+
 	if ( ! ldb_dn_validate(dn)) {
 		return false;
 	}
@@ -1115,9 +1157,24 @@
 		return false;
 	}
 
+	/* free components */
+	for (i = num; i > 0; i--) {
+		LDB_FREE(dn->components[dn->comp_num - i].name);
+		LDB_FREE(dn->components[dn->comp_num - i].value.data);
+		LDB_FREE(dn->components[dn->comp_num - i].cf_name);
+		LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
+	}
+	
 	dn->comp_num -= num;
 
-	dn->valid_case = false;
+	if (dn->valid_case) {
+		for (i = 0; i < dn->comp_num; i++) {
+			LDB_FREE(dn->components[i].cf_name);
+			LDB_FREE(dn->components[i].cf_value.data);
+		}
+		dn->valid_case = false;
+		LDB_FREE(dn->casefold);
+	}
 
 	if (dn->valid_lin) {	
 		dn->valid_lin = false;
@@ -1140,12 +1197,25 @@
 	}
 
 	for (i = 0, j = num; j < dn->comp_num; i++, j++) {
+		if (i < num) {
+			LDB_FREE(dn->components[i].name);
+			LDB_FREE(dn->components[i].value.data);
+			LDB_FREE(dn->components[i].cf_name);
+			LDB_FREE(dn->components[i].cf_value.data);
+		}
 		dn->components[i] = dn->components[j];
 	}
 
 	dn->comp_num -= num;
 
-	dn->valid_case = false;
+	if (dn->valid_case) {
+		for (i = 0; i < dn->comp_num; i++) {
+			LDB_FREE(dn->components[i].cf_name);
+			LDB_FREE(dn->components[i].cf_value.data);
+		}
+		dn->valid_case = false;
+	}
+	LDB_FREE(dn->casefold);
 
 	if (dn->valid_lin) {	
 		dn->valid_lin = false;
@@ -1182,55 +1252,64 @@
 */
 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
 	int i;
+	TALLOC_CTX *tmpctx;
 	char *cracked = NULL;
  
 	if ( ! ldb_dn_validate(dn)) {
 		return NULL;
 	}
+
+	tmpctx = talloc_new(mem_ctx);
+
 	/* Walk backwards down the DN, grabbing 'dc' components at first */
 	for (i = dn->comp_num - 1 ; i >= 0; i--) {
 		if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
 			break;
 		}
 		if (cracked) {
-			cracked = talloc_asprintf(mem_ctx, "%s.%s",
-						  ldb_dn_escape_value(mem_ctx, dn->components[i].value),
+			cracked = talloc_asprintf(tmpctx, "%s.%s",
+						  ldb_dn_escape_value(tmpctx, dn->components[i].value),
 						  cracked);
 		} else {
-			cracked = ldb_dn_escape_value(mem_ctx, dn->components[i].value);
+			cracked = ldb_dn_escape_value(tmpctx, dn->components[i].value);
 		}
 		if (!cracked) {
-			return NULL;
+			goto done;
 		}
 	}
 
 	/* Only domain components?  Finish here */
 	if (i < 0) {
 		if (ex_format) {
-			cracked = talloc_asprintf(mem_ctx, "%s\n", cracked);
+			cracked = talloc_asprintf(tmpctx, "%s\n", cracked);
 		} else {
-			cracked = talloc_asprintf(mem_ctx, "%s/", cracked);
+			cracked = talloc_asprintf(tmpctx, "%s/", cracked);
 		}
-		return cracked;
+		talloc_steal(mem_ctx, cracked);
+		goto done;
 	}
 
 	/* Now walk backwards appending remaining components */
 	for (; i > 0; i--) {
-		cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked, 
-					  ldb_dn_escape_value(mem_ctx, dn->components[i].value));
+		cracked = talloc_asprintf(tmpctx, "%s/%s", cracked, 
+					  ldb_dn_escape_value(tmpctx, dn->components[i].value));
 		if (!cracked) {
-			return NULL;
+			goto done;
 		}
 	}
 
 	/* Last one, possibly a newline for the 'ex' format */
 	if (ex_format) {
-		cracked = talloc_asprintf(mem_ctx, "%s\n%s", cracked, 
-					  ldb_dn_escape_value(mem_ctx, dn->components[i].value));
+		cracked = talloc_asprintf(tmpctx, "%s\n%s", cracked, 
+					  ldb_dn_escape_value(tmpctx, dn->components[i].value));
 	} else {
-		cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked, 
-					  ldb_dn_escape_value(mem_ctx, dn->components[i].value));
+		cracked = talloc_asprintf(tmpctx, "%s/%s", cracked, 
+					  ldb_dn_escape_value(tmpctx, dn->components[i].value));
 	}
+
+	talloc_steal(mem_ctx, cracked);
+done:
+	talloc_free(tmpctx);
 	return cracked;
 }
 
@@ -1309,6 +1388,7 @@
 	v.length = val.length;
 	v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
 	if ( ! v.data) {
+		talloc_free(n);
 		return LDB_ERR_OTHER;
 	}
 
@@ -1317,8 +1397,15 @@
 	dn->components[num].name = n;
 	dn->components[num].value = v;
 
-	if (dn->valid_case) dn->valid_case = false;
-	if (dn->casefold) LDB_FREE(dn->casefold);
+	if (dn->valid_case) {
+		int i;
+		for (i = 0; i < dn->comp_num; i++) {
+			LDB_FREE(dn->components[i].cf_name);
+			LDB_FREE(dn->components[i].cf_value.data);
+		}
+		dn->valid_case = false;
+	}
+	LDB_FREE(dn->casefold);
 
 	return LDB_SUCCESS;
 }



More information about the samba-cvs mailing list