summaryrefslogtreecommitdiff
path: root/source4/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib')
-rw-r--r--source4/lib/ldb/common/ldb_dn.c155
1 files changed, 121 insertions, 34 deletions
diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c
index 8ee78ca06a..fff70a883f 100644
--- a/source4/lib/ldb/common/ldb_dn.c
+++ b/source4/lib/ldb/common/ldb_dn.c
@@ -203,6 +203,8 @@ char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
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 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
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 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
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 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
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 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
}
*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 @@ static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
}
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 @@ static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
&(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 @@ const char *ldb_dn_get_casefold(struct ldb_dn *dn)
}
*(--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 @@ int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
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 @@ int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
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 @@ static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_d
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 @@ struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *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;
- }
+ 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 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
}
}
- 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 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
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_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
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 @@ bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
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 @@ bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
}
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 @@ struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
*/
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 @@ int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const str
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 @@ int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const str
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;
}