summaryrefslogtreecommitdiff
path: root/source4/lib/ldb/ldb_tdb/ldb_tdb.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-02-13 12:27:57 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:09:48 -0500
commit5a88d5211ba0f6b1d09cdd92489b34d0e603716b (patch)
treec344f9bb56c5e22e9f32ca0bc5f4f82a932cce05 /source4/lib/ldb/ldb_tdb/ldb_tdb.c
parente40da81aa4c279240c5ae3f1810fb9cedc15765d (diff)
downloadsamba-5a88d5211ba0f6b1d09cdd92489b34d0e603716b.tar.gz
samba-5a88d5211ba0f6b1d09cdd92489b34d0e603716b.tar.bz2
samba-5a88d5211ba0f6b1d09cdd92489b34d0e603716b.zip
r5374: - changed the dn key code in the ldb tdb backend to correctly honor
the case sensitive/insensitive flags on sections of a dn. So if a dn is made up of 4 attributes, and 2 of those are case insensitive and 2 are case sensitive, then all the attribute names are uppercases, but only the values of the case insensitive attributes are uppercased when forming the tdb key. - added code to canonicalise the dn, removing leading and trailing spaces from attribute names and values - when the @ATTRIBUTES record changes, fix the dn keys of any records that should now have new dn keys due to changes in the case sensitivity of the record I really did this to allow me to make the WINS database properly case insensitive, but it is also the correct general fix for ldb, as it matches the LDAP specification (and w2k LDAP server behaviour) (This used to be commit 0f034dc5636d182a1d9207ad662b3fc8df7ca3e4)
Diffstat (limited to 'source4/lib/ldb/ldb_tdb/ldb_tdb.c')
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c81
1 files changed, 79 insertions, 2 deletions
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index b1de96986d..07a9fa8866 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -42,6 +42,82 @@
#define LDBLOCK "INT_LDBLOCK"
+
+/*
+ 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
+*/
+static char *ltdb_dn_fold(struct ldb_module *module, const char *dn)
+{
+ const char *dn_orig = dn;
+ struct ldb_context *ldb = module->ldb;
+ TALLOC_CTX *tmp_ctx = talloc_new(ldb);
+ char *ret;
+ size_t len;
+
+ ret = talloc_strdup(tmp_ctx, "");
+ if (ret == NULL) goto failed;
+
+ while ((len = strcspn(dn, ",")) > 0) {
+ char *p = strchr(dn, '=');
+ char *attr, *value;
+ int flags;
+
+ if (p == NULL || (p-dn) > len) goto failed;
+
+ attr = talloc_strndup(tmp_ctx, dn, p-dn);
+ if (attr == NULL) goto failed;
+
+ /* trim spaces from the attribute name */
+ while (' ' == *attr) attr++;
+ while (' ' == attr[strlen(attr)-1]) {
+ attr[strlen(attr)-1] = 0;
+ }
+ if (*attr == 0) goto failed;
+
+ value = talloc_strndup(tmp_ctx, p+1, len-(p+1-dn));
+ if (value == NULL) goto failed;
+
+ /* trim spaces from the value */
+ while (' ' == *value) value++;
+ while (' ' == value[strlen(value)-1]) {
+ value[strlen(value)-1] = 0;
+ }
+ if (*value == 0) goto failed;
+
+ flags = ltdb_attribute_flags(module, attr);
+
+ attr = ldb_casefold(ldb, attr);
+ if (attr == NULL) goto failed;
+ talloc_steal(tmp_ctx, attr);
+
+ if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
+ value = ldb_casefold(ldb, value);
+ if (value == NULL) goto failed;
+ talloc_steal(tmp_ctx, value);
+ }
+
+ if (dn[len] == ',') {
+ ret = talloc_asprintf_append(ret, "%s=%s,", attr, value);
+ } else {
+ ret = talloc_asprintf_append(ret, "%s=%s", attr, value);
+ }
+ if (ret == NULL) goto failed;
+
+ dn += len;
+ if (*dn == ',') dn++;
+ }
+
+ talloc_steal(ldb, ret);
+ talloc_free(tmp_ctx);
+ return ret;
+
+failed:
+ talloc_free(tmp_ctx);
+ return ldb_casefold(ldb, dn_orig);
+}
+
/*
form a TDB_DATA for a record key
caller frees
@@ -65,7 +141,8 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn)
there are 3 cases dealt with in this code:
- 1) if the dn doesn't start with @INDEX: then uppercase whole dn
+ 1) if the dn doesn't start with @INDEX: then uppercase the attribute
+ names and the attributes values of case insensitive attributes
2) if the dn starts with @INDEX:attr and 'attr' is a case insensitive
attribute then uppercase whole dn
3) if the dn starts with @INDEX:attr and 'attr' is a case sensitive
@@ -95,7 +172,7 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn)
}
talloc_free(attr_name);
} else {
- dn_folded = ldb_casefold(ldb, dn);
+ dn_folded = ltdb_dn_fold(module, dn);
}
if (!dn_folded) {