summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-06-06 22:04:55 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:08:55 -0500
commitefddd37af84b9db429237a491cb74a2c12c505cb (patch)
tree84a29b84eaa6788ec96cccb0882ea9b747163503
parent4f422081a79704827b13571540143b8b57e6b74c (diff)
downloadsamba-efddd37af84b9db429237a491cb74a2c12c505cb.tar.gz
samba-efddd37af84b9db429237a491cb74a2c12c505cb.tar.bz2
samba-efddd37af84b9db429237a491cb74a2c12c505cb.zip
r16066: The OSX AD plugin uses objectCategory searches a lot, and uses them
both fully qualified and in the 'short' form. Now we test and support this query format. Andrew Bartlett (This used to be commit 9ddcfacbcedc5eea2730d4bf902c0fcd02bcfa11)
-rw-r--r--source4/lib/ldb/common/ldb_attributes.c1
-rw-r--r--source4/lib/ldb/common/ldb_match.c7
-rw-r--r--source4/lib/ldb/samba/ldif_handlers.c81
-rwxr-xr-xtestprogs/ejs/ldap.js22
4 files changed, 104 insertions, 7 deletions
diff --git a/source4/lib/ldb/common/ldb_attributes.c b/source4/lib/ldb/common/ldb_attributes.c
index 679a05f244..13e721a266 100644
--- a/source4/lib/ldb/common/ldb_attributes.c
+++ b/source4/lib/ldb/common/ldb_attributes.c
@@ -166,7 +166,6 @@ int ldb_setup_wellknown_attributes(struct ldb_context *ldb)
{ "dn", LDB_SYNTAX_DN },
{ "ncName", LDB_SYNTAX_DN },
{ "distinguishedName", LDB_SYNTAX_DN },
- { "objectCategory", LDB_SYNTAX_DN },
{ "cn", LDB_SYNTAX_DIRECTORY_STRING },
{ "dc", LDB_SYNTAX_DIRECTORY_STRING },
{ "ou", LDB_SYNTAX_DIRECTORY_STRING },
diff --git a/source4/lib/ldb/common/ldb_match.c b/source4/lib/ldb/common/ldb_match.c
index 810191c5ec..f3ecbe0381 100644
--- a/source4/lib/ldb/common/ldb_match.c
+++ b/source4/lib/ldb/common/ldb_match.c
@@ -207,8 +207,11 @@ static int ldb_wildcard_compare(struct ldb_context *ldb,
chunk = tree->u.substring.chunks[c];
if(h->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto failed;
- /* FIXME: case of embedded nulls */
- if (strncmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto failed;
+ /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */
+ if (cnk.length > val.length) {
+ goto failed;
+ }
+ if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto failed;
val.length -= cnk.length;
val.data += cnk.length;
c++;
diff --git a/source4/lib/ldb/samba/ldif_handlers.c b/source4/lib/ldb/samba/ldif_handlers.c
index e84dfea600..28bc5ea997 100644
--- a/source4/lib/ldb/samba/ldif_handlers.c
+++ b/source4/lib/ldb/samba/ldif_handlers.c
@@ -1,8 +1,8 @@
/*
ldb database library - ldif handlers for Samba
- Copyright (C) Andrew Tridgell 2005
-
+ Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Andrew Bartlett 2006
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
** under the LGPL
@@ -275,6 +275,75 @@ static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ct
return 0;
}
+/*
+ canonicolise an objectCategory. We use the short form as the cannoical form:
+ cn=Person,cn=Schema,cn=Configuration,<basedn> becomes 'person'
+*/
+
+static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_ctx,
+ const struct ldb_val *in, struct ldb_val *out)
+{
+ struct ldb_dn *dn1 = NULL;
+ const char *oc1;
+
+ dn1 = ldb_dn_explode(mem_ctx, (char *)in->data);
+ if (dn1 == NULL) {
+ oc1 = talloc_strndup(mem_ctx, in->data, in->length);
+ } else if (dn1->comp_num >= 1 && strcasecmp(dn1->components[0].name, "cn") == 0) {
+ oc1 = talloc_strndup(mem_ctx, dn1->components[0].value.data,
+ dn1->components[0].value.length);
+ } else {
+ return -1;
+ }
+
+ oc1 = ldb_casefold(ldb, mem_ctx, oc1);
+ out->data = oc1;
+ out->length = strlen(oc1);
+ return 0;
+}
+
+static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx,
+ const struct ldb_val *v1,
+ const struct ldb_val *v2)
+{
+ struct ldb_dn *dn1 = NULL, *dn2 = NULL;
+ const char *oc1, *oc2;
+
+ dn1 = ldb_dn_explode(mem_ctx, (char *)v1->data);
+ if (dn1 == NULL) {
+ oc1 = talloc_strndup(mem_ctx, v1->data, v1->length);
+ } else if (dn1->comp_num >= 1 && strcasecmp(dn1->components[0].name, "cn") == 0) {
+ oc1 = talloc_strndup(mem_ctx, dn1->components[0].value.data,
+ dn1->components[0].value.length);
+ } else {
+ oc1 = NULL;
+ }
+
+ dn2 = ldb_dn_explode(mem_ctx, (char *)v2->data);
+ if (dn2 == NULL) {
+ oc2 = talloc_strndup(mem_ctx, v2->data, v2->length);
+ } else if (dn2->comp_num >= 2 && strcasecmp(dn2->components[0].name, "cn") == 0) {
+ oc2 = talloc_strndup(mem_ctx, dn2->components[0].value.data,
+ dn2->components[0].value.length);
+ } else {
+ oc2 = NULL;
+ }
+
+ oc1 = ldb_casefold(ldb, mem_ctx, oc1);
+ oc2 = ldb_casefold(ldb, mem_ctx, oc2);
+ if (!oc1 && oc2) {
+ return -1;
+ }
+ if (oc1 && !oc2) {
+ return 1;
+ }
+ if (!oc1 && !oc2) {
+ return -1;
+ }
+
+ return strcmp(oc1, oc2);
+}
+
static const struct ldb_attrib_handler samba_handlers[] = {
{
.attr = "objectSid",
@@ -323,6 +392,14 @@ static const struct ldb_attrib_handler samba_handlers[] = {
.ldif_write_fn = ldif_write_objectGUID,
.canonicalise_fn = ldb_canonicalise_objectGUID,
.comparison_fn = ldb_comparison_objectGUID
+ },
+ {
+ .attr = "objectCategory",
+ .flags = 0,
+ .ldif_read_fn = ldb_handler_copy,
+ .ldif_write_fn = ldb_handler_copy,
+ .canonicalise_fn = ldif_canonicalise_objectCategory,
+ .comparison_fn = ldif_comparison_objectCategory,
}
};
diff --git a/testprogs/ejs/ldap.js b/testprogs/ejs/ldap.js
index db36e8cb6a..2429b9da5a 100755
--- a/testprogs/ejs/ldap.js
+++ b/testprogs/ejs/ldap.js
@@ -167,6 +167,15 @@ objectClass: user
assert(res[0].dn == res2[0].dn);
+ println("Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon))");
+ var res3 = ldb.search("(&(cn=ldaptestuser)(objectCategory=PerSon))");
+ if (res.length != 1) {
+ println("Could not find (&(cn=ldaptestuser)(objectCategory=PerSon))");
+ assert(res.length == 1);
+ }
+
+ assert(res[0].dn == res3[0].dn);
+
ok = ldb.del(res[0].dn);
if (!ok) {
println(ldb.errstring());
@@ -194,13 +203,22 @@ objectClass: user
println("Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + base_dn + "))");
var res2 = ldb.search("(&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + base_dn + "))");
- if (res.length != 1) {
+ if (res2.length != 1) {
println("Could not find (&(cn=ldaptestcomputer)(objectCategory=cn=computer,cn=schema,cn=configuration," + base_dn + "))");
- assert(res.length == 1);
+ assert(res2.length == 1);
}
assert(res[0].dn == res2[0].dn);
+ println("Testing ldb.search for (&(cn=ldaptestcomputer)(objectCategory=compuTER))");
+ var res3 = ldb.search("(&(cn=ldaptestcomputer)(objectCategory=compuTER))");
+ if (res3.length != 1) {
+ println("Could not find (&(cn=ldaptestcomputer)(objectCategory=compuTER))");
+ assert(res3.length == 1);
+ }
+
+ assert(res[0].dn == res3[0].dn);
+
ok = ldb.del(res[0].dn);
if (!ok) {
println(ldb.errstring());