From efddd37af84b9db429237a491cb74a2c12c505cb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jun 2006 22:04:55 +0000 Subject: [PATCH] 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) --- source4/lib/ldb/common/ldb_attributes.c | 1 - source4/lib/ldb/common/ldb_match.c | 7 ++- source4/lib/ldb/samba/ldif_handlers.c | 81 ++++++++++++++++++++++++- testprogs/ejs/ldap.js | 22 ++++++- 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 679a05f2440..13e721a266e 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 810191c5ec3..f3ecbe03815 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 e84dfea6004..28bc5ea997d 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, 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 db36e8cb6ac..2429b9da5ad 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()); -- 2.34.1