Merge branch 'master' of ssh://git.samba.org/data/git/abartlet/samba into extended...
[abartlet/samba.git/.git] / source4 / lib / ldb / common / ldb_dn.c
index 5ffada8a2eab50890bff0f33fffe13d19de87ff6..13c01f4e70dcb4d049d697b8e1dd6789b1eb59e6 100644 (file)
@@ -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;
@@ -70,7 +76,7 @@ struct ldb_dn {
        struct ldb_dn_component *components;
 
        unsigned int extended_comp_num;
-       struct ldb_dn_component *extended_components;
+       struct ldb_dn_extended_component *extended_components;
 };
 
 /* strdn may be NULL */
@@ -302,6 +308,8 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
                                } else {
                                        in_extended = false;
                                        in_attr = true;
+                                       dt = d;
+
                                        continue;
                                }
                        }
@@ -330,7 +338,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
 
                                dn->extended_components = talloc_realloc(dn,
                                                                         dn->extended_components,
-                                                                        struct ldb_dn_component,
+                                                                        struct ldb_dn_extended_component,
                                                                         dn->extended_comp_num + 1);
                                if ( ! dn->extended_components) {
                                        /* ouch ! */
@@ -358,7 +366,10 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
                                dn->extended_comp_num++;
 
                                if (*p == '\0') {
-                                       continue;
+                                       /* We have reached the end (extended component only)! */
+                                       talloc_free(data);
+                                       return true;
+
                                } else if (*p == ';') {
                                        p++;
                                        continue;
@@ -369,6 +380,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn)
                        }
 
                        *d++ = *p++;
+                       continue;
                }
                if (in_attr) {
                        if (trim) {
@@ -696,7 +708,7 @@ const char *ldb_dn_get_linearized(struct ldb_dn *dn)
        return dn->linearized;
 }
 
-char *ldb_dn_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
+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;
@@ -706,6 +718,14 @@ char *ldb_dn_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
                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;
@@ -745,8 +765,6 @@ char *ldb_dn_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
 
        if (dn->extended_comp_num && *linearized) {
                p = talloc_asprintf_append(p, ";%s", linearized);
-       } else if (dn->extended_comp_num == 0) {
-               p = talloc_strdup(mem_ctx, linearized);
        }
 
        if (!p) {
@@ -1053,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;
@@ -1089,14 +1131,14 @@ 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_component, dn->extended_comp_num);
+               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_copy_component(new_dn->extended_components, &dn->extended_components[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;
@@ -1648,7 +1690,7 @@ const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const cha
                return NULL;
        }
        for (i=0; i < dn->extended_comp_num; i++) {
-               if (strcmp(dn->extended_components[i].name, name) == 0) {
+               if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
                        return &dn->extended_components[i].value;
                }
        }
@@ -1657,7 +1699,7 @@ const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const cha
 
 int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val)
 {
-       struct ldb_dn_component *p;
+       struct ldb_dn_extended_component *p;
        int i;
                                
        if ( ! ldb_dn_validate(dn)) {
@@ -1665,10 +1707,16 @@ int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const str
        }
 
        for (i=0; i < dn->extended_comp_num; i++) {
-               if (strcmp(dn->extended_components[i].name, name) == 0) {
+               if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
                        if (val) {
-                               talloc_steal(dn->extended_components, val->data);
-                               dn->extended_components[i].value = *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],
@@ -1676,11 +1724,11 @@ int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const str
                                }
                                dn->extended_comp_num--;
                                
-                               p = talloc_realloc(dn,
+                               dn->extended_components = talloc_realloc(dn,
                                                   dn->extended_components,
-                                                  struct ldb_dn_component,
+                                                  struct ldb_dn_extended_component,
                                                   dn->extended_comp_num);
-                               if (!p) {
+                               if (!dn->extended_components) {
                                        dn->invalid = true;
                                        return LDB_ERR_OPERATIONS_ERROR;
                                }
@@ -1689,25 +1737,26 @@ int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const str
                }
        }
 
-       p = talloc_realloc(dn,
-                          dn->extended_components,
-                          struct ldb_dn_component,
-                          dn->extended_comp_num + 1);
-       if (!p) {
+       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 = *val;
+       
+       p[dn->extended_comp_num].value = ldb_val_dup(dn->extended_components, val);
        p[dn->extended_comp_num].name = talloc_strdup(p, name);
-
-       if (!p[dn->extended_comp_num].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;
 }
 
@@ -1732,7 +1781,8 @@ bool ldb_dn_is_special(struct ldb_dn *dn)
 bool ldb_dn_has_extended(struct ldb_dn *dn)
 {
        if ( ! dn || dn->invalid) return false;
-       return dn->extended_comp_num;
+       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)
@@ -1744,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;
 }