📄 ldb_dn.c
字号:
*/int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn){ int ret; int n_base, n_dn; if ( ! base || base->invalid) return 1; if ( ! dn || dn->invalid) return -1; if (( ! base->valid_case) || ( ! dn->valid_case)) { if (base->linearized && dn->linearized) { /* try with a normal compare first, if we are lucky * we will avoid exploding and casfolding */ int dif; dif = strlen(dn->linearized) - strlen(base->linearized); if (dif < 0) return dif; if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0; } if ( ! ldb_dn_casefold_internal(base)) { return 1; } if ( ! ldb_dn_casefold_internal(dn)) { return -1; } } /* if base has more components, * they don't have the same base */ if (base->comp_num > dn->comp_num) { return (dn->comp_num - base->comp_num); } 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; } } n_base = base->comp_num - 1; n_dn = dn->comp_num - 1; while (n_base >= 0) { /* compare attr names */ ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name); if (ret != 0) return ret; /* compare attr.cf_value. */ if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) { return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length; } ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data); if (ret != 0) return ret; n_base--; n_dn--; } return 0;}/* compare DNs using casefolding compare functions. If they match, then return 0 */int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1){ int i, ret; if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1; if (( ! dn0->valid_case) || ( ! dn1->valid_case)) { if (dn0->linearized && dn1->linearized) { /* try with a normal compare first, if we are lucky * we will avoid exploding and casfolding */ if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0; } if ( ! ldb_dn_casefold_internal(dn0)) { return 1; } if ( ! ldb_dn_casefold_internal(dn1)) { return -1; } } if (dn0->comp_num != dn1->comp_num) { return (dn1->comp_num - dn0->comp_num); } 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; } } for (i = 0; i < dn0->comp_num; i++) { /* compare attr names */ ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name); if (ret != 0) return ret; /* compare attr.cf_value. */ if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) { return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length; } ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data); if (ret != 0) return ret; } return 0;}static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src){ struct ldb_dn_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; } if (src->cf_value.data) { dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value)); if (dst.cf_value.data == NULL) { LDB_FREE(dst.value.data); LDB_FREE(dst.name); return dst; } dst.cf_name = talloc_strdup(mem_ctx, src->cf_name); if (dst.cf_name == NULL) { LDB_FREE(dst.cf_name); LDB_FREE(dst.value.data); LDB_FREE(dst.name); return dst; } } else { dst.cf_value.data = NULL; dst.cf_name = NULL; } return dst;}struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn){ struct ldb_dn *new_dn; if (!dn || dn->invalid) { return NULL; } new_dn = talloc_zero(mem_ctx, struct ldb_dn); if ( !new_dn) { return NULL; } *new_dn = *dn; if (dn->components) { int i; new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num); if ( ! new_dn->components) { talloc_free(new_dn); return NULL; } for (i = 0; i < dn->comp_num; i++) { new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]); if ( ! new_dn->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) { talloc_free(new_dn); return NULL; } } if (dn->linearized) { new_dn->linearized = talloc_strdup(new_dn, dn->linearized); if ( ! new_dn->linearized) { talloc_free(new_dn); return NULL; } } return new_dn;}/* modify the given dn by adding a base. * * return true if successful and false if not * if false is returned the dn may be marked invalid */bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base){ const char *s; char *t; if ( !base || base->invalid || !dn || dn->invalid) { return false; } if (dn->components) { int i; if ( ! ldb_dn_validate(base)) { return false; } s = NULL; if (dn->valid_case) { if ( ! (s = ldb_dn_get_casefold(base))) { return false; } } dn->components = talloc_realloc(dn, dn->components, struct ldb_dn_component, dn->comp_num + base->comp_num); if ( ! dn->components) { dn->invalid = true; return false; } for (i = 0; i < base->comp_num; dn->comp_num++, i++) { dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]); if (dn->components[dn->comp_num].value.data == NULL) { dn->invalid = true; return false; } } if (dn->casefold && s) { if (*dn->casefold) { t = talloc_asprintf(dn, "%s,%s", dn->casefold, s); } else { t = talloc_strdup(dn, s); } LDB_FREE(dn->casefold); dn->casefold = t; } } if (dn->linearized) { s = ldb_dn_get_linearized(base); if ( ! s) { return false; } if (*dn->linearized) { t = talloc_asprintf(dn, "%s,%s", dn->linearized, s); } else { t = talloc_strdup(dn, s); } if ( ! t) { dn->invalid = true; return false; } LDB_FREE(dn->linearized); dn->linearized = t; } return true;}/* modify the given dn by adding a base. * * return true if successful and false if not * if false is returned the dn may be marked invalid */bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...){ struct ldb_dn *base; char *base_str; va_list ap; bool ret; if ( !dn || dn->invalid) { return false; } va_start(ap, base_fmt); base_str = talloc_vasprintf(dn, base_fmt, ap); va_end(ap); if (base_str == NULL) { return false; } base = ldb_dn_new(base_str, dn->ldb, base_str); ret = ldb_dn_add_base(dn, base); talloc_free(base_str); return ret;} /* modify the given dn by adding children elements. * * return true if successful and false if not * if false is returned the dn may be marked invalid */bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child){ const char *s; char *t; if ( !child || child->invalid || !dn || dn->invalid) { return false; } if (dn->components) { int n, i, j; if ( ! ldb_dn_validate(child)) { return false; } s = NULL; if (dn->valid_case) { if ( ! (s = ldb_dn_get_casefold(child))) { return false; } } n = dn->comp_num + child->comp_num; dn->components = talloc_realloc(dn, dn->components, struct ldb_dn_component, n); if ( ! dn->components) { dn->invalid = true; return false; } for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) { dn->components[j] = dn->components[i]; } for (i = 0; i < child->comp_num; i++) { dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]); if (dn->components[i].value.data == NULL) { dn->invalid = true; return false; } } dn->comp_num = n; if (dn->casefold && s) { t = talloc_asprintf(dn, "%s,%s", s, dn->casefold); LDB_FREE(dn->casefold); dn->casefold = t; } } if (dn->linearized) { s = ldb_dn_get_linearized(child); if ( ! s) { return false; } t = talloc_asprintf(dn, "%s,%s", s, dn->linearized); if ( ! t) { dn->invalid = true; return false; } LDB_FREE(dn->linearized); dn->linearized = t; } return true;}/* modify the given dn by adding children elements. * * return true if successful and false if not * if false is returned the dn may be marked invalid */bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...){ struct ldb_dn *child; char *child_str; va_list ap; bool ret; if ( !dn || dn->invalid) { return false; } va_start(ap, child_fmt); child_str = talloc_vasprintf(dn, child_fmt, ap); va_end(ap); if (child_str == NULL) { return false; } child = ldb_dn_new(child_str, dn->ldb, child_str); ret = ldb_dn_add_child(dn, child); talloc_free(child_str); return ret;}bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num){ int i; if ( ! ldb_dn_validate(dn)) { return false; } if (dn->comp_num < 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; 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); LDB_FREE(dn->linearized); return true;}bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num){ int i, j; if ( ! ldb_dn_validate(dn)) { return false; } if (dn->comp_num < num) { return false; } 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; 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); LDB_FREE(dn->linearized); return true;}struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn){ struct ldb_dn *new_dn; new_dn = ldb_dn_copy(mem_ctx, dn); if ( !new_dn ) { return NULL; } if ( ! ldb_dn_remove_child_components(new_dn, 1)) { talloc_free(new_dn); return NULL; } return new_dn;}/* Create a 'canonical name' string from a DN: ie dc=samba,dc=org -> samba.org/ uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator There are two formats, the EX format has the last / replaced with a newline (\n).*/static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) { int i; TALLOC_CTX *tmpctx; char *cracked = NULL; const char *format = (ex_format ? "\n" : "/" ); 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(tmpctx, "%s.%s", ldb_dn_escape_value(tmpctx, dn->components[i].value), cracked); } else { cracked = ldb_dn_escape_value(tmpctx, dn->components[i].value); } if (!cracked) { goto done; } } /* Only domain components? Finish here */ if (i < 0) { cracked = talloc_strdup_append_buffer(cracked, format); talloc_steal(mem_ctx, cracked); goto done; } /* Now walk backwards appending remaining components */ for (; i > 0; i--) { cracked = talloc_asprintf_append_buffer(cracked, "/%s", ldb_dn_escape_value(tmpctx, dn->components[i].value)); if (!cracked) { goto done; } } /* Last one, possibly a newline for the 'ex' format */ cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format, ldb_dn_escape_value(tmpctx, dn->components[i].value)); talloc_steal(mem_ctx, cracked);done: talloc_free(tmpctx); return cracked;}/* 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); return LDB_SUCCESS;}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_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 (dn->linearized && (dn->linearized[0] == '\0')) return true; return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -