summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/common
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-05-01 09:45:56 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:51:38 -0500
commit0dad5a34273bf5cadcfd4a36d69bdffbf69eb073 (patch)
tree78ddbe4e053287a0e7a0300e945627ce4b24bc29 /source4/lib/ldb/common
parenta2b6d47390a07f0d2a737d17144f825a9733d5bf (diff)
downloadsamba-0dad5a34273bf5cadcfd4a36d69bdffbf69eb073.tar.gz
samba-0dad5a34273bf5cadcfd4a36d69bdffbf69eb073.tar.bz2
samba-0dad5a34273bf5cadcfd4a36d69bdffbf69eb073.zip
r435: a major upgrade for ldb
- added the ability to mark record attributes as being CASE_INSENSITIVE, WILDCARD or INTEGER. - added the ability to support objectclass subclasses, and to search by a parent class - added internal support for case insensitive versus case sensitive indexing (not UTF8 compliant yet) - cleaned up a number of const warnings - added a number of helper functions for fetching integers, strings and doubles - added a in-memory cache for important database properties, supported by a database sequence number - changed some variable names to avoid conflicts with C++ (This used to be commit f2bf06f25c2e6c744817711c7bedbd1d3b52f994)
Diffstat (limited to 'source4/lib/ldb/common')
-rw-r--r--source4/lib/ldb/common/ldb_ldif.c30
-rw-r--r--source4/lib/ldb/common/ldb_msg.c71
-rw-r--r--source4/lib/ldb/common/ldb_utf8.c87
3 files changed, 174 insertions, 14 deletions
diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c
index fcf0150557..1ca585ca80 100644
--- a/source4/lib/ldb/common/ldb_ldif.c
+++ b/source4/lib/ldb/common/ldb_ldif.c
@@ -407,6 +407,7 @@ void ldif_read_free(struct ldb_ldif *ldif)
struct ldb_message *msg = &ldif->msg;
int i;
for (i=0;i<msg->num_elements;i++) {
+ if (msg->elements[i].name) free(msg->elements[i].name);
if (msg->elements[i].values) free(msg->elements[i].values);
}
if (msg->elements) free(msg->elements);
@@ -431,11 +432,16 @@ static int msg_add_empty(struct ldb_message *msg, const char *name, unsigned fla
el = &msg->elements[msg->num_elements];
- el->name = name;
+ el->name = strdup(name);
el->num_values = 0;
el->values = NULL;
el->flags = flags;
+ if (!el->name) {
+ errno = ENOMEM;
+ return -1;
+ }
+
msg->num_elements++;
return 0;
@@ -478,7 +484,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
}
/* first line must be a dn */
- if (strcmp(attr, "dn") != 0) {
+ if (ldb_attr_cmp(attr, "dn") != 0) {
fprintf(stderr, "First line must be a dn not '%s'\n", attr);
goto failed;
}
@@ -489,10 +495,10 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
struct ldb_message_element *el;
int empty = 0;
- if (strcmp(attr, "changetype") == 0) {
+ if (ldb_attr_cmp(attr, "changetype") == 0) {
int i;
for (i=0;ldb_changetypes[i].name;i++) {
- if (strcmp((char *)value.data, ldb_changetypes[i].name) == 0) {
+ if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) {
ldif->changetype = ldb_changetypes[i].changetype;
break;
}
@@ -505,19 +511,19 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
continue;
}
- if (strcmp(attr, "add") == 0) {
+ if (ldb_attr_cmp(attr, "add") == 0) {
flags = LDB_FLAG_MOD_ADD;
empty = 1;
}
- if (strcmp(attr, "delete") == 0) {
+ if (ldb_attr_cmp(attr, "delete") == 0) {
flags = LDB_FLAG_MOD_DELETE;
empty = 1;
}
- if (strcmp(attr, "replace") == 0) {
+ if (ldb_attr_cmp(attr, "replace") == 0) {
flags = LDB_FLAG_MOD_REPLACE;
empty = 1;
}
- if (strcmp(attr, "-") == 0) {
+ if (ldb_attr_cmp(attr, "-") == 0) {
flags = 0;
continue;
}
@@ -531,7 +537,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
el = &msg->elements[msg->num_elements-1];
- if (msg->num_elements > 0 && strcmp(attr, el->name) == 0 &&
+ if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 &&
flags == el->flags) {
/* its a continuation */
el->values =
@@ -549,11 +555,11 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
if (!msg->elements) {
goto failed;
}
- msg->elements[msg->num_elements].flags = flags;
- msg->elements[msg->num_elements].name = attr;
el = &msg->elements[msg->num_elements];
+ el->flags = flags;
+ el->name = strdup(attr);
el->values = malloc_p(struct ldb_val);
- if (!el->values) {
+ if (!el->values || !el->name) {
goto failed;
}
el->num_values = 1;
diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c
index 633cc91f2c..8eb8a8c5ef 100644
--- a/source4/lib/ldb/common/ldb_msg.c
+++ b/source4/lib/ldb/common/ldb_msg.c
@@ -43,23 +43,40 @@ struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg,
{
int i;
for (i=0;i<msg->num_elements;i++) {
- if (strcmp(msg->elements[i].name, attr_name) == 0) {
+ if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
return &msg->elements[i];
}
}
return NULL;
}
+/*
+ see if two ldb_val structures contain exactly the same data
+ return 1 for a match, 0 for a mis-match
+*/
+int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2)
+{
+ if (v1->length != v2->length) return 0;
+
+ if (v1->length == 0) return 1;
+
+ if (memcmp(v1->data, v2->data, v1->length) == 0) {
+ return 1;
+ }
+
+ return 0;
+}
/*
find a value in an element
+ assumes case sensitive comparison
*/
struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el,
struct ldb_val *val)
{
int i;
for (i=0;i<el->num_values;i++) {
- if (ldb_val_equal(val, &el->values[i])) {
+ if (ldb_val_equal_exact(val, &el->values[i])) {
return &el->values[i];
}
}
@@ -113,6 +130,7 @@ int ldb_msg_add(struct ldb_message *msg,
/*
compare two ldb_message_element structures
+ assumes case senistive comparison
*/
int ldb_msg_element_compare(struct ldb_message_element *el1,
struct ldb_message_element *el2)
@@ -131,3 +149,52 @@ int ldb_msg_element_compare(struct ldb_message_element *el1,
return 0;
}
+
+
+/*
+ convenience functions to return common types from a message
+ these return the first value if the attribute is multi-valued
+*/
+int ldb_msg_find_int(const struct ldb_message *msg,
+ const char *attr_name,
+ int default_value)
+{
+ struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name);
+ if (!el || el->num_values == 0) {
+ return default_value;
+ }
+ return strtol(el->values[0].data, NULL, 0);
+}
+
+unsigned int ldb_msg_find_uint(const struct ldb_message *msg,
+ const char *attr_name,
+ int default_value)
+{
+ struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name);
+ if (!el || el->num_values == 0) {
+ return default_value;
+ }
+ return strtoul(el->values[0].data, NULL, 0);
+}
+
+double ldb_msg_find_double(const struct ldb_message *msg,
+ const char *attr_name,
+ double default_value)
+{
+ struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name);
+ if (!el || el->num_values == 0) {
+ return default_value;
+ }
+ return strtod(el->values[0].data, NULL);
+}
+
+const char *ldb_msg_find_string(const struct ldb_message *msg,
+ const char *attr_name,
+ const char *default_value)
+{
+ struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name);
+ if (!el || el->num_values == 0) {
+ return default_value;
+ }
+ return el->values[0].data;
+}
diff --git a/source4/lib/ldb/common/ldb_utf8.c b/source4/lib/ldb/common/ldb_utf8.c
new file mode 100644
index 0000000000..7767b0955e
--- /dev/null
+++ b/source4/lib/ldb/common/ldb_utf8.c
@@ -0,0 +1,87 @@
+/*
+ ldb database library
+
+ Copyright (C) Andrew Tridgell 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 utf8 handling
+ *
+ * Description: case folding and case comparison for UTF8 strings
+ *
+ * Author: Andrew Tridgell
+ */
+
+#include "includes.h"
+
+/*
+ TODO:
+ a simple case folding function - will be replaced by a UTF8 aware function later
+*/
+char *ldb_casefold(const char *s)
+{
+ int i;
+ char *ret = strdup(s);
+ if (!s) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ for (i=0;ret[i];i++) {
+ ret[i] = toupper(ret[i]);
+ }
+ return ret;
+}
+
+/*
+ a caseless compare, optimised for 7 bit
+ TODO: doesn't yet handle UTF8
+*/
+static int ldb_caseless_cmp(const char *s1, const char *s2)
+{
+ int i;
+ for (i=0;s1[i] != 0;i++) {
+ int c1 = toupper(s1[i]), c2 = toupper(s2[i]);
+ if (c1 != c2) {
+ return c1 - c2;
+ }
+ }
+ return s2[i];
+}
+
+/*
+ compare two basedn fields
+ return 0 for match
+*/
+int ldb_dn_cmp(const char *dn1, const char *dn2)
+{
+ return ldb_caseless_cmp(dn1, dn2);
+}
+
+/*
+ compare two attributes
+ return 0 for match
+*/
+int ldb_attr_cmp(const char *dn1, const char *dn2)
+{
+ return ldb_caseless_cmp(dn1, dn2);
+}