+/* Wrapper functions for the above, for the two different string formats */
+char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
+ return ldb_dn_canonical(mem_ctx, dn, 0);
+
+}
+
+char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
+ return ldb_dn_canonical(mem_ctx, dn, 1);
+}
+
+int ldb_dn_get_comp_num(struct ldb_dn *dn)
+{
+ if ( ! ldb_dn_validate(dn)) {
+ return -1;
+ }
+ return dn->comp_num;
+}
+
+const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
+{
+ if ( ! ldb_dn_validate(dn)) {
+ return NULL;
+ }
+ if (num >= dn->comp_num) return NULL;
+ return dn->components[num].name;
+}
+
+const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
+{
+ if ( ! ldb_dn_validate(dn)) {
+ return NULL;
+ }
+ if (num >= dn->comp_num) return NULL;
+ return &dn->components[num].value;
+}
+
+const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
+{
+ if ( ! ldb_dn_validate(dn)) {
+ return NULL;
+ }
+ if (dn->comp_num == 0) return NULL;
+ return dn->components[0].name;
+}
+
+const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
+{
+ if ( ! ldb_dn_validate(dn)) {
+ return NULL;
+ }
+ if (dn->comp_num == 0) return NULL;
+ return &dn->components[0].value;
+}
+
+int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
+{
+ char *n;
+ struct ldb_val v;
+
+ if ( ! ldb_dn_validate(dn)) {
+ return LDB_ERR_OTHER;
+ }
+
+ if (num >= dn->comp_num) {
+ return LDB_ERR_OTHER;
+ }
+
+ n = talloc_strdup(dn, name);
+ if ( ! n) {
+ return LDB_ERR_OTHER;
+ }
+
+ 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;
+ }
+
+ talloc_free(dn->components[num].name);
+ talloc_free(dn->components[num].value.data);
+ dn->components[num].name = n;
+ dn->components[num].value = v;
+
+ 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);
+ 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;
+ return ! dn->invalid;
+}
+
+bool ldb_dn_is_special(struct ldb_dn *dn)
+{
+ if ( ! dn || dn->invalid) return false;
+ 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;
+ return ! strcmp(dn->linearized, 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;
+}