summaryrefslogtreecommitdiff
path: root/ldb/common
diff options
context:
space:
mode:
Diffstat (limited to 'ldb/common')
-rw-r--r--ldb/common/attrib_handlers.c6
-rw-r--r--ldb/common/ldb.c7
-rw-r--r--ldb/common/ldb_attributes.c47
-rw-r--r--ldb/common/ldb_controls.c20
-rw-r--r--ldb/common/ldb_dn.c453
-rw-r--r--ldb/common/ldb_ldif.c16
-rw-r--r--ldb/common/ldb_match.c2
-rw-r--r--ldb/common/ldb_modules.c17
8 files changed, 492 insertions, 76 deletions
diff --git a/ldb/common/attrib_handlers.c b/ldb/common/attrib_handlers.c
index fb57e2da..5ec86b5b 100644
--- a/ldb/common/attrib_handlers.c
+++ b/ldb/common/attrib_handlers.c
@@ -240,7 +240,7 @@ int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx,
out->length = 0;
out->data = NULL;
- dn = ldb_dn_new(ldb, mem_ctx, (char *)in->data);
+ dn = ldb_dn_from_ldb_val(ldb, mem_ctx, in);
if ( ! ldb_dn_validate(dn)) {
return LDB_ERR_INVALID_DN_SYNTAX;
}
@@ -268,10 +268,10 @@ int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx,
struct ldb_dn *dn1 = NULL, *dn2 = NULL;
int ret;
- dn1 = ldb_dn_new(ldb, mem_ctx, (char *)v1->data);
+ dn1 = ldb_dn_from_ldb_val(ldb, mem_ctx, v1);
if ( ! ldb_dn_validate(dn1)) return -1;
- dn2 = ldb_dn_new(ldb, mem_ctx, (char *)v2->data);
+ dn2 = ldb_dn_from_ldb_val(ldb, mem_ctx, v2);
if ( ! ldb_dn_validate(dn2)) {
talloc_free(dn1);
return -1;
diff --git a/ldb/common/ldb.c b/ldb/common/ldb.c
index bb710334..c013565d 100644
--- a/ldb/common/ldb.c
+++ b/ldb/common/ldb.c
@@ -394,7 +394,6 @@ static int ldb_autotransaction_request(struct ldb_context *ldb,
int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
{
struct event_context *ev;
- int ret;
if (!handle) {
return LDB_ERR_UNAVAILABLE;
@@ -411,8 +410,7 @@ int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
switch (type) {
case LDB_WAIT_NONE:
- ret = event_loop_once(ev);
- if (ret) return LDB_ERR_OPERATIONS_ERROR;
+ event_loop_once(ev);
if (handle->state == LDB_ASYNC_DONE ||
handle->status != LDB_SUCCESS) {
return handle->status;
@@ -421,8 +419,7 @@ int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type)
case LDB_WAIT_ALL:
while (handle->state != LDB_ASYNC_DONE) {
- ret = event_loop_once(ev);
- if (ret) return LDB_ERR_OPERATIONS_ERROR;
+ event_loop_once(ev);
if (handle->status != LDB_SUCCESS) {
return handle->status;
}
diff --git a/ldb/common/ldb_attributes.c b/ldb/common/ldb_attributes.c
index 747f2417..001bc45e 100644
--- a/ldb/common/ldb_attributes.c
+++ b/ldb/common/ldb_attributes.c
@@ -225,3 +225,50 @@ int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
return LDB_SUCCESS;
}
+
+/*
+ add a extended dn syntax to the ldb_schema
+*/
+int ldb_dn_extended_add_syntax(struct ldb_context *ldb,
+ unsigned flags,
+ const struct ldb_dn_extended_syntax *syntax)
+{
+ int n;
+ struct ldb_dn_extended_syntax *a;
+
+ if (!syntax) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ n = ldb->schema.num_dn_extended_syntax + 1;
+
+ a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax,
+ struct ldb_dn_extended_syntax, n);
+
+ if (!a) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ a[ldb->schema.num_dn_extended_syntax] = *syntax;
+ ldb->schema.dn_extended_syntax = a;
+
+ ldb->schema.num_dn_extended_syntax = n;
+
+ return LDB_SUCCESS;
+}
+
+/*
+ return the extended dn syntax for a given name
+*/
+const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb,
+ const char *name)
+{
+ int i;
+ for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) {
+ if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) {
+ return &ldb->schema.dn_extended_syntax[i];
+ }
+ }
+ return NULL;
+}
+
diff --git a/ldb/common/ldb_controls.c b/ldb/common/ldb_controls.c
index e3f85514..6fad5012 100644
--- a/ldb/common/ldb_controls.c
+++ b/ldb/common/ldb_controls.c
@@ -53,6 +53,26 @@ struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char
return NULL;
}
+/* check if a control with the specified "oid" exist and return it */
+/* returns NULL if not found */
+struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid)
+{
+ int i;
+
+ /* check if there's a paged request control */
+ if (rep->controls != NULL) {
+ for (i = 0; rep->controls[i]; i++) {
+ if (strcmp(oid, rep->controls[i]->oid) == 0) {
+ break;
+ }
+ }
+
+ return rep->controls[i];
+ }
+
+ return NULL;
+}
+
/* saves the current controls list into the "saver" and replace the one in req with a new one excluding
the "exclude" control */
/* returns False on error */
diff --git a/ldb/common/ldb_dn.c b/ldb/common/ldb_dn.c
index c0d36cfb..02e21a2b 100644
--- a/ldb/common/ldb_dn.c
+++ b/ldb/common/ldb_dn.c
@@ -52,6 +52,12 @@ struct ldb_dn_component {
struct ldb_val cf_value;
};
+struct ldb_dn_extended_component {
+
+ char *name;
+ struct ldb_val value;
+};
+
struct ldb_dn {
struct ldb_context *ldb;
@@ -63,11 +69,14 @@ struct ldb_dn {
bool valid_case;
char *linearized;
+ char *extended_linearized;
char *casefold;
unsigned int comp_num;
struct ldb_dn_component *components;
+ unsigned int extended_comp_num;
+ struct ldb_dn_extended_component *extended_components;
};
/* strdn may be NULL */
@@ -85,28 +94,34 @@ struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const
if (strdn->data && strdn->length) {
if (strdn->data[0] == '@') {
dn->special = true;
+ }
+ dn->extended_linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
+ LDB_DN_NULL_FAILED(dn->extended_linearized);
+
+ if (strdn->data[0] == '<') {
+ const char *p_save, *p = dn->extended_linearized;
+ do {
+ p_save = p;
+ p = strstr(p, ">;");
+ if (p) {
+ p = p + 2;
+ }
+ } while (p);
+
+ if (p_save == dn->extended_linearized) {
+ dn->linearized = talloc_strdup(dn, "");
+ } else {
+ dn->linearized = talloc_strdup(dn, p_save);
+ }
+ LDB_DN_NULL_FAILED(dn->linearized);
+ } else {
+ dn->linearized = dn->extended_linearized;
+ dn->extended_linearized = NULL;
}
- if (strdn->length >= 6 && strncasecmp((const char *)strdn->data, "<GUID=", 6) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a GUID string to ldb_dn structure */
- } else if (strdn->length >= 8 && strncasecmp((const char *)strdn->data, "<SID=", 8) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a SID string to ldb_dn structure */
- } else if (strdn->length >= 8 && strncasecmp((const char *)strdn->data, "<WKGUID=", 8) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a WKGUID string to ldb_dn structure */
- }
- dn->linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
} else {
dn->linearized = talloc_strdup(dn, "");
+ LDB_DN_NULL_FAILED(dn->linearized);
}
- LDB_DN_NULL_FAILED(dn->linearized);
return dn;
@@ -126,47 +141,21 @@ struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *st
struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
{
- struct ldb_dn *dn;
char *strdn;
va_list ap;
if ( (! mem_ctx) || (! ldb)) return NULL;
- dn = talloc_zero(mem_ctx, struct ldb_dn);
- LDB_DN_NULL_FAILED(dn);
-
- dn->ldb = ldb;
-
va_start(ap, new_fmt);
- strdn = talloc_vasprintf(dn, new_fmt, ap);
+ strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
va_end(ap);
- LDB_DN_NULL_FAILED(strdn);
-
- if (strdn[0] == '@') {
- dn->special = true;
- }
- if (strncasecmp(strdn, "<GUID=", 6) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a GUID string to ldb_dn structure */
- } else if (strncasecmp(strdn, "<SID=", 8) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a SID string to ldb_dn structure */
- } else if (strncasecmp(strdn, "<WKGUID=", 8) == 0) {
- /* this is special DN returned when the
- * exploded_dn control is used */
- dn->special = true;
- /* FIXME: add a WKGUID string to ldb_dn structure */
- }
- dn->linearized = strdn;
- return dn;
-
-failed:
- talloc_free(dn);
+ if (strdn) {
+ struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
+ talloc_free(strdn);
+ return dn;
+ }
+
return NULL;
}
@@ -235,15 +224,19 @@ char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
*/
static bool ldb_dn_explode(struct ldb_dn *dn)
{
- char *p, *data, *d, *dt, *t;
+ char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
bool trim = false;
+ bool in_extended = false;
+ bool in_ex_name = false;
+ bool in_ex_value = false;
bool in_attr = false;
bool in_value = false;
bool in_quote = false;
bool is_oid = false;
bool escape = false;
unsigned x;
- int l;
+ int l, ret;
+ char *parse_dn;
if ( ! dn || dn->invalid) return false;
@@ -251,12 +244,18 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
return true;
}
- if ( ! dn->linearized) {
+ if (dn->extended_linearized) {
+ parse_dn = dn->extended_linearized;
+ } else {
+ parse_dn = dn->linearized;
+ }
+
+ if ( ! parse_dn ) {
return false;
}
/* Empty DNs */
- if (dn->linearized[0] == '\0') {
+ if (parse_dn[0] == '\0') {
return true;
}
@@ -268,6 +267,9 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
/* make sure we free this if alloced previously before replacing */
talloc_free(dn->components);
+ talloc_free(dn->extended_components);
+ dn->extended_components = NULL;
+
/* 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);
@@ -277,19 +279,109 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
dn->comp_num = 0;
/* Components data space is allocated here once */
- data = talloc_array(dn->components, char, strlen(dn->linearized) + 1);
+ data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
if (!data) {
return false;
}
- p = dn->linearized;
- in_attr = true;
+ p = parse_dn;
+ in_extended = true;
+ in_ex_name = false;
+ in_ex_value = false;
trim = true;
t = NULL;
d = dt = data;
while (*p) {
+ if (in_extended) {
+
+ if (!in_ex_name && !in_ex_value) {
+
+ if (p[0] == '<') {
+ p++;
+ ex_name = d;
+ in_ex_name = true;
+ continue;
+ } else if (p[0] == '\0') {
+ p++;
+ continue;
+ } else {
+ in_extended = false;
+ in_attr = true;
+ dt = d;
+
+ continue;
+ }
+ }
+
+ if (in_ex_name && *p == '=') {
+ *d++ = '\0';
+ p++;
+ ex_value = d;
+ in_ex_name = false;
+ in_ex_value = true;
+ continue;
+ }
+
+ if (in_ex_value && *p == '>') {
+ const struct ldb_dn_extended_syntax *extended_syntax;
+ struct ldb_val ex_val = {
+ .data = ex_value,
+ .length = d - ex_value
+ };
+
+ *d++ = '\0';
+ p++;
+ in_ex_value = false;
+
+ /* Process name and ex_value */
+
+ dn->extended_components = talloc_realloc(dn,
+ dn->extended_components,
+ struct ldb_dn_extended_component,
+ dn->extended_comp_num + 1);
+ if ( ! dn->extended_components) {
+ /* ouch ! */
+ goto failed;
+ }
+
+ extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
+ if (!extended_syntax) {
+ /* We don't know about this type of extended DN */
+ goto failed;
+ }
+
+ dn->extended_components[dn->extended_comp_num].name = talloc_strdup(dn->extended_components, ex_name);
+ if (!dn->extended_components[dn->extended_comp_num].name) {
+ /* ouch */
+ goto failed;
+ }
+ ret = extended_syntax->read_fn(dn->ldb, dn->extended_components,
+ &ex_val, &dn->extended_components[dn->extended_comp_num].value);
+ if (ret != LDB_SUCCESS) {
+ dn->invalid = true;
+ goto failed;
+ }
+
+ dn->extended_comp_num++;
+ if (*p == '\0') {
+ /* We have reached the end (extended component only)! */
+ talloc_free(data);
+ return true;
+
+ } else if (*p == ';') {
+ p++;
+ continue;
+ } else {
+ dn->invalid = true;
+ goto failed;
+ }
+ }
+
+ *d++ = *p++;
+ continue;
+ }
if (in_attr) {
if (trim) {
if (*p == ' ') {
@@ -315,6 +407,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
goto failed;
}
+ /* Copy this character across from parse_dn, now we have trimmed out spaces */
*d++ = *p++;
continue;
}
@@ -339,6 +432,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
trim = true;
l = 0;
+ /* Terminate this string in d (which is a copy of parse_dn with spaces trimmed) */
*d++ = '\0';
dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
if ( ! dn->components[dn->comp_num].name) {
@@ -614,6 +708,74 @@ const char *ldb_dn_get_linearized(struct ldb_dn *dn)
return dn->linearized;
}
+char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
+{
+ const char *linearized = ldb_dn_get_linearized(dn);
+ char *p;
+ int i;
+
+ if (!linearized) {
+ return NULL;
+ }
+
+ if (!ldb_dn_has_extended(dn)) {
+ return talloc_strdup(mem_ctx, linearized);
+ }
+
+ if (!ldb_dn_validate(dn)) {
+ return NULL;
+ }
+
+ for (i=0; i < dn->extended_comp_num; i++) {
+ struct ldb_val val;
+ int ret;
+ const struct ldb_dn_extended_syntax *extended_syntax;
+ const char *name = dn->extended_components[i].name;
+
+ extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
+
+ if (mode == 1) {
+ ret = extended_syntax->write_clear_fn(dn->ldb, mem_ctx,
+ &dn->extended_components[i].value,
+ &val);
+ } else if (mode == 0) {
+ ret = extended_syntax->write_hex_fn(dn->ldb, mem_ctx,
+ &dn->extended_components[i].value,
+ &val);
+ } else {
+ ret = -1;
+ }
+
+ if (ret != LDB_SUCCESS) {
+ return NULL;
+ }
+
+ if (i == 0) {
+ p = talloc_asprintf(mem_ctx, "<%s=%s>", dn->extended_components[i].name, val.data);
+ } else {
+ p = talloc_asprintf_append(p, ";<%s=%s>", dn->extended_components[i].name, val.data);
+ }
+
+ talloc_free(val.data);
+
+ if (!p) {
+ return NULL;
+ }
+ }
+
+ if (dn->extended_comp_num && *linearized) {
+ p = talloc_asprintf_append(p, ";%s", linearized);
+ }
+
+ if (!p) {
+ return NULL;
+ }
+
+ return p;
+}
+
+
+
char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
{
return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
@@ -909,6 +1071,30 @@ static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_d
return dst;
}
+static struct ldb_dn_extended_component ldb_dn_extended_copy_component(void *mem_ctx, struct ldb_dn_extended_component *src)
+{
+ struct ldb_dn_extended_component dst;
+
+ memset(&dst, 0, sizeof(dst));
+
+ if (src == NULL) {
+ return dst;
+ }
+
+ dst.value = ldb_val_dup(mem_ctx, &(src->value));
+ if (dst.value.data == NULL) {
+ return dst;
+ }
+
+ dst.name = talloc_strdup(mem_ctx, src->name);
+ if (dst.name == NULL) {
+ LDB_FREE(dst.value.data);
+ return dst;
+ }
+
+ return dst;
+}
+
struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
{
struct ldb_dn *new_dn;
@@ -942,6 +1128,24 @@ struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
}
}
+ if (dn->extended_components) {
+ int i;
+
+ new_dn->extended_components = talloc_zero_array(new_dn, struct ldb_dn_extended_component, dn->extended_comp_num);
+ if ( ! new_dn->extended_components) {
+ talloc_free(new_dn);
+ return NULL;
+ }
+
+ for (i = 0; i < dn->extended_comp_num; i++) {
+ new_dn->extended_components[i] = ldb_dn_extended_copy_component(new_dn->extended_components, &dn->extended_components[i]);
+ if ( ! new_dn->extended_components[i].value.data) {
+ talloc_free(new_dn);
+ return NULL;
+ }
+ }
+ }
+
if (dn->casefold) {
new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
if ( ! new_dn->casefold) {
@@ -958,6 +1162,14 @@ struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
}
}
+ if (dn->extended_linearized) {
+ new_dn->extended_linearized = talloc_strdup(new_dn, dn->extended_linearized);
+ if ( ! new_dn->extended_linearized) {
+ talloc_free(new_dn);
+ return NULL;
+ }
+ }
+
return new_dn;
}
@@ -1037,6 +1249,13 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
dn->linearized = t;
}
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ if (dn->extended_linearized) {
+ LDB_FREE(dn->extended_linearized);
+ }
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
return true;
}
@@ -1149,6 +1368,12 @@ bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
dn->linearized = t;
}
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
+
return true;
}
@@ -1218,6 +1443,12 @@ bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
LDB_FREE(dn->casefold);
LDB_FREE(dn->linearized);
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
+
return true;
}
@@ -1256,6 +1487,11 @@ bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
LDB_FREE(dn->casefold);
LDB_FREE(dn->linearized);
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
return true;
}
@@ -1273,6 +1509,11 @@ struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
return NULL;
}
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ LDB_FREE(dn->extended_components);
+ dn->extended_comp_num = 0;
return new_dn;
}
@@ -1434,9 +1675,97 @@ int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const str
LDB_FREE(dn->casefold);
LDB_FREE(dn->linearized);
+ /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
+ LDB_FREE(dn->extended_linearized);
+
+ dn->extended_comp_num = 0;
+ LDB_FREE(dn->extended_components);
return LDB_SUCCESS;
}
+const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name)
+{
+ int i;
+ if ( ! ldb_dn_validate(dn)) {
+ return NULL;
+ }
+ for (i=0; i < dn->extended_comp_num; i++) {
+ if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
+ return &dn->extended_components[i].value;
+ }
+ }
+ return NULL;
+}
+
+int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val)
+{
+ struct ldb_dn_extended_component *p;
+ int i;
+
+ if ( ! ldb_dn_validate(dn)) {
+ return LDB_ERR_OTHER;
+ }
+
+ for (i=0; i < dn->extended_comp_num; i++) {
+ if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
+ if (val) {
+ dn->extended_components[i].value = ldb_val_dup(dn->extended_components, val);
+
+ dn->extended_components[i].name = talloc_strdup(dn->extended_components, name);
+ if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ } else {
+ if (i != (dn->extended_comp_num - 1)) {
+ memmove(&dn->extended_components[i], &dn->extended_components[i+1],
+ ((dn->extended_comp_num-1) - i)*sizeof(*dn->extended_components));
+ }
+ dn->extended_comp_num--;
+
+ dn->extended_components = talloc_realloc(dn,
+ dn->extended_components,
+ struct ldb_dn_extended_component,
+ dn->extended_comp_num);
+ if (!dn->extended_components) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ return LDB_SUCCESS;
+ }
+ }
+ }
+
+ p = dn->extended_components
+ = talloc_realloc(dn,
+ dn->extended_components,
+ struct ldb_dn_extended_component,
+ dn->extended_comp_num + 1);
+ if (!dn->extended_components) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ p[dn->extended_comp_num].value = ldb_val_dup(dn->extended_components, val);
+ p[dn->extended_comp_num].name = talloc_strdup(p, name);
+
+ if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
+ dn->invalid = true;
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ dn->extended_components = p;
+ dn->extended_comp_num++;
+
+ return LDB_SUCCESS;
+}
+
+void ldb_dn_remove_extended_components(struct ldb_dn *dn)
+{
+ dn->extended_comp_num = 0;
+ LDB_FREE(dn->extended_components);
+}
+
bool ldb_dn_is_valid(struct ldb_dn *dn)
{
if ( ! dn) return false;
@@ -1449,6 +1778,13 @@ bool ldb_dn_is_special(struct ldb_dn *dn)
return dn->special;
}
+bool ldb_dn_has_extended(struct ldb_dn *dn)
+{
+ if ( ! dn || dn->invalid) return false;
+ if (dn->extended_linearized && (dn->extended_linearized[0] == '<')) return true;
+ return dn->extended_comp_num != 0;
+}
+
bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
{
if ( ! dn || dn->invalid) return false;
@@ -1458,6 +1794,7 @@ bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
bool ldb_dn_is_null(struct ldb_dn *dn)
{
if ( ! dn || dn->invalid) return false;
+ if (ldb_dn_has_extended(dn)) return false;
if (dn->linearized && (dn->linearized[0] == '\0')) return true;
return false;
}
diff --git a/ldb/common/ldb_ldif.c b/ldb/common/ldb_ldif.c
index fb93e17c..619c10e1 100644
--- a/ldb/common/ldb_ldif.c
+++ b/ldb/common/ldb_ldif.c
@@ -278,13 +278,15 @@ int ldb_ldif_write(struct ldb_context *ldb,
TALLOC_CTX *mem_ctx;
unsigned int i, j;
int total=0, ret;
+ char *p;
const struct ldb_message *msg;
mem_ctx = talloc_named_const(NULL, 0, "ldb_ldif_write");
msg = ldif->msg;
-
- ret = fprintf_fn(private_data, "dn: %s\n", ldb_dn_get_linearized(msg->dn));
+ p = ldb_dn_get_extended_linearized(mem_ctx, msg->dn, 1);
+ ret = fprintf_fn(private_data, "dn: %s\n", p);
+ talloc_free(p);
CHECK_RET;
if (ldif->changetype != LDB_CHANGETYPE_NONE) {
@@ -328,8 +330,10 @@ int ldb_ldif_write(struct ldb_context *ldb,
for (j=0;j<msg->elements[i].num_values;j++) {
struct ldb_val v;
ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v);
- CHECK_RET;
- if (ldb_should_b64_encode(&v)) {
+ if (ret != LDB_SUCCESS) {
+ v = msg->elements[i].values[j];
+ }
+ if (ret != LDB_SUCCESS || ldb_should_b64_encode(&v)) {
ret = fprintf_fn(private_data, "%s:: ",
msg->elements[i].name);
CHECK_RET;
@@ -562,11 +566,11 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
goto failed;
}
- msg->dn = ldb_dn_new(msg, ldb, (char *)value.data);
+ msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value);
if ( ! ldb_dn_validate(msg->dn)) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n",
- value.data);
+ (char *)value.data);
goto failed;
}
diff --git a/ldb/common/ldb_match.c b/ldb/common/ldb_match.c
index 64d0e547..4cde739d 100644
--- a/ldb/common/ldb_match.c
+++ b/ldb/common/ldb_match.c
@@ -147,7 +147,7 @@ static int ldb_match_equality(struct ldb_context *ldb,
int ret;
if (ldb_attr_dn(tree->u.equality.attr) == 0) {
- valuedn = ldb_dn_new(ldb, ldb, (char *)tree->u.equality.value.data);
+ valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value);
if (valuedn == NULL) {
return 0;
}
diff --git a/ldb/common/ldb_modules.c b/ldb/common/ldb_modules.c
index 2b453bb0..8db28d26 100644
--- a/ldb/common/ldb_modules.c
+++ b/ldb/common/ldb_modules.c
@@ -40,6 +40,9 @@
#define LDB_MODULE_PREFIX "modules:"
#define LDB_MODULE_PREFIX_LEN 8
+static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name,
+ const char *symbol);
+
void ldb_set_modules_dir(struct ldb_context *ldb, const char *path)
{
talloc_free(ldb->modules_dir);
@@ -291,8 +294,8 @@ int ldb_register_module(const struct ldb_module_ops *ops)
return 0;
}
-void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name,
- const char *symbol)
+static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name,
+ const char *symbol)
{
char *path;
void *handle;
@@ -334,6 +337,10 @@ int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, str
for (i = 0; module_list[i] != NULL; i++) {
struct ldb_module *current;
const struct ldb_module_ops *ops;
+
+ if (strcmp(module_list[i], "") == 0) {
+ continue;
+ }
ops = ldb_find_module_ops(module_list[i]);
if (ops == NULL) {
@@ -580,10 +587,13 @@ struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb)
* req: the original request passed to your module
* msg: reply message (must be a talloc pointer, and it will be stolen
* on the ldb_reply that is sent to the callback)
+ * ctrls: controls to send in the reply (must be a talloc pointer, and it will be stolen
+ * on the ldb_reply that is sent to the callback)
*/
int ldb_module_send_entry(struct ldb_request *req,
- struct ldb_message *msg)
+ struct ldb_message *msg,
+ struct ldb_control **ctrls)
{
struct ldb_reply *ares;
@@ -595,6 +605,7 @@ int ldb_module_send_entry(struct ldb_request *req,
}
ares->type = LDB_REPLY_ENTRY;
ares->message = talloc_steal(ares, msg);
+ ares->controls = talloc_steal(ares, ctrls);
ares->error = LDB_SUCCESS;
return req->callback(req, ares);