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; }