summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/common
diff options
context:
space:
mode:
authorDerrell Lipman <derrell@samba.org>2005-06-09 02:47:26 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:17:51 -0500
commita6717fae681f89cf427e282d645029ca0b3e4d44 (patch)
treec5b5c53eaa75bc6dcb17a72aed261baaa9548a5a /source4/lib/ldb/common
parent322f0df3f124c95f2f50abbb2c07616a6cf721c0 (diff)
downloadsamba-a6717fae681f89cf427e282d645029ca0b3e4d44.tar.gz
samba-a6717fae681f89cf427e282d645029ca0b3e4d44.tar.bz2
samba-a6717fae681f89cf427e282d645029ca0b3e4d44.zip
r7418: work in progress
(This used to be commit 2a13e7655b1bce88694ddbb6a4d9349008ba42f0)
Diffstat (limited to 'source4/lib/ldb/common')
-rw-r--r--source4/lib/ldb/common/ldb_explode_dn.c218
-rw-r--r--source4/lib/ldb/common/ldb_utf8.c4
2 files changed, 151 insertions, 71 deletions
diff --git a/source4/lib/ldb/common/ldb_explode_dn.c b/source4/lib/ldb/common/ldb_explode_dn.c
index 4e71bc70d1..d3f278c776 100644
--- a/source4/lib/ldb/common/ldb_explode_dn.c
+++ b/source4/lib/ldb/common/ldb_explode_dn.c
@@ -30,82 +30,67 @@
} while(0)
+/*
+ * Forward declarations
+ */
static char
octet_from_hex(char * p,
- char * ret)
-{
- unsigned char low_char;
- unsigned char high_char;
-
- unsigned char low_binary;
- unsigned char high_binary;
-
- if (p[0] == '\0' || p[1] == '\0') {
- return -1;
- }
-
- high_char = p[0];
- low_char = p[1];
-
- if (high_char >= '0' && high_char <= '9') {
- high_binary = high_char - '0';
- } else if (high_char >= 'A' && high_char <= 'F') {
- high_binary = 10 + (high_char - 'A');
- } else if (high_char >= 'a' && high_char <= 'f') {
- high_binary = 10 + (high_char - 'a');
- } else {
- return -1;
- }
-
- if (low_char >= '0' && low_char <= '9') {
- low_binary = low_char - '0';
- } else if (low_char >= 'A' && low_char <= 'F') {
- low_binary = 10 + (low_char - 'A');
- } else if (low_char >= 'a' && low_char <= 'f') {
- low_binary = 10 + (low_char - 'a');
- } else {
- return -1;
- }
-
- *ret = (char) ((high_binary << 4) | low_binary);
- return 0;
-}
+ char * ret);
static char *
parse_slash(char *p,
- char *end)
-{
- switch (*(p + 1)) {
- case ',':
- case '=':
- case '\n':
- case '+':
- case '<':
- case '>':
- case '#':
- case ';':
- case '\\':
- case '"':
- memmove(p, p + 1, end - (p + 1));
- return (end - 1);
-
- default:
- if (*(p + 1) != '\0' && *(p + 2) != '\0') {
- if (octet_from_hex(p + 1, p) < 0) {
- return NULL;
- }
- memmove(p + 1, p + 3, end - (p + 3));
- return (end - 2);
- } else {
- return NULL;
- }
- }
-}
-
+ 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)
+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;
@@ -222,6 +207,14 @@ ldb_explode_dn(void *mem_ctx,
goto failed;
}
+ /* attribute names are always case-folded */
+ 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);
@@ -314,6 +307,19 @@ ldb_explode_dn(void *mem_ctx,
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);
@@ -460,3 +466,77 @@ failed:
ldb_debug(mem_ctx, LDB_DEBUG_TRACE, "Failed to parse %s\n", orig_dn);
return NULL;
}
+
+
+static char
+octet_from_hex(char * p,
+ char * ret)
+{
+ unsigned char low_char;
+ unsigned char high_char;
+
+ unsigned char low_binary;
+ unsigned char high_binary;
+
+ if (p[0] == '\0' || p[1] == '\0') {
+ return -1;
+ }
+
+ high_char = p[0];
+ low_char = p[1];
+
+ if (high_char >= '0' && high_char <= '9') {
+ high_binary = high_char - '0';
+ } else if (high_char >= 'A' && high_char <= 'F') {
+ high_binary = 10 + (high_char - 'A');
+ } else if (high_char >= 'a' && high_char <= 'f') {
+ high_binary = 10 + (high_char - 'a');
+ } else {
+ return -1;
+ }
+
+ if (low_char >= '0' && low_char <= '9') {
+ low_binary = low_char - '0';
+ } else if (low_char >= 'A' && low_char <= 'F') {
+ low_binary = 10 + (low_char - 'A');
+ } else if (low_char >= 'a' && low_char <= 'f') {
+ low_binary = 10 + (low_char - 'a');
+ } else {
+ return -1;
+ }
+
+ *ret = (char) ((high_binary << 4) | low_binary);
+ return 0;
+}
+
+static char *
+parse_slash(char *p,
+ char *end)
+{
+ switch (*(p + 1)) {
+ case ',':
+ case '=':
+ case '\n':
+ case '+':
+ case '<':
+ case '>':
+ case '#':
+ case ';':
+ case '\\':
+ case '"':
+ memmove(p, p + 1, end - (p + 1));
+ return (end - 1);
+
+ default:
+ if (*(p + 1) != '\0' && *(p + 2) != '\0') {
+ if (octet_from_hex(p + 1, p) < 0) {
+ return NULL;
+ }
+ memmove(p + 1, p + 3, end - (p + 3));
+ return (end - 2);
+ } else {
+ return NULL;
+ }
+ }
+}
+
diff --git a/source4/lib/ldb/common/ldb_utf8.c b/source4/lib/ldb/common/ldb_utf8.c
index 9cbb5646dd..dc25d6cf13 100644
--- a/source4/lib/ldb/common/ldb_utf8.c
+++ b/source4/lib/ldb/common/ldb_utf8.c
@@ -41,10 +41,10 @@
TODO:
a simple case folding function - will be replaced by a UTF8 aware function later
*/
-char *ldb_casefold(struct ldb_context *ldb, const char *s)
+char *ldb_casefold(void *mem_ctx, const char *s)
{
int i;
- char *ret = talloc_strdup(ldb, s);
+ char *ret = talloc_strdup(mem_ctx, s);
if (!s) {
errno = ENOMEM;
return NULL;