From e1e95277c0c7f86b15acd70ee3151ec2b3131c5e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 27 Jun 2005 00:00:50 +0000 Subject: r7937: main file was missing (This used to be commit 3898cdb0dc4722a7eb60a61b54ef778dab475aed) --- source4/lib/ldb/common/ldb_dn.c | 471 ++++++++++++++++++++++++++++ source4/lib/ldb/common/ldb_explode_dn.c | 512 ------------------------------- source4/lib/ldb/include/ldb_dn.h | 42 +++ source4/lib/ldb/include/ldb_explode_dn.h | 46 --- 4 files changed, 513 insertions(+), 558 deletions(-) create mode 100644 source4/lib/ldb/common/ldb_dn.c delete mode 100644 source4/lib/ldb/common/ldb_explode_dn.c create mode 100644 source4/lib/ldb/include/ldb_dn.h delete mode 100644 source4/lib/ldb/include/ldb_explode_dn.h (limited to 'source4') diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c new file mode 100644 index 0000000000..7ae314e46c --- /dev/null +++ b/source4/lib/ldb/common/ldb_dn.c @@ -0,0 +1,471 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb + * + * Component: ldb dn explode and utility functions + * + * Description: - explode a dn into it's own basic elements + * and put them in a structure + * - manipulate ldb_dn structures + * + * Author: Simo Sorce + */ + +#include "includes.h" +#include "ldb/include/ldb.h" +#include "ldb/include/ldb_private.h" +#include "ldb/include/ldb_dn.h" + + +#define LDB_DN_NULL_RETURN(x) do { if (!x) return NULL; } while(0) + +static char *escape_string(void *mem_ctx, const char *src) +{ + const char *p, *s; + char *d, *dst; + + LDB_DN_NULL_RETURN(src); + + /* allocate destination string, it will be at most 3 times the source */ + dst = d = talloc_array(mem_ctx, char, strlen(src) * 3 + 1); + LDB_DN_NULL_RETURN(dst); + + p = s = src; + + while (p) { + p += strcspn(p, ",=\n+<>#;\\\""); + if (*p == '\0') /* no special s found, all ok */ + break; + + if (*p) { /* copy part of the string and escape */ + memcpy(d, s, p - s); + d += (p - s); + *d++ = '\\'; + *d++ = *p++; + s = p; + } + } + + /* copy the last part (with zero) and return */ + memcpy(d, s, &src[strlen(src)] - s + 1); + + return dst; +} + +static char *unescape_string(void *mem_ctx, const char *src) +{ + unsigned x; + char *p, *dst, *end; + + LDB_DN_NULL_RETURN(src); + + dst = p = talloc_strdup(mem_ctx, src); + LDB_DN_NULL_RETURN(dst); + + end = &dst[strlen(dst)]; + + while (*p) { + p += strcspn(p, ",=\n+<>#;\\\""); + if (*p == '\0') /* no escapes or specials found, all ok */ + return dst; + + if (*p == '\\') { + if (strchr(",=\n+<>#;\\\"", p[1])) { + memmove(p, p + 1, end - (p + 1) + 1); + end--; + p++; + continue; + } + + if (sscanf(p + 1, "%02x", &x) == 1) { + *p = (unsigned char)x; + memmove(p + 1, p + 3, end - (p + 3) + 1); + end -= 2; + p++; + continue; + } + } + + /* a string with not escaped specials is invalid */ + + return NULL; + } + + return dst; +} + +static char *seek_to_separator(char *string, const char *separator) +{ + char *p; + + p = strchr(string, '='); + + LDB_DN_NULL_RETURN(p); + + p++; + + /* check if there are quotes surrounding the value */ + p += strspn(p, " \n"); /* skip white spaces after '=' */ + + if (*p == '\"') { + p++; + while (*p != '\"') { + p = strchr(p, '\"'); + LDB_DN_NULL_RETURN(p); + + if (*(p - 1) == '\\') + p++; + } + } + + p += strcspn(p, separator); + + return p; +} + +static char *ldb_dn_trim_string(char *string, const char *edge) +{ + char *s, *p; + + /* seek out edge from start of string */ + s = string + strspn(string, edge); + + /* backwards skip from end of string */ + p = &s[strlen(s) - 1]; + while (p > s && strchr(edge, *p)) { + *p = '\0'; + p--; + } + + return s; +} + +static struct ldb_dn_attribute *ldb_dn_explode_attribute(void *mem_ctx, char *raw_attribute) +{ + struct ldb_dn_attribute *at; + char *p; + + at = talloc(mem_ctx, struct ldb_dn_attribute); + LDB_DN_NULL_RETURN(at); + + p = strchr(raw_attribute, '='); + + LDB_DN_NULL_RETURN(p); + + *p = '\0'; + + at->name = talloc_strdup(at, ldb_dn_trim_string(raw_attribute, " \n")); + LDB_DN_NULL_RETURN(at->name); + + p++; + + p = ldb_dn_trim_string(p, " \n"); + + if (*p == '\"') { /* quotes at start means there must be quotes at the end */ + if (p[strlen(p) - 1] != '\"') /* malformed value */ + return NULL; + + p++; + p[strlen(p) - 1] = '\0'; + at->value = talloc_strdup(at, p); + + return at; + } + /* no quotes means we must unescape the string */ + at->value = unescape_string(at, p); + LDB_DN_NULL_RETURN(at->value); + + return at; +} + +static struct ldb_dn_component *explode_component(void *mem_ctx, char *raw_component) +{ + struct ldb_dn_component *dc; + char *p; + + dc = talloc(mem_ctx, struct ldb_dn_component); + LDB_DN_NULL_RETURN(dc); + + dc->attr_num = 0; + dc->attributes = NULL; + + p = raw_component; + + /* get the components */ + do { + char *t; + + /* terminate the current attribute and return pointer to the next one */ + t = seek_to_separator(p, "+"); + LDB_DN_NULL_RETURN(t); + + if (*t) { /* here there is a separator */ + *t = '\0'; /*terminate */ + t++; /* a separtor means there's another attribute that follows */ + } + + /* allocate attributes pointer */ + dc->attributes = talloc_realloc(dc, dc->attributes, + struct ldb_dn_attribute *, + dc->attr_num + 1); + LDB_DN_NULL_RETURN(dc->attributes); + + /* store the exploded attirbute in the main structure */ + dc->attributes[dc->attr_num] = ldb_dn_explode_attribute(dc->attributes, p); + LDB_DN_NULL_RETURN(dc->attributes[dc->attr_num]); + + dc->attr_num++; + + /* jump to the next attribute if any */ + p = t; + + } while(*p); + + return dc; +} + +/* FIXME: currently consider a dn composed of only case insensitive attributes + this is not correct and need to be fixed soon */ +static void ldb_dn_sort_attributes(struct ldb_dn *edn) +{ + struct ldb_dn_attribute *at0, *at1; + int i, j, k, l; + + for (i = 0; i < edn->comp_num; i++) { + if (edn->components[i]->attr_num > 1) { + + /* it is very unlikely that there is a multivalued RDN. In that + unlikely case it is very unlikely you will find more than 2 + values. So the use of bubble sort here seem to be acceptable */ + for (j = 0; (j + 1) < edn->components[i]->attr_num; j++) { + for (k = j; k >= 0; k--) { + at0 = edn->components[i]->attributes[k]; + at1 = edn->components[i]->attributes[k + 1]; + l = ldb_caseless_cmp(at0->name, at1->name); + if (l > 0) { + /* already sorted, so no bubbles to move exit inner loop */ + break; + } + if (l == 0) { + if (ldb_caseless_cmp(at0->value, at1->value) >= 0) { + /* already sorted, so no bubbles to move exit inner loop */ + break; + } + } + + edn->components[i]->attributes[k] = at1; + edn->components[i]->attributes[k + 1] = at0; + } + } + } + } +} + +struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn) +{ + struct ldb_dn *edn; /* the exploded dn */ + char *pdn, *p; + + /* Allocate a structure to hold the exploded DN */ + edn = talloc(mem_ctx, struct ldb_dn); + LDB_DN_NULL_RETURN(edn); + + /* Initially there are no components */ + edn->comp_num = 0; + edn->components = NULL; + + pdn = p = talloc_strdup(edn, dn); + if (!pdn) + goto error; + + /* get the components */ + do { + char *t; + + /* terminate the current component and return pointer to the next one */ + t = seek_to_separator(p, ",;"); + if (t == NULL) + goto error; + + if (*t) { /* here there is a separator */ + *t = '\0'; /*terminate */ + t++; /* a separtor means there's another component that follows */ + } + + /* allocate space to hold the dn component */ + edn->components = talloc_realloc(edn, edn->components, + struct ldb_dn_component *, + edn->comp_num + 1); + if (edn->components == NULL) + goto error; + + /* store the exploded component in the main structure */ + edn->components[edn->comp_num] = explode_component(edn->components, p); + if (edn->components[edn->comp_num] == NULL) + goto error; + + edn->comp_num++; + + /* jump to the next component if any */ + p = t; + + } while(*p); + + /* sort attributes if there's any multivalued component */ + ldb_dn_sort_attributes(edn); + + talloc_free(pdn); + return edn; + +error: + talloc_free(edn); + return NULL; +} + +char *ldb_dn_linearize(void *mem_ctx, struct ldb_dn *edn) +{ + char *dn, *format, *ename, *evalue; + int i, j; + + dn = talloc_strdup(mem_ctx, ""); + LDB_DN_NULL_RETURN(dn); + + for (i = 0; i < edn->comp_num; i++) { + if (i != 0) { + dn = talloc_append_string(mem_ctx, dn, ","); + } + for (j = 0; j < edn->components[i]->attr_num; j++) { + if (i != 0 && j == 0) + format = ",%s=%s"; + else if (i == 0 && j == 0) + format = "%s=%s"; + else + format = "+%s=%s"; + + ename = escape_string(mem_ctx, edn->components[i]->attributes[j]->name); + LDB_DN_NULL_RETURN(ename); + + evalue = escape_string(mem_ctx, edn->components[i]->attributes[j]->value); + LDB_DN_NULL_RETURN(evalue); + + dn = talloc_asprintf_append(dn, format, ename, evalue); + LDB_DN_NULL_RETURN(dn); + + talloc_free(ename); + talloc_free(evalue); + } + } + + return dn; +} + +/* FIXME: currently consider a dn composed of only case insensitive attributes + this is not correct and need to be fixed soon */ +int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1) +{ + struct ldb_dn_attribute *at0, *at1; + int i, j, k; + + /* if the number of components doesn't match they differ */ + if (edn0->comp_num != edn1->comp_num) + return (edn1->comp_num - edn0->comp_num); + + for (i = 0; i < edn0->comp_num; i++) { + + /* if the number of attributes per component doesn't match they differ */ + if (edn0->components[i]->attr_num != edn1->components[i]->attr_num) + return (edn1->components[i]->attr_num - edn0->components[i]->attr_num); + + for (j = 0; j < edn0->components[i]->attr_num; j++) { + at0 = edn0->components[i]->attributes[j]; + at1 = edn1->components[i]->attributes[j]; + + /* compare names */ + k = ldb_caseless_cmp(at0->name, at1->name); + if (k) + return k; + + /* names match, compare values */ + k = ldb_caseless_cmp(at0->value, at1->value); + if (k) + return k; + } + } +} + +/* + casefold a dn. We need to uppercase the attribute names, and the + attribute values of case insensitive attributes. We also need to remove + extraneous spaces between elements +*/ +struct ldb_dn *ldb_dn_casefold(void *mem_ctx, struct ldb_dn *edn, void *user_data, + int (* case_fold_attr_fn)(void * user_data, char * attr)) +{ + struct ldb_dn *cedn; + int i, j; + + cedn = talloc(mem_ctx, struct ldb_dn); + LDB_DN_NULL_RETURN(cedn); + + cedn->comp_num = edn->comp_num; + cedn->components = talloc_array(cedn, struct ldb_dn_component *, edn->comp_num); + LDB_DN_NULL_RETURN(cedn->components); + + for (i = 0; i < edn->comp_num; i++) { + struct ldb_dn_component *dc; + + dc = talloc(cedn->components, struct ldb_dn_component); + LDB_DN_NULL_RETURN(dc); + + dc->attr_num = edn->components[i]->attr_num; + dc->attributes = edn->components[i]->attributes; + LDB_DN_NULL_RETURN(dc->attributes); + + for (j = 0; j < edn->components[i]->attr_num; j++) { + struct ldb_dn_attribute *at; + + at = talloc(dc->attributes, struct ldb_dn_attribute); + LDB_DN_NULL_RETURN(at); + + at->name = ldb_casefold(at, edn->components[i]->attributes[j]->name); + LDB_DN_NULL_RETURN(at->name); + + if (case_fold_attr_fn(user_data, at->name)) { + at->value = ldb_casefold(at, edn->components[i]->attributes[j]->value); + } else { + at->value = talloc_strdup(at, edn->components[i]->attributes[j]->value); + } + LDB_DN_NULL_RETURN(at->value); + + dc->attributes[j] = at; + } + + cedn->components[i] = dc; + } + + return cedn; +} + diff --git a/source4/lib/ldb/common/ldb_explode_dn.c b/source4/lib/ldb/common/ldb_explode_dn.c deleted file mode 100644 index 0e2efa876c..0000000000 --- a/source4/lib/ldb/common/ldb_explode_dn.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2004 - Copyright (C) Derrell Lipman 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * Name: ldb - * - * Component: ldb dn parsing - * - * Description: explode a dn into it's own basic elements - * and put them in a structure - * - * Author: Simo Sorce - * Author: Derrell Lipman - */ - -#include "includes.h" -#include "ldb/include/ldb.h" -#include "ldb/include/ldb_private.h" -#include "ldb/include/ldb_explode_dn.h" - -#define LDB_PARSE_DN_INVALID(x) do { \ - if (x) { \ - goto failed; \ - } \ -} while(0) - - -/* - * Forward declarations - */ - -static char * -parse_slash(char *p, - char *end); - - - -/* - * Public functions - */ - -/* - * ldb_explode_dn() - * - * Explode, normalize, and optionally case-fold a DN string. The result is a - * structure containing arrays of the constituent RDNs. - * - * Parameters: - * mem_ctx - - * talloc context on which all allocated memory is hung - * - * orig_dn - - * The distinguished name, in string format, to be exploded - * - * hUserData - - * Data handle provided by the caller, and passed back to the caller in - * the case_fold_attr_fn callback function. This handle is not otherwise - * used within this function. - * - * case_fold_attr_fn - - * Pointer to a callback function which will be called to determine if a - * particular attribute type (name) requires case-folding of its values. - * If this function pointer is non-null, then attribute names will always - * be case-folded. Additionally, the function pointed to by - * case_fold_attr_fn will be called with the data handle (hUserData) and - * an attribute name as its parameters, and should return TRUE or FALSE to - * indicate whether values of that attribute type should be case-folded. - * - * If case_fold_attr_fn is null, then neither attribute names nor - * attribute values will be case-folded. - * - * Returns: - * Upon success, an ldb_dn structure pointer is returned, containing the - * exploded DN. - * - * If memory could not be allocated or if the DN was improperly formatted, - * NULL is returned. - */ -struct ldb_dn * -ldb_explode_dn(void * mem_ctx, - const char * orig_dn, - void * hUserData, - int (*case_fold_attr_fn)(void * hUserData, - char * attr)) -{ - struct ldb_dn * dn; - struct ldb_dn_component * component; - struct ldb_dn_attribute * attribute; - char * p; - char * start; - char * separator; - char * src; - char * dest; - char * dn_copy; - char * dn_end; - int i; - int size; - int orig_len; - - /* Allocate a structure to hold the exploded DN */ - if ((dn = talloc(mem_ctx, struct ldb_dn)) == NULL) { - return NULL; - } - - /* Initially there are no components */ - dn->comp_num = 0; - - /* Allocate the component array, with space for one component */ - if ((dn->components = - talloc_array(dn, struct ldb_dn_component *, 1)) == NULL) { - - goto failed; - } - - /* Allocate the first component */ - if ((component = talloc(dn, struct ldb_dn_component)) == NULL) { - goto failed; - } - - /* This component has no attributes yet */ - component->attr_num = 0; - - /* Get the length of the provided DN */ - if ((orig_len = strlen(orig_dn)) == 0) { - - /* We found a zero-length DN. Return it. */ - if ((dn->dn = talloc_strdup(dn, orig_dn)) == NULL) { - goto failed; - } - return dn; - } - - /* Copy the provided DN so we can manipulate it */ - if ((dn_copy = talloc_strdup(mem_ctx, orig_dn)) == NULL) { - goto failed; - } - - p = dn_copy; - - /* Our copy may end shorter than the original as we unescape chars */ - dn_end = dn_copy + orig_len + 1; - - /* For each attribute/value pair... */ - do { - /* Allocate an array to hold the attributes, initially len 1 */ - if ((component->attributes = - talloc_array(component, - struct ldb_dn_attribute *, 1)) == NULL) { - goto failed; - } - - /* Allocate this attribute */ - if ((attribute = - talloc(component, struct ldb_dn_attribute)) == NULL) { - goto failed; - } - - /* skip white space */ - while (*p == ' ' || *p == '\n') { - p++; - } - - /* start parsing this component */ - do { - /* Save pointer to beginning of attribute name */ - start = p; - - /* find our attribute/value separator '=' */ - while (*p != '\0' && *p != '=') { - if (*p == '\\') { - if ((dn_end = - parse_slash(p, dn_end)) == NULL) { - goto failed; - } - } - p++; - } - - /* Ensure we found the attribute/value separator */ - if (*p != '=') { - goto failed; - } - - /* Save pointer to separator */ - separator = p; - - /* remove trailing white space from attribute name */ - while (p > start && - (*(p - 1) == ' ' || *(p - 1) == '\n')) { - - p--; - } - LDB_PARSE_DN_INVALID((p - start) < 1); - - /* save attribute name */ - if ((attribute->name = - talloc_strndup(attribute, - start, - p - start)) == NULL) { - goto failed; - } - - /* see if this attribute name needs case folding */ - if (case_fold_attr_fn != NULL && - (* case_fold_attr_fn)(hUserData, - attribute->name)) { - p = attribute->name; - if ((attribute->name = - ldb_casefold(attribute, p)) == NULL) { - goto failed; - } - talloc_free(p); - } - - ldb_debug(mem_ctx, - LDB_DEBUG_TRACE, - "attribute name: [%s]\n", attribute->name); - - /* skip white space after the separator */ - p = separator + 1; - p += strspn(p, " \n"); - - /* ensure there's a value here */ - if (*p == '\0') { - goto failed; - } - - /* check if the value is enclosed in QUOTATION */ - if (*p == '"') { - /* save pointer to beginning of attr value */ - start = p + 1; - - /* find the trailing QUOTE */ - while (*p != '\0' && *p != '"') { - if (*p == '\\') { - if ((dn_end = - parse_slash(p, dn_end)) == NULL) { - goto failed; - } - } - - p++; - } - - /* skip spaces until the separator */ - if (*p == '\0') { - /* We're already at end of string */ - separator = p; - } else { - /* Skip spaces */ - separator = p + 1 + strspn(p+1, " \n"); - } - - /* must be end of string or a separator here */ - if (*separator != '\0' && - *separator != ',' && - *separator != ';' && - *separator != '+') { - /* Error Malformed DN */ - goto failed; - } - } else { - /* - * Value is not quouted. - */ - - /* save pointer to beginning of value */ - start = p; - - /* find end of value */ - while (*p != '\0' && - *p != ',' && - *p != ';' && - *p != '+') { - - if (*p == '\\') { - if ((dn_end = - parse_slash(p, dn_end)) == NULL) { - goto failed; - } - } - - p++; - } - - /* save pointer to the terminating separator */ - separator = p; - - /* remove trailing whitespace */ - while (p > start && - (*(p - 1) == ' ' || - *(p - 1) == '\n')) { - - p--; - } - } - LDB_PARSE_DN_INVALID((p - start) < 1); - - /* save the value */ - if ((attribute->value = - talloc_strndup(attribute, - start, - p - start)) == NULL) { - goto failed; - } - - /* see if this attribute value needs case folding */ - if (case_fold_attr_fn != NULL && - (* case_fold_attr_fn)(hUserData, - attribute->name)) { - /* yup, case-fold it. */ - p = attribute->value; - if ((attribute->value = - ldb_casefold(attribute, p)) == NULL) { - goto failed; - } - talloc_free(p); - } - - ldb_debug(mem_ctx, - LDB_DEBUG_TRACE, - "attribute value: [%s]\n", attribute->value); - - /* save the entire RDN */ - if ((attribute->rdn = - talloc_asprintf(attribute, - "%s=%s", - attribute->name, - attribute->value)) == NULL) { - goto failed; - } - - ldb_debug(mem_ctx, - LDB_DEBUG_TRACE, - "attribute: [%s]\n", attribute->rdn); - - /* add this attribute to the attribute list */ - component->attributes[component->attr_num] = attribute; - component->attr_num++; - - /* is this a multi-valued attribute? */ - if (*separator == '+') { - /* Yup. prepare for the next value. */ - if ((component->attributes = - talloc_realloc(component, - component->attributes, - struct ldb_dn_attribute *, - component->attr_num + 1)) == NULL) { - goto failed; - } - - /* allocate new attribute structure */ - if ((attribute = - talloc(component, - struct ldb_dn_attribute)) == NULL) { - goto failed; - } - } - - /* if we're not at end of string, skip white space */ - if (*separator != '\0') { - /* skip spaces past the separator */ - p = separator + 1; - p += strspn(p, " \n"); - } - - } while (*separator == '+'); - - /* find total length of all attributes */ - for (i = 0, size = 0; i < component->attr_num; i++) { - size += strlen(component->attributes[i]->rdn) + 1; - } - - /* - * rebuild the normalized component - */ - - /* allocate space for the normalized component */ - if ((dest = talloc_size(component, size)) == NULL) { - - goto failed; - } - - /* Save the pointer to the beginning of the string */ - component->component = dest; - - /* copy each of the attributes to the normalized component */ - for (i = 0; i < component->attr_num; i++) { - if (i != 0) { - *dest++ = '+'; - } - src = component->attributes[i]->rdn; - - /* we are guaranteed to have enough space in dest */ - size = strlen(src); - strncpy(dest, src, size + 1); - dest += size; - } - - ldb_debug(mem_ctx, - LDB_DEBUG_TRACE, - "component: [%s]\n", component->component); - - /* insert the component into the component list */ - dn->components[dn->comp_num] = component; - dn->comp_num++; - - /* if there are additional components... */ - if (*separator == ',' || *separator == ';') { - /* ... then prepare to parse them */ - if ((dn->components = - talloc_realloc(dn, - dn->components, - struct ldb_dn_component *, - dn->comp_num + 1)) == NULL || - (component = - talloc(dn, struct ldb_dn_component)) == NULL) { - - goto failed; - } - - component->attr_num = 0; - } - - /* update pointer to after the separator */ - p = separator + 1; - - } while(*separator == ',' || *separator == ';'); - - /* find total length of all components */ - for (i = 0, size = 0; i < dn->comp_num; i++) { - size = size + strlen(dn->components[i]->component) + 1; - } - - /* rebuild the normalized DN */ - if ((dest = talloc_size(dn, size)) == NULL) { - goto failed; - } - - /* Save the pointer to the beginning of the */ - dn->dn = dest; - - /* copy the normalized components into the DN */ - for (i = 0; i < dn->comp_num; i++) { - - /* add a separator between DN components */ - if (i != 0) { - *dest++ = ','; - } - - /* point to this component of the DN */ - src = dn->components[i]->component; - - /* we are guaranteed to have enough space in dest */ - size = strlen(src); - strncpy(dest, src, size + 1); - dest += size; - } - - ldb_debug(mem_ctx, LDB_DEBUG_TRACE, "dn: [%s]\n", dn->dn); - - /* we don't need the copy of the DN any more */ - talloc_free(dn_copy); - - /* give 'em what they came for! */ - return dn; - -failed: - /* something went wrong. free memory and tell 'em it failed */ - talloc_free(dn); - ldb_debug(mem_ctx, LDB_DEBUG_TRACE, "Failed to parse %s\n", orig_dn); - return NULL; -} - - -static char *parse_slash(char *p, char *end) -{ - unsigned x; - if (strchr(",=\n+<>#;\\\"", p[1])) { - memmove(p, p + 1, end - (p + 1)); - return (end - 1); - } - if (sscanf(p + 1, "%02x", &x) == 1) { - *p = (unsigned char)x; - memmove(p + 1, p + 3, end - (p + 3)); - return (end - 2); - } - return NULL; -} - diff --git a/source4/lib/ldb/include/ldb_dn.h b/source4/lib/ldb/include/ldb_dn.h new file mode 100644 index 0000000000..f355ee4879 --- /dev/null +++ b/source4/lib/ldb/include/ldb_dn.h @@ -0,0 +1,42 @@ +/* + Unix SMB/CIFS implementation. + LDAP server + Copyright (C) Simo Sorce 2004 + Copyright (C) Derrell Lipman 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +struct ldb_dn_attribute { + char *name; + char *value; +}; + +struct ldb_dn_component { + int attr_num; + struct ldb_dn_attribute **attributes; +}; + +struct ldb_dn { + int comp_num; + struct ldb_dn_component **components; +}; + + +struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn); +char *ldb_dn_linearize(void *mem_ctx, struct ldb_dn *edn); +int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1); +struct ldb_dn *ldb_dn_casefold(void *mem_ctx, struct ldb_dn *edn, void *user_data, + int (* case_fold_attr_fn)(void * user_data, char * attr)); diff --git a/source4/lib/ldb/include/ldb_explode_dn.h b/source4/lib/ldb/include/ldb_explode_dn.h deleted file mode 100644 index af9829ba40..0000000000 --- a/source4/lib/ldb/include/ldb_explode_dn.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Unix SMB/CIFS implementation. - LDAP server - Copyright (C) Simo Sorce 2004 - Copyright (C) Derrell Lipman 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -struct ldb_dn_attribute { - char * rdn; - char * name; - char * value; -}; - -struct ldb_dn_component { - char * component; - int attr_num; - struct ldb_dn_attribute ** attributes; -}; - -struct ldb_dn { - char * dn; - int comp_num; - struct ldb_dn_component ** components; -}; - - -extern struct ldb_dn * -ldb_explode_dn(void * mem_ctx, - const char * orig_dn, - void * hUserData, - int (*case_fold_attr_fn)(void * hUserData, - char * attr)); -- cgit