summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/common
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-12-18 15:40:05 -0800
committerJeremy Allison <jra@samba.org>2008-12-18 15:40:05 -0800
commit4283ae489b6e227beba196e8a315a9727f03cc07 (patch)
tree7308561653b9e52eab8fc13181c0ad41ae2da208 /source4/lib/ldb/common
parentf9bb8fbe832409893b17f2113d7b35b9ffe91540 (diff)
parentd031472227b44d040698e6dff52dc79028fde854 (diff)
downloadsamba-4283ae489b6e227beba196e8a315a9727f03cc07.tar.gz
samba-4283ae489b6e227beba196e8a315a9727f03cc07.tar.bz2
samba-4283ae489b6e227beba196e8a315a9727f03cc07.zip
Merge branch 'master' of ssh://jra@git.samba.org/data/git/samba
Diffstat (limited to 'source4/lib/ldb/common')
-rw-r--r--source4/lib/ldb/common/ldb_attributes.c47
-rw-r--r--source4/lib/ldb/common/ldb_controls.c20
-rw-r--r--source4/lib/ldb/common/ldb_dn.c453
-rw-r--r--source4/lib/ldb/common/ldb_ldif.c6
-rw-r--r--source4/lib/ldb/common/ldb_modules.c6
5 files changed, 471 insertions, 61 deletions
diff --git a/source4/lib/ldb/common/ldb_attributes.c b/source4/lib/ldb/common/ldb_attributes.c
index 747f241781..48f9e11caf 100644
--- a/source4/lib/ldb/common/ldb_attributes.c
+++ b/source4/lib/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 0;
+}
+
+/*
+ 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/source4/lib/ldb/common/ldb_controls.c b/source4/lib/ldb/common/ldb_controls.c
index e3f8551407..6fad5012b6 100644
--- a/source4/lib/ldb/common/ldb_controls.c
+++ b/source4/lib/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/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c
index e36aea4e69..13c01f4e70 100644
--- a/source4/lib/ldb/common/ldb_dn.c
+++ b/source4/lib/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 >= 5 && strncasecmp((const char *)strdn->data, "<SID=", 5) == 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=", 5) == 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 0;
+ }
+ }
+ }
+
+ 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 0;
+}
+
+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/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c
index 69490e670b..619c10e11e 100644
--- a/source4/lib/ldb/common/ldb_ldif.c
+++ b/source4/lib/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) {
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index ab0f4c51cc..8db28d262c 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -587,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;
@@ -602,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);