summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/ldb/common/ldb_explode_dn.c218
-rw-r--r--source4/lib/ldb/common/ldb_utf8.c4
-rw-r--r--source4/lib/ldb/include/ldb.h2
-rw-r--r--source4/lib/ldb/include/ldb_explode_dn.h7
-rw-r--r--source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c58
5 files changed, 187 insertions, 102 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;
diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h
index 8ccf8967cb..91a826447a 100644
--- a/source4/lib/ldb/include/ldb.h
+++ b/source4/lib/ldb/include/ldb.h
@@ -203,7 +203,7 @@ const char *ldb_errstring(struct ldb_context *ldb);
/*
casefold a string (should be UTF8, but at the moment it isn't)
*/
-char *ldb_casefold(struct ldb_context *ldb, const char *s);
+char *ldb_casefold(void *mem_ctx, const char *s);
/*
ldif manipulation functions
diff --git a/source4/lib/ldb/include/ldb_explode_dn.h b/source4/lib/ldb/include/ldb_explode_dn.h
index 78768ebb80..af9829ba40 100644
--- a/source4/lib/ldb/include/ldb_explode_dn.h
+++ b/source4/lib/ldb/include/ldb_explode_dn.h
@@ -39,5 +39,8 @@ struct ldb_dn {
extern 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));
diff --git a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
index 147ee599a9..4f774efbae 100644
--- a/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
+++ b/source4/lib/ldb/ldb_sqlite3/ldb_sqlite3.c
@@ -37,6 +37,7 @@
#include "ldb/include/ldb.h"
#include "ldb/include/ldb_private.h"
#include "ldb/include/ldb_parse.h"
+#include "ldb/include/ldb_explode_dn.h"
#include "ldb/ldb_sqlite3/ldb_sqlite3.h"
#ifndef FALSE
@@ -172,9 +173,11 @@ lsqlite3_option_find(const struct lsqlite3_private *lsqlite3,
callback function used in call to ldb_dn_fold() for determining whether an
attribute type requires case folding.
*/
-static int lsqlite3_case_fold_attr_required(struct ldb_module *module,
- char *attr)
+static int lsqlite3_case_fold_attr_required(void * hUserData,
+ char *attr)
{
+// struct ldb_module * module = hUserData;
+
#warning "currently, all attributes require case folding"
return TRUE;
}
@@ -184,9 +187,9 @@ static int lsqlite3_case_fold_attr_required(struct ldb_module *module,
* rename a record
*/
static int
-lsqlite3_rename(struct ldb_module *module,
- const char *olddn,
- const char *newdn)
+lsqlite3_rename(struct ldb_module * module,
+ const char * olddn,
+ const char * newdn)
{
/* ignore ltdb specials */
if (olddn[0] == '@' ||newdn[0] == '@') {
@@ -478,7 +481,7 @@ lsqlite3_search(struct ldb_module * module,
{
int ret;
int bLoop;
- long long eid;
+ long long eid = 0;
char * sql;
char * sql_constraints;
char * table_list;
@@ -509,7 +512,7 @@ lsqlite3_search(struct ldb_module * module,
pTail,
-1,
&pStmt,
- &pTail)) != SQLITE_OK) {
+ NULL)) != SQLITE_OK) {
ret = -1;
break;
}
@@ -541,17 +544,24 @@ lsqlite3_search(struct ldb_module * module,
* Normal condition is only one time through loop. Loop is
* rerun in error conditions, via "continue", above.
*/
+ sqlite3_free(discard_const_p(char, pTail));
ret = 0;
bLoop = FALSE;
}
+ if (ret != 0) {
+ sqlite3_free(discard_const_p(char, pTail));
+ return -1;
+ }
+
/* Parse the filter expression into a tree we can work with */
if ((pTree = ldb_parse_tree(module->ldb, pExpression)) == NULL) {
+ sqlite3_free(discard_const_p(char, pTail));
return -1;
}
/* Allocate a temporary talloc context */
- hTalloc = talloc_new(module);
+ hTalloc = talloc_new(module->ldb);
/* Move the parse tree to our temporary context */
talloc_steal(hTalloc, pTree);
@@ -756,28 +766,20 @@ lsqlite3_new_dn(struct ldb_module * module,
char * pDN,
long long * pEID)
{
- char * pName;
- char * pValue;
-
- /* Normalize the distinguished name */
- pDN = ldb_dn_fold(module, pDN, lsqlite3_case_fold_attr_required);
-
- /* Parse the DN into its constituent components */
-#warning "this simple parse of DN ignores escaped '=' and ','. fix it."
- while (pDN != NULL) {
- pName = strsep(&pValue, "=");
-
- if (pDN == NULL) {
- /* Attribute name without value? Should not occur. */
- return -1;
- }
-
- pValue = pName;
- strsep(&pValue, "=");
-
-#warning "*** lsqlite3_new_dn() not yet fully implemented ***"
+ struct ldb_dn * pExplodedDN;
+ struct ldb_context * ldb = module->ldb;
+// struct lsqlite3_private * lsqlite3 = module->private_data;
+
+ /* Explode and normalize the DN */
+ if ((pExplodedDN =
+ ldb_explode_dn(ldb,
+ pDN,
+ ldb,
+ lsqlite3_case_fold_attr_required)) == NULL) {
+ return -1;
}
+#warning "*** lsqlite3_new_dn() not yet fully implemented ***"
return -1;
}