The Samba-Bugzilla – Attachment 10824 Details for
Bug 10493
LDAP extended rule 1.2.840.113556.1.4.1941 LDAP_MATCHING_RULE_IN_CHAIN not working
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
4.2 patch cherry-picked from master
ldap-recursive-search-4.2.patch (text/plain), 46.48 KB, created by
Andrew Bartlett
on 2015-03-06 02:41:27 UTC
(
hide
)
Description:
4.2 patch cherry-picked from master
Filename:
MIME Type:
Creator:
Andrew Bartlett
Created:
2015-03-06 02:41:27 UTC
Size:
46.48 KB
patch
obsolete
>From df295ff86c83b21bf2a77e17433cad425f5bc454 Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <samuelcabrero@kernevil.me> >Date: Tue, 28 Oct 2014 11:53:01 +0100 >Subject: [PATCH 1/8] s4:dsdb/extended_dn_in: Fix DNs and filter expressions in > extended match ops > >Signed-off-by: Samuel Cabrero <samuelcabrero@kernevil.me> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit c3ca217969fd42853d477f430ee3975382fe64ef) >BUG: https://bugzilla.samba.org/show_bug.cgi?id=10493 >--- > source4/dsdb/samdb/ldb_modules/extended_dn_in.c | 48 ++++++++++++++++++------- > 1 file changed, 35 insertions(+), 13 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c >index f738bc4..bf0da81 100644 >--- a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c >+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c >@@ -342,18 +342,18 @@ static int extended_dn_filter_callback(struct ldb_parse_tree *tree, void *privat > { > struct extended_dn_filter_ctx *filter_ctx; > int ret; >- struct ldb_dn *dn; >+ struct ldb_dn *dn = NULL; > const struct ldb_val *sid_val, *guid_val; > const char *no_attrs[] = { NULL }; > struct ldb_result *res; >- const struct dsdb_attribute *attribute; >- bool has_extended_component; >+ const struct dsdb_attribute *attribute = NULL; >+ bool has_extended_component = false; > enum ldb_scope scope; > struct ldb_dn *base_dn; > const char *expression; > uint32_t dsdb_flags; > >- if (tree->operation != LDB_OP_EQUALITY) { >+ if (tree->operation != LDB_OP_EQUALITY && tree->operation != LDB_OP_EXTENDED) { > return LDB_SUCCESS; > } > >@@ -368,7 +368,11 @@ static int extended_dn_filter_callback(struct ldb_parse_tree *tree, void *privat > /* Schema not setup yet */ > return LDB_SUCCESS; > } >- attribute = dsdb_attribute_by_lDAPDisplayName(filter_ctx->schema, tree->u.equality.attr); >+ if (tree->operation == LDB_OP_EQUALITY) { >+ attribute = dsdb_attribute_by_lDAPDisplayName(filter_ctx->schema, tree->u.equality.attr); >+ } else if (tree->operation == LDB_OP_EXTENDED) { >+ attribute = dsdb_attribute_by_lDAPDisplayName(filter_ctx->schema, tree->u.extended.attr); >+ } > if (attribute == NULL) { > return LDB_SUCCESS; > } >@@ -377,8 +381,13 @@ static int extended_dn_filter_callback(struct ldb_parse_tree *tree, void *privat > return LDB_SUCCESS; > } > >- has_extended_component = (memchr(tree->u.equality.value.data, '<', >- tree->u.equality.value.length) != NULL); >+ if (tree->operation == LDB_OP_EQUALITY) { >+ has_extended_component = (memchr(tree->u.equality.value.data, '<', >+ tree->u.equality.value.length) != NULL); >+ } else if (tree->operation == LDB_OP_EXTENDED) { >+ has_extended_component = (memchr(tree->u.extended.value.data, '<', >+ tree->u.extended.value.length) != NULL); >+ } > > /* > * Don't turn it into an extended DN if we're talking to OpenLDAP. >@@ -391,7 +400,11 @@ static int extended_dn_filter_callback(struct ldb_parse_tree *tree, void *privat > return LDB_SUCCESS; > } > >- dn = ldb_dn_from_ldb_val(filter_ctx, ldb_module_get_ctx(filter_ctx->module), &tree->u.equality.value); >+ if (tree->operation == LDB_OP_EQUALITY) { >+ dn = ldb_dn_from_ldb_val(filter_ctx, ldb_module_get_ctx(filter_ctx->module), &tree->u.equality.value); >+ } else if (tree->operation == LDB_OP_EXTENDED) { >+ dn = ldb_dn_from_ldb_val(filter_ctx, ldb_module_get_ctx(filter_ctx->module), &tree->u.extended.value); >+ } > if (dn == NULL) { > /* testing against windows shows that we don't raise > an error here */ >@@ -467,12 +480,21 @@ static int extended_dn_filter_callback(struct ldb_parse_tree *tree, void *privat > } > > /* replace the search expression element with the matching DN */ >- tree->u.equality.value.data = (uint8_t *)talloc_strdup(tree, >- ldb_dn_get_extended_linearized(tree, res->msgs[0]->dn, 1)); >- if (tree->u.equality.value.data == NULL) { >- return ldb_oom(ldb_module_get_ctx(filter_ctx->module)); >+ if (tree->operation == LDB_OP_EQUALITY) { >+ tree->u.equality.value.data = >+ (uint8_t *)talloc_strdup(tree, ldb_dn_get_extended_linearized(tree, res->msgs[0]->dn, 1)); >+ if (tree->u.equality.value.data == NULL) { >+ return ldb_oom(ldb_module_get_ctx(filter_ctx->module)); >+ } >+ tree->u.equality.value.length = strlen((const char *)tree->u.equality.value.data); >+ } else if (tree->operation == LDB_OP_EXTENDED) { >+ tree->u.extended.value.data = >+ (uint8_t *)talloc_strdup(tree, ldb_dn_get_extended_linearized(tree, res->msgs[0]->dn, 1)); >+ if (tree->u.extended.value.data == NULL) { >+ return ldb_oom(ldb_module_get_ctx(filter_ctx->module)); >+ } >+ tree->u.extended.value.length = strlen((const char *)tree->u.extended.value.data); > } >- tree->u.equality.value.length = strlen((const char *)tree->u.equality.value.data); > talloc_free(res); > > filter_ctx->matched = true; >-- >2.1.4 > > >From 6a8e3c4da628265018bb62c66a7f528c815a7c27 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 19 Dec 2014 15:39:59 +1300 >Subject: [PATCH 2/8] dsdb: Improve code clarity for > ldb_extended_dn_in_openldap mode > >Pair-programmed-with: Garming Sam <garming@catalyst.net.nz> >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 172aa0ee3885720464e8eacd728eb1a1342fc9b4) >BUG: https://bugzilla.samba.org/show_bug.cgi?id=10493 >--- > source4/dsdb/samdb/ldb_modules/extended_dn_in.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c >index bf0da81..4127036 100644 >--- a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c >+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c >@@ -395,9 +395,13 @@ static int extended_dn_filter_callback(struct ldb_parse_tree *tree, void *privat > * pointer and a boolean to tell us the exact same thing. > */ > if (!has_extended_component) { >- if (!attribute->one_way_link || >- ldb_module_get_ops(filter_ctx->module) == &ldb_extended_dn_in_openldap_module_ops) >- return LDB_SUCCESS; >+ if (!attribute->one_way_link) { >+ return LDB_SUCCESS; >+ } >+ >+ if (ldb_module_get_ops(filter_ctx->module) == &ldb_extended_dn_in_openldap_module_ops) { >+ return LDB_SUCCESS; >+ } > } > > if (tree->operation == LDB_OP_EQUALITY) { >-- >2.1.4 > > >From d7b15ebb4e0c00c56e26f63c6ed1a449964ae4a3 Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <samuelcabrero@kernevil.me> >Date: Thu, 23 Oct 2014 16:47:07 +0200 >Subject: [PATCH 3/8] dsdb: Define syntax access point oid string as a macro > >Signed-off-by: Samuel Cabrero <samuelcabrero@kernevil.me> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 913cd47875eabefc9090c05066b6b2a5acbe9977) >BUG: https://bugzilla.samba.org/show_bug.cgi?id=10493 >--- > source4/dsdb/common/dsdb_dn.h | 1 + > source4/dsdb/schema/schema_syntax.c | 2 +- > 2 files changed, 2 insertions(+), 1 deletion(-) > >diff --git a/source4/dsdb/common/dsdb_dn.h b/source4/dsdb/common/dsdb_dn.h >index b455c7f..8aadac7 100644 >--- a/source4/dsdb/common/dsdb_dn.h >+++ b/source4/dsdb/common/dsdb_dn.h >@@ -8,6 +8,7 @@ struct dsdb_dn { > #define DSDB_SYNTAX_BINARY_DN "1.2.840.113556.1.4.903" > #define DSDB_SYNTAX_STRING_DN "1.2.840.113556.1.4.904" > #define DSDB_SYNTAX_OR_NAME "1.2.840.113556.1.4.1221" >+#define DSDB_SYNTAX_ACCESS_POINT "1.3.6.1.4.1.1466.115.121.1.2" > > > /* RMD_FLAGS component in a DN */ >diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c >index c9ff588..2f48b25 100644 >--- a/source4/dsdb/schema/schema_syntax.c >+++ b/source4/dsdb/schema/schema_syntax.c >@@ -2605,7 +2605,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = { > },{ > /* not used in w2k3 schema */ > .name = "Object(Access-Point)", >- .ldap_oid = "1.3.6.1.4.1.1466.115.121.1.2", >+ .ldap_oid = DSDB_SYNTAX_ACCESS_POINT, > .oMSyntax = 127, > .oMObjectClass = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e"), > .attributeSyntax_oid = "2.5.5.14", >-- >2.1.4 > > >From 31dc0251d33645ead0ef1c832bf93c5d631700ff Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <samuelcabrero@kernevil.me> >Date: Fri, 24 Oct 2014 17:52:47 +0200 >Subject: [PATCH 4/8] ldb-samba: Implement transitive extended matching > >Documented in [MS-ADTS] section 3.1.1.3.4.4.3 LDAP_MATCHING_RULE_TRANSITIVE_EVAL > >This allows a search filter such as: > > member:1.2.840.113556.1.4.1941:=cn=user,cn=users,dc=samba,dc=example,dc=com > >This searches not only the member attribute, but also any member >attributes that point at an object with this member in them. All the >various DN syntax types are supported, not just plain DNs. > >Signed-off-by: Samuel Cabrero <samuelcabrero@kernevil.me> >(abartlet: Fixed compile error: return makes integer from pointer without a cast) >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=10493 >(cherry picked from commit 2a22ba34cd6f28950246b54c6577c922c61f4fdb) >--- > lib/ldb-samba/ldb_matching_rules.c | 338 +++++++++++++++++++++++++++++++++++++ > lib/ldb-samba/ldb_matching_rules.h | 28 +++ > lib/ldb-samba/ldif_handlers.c | 6 + > lib/ldb-samba/wscript_build | 2 +- > 4 files changed, 373 insertions(+), 1 deletion(-) > create mode 100644 lib/ldb-samba/ldb_matching_rules.c > create mode 100644 lib/ldb-samba/ldb_matching_rules.h > >diff --git a/lib/ldb-samba/ldb_matching_rules.c b/lib/ldb-samba/ldb_matching_rules.c >new file mode 100644 >index 0000000..3a51c29 >--- /dev/null >+++ b/lib/ldb-samba/ldb_matching_rules.c >@@ -0,0 +1,338 @@ >+/* >+ Unix SMB/CIFS implementation. >+ >+ ldb database library - Extended match rules >+ >+ Copyright (C) 2014 Samuel Cabrero <samuelcabrero@kernevil.me> >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation; either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program 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 General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#include "includes.h" >+#include <ldb_module.h> >+#include "dsdb/samdb/samdb.h" >+#include "ldb_matching_rules.h" >+ >+static int ldb_eval_transitive_filter_helper(TALLOC_CTX *mem_ctx, >+ struct ldb_context *ldb, >+ const char *attr, >+ const struct dsdb_dn *dn_to_match, >+ const char *dn_oid, >+ struct dsdb_dn *to_visit, >+ struct dsdb_dn **visited, >+ unsigned int *visited_count, >+ bool *matched) >+{ >+ TALLOC_CTX *tmp_ctx; >+ int ret, i, j; >+ struct ldb_result *res; >+ struct ldb_message *msg; >+ struct ldb_message_element *el; >+ const char *attrs[] = { attr, NULL }; >+ >+ tmp_ctx = talloc_new(mem_ctx); >+ if (tmp_ctx == NULL) { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ /* >+ * Fetch the entry to_visit >+ * >+ * NOTE: This is a new LDB search from the TOP of the module >+ * stack. This means that this search runs the whole stack >+ * from top to bottom. >+ * >+ * This may seem to be in-efficient, but it is also the only >+ * way to ensure that the ACLs for this search are applied >+ * correctly. >+ * >+ * Note also that we don't have the original request >+ * here, so we can not apply controls or timeouts here. >+ */ >+ ret = dsdb_search_dn(ldb, tmp_ctx, &res, to_visit->dn, attrs, 0); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ if (res->count != 1) { >+ talloc_free(tmp_ctx); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ msg = res->msgs[0]; >+ >+ /* Fetch the attribute to match from the entry being visited */ >+ el = ldb_msg_find_element(msg, attr); >+ if (el == NULL) { >+ /* This entry does not have the attribute to match */ >+ talloc_free(tmp_ctx); >+ *matched = false; >+ return LDB_SUCCESS; >+ } >+ >+ /* >+ * If the value to match is present in the attribute values of the >+ * current entry being visited, set matched to true and return OK >+ */ >+ for (i=0; i<el->num_values; i++) { >+ struct dsdb_dn *dn; >+ dn = dsdb_dn_parse(tmp_ctx, ldb, &el->values[i], dn_oid); >+ if (dn == NULL) { >+ talloc_free(tmp_ctx); >+ *matched = false; >+ return LDB_ERR_INVALID_DN_SYNTAX; >+ } >+ >+ if (ldb_dn_compare(dn_to_match->dn, dn->dn) == 0) { >+ talloc_free(tmp_ctx); >+ *matched = true; >+ return LDB_SUCCESS; >+ } >+ } >+ >+ /* >+ * If arrived here, the value to match is not in the values of the >+ * entry being visited. Add the entry being visited (to_visit) >+ * to the visited array. The array is (re)allocated in the parent >+ * memory context. >+ */ >+ if (visited == NULL) { >+ visited = talloc_array(mem_ctx, struct dsdb_dn *, 1); >+ if (visited == NULL) { >+ talloc_free(tmp_ctx); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ visited[0] = to_visit; >+ (*visited_count) = 1; >+ } else { >+ visited = talloc_realloc(mem_ctx, visited, struct dsdb_dn *, >+ (*visited_count) + 1); >+ if (visited == NULL) { >+ talloc_free(tmp_ctx); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ visited[(*visited_count)] = to_visit; >+ (*visited_count)++; >+ } >+ >+ /* >+ * steal to_visit into visited array context, as it has to live until >+ * the array is freed. >+ */ >+ talloc_steal(visited, to_visit); >+ >+ /* >+ * Iterate over the values of the attribute of the entry being >+ * visited (to_visit) and follow them, calling this function >+ * recursively. >+ * If the value is in the visited array, skip it. >+ * Otherwise, follow the link and visit it. >+ */ >+ for (i=0; i<el->num_values; i++) { >+ struct dsdb_dn *next_to_visit; >+ bool skip = false; >+ >+ next_to_visit = dsdb_dn_parse(tmp_ctx, ldb, &el->values[i], dn_oid); >+ if (next_to_visit == NULL) { >+ talloc_free(tmp_ctx); >+ *matched = false; >+ return LDB_ERR_INVALID_DN_SYNTAX; >+ } >+ >+ /* >+ * If the value is already in the visited array, skip it. >+ * Note the last element of the array is ignored because it is >+ * the current entry DN. >+ */ >+ for (j=0; j < (*visited_count) - 1; j++) { >+ struct dsdb_dn *visited_dn = visited[j]; >+ if (ldb_dn_compare(visited_dn->dn, >+ next_to_visit->dn) == 0) { >+ skip = true; >+ break; >+ } >+ } >+ if (skip) { >+ talloc_free(next_to_visit); >+ continue; >+ } >+ >+ /* If the value is not in the visited array, evaluate it */ >+ ret = ldb_eval_transitive_filter_helper(tmp_ctx, ldb, attr, >+ dn_to_match, dn_oid, >+ next_to_visit, >+ visited, visited_count, >+ matched); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(tmp_ctx); >+ return ret; >+ } >+ if (*matched) { >+ talloc_free(tmp_ctx); >+ return LDB_SUCCESS; >+ } >+ } >+ >+ talloc_free(tmp_ctx); >+ *matched = false; >+ return LDB_SUCCESS; >+} >+ >+/* >+ * This function parses the linked attribute value to match, whose syntax >+ * will be one of the different DN syntaxes, into a ldb_dn struct. >+ */ >+static int ldb_eval_transitive_filter(TALLOC_CTX *mem_ctx, >+ struct ldb_context *ldb, >+ const char *attr, >+ const struct ldb_val *value_to_match, >+ struct dsdb_dn *current_object_dn, >+ bool *matched) >+{ >+ const struct dsdb_schema *schema; >+ const struct dsdb_attribute *schema_attr; >+ struct dsdb_dn *dn_to_match; >+ const char *dn_oid; >+ unsigned int count; >+ >+ schema = dsdb_get_schema(ldb, mem_ctx); >+ if (schema == NULL) { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ schema_attr = dsdb_attribute_by_lDAPDisplayName(schema, attr); >+ if (schema_attr == NULL) { >+ return LDB_ERR_NO_SUCH_ATTRIBUTE; >+ } >+ >+ /* This is the DN syntax of the attribute being matched */ >+ dn_oid = schema_attr->syntax->ldap_oid; >+ >+ /* >+ * Build a ldb_dn struct holding the value to match, which is the >+ * value entered in the search filter >+ */ >+ dn_to_match = dsdb_dn_parse(mem_ctx, ldb, value_to_match, dn_oid); >+ if (dn_to_match == NULL) { >+ *matched = false; >+ return LDB_ERR_INVALID_DN_SYNTAX; >+ } >+ >+ return ldb_eval_transitive_filter_helper(mem_ctx, ldb, attr, >+ dn_to_match, dn_oid, >+ current_object_dn, >+ NULL, &count, matched); >+} >+ >+/* >+ * This rule provides recursive search of a link attribute >+ * >+ * Documented in [MS-ADTS] section 3.1.1.3.4.4.3 LDAP_MATCHING_RULE_TRANSITIVE_EVAL >+ * This allows a search filter such as: >+ * >+ * member:1.2.840.113556.1.4.1941:=cn=user,cn=users,dc=samba,dc=example,dc=com >+ * >+ * This searches not only the member attribute, but also any member >+ * attributes that point at an object with this member in them. All the >+ * various DN syntax types are supported, not just plain DNs. >+ * >+ */ >+static int ldb_comparator_trans(struct ldb_context *ldb, >+ const char *oid, >+ const struct ldb_message *msg, >+ const char *attribute_to_match, >+ const struct ldb_val *value_to_match, >+ bool *matched) >+{ >+ const struct dsdb_schema *schema; >+ const struct dsdb_attribute *schema_attr; >+ struct ldb_dn *msg_dn; >+ struct dsdb_dn *dsdb_msg_dn; >+ TALLOC_CTX *tmp_ctx; >+ int ret; >+ >+ tmp_ctx = talloc_new(ldb); >+ if (tmp_ctx == NULL) { >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ /* >+ * If the target attribute to match is not a linked attribute, then >+ * the filter evaluates to undefined >+ */ >+ schema = dsdb_get_schema(ldb, tmp_ctx); >+ if (schema == NULL) { >+ talloc_free(tmp_ctx); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ schema_attr = dsdb_attribute_by_lDAPDisplayName(schema, attribute_to_match); >+ if (schema_attr == NULL) { >+ talloc_free(tmp_ctx); >+ return LDB_ERR_NO_SUCH_ATTRIBUTE; >+ } >+ >+ /* >+ * This extended match filter is only valid for linked attributes, >+ * following the MS definition (the schema attribute has a linkID >+ * defined). See dochelp request 114111212024789 on cifs-protocols >+ * mailing list. >+ */ >+ if (schema_attr->linkID == 0) { >+ talloc_free(tmp_ctx); >+ return LDB_ERR_INAPPROPRIATE_MATCHING; >+ } >+ >+ /* Duplicate original msg dn as the msg must not be modified */ >+ msg_dn = ldb_dn_copy(tmp_ctx, msg->dn); >+ if (msg_dn == NULL) { >+ talloc_free(tmp_ctx); >+ return LDB_ERR_OPERATIONS_ERROR; >+ } >+ >+ /* >+ * Build a dsdb dn from the message copied DN, which should be a plain >+ * DN syntax. >+ */ >+ dsdb_msg_dn = dsdb_dn_construct(tmp_ctx, msg_dn, data_blob_null, >+ LDB_SYNTAX_DN); >+ if (dsdb_msg_dn == NULL) { >+ *matched = false; >+ return LDB_ERR_INVALID_DN_SYNTAX; >+ } >+ >+ ret = ldb_eval_transitive_filter(tmp_ctx, ldb, >+ attribute_to_match, >+ value_to_match, >+ dsdb_msg_dn, matched); >+ talloc_free(tmp_ctx); >+ return ret; >+} >+ >+ >+int ldb_register_samba_matching_rules(struct ldb_context *ldb) >+{ >+ struct ldb_extended_match_rule *transitive_eval; >+ int ret; >+ >+ transitive_eval = talloc_zero(ldb, struct ldb_extended_match_rule); >+ transitive_eval->oid = SAMBA_LDAP_MATCH_RULE_TRANSITIVE_EVAL; >+ transitive_eval->callback = ldb_comparator_trans; >+ ret = ldb_register_extended_match_rule(ldb, transitive_eval); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(transitive_eval); >+ return ret; >+ } >+ >+ return LDB_SUCCESS; >+} >diff --git a/lib/ldb-samba/ldb_matching_rules.h b/lib/ldb-samba/ldb_matching_rules.h >new file mode 100644 >index 0000000..e969b3d >--- /dev/null >+++ b/lib/ldb-samba/ldb_matching_rules.h >@@ -0,0 +1,28 @@ >+/* >+ Unix SMB/CIFS implementation. >+ >+ ldb database library - Extended match rules >+ >+ Copyright (C) 2014 Samuel Cabrero <samuelcabrero@kernevil.me> >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation; either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program 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 General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#ifndef _LDB_MATCHING_RULES_H_ >+#define _LDB_MATCHING_RULES_H_ >+ >+/* This rule provides recursive search of a link attribute */ >+#define SAMBA_LDAP_MATCH_RULE_TRANSITIVE_EVAL "1.2.840.113556.1.4.1941" >+ >+#endif /* _LDB_MATCHING_RULES_H_ */ >diff --git a/lib/ldb-samba/ldif_handlers.c b/lib/ldb-samba/ldif_handlers.c >index d9d799c..8df477d 100644 >--- a/lib/ldb-samba/ldif_handlers.c >+++ b/lib/ldb-samba/ldif_handlers.c >@@ -1606,6 +1606,12 @@ int ldb_register_samba_handlers(struct ldb_context *ldb) > > } > >+ ret = ldb_register_samba_matching_rules(ldb); >+ if (ret != LDB_SUCCESS) { >+ talloc_free(ldb); >+ return LDB_SUCCESS; >+ } >+ > ret = ldb_set_opaque(ldb, "SAMBA_HANDLERS_REGISTERED", (void*)1); > if (ret != LDB_SUCCESS) { > return ret; >diff --git a/lib/ldb-samba/wscript_build b/lib/ldb-samba/wscript_build >index 7016b2f..6ad9698 100644 >--- a/lib/ldb-samba/wscript_build >+++ b/lib/ldb-samba/wscript_build >@@ -5,7 +5,7 @@ > # the symbols of all of ldb_ildap's dependencies. > > bld.SAMBA_LIBRARY('ldbsamba', >- source='ldif_handlers.c', >+ source='ldif_handlers.c ldb_matching_rules.c', > autoproto='ldif_handlers_proto.h', > public_deps='ldb', > deps='samba-security ndr NDR_DRSBLOBS NDR_DNSP ldbwrap samdb-common SAMDB_SCHEMA tdb errors', >-- >2.1.4 > > >From a5ea1300896d94135b5934d6bb30429e30cee6b1 Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <samuelcabrero@kernevil.me> >Date: Mon, 27 Oct 2014 18:21:04 +0100 >Subject: [PATCH 5/8] ldb-samba-tests: Add tests for transitive matching rule > >Signed-off-by: Samuel Cabrero <samuelcabrero@kernevil.me> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit 5f47ca786ef65ed61b9a061e2d11a633344a3dcc) >BUG: https://bugzilla.samba.org/show_bug.cgi?id=10493 >--- > lib/ldb-samba/tests/match_rules.py | 473 +++++++++++++++++++++++++++++++++++++ > source4/selftest/tests.py | 1 + > 2 files changed, 474 insertions(+) > create mode 100755 lib/ldb-samba/tests/match_rules.py > >diff --git a/lib/ldb-samba/tests/match_rules.py b/lib/ldb-samba/tests/match_rules.py >new file mode 100755 >index 0000000..cb18248 >--- /dev/null >+++ b/lib/ldb-samba/tests/match_rules.py >@@ -0,0 +1,473 @@ >+#!/usr/bin/env python >+ >+import optparse >+import sys >+import os >+import unittest >+import samba >+import samba.getopt as options >+ >+from samba.tests.subunitrun import SubunitOptions, TestProgram >+ >+from samba.tests import delete_force >+from samba.dcerpc import security, misc >+from samba.samdb import SamDB >+from samba.auth import system_session >+from samba.ndr import ndr_unpack >+from ldb import Message, MessageElement, Dn >+from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, FLAG_MOD_DELETE >+from ldb import SCOPE_BASE, SCOPE_SUBTREE >+ >+class MatchRulesTests(samba.tests.TestCase): >+ def setUp(self): >+ super(MatchRulesTests, self).setUp() >+ self.lp = lp >+ self.ldb = SamDB(host, credentials=creds, session_info=system_session(lp), lp=lp) >+ self.base_dn = self.ldb.domain_dn() >+ self.ou = "ou=matchrulestest,%s" % self.base_dn >+ self.ou_users = "ou=users,%s" % self.ou >+ self.ou_groups = "ou=groups,%s" % self.ou >+ self.ou_computers = "ou=computers,%s" % self.ou >+ >+ # Add a organizational unit to create objects >+ self.ldb.add({ >+ "dn": self.ou, >+ "objectclass": "organizationalUnit"}) >+ >+ # Add the following OU hierarchy and set otherWellKnownObjects, >+ # which has BinaryDN syntax: >+ # >+ # o1 >+ # |--> o2 >+ # | |--> o3 >+ # | | |-->o4 >+ >+ self.ldb.add({ >+ "dn": "OU=o1,%s" % self.ou, >+ "objectclass": "organizationalUnit"}) >+ self.ldb.add({ >+ "dn": "OU=o2,OU=o1,%s" % self.ou, >+ "objectclass": "organizationalUnit"}) >+ self.ldb.add({ >+ "dn": "OU=o3,OU=o2,OU=o1,%s" % self.ou, >+ "objectclass": "organizationalUnit"}) >+ self.ldb.add({ >+ "dn": "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou, >+ "objectclass": "organizationalUnit"}) >+ >+ m = Message() >+ m.dn = Dn(self.ldb, self.ou) >+ m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000001:OU=o1,%s" % self.ou, >+ FLAG_MOD_ADD, "otherWellKnownObjects") >+ self.ldb.modify(m) >+ >+ m = Message() >+ m.dn = Dn(self.ldb, "OU=o1,%s" % self.ou) >+ m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000002:OU=o2,OU=o1,%s" % self.ou, >+ FLAG_MOD_ADD, "otherWellKnownObjects") >+ self.ldb.modify(m) >+ >+ m = Message() >+ m.dn = Dn(self.ldb, "OU=o2,OU=o1,%s" % self.ou) >+ m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000003:OU=o3,OU=o2,OU=o1,%s" % self.ou, >+ FLAG_MOD_ADD, "otherWellKnownObjects") >+ self.ldb.modify(m) >+ >+ m = Message() >+ m.dn = Dn(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou) >+ m["otherWellKnownObjects"] = MessageElement("B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou, >+ FLAG_MOD_ADD, "otherWellKnownObjects") >+ self.ldb.modify(m) >+ >+ # Create OU for users and groups >+ self.ldb.add({ >+ "dn": self.ou_users, >+ "objectclass": "organizationalUnit"}) >+ self.ldb.add({ >+ "dn": self.ou_groups, >+ "objectclass": "organizationalUnit"}) >+ self.ldb.add({ >+ "dn": self.ou_computers, >+ "objectclass": "organizationalUnit"}) >+ >+ # Add four groups >+ self.ldb.add({ >+ "dn": "cn=g1,%s" % self.ou_groups, >+ "objectclass": "group" }) >+ self.ldb.add({ >+ "dn": "cn=g2,%s" % self.ou_groups, >+ "objectclass": "group" }) >+ self.ldb.add({ >+ "dn": "cn=g3,%s" % self.ou_groups, >+ "objectclass": "group" }) >+ self.ldb.add({ >+ "dn": "cn=g4,%s" % self.ou_groups, >+ "objectclass": "group" }) >+ >+ # Add four users >+ self.ldb.add({ >+ "dn": "cn=u1,%s" % self.ou_users, >+ "objectclass": "user"}) >+ self.ldb.add({ >+ "dn": "cn=u2,%s" % self.ou_users, >+ "objectclass": "user"}) >+ self.ldb.add({ >+ "dn": "cn=u3,%s" % self.ou_users, >+ "objectclass": "user"}) >+ self.ldb.add({ >+ "dn": "cn=u4,%s" % self.ou_users, >+ "objectclass": "user"}) >+ >+ # Add computers to test Object(DN-Binary) syntax >+ self.ldb.add({ >+ "dn": "cn=c1,%s" % self.ou_computers, >+ "objectclass": "computer", >+ "dNSHostName": "c1.%s" % self.lp.get("realm").lower(), >+ "servicePrincipalName": ["HOST/c1"], >+ "sAMAccountName": "c1$", >+ "userAccountControl": "83890178"}) >+ >+ self.ldb.add({ >+ "dn": "cn=c2,%s" % self.ou_computers, >+ "objectclass": "computer", >+ "dNSHostName": "c2.%s" % self.lp.get("realm").lower(), >+ "servicePrincipalName": ["HOST/c2"], >+ "sAMAccountName": "c2$", >+ "userAccountControl": "83890178"}) >+ >+ self.ldb.add({ >+ "dn": "cn=c3,%s" % self.ou_computers, >+ "objectclass": "computer", >+ "dNSHostName": "c3.%s" % self.lp.get("realm").lower(), >+ "servicePrincipalName": ["HOST/c3"], >+ "sAMAccountName": "c3$", >+ "userAccountControl": "83890178"}) >+ >+ # Create the following hierarchy: >+ # g4 >+ # |--> u4 >+ # |--> g3 >+ # | |--> u3 >+ # | |--> g2 >+ # | | |--> u2 >+ # | | |--> g1 >+ # | | | |--> u1 >+ >+ # u1 member of g1 >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=g1,%s" % self.ou_groups) >+ m["member"] = MessageElement("cn=u1,%s" % self.ou_users, >+ FLAG_MOD_ADD, "member") >+ self.ldb.modify(m) >+ >+ # u2 member of g2 >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=g2,%s" % self.ou_groups) >+ m["member"] = MessageElement("cn=u2,%s" % self.ou_users, >+ FLAG_MOD_ADD, "member") >+ self.ldb.modify(m) >+ >+ # u3 member of g3 >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=g3,%s" % self.ou_groups) >+ m["member"] = MessageElement("cn=u3,%s" % self.ou_users, >+ FLAG_MOD_ADD, "member") >+ self.ldb.modify(m) >+ >+ # u4 member of g4 >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=g4,%s" % self.ou_groups) >+ m["member"] = MessageElement("cn=u4,%s" % self.ou_users, >+ FLAG_MOD_ADD, "member") >+ self.ldb.modify(m) >+ >+ # g3 member of g4 >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=g4,%s" % self.ou_groups) >+ m["member"] = MessageElement("cn=g3,%s" % self.ou_groups, >+ FLAG_MOD_ADD, "member") >+ self.ldb.modify(m) >+ >+ # g2 member of g3 >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=g3,%s" % self.ou_groups) >+ m["member"] = MessageElement("cn=g2,%s" % self.ou_groups, >+ FLAG_MOD_ADD, "member") >+ self.ldb.modify(m) >+ >+ # g1 member of g2 >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=g2,%s" % self.ou_groups) >+ m["member"] = MessageElement("cn=g1,%s" % self.ou_groups, >+ FLAG_MOD_ADD, "member") >+ self.ldb.modify(m) >+ >+ # The msDS-RevealedUsers is owned by system and cannot be modified >+ # directly. Set the schemaUpgradeInProgress flag as workaround >+ # and create this hierarchy: >+ # ou=computers >+ # |-> c1 >+ # | |->c2 >+ # | | |->u1 >+ m = Message() >+ m.dn = Dn(self.ldb, "") >+ m["e1"] = MessageElement("1", FLAG_MOD_REPLACE, "schemaUpgradeInProgress") >+ self.ldb.modify(m) >+ >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=c2,%s" % self.ou_computers) >+ m["e1"] = MessageElement("B:8:01010101:cn=c3,%s" % self.ou_computers, >+ FLAG_MOD_ADD, "msDS-RevealedUsers") >+ self.ldb.modify(m) >+ >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=c1,%s" % self.ou_computers) >+ m["e1"] = MessageElement("B:8:01010101:cn=c2,%s" % self.ou_computers, >+ FLAG_MOD_ADD, "msDS-RevealedUsers") >+ self.ldb.modify(m) >+ >+ m = Message() >+ m.dn = Dn(self.ldb, "") >+ m["e1"] = MessageElement("0", FLAG_MOD_REPLACE, "schemaUpgradeInProgress") >+ self.ldb.modify(m) >+ >+ # Add a couple of ms-Exch-Configuration-Container to test forward-link >+ # attributes without backward link (addressBookRoots2) >+ # e1 >+ # |--> e2 >+ # | |--> c1 >+ self.ldb.add({ >+ "dn": "cn=e1,%s" % self.ou, >+ "objectclass": "msExchConfigurationContainer"}) >+ self.ldb.add({ >+ "dn": "cn=e2,%s" % self.ou, >+ "objectclass": "msExchConfigurationContainer"}) >+ >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=e2,%s" % self.ou) >+ m["e1"] = MessageElement("cn=c1,%s" % self.ou_computers, >+ FLAG_MOD_ADD, "addressBookRoots2") >+ self.ldb.modify(m) >+ >+ m = Message() >+ m.dn = Dn(self.ldb, "cn=e1,%s" % self.ou) >+ m["e1"] = MessageElement("cn=e2,%s" % self.ou, >+ FLAG_MOD_ADD, "addressBookRoots2") >+ self.ldb.modify(m) >+ >+ def tearDown(self): >+ super(MatchRulesTests, self).tearDown() >+ delete_force(self.ldb, "cn=u4,%s" % self.ou_users) >+ delete_force(self.ldb, "cn=u3,%s" % self.ou_users) >+ delete_force(self.ldb, "cn=u2,%s" % self.ou_users) >+ delete_force(self.ldb, "cn=u1,%s" % self.ou_users) >+ delete_force(self.ldb, "cn=g4,%s" % self.ou_groups) >+ delete_force(self.ldb, "cn=g3,%s" % self.ou_groups) >+ delete_force(self.ldb, "cn=g2,%s" % self.ou_groups) >+ delete_force(self.ldb, "cn=g1,%s" % self.ou_groups) >+ delete_force(self.ldb, "cn=c1,%s" % self.ou_computers) >+ delete_force(self.ldb, "cn=c2,%s" % self.ou_computers) >+ delete_force(self.ldb, "cn=c3,%s" % self.ou_computers) >+ delete_force(self.ldb, self.ou_users) >+ delete_force(self.ldb, self.ou_groups) >+ delete_force(self.ldb, self.ou_computers) >+ delete_force(self.ldb, "OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou) >+ delete_force(self.ldb, "OU=o3,OU=o2,OU=o1,%s" % self.ou) >+ delete_force(self.ldb, "OU=o2,OU=o1,%s" % self.ou) >+ delete_force(self.ldb, "OU=o1,%s" % self.ou) >+ delete_force(self.ldb, "CN=e2,%s" % self.ou) >+ delete_force(self.ldb, "CN=e1,%s" % self.ou) >+ delete_force(self.ldb, self.ou) >+ >+ def test_u1_member_of_g4(self): >+ # Search without transitive match must return 0 results >+ res1 = self.ldb.search("cn=g4,%s" % self.ou_groups, >+ scope=SCOPE_BASE, >+ expression="member=cn=u1,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 0) >+ >+ res1 = self.ldb.search("cn=u1,%s" % self.ou_users, >+ scope=SCOPE_BASE, >+ expression="memberOf=cn=g4,%s" % self.ou_groups) >+ self.assertTrue(len(res1) == 0) >+ >+ # Search with transitive match must return 1 results >+ res1 = self.ldb.search("cn=g4,%s" % self.ou_groups, >+ scope=SCOPE_BASE, >+ expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search("cn=u1,%s" % self.ou_users, >+ scope=SCOPE_BASE, >+ expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups) >+ self.assertTrue(len(res1) == 1) >+ >+ def test_g1_member_of_g4(self): >+ # Search without transitive match must return 0 results >+ res1 = self.ldb.search("cn=g4,%s" % self.ou_groups, >+ scope=SCOPE_BASE, >+ expression="member=cn=g1,%s" % self.ou_groups) >+ self.assertTrue(len(res1) == 0) >+ >+ res1 = self.ldb.search("cn=g1,%s" % self.ou_groups, >+ scope=SCOPE_BASE, >+ expression="memberOf=cn=g4,%s" % self.ou_groups) >+ self.assertTrue(len(res1) == 0) >+ >+ # Search with transitive match must return 1 results >+ res1 = self.ldb.search("cn=g4,%s" % self.ou_groups, >+ scope=SCOPE_BASE, >+ expression="member:1.2.840.113556.1.4.1941:=cn=g1,%s" % self.ou_groups) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search("cn=g1,%s" % self.ou_groups, >+ scope=SCOPE_BASE, >+ expression="memberOf:1.2.840.113556.1.4.1941:=cn=g4,%s" % self.ou_groups) >+ self.assertTrue(len(res1) == 1) >+ >+ def test_u1_groups(self): >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member=cn=u1,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member:1.2.840.113556.1.4.1941:=cn=u1,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 4) >+ >+ def test_u2_groups(self): >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member=cn=u2,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member:1.2.840.113556.1.4.1941:=cn=u2,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 3) >+ >+ def test_u3_groups(self): >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member=cn=u3,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member:1.2.840.113556.1.4.1941:=cn=u3,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 2) >+ >+ def test_u4_groups(self): >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member=cn=u4,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member:1.2.840.113556.1.4.1941:=cn=u4,%s" % self.ou_users) >+ self.assertTrue(len(res1) == 1) >+ >+ def test_extended_dn(self): >+ res1 = self.ldb.search("cn=u1,%s" % self.ou_users, >+ scope=SCOPE_BASE, >+ expression="objectClass=*", >+ attrs=['objectSid', 'objectGUID']) >+ self.assertTrue(len(res1) == 1) >+ >+ sid = self.ldb.schema_format_value("objectSid", res1[0]["objectSid"][0]) >+ guid = self.ldb.schema_format_value("objectGUID", res1[0]['objectGUID'][0]) >+ >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member=<SID=%s>" % sid) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member=<GUID=%s>" % guid) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member:1.2.840.113556.1.4.1941:=<SID=%s>" % sid) >+ self.assertTrue(len(res1) == 4) >+ >+ res1 = self.ldb.search(self.ou_groups, >+ scope=SCOPE_SUBTREE, >+ expression="member:1.2.840.113556.1.4.1941:=<GUID=%s>" % guid) >+ self.assertTrue(len(res1) == 4) >+ >+ def test_object_dn_binary(self): >+ res1 = self.ldb.search(self.ou_computers, >+ scope=SCOPE_SUBTREE, >+ expression="msDS-RevealedUsers=B:8:01010101:cn=c3,%s" % self.ou_computers) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.ou_computers, >+ scope=SCOPE_SUBTREE, >+ expression="msDS-RevealedUsers:1.2.840.113556.1.4.1941:=B:8:01010101:cn=c3,%s" % self.ou_computers) >+ self.assertTrue(len(res1) == 2) >+ >+ def test_one_way_links(self): >+ res1 = self.ldb.search(self.ou, >+ scope=SCOPE_SUBTREE, >+ expression="addressBookRoots2=cn=c1,%s" % self.ou_computers) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.ou, >+ scope=SCOPE_SUBTREE, >+ expression="addressBookRoots2:1.2.840.113556.1.4.1941:=cn=c1,%s" % self.ou_computers) >+ self.assertTrue(len(res1) == 2) >+ >+ def test_not_linked_attrs(self): >+ res1 = self.ldb.search(self.base_dn, >+ scope=SCOPE_BASE, >+ expression="wellKnownObjects=B:32:aa312825768811d1aded00c04fd8d5cd:CN=computers,%s" % self.base_dn) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.base_dn, >+ scope=SCOPE_BASE, >+ expression="wellKnownObjects:1.2.840.113556.1.4.1941:=B:32:aa312825768811d1aded00c04fd8d5cd:CN=computers,%s" % self.base_dn) >+ self.assertTrue(len(res1) == 0) >+ >+ >+ res1 = self.ldb.search(self.ou, >+ scope=SCOPE_SUBTREE, >+ expression="otherWellKnownObjects=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou) >+ self.assertTrue(len(res1) == 1) >+ >+ res1 = self.ldb.search(self.ou, >+ scope=SCOPE_SUBTREE, >+ expression="otherWellKnownObjects:1.2.840.113556.1.4.1941:=B:32:00000000000000000000000000000004:OU=o4,OU=o3,OU=o2,OU=o1,%s" % self.ou) >+ self.assertTrue(len(res1) == 0) >+ >+parser = optparse.OptionParser("match_rules.py [options] <host>") >+sambaopts = options.SambaOptions(parser) >+parser.add_option_group(sambaopts) >+parser.add_option_group(options.VersionOptions(parser)) >+ >+# use command line creds if available >+credopts = options.CredentialsOptions(parser) >+parser.add_option_group(credopts) >+opts, args = parser.parse_args() >+subunitopts = SubunitOptions(parser) >+parser.add_option_group(subunitopts) >+ >+if len(args) < 1: >+ parser.print_usage() >+ sys.exit(1) >+ >+host = args[0] >+ >+lp = sambaopts.get_loadparm() >+creds = credopts.get_credentials(lp) >+ >+if not "://" in host: >+ if os.path.isfile(host): >+ host = "tdb://%s" % host >+ else: >+ host = "ldap://%s" % host >+ >+TestProgram(module=__name__, opts=subunitopts) >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 7c4f888..28acefa 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -471,6 +471,7 @@ planoldpythontestsuite("dc", "dsdb_schema_info", > extra_args=['-U"$DOMAIN/$DC_USERNAME%$DC_PASSWORD"']) > plantestsuite_loadlist("samba4.urgent_replication.python(dc)", "dc:local", [python, os.path.join(samba4srcdir, "dsdb/tests/python/urgent_replication.py"), '$PREFIX_ABS/dc/private/sam.ldb', '$LOADLIST', '$LISTOPT']) > plantestsuite_loadlist("samba4.ldap.dirsync.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/dirsync.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) >+plantestsuite_loadlist("samba4.ldap.match_rules.python", "dc", [python, os.path.join(srcdir(), "lib/ldb-samba/tests/match_rules.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) > plantestsuite_loadlist("samba4.ldap.sites.python(dc)", "dc", [python, os.path.join(samba4srcdir, "dsdb/tests/python/sites.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) > for env in ["dc", "fl2000dc", "fl2003dc", "fl2008r2dc"]: > plantestsuite_loadlist("samba4.ldap_schema.python(%s)" % env, env, [python, os.path.join(samba4srcdir, "dsdb/tests/python/ldap_schema.py"), '$SERVER', '-U"$USERNAME%$PASSWORD"', '--workgroup=$DOMAIN', '$LOADLIST', '$LISTOPT']) >-- >2.1.4 > > >From f8337bb6006c3faf88ceb4727d25dcf6be781edc Mon Sep 17 00:00:00 2001 >From: Samuel Cabrero <samuelcabrero@kernevil.me> >Date: Mon, 10 Nov 2014 16:06:45 +0100 >Subject: [PATCH 6/8] s4:dsdb: Fix not freed temp memory context > >Signed-off-by: Samuel Cabrero <samuelcabrero@kernevil.me> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit afe6e576b95fc3f08945b379ecb37f73ebceb16a) >BUG: https://bugzilla.samba.org/show_bug.cgi?id=10493 >--- > source4/dsdb/common/dsdb_dn.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/source4/dsdb/common/dsdb_dn.c b/source4/dsdb/common/dsdb_dn.c >index ab42776..ccfbe36 100644 >--- a/source4/dsdb/common/dsdb_dn.c >+++ b/source4/dsdb/common/dsdb_dn.c >@@ -211,6 +211,7 @@ struct dsdb_dn *dsdb_dn_parse(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, > > dsdb_dn = dsdb_dn_construct(mem_ctx, dn, bval, dn_oid); > >+ talloc_free(tmp_ctx); > return dsdb_dn; > > failed: >-- >2.1.4 > > >From 4c14e639c258ea2f5f8d6d6db84d669d16fb2222 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 19 Dec 2014 15:46:30 +1300 >Subject: [PATCH 7/8] dsdb: Only parse SAMBA_LDAP_MATCH_RULE_TRANSITIVE_EVAL as > a DN > >This avoids trying to parse some other rule, like bitwise and, that may be applied to this attribute > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Pair-programmed-with: Garming Sam <garming@catalyst.net.nz> >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 1a012d591bca727b5cabacf6455d2009afb16bd7) >BUG: https://bugzilla.samba.org/show_bug.cgi?id=10493 >--- > source4/dsdb/samdb/ldb_modules/extended_dn_in.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c >index 4127036..b7ca636 100644 >--- a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c >+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c >@@ -35,6 +35,7 @@ > #include <ldb_module.h> > #include "dsdb/samdb/samdb.h" > #include "dsdb/samdb/ldb_modules/util.h" >+#include "lib/ldb-samba/ldb_matching_rules.h" > > /* > TODO: if relax is not set then we need to reject the fancy RMD_* and >@@ -406,7 +407,8 @@ static int extended_dn_filter_callback(struct ldb_parse_tree *tree, void *privat > > if (tree->operation == LDB_OP_EQUALITY) { > dn = ldb_dn_from_ldb_val(filter_ctx, ldb_module_get_ctx(filter_ctx->module), &tree->u.equality.value); >- } else if (tree->operation == LDB_OP_EXTENDED) { >+ } else if (tree->operation == LDB_OP_EXTENDED >+ && (strcmp(tree->u.extended.rule_id, SAMBA_LDAP_MATCH_RULE_TRANSITIVE_EVAL) == 0)) { > dn = ldb_dn_from_ldb_val(filter_ctx, ldb_module_get_ctx(filter_ctx->module), &tree->u.extended.value); > } > if (dn == NULL) { >-- >2.1.4 > > >From 32cffae3bec03d43c06336991980892973121e2b Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 19 Dec 2014 16:02:40 +1300 >Subject: [PATCH 8/8] lib/ldb-samba: Add comment dicouraging use of > schemaUpgradeInProgress > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Pair-programmed-with: Garming Sam <garming@catalyst.net.nz> >Signed-off-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Garming Sam <garming@samba.org> >Autobuild-Date(master): Mon Dec 22 02:42:42 CET 2014 on sn-devel-104 > >(cherry picked from commit 7cfe6e91177e93f80d4d7e02d1414ca80641e13c) >BUG: https://bugzilla.samba.org/show_bug.cgi?id=10493 >--- > lib/ldb-samba/tests/match_rules.py | 10 ++++++++++ > 1 file changed, 10 insertions(+) > >diff --git a/lib/ldb-samba/tests/match_rules.py b/lib/ldb-samba/tests/match_rules.py >index cb18248..6b31392 100755 >--- a/lib/ldb-samba/tests/match_rules.py >+++ b/lib/ldb-samba/tests/match_rules.py >@@ -209,6 +209,16 @@ class MatchRulesTests(samba.tests.TestCase): > # |-> c1 > # | |->c2 > # | | |->u1 >+ >+ # >+ # While appropriate for this test, this is NOT a good practice >+ # in general. This is only done here because the alternative >+ # is to make a schema modification. >+ # >+ # IF/WHEN Samba protects this attribute better, this >+ # particular part of the test can be removed, as the same code >+ # is covered by the addressBookRoots2 case well enough. >+ # > m = Message() > m.dn = Dn(self.ldb, "") > m["e1"] = MessageElement("1", FLAG_MOD_REPLACE, "schemaUpgradeInProgress") >-- >2.1.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
abartlet
:
review?
(
jelmer
)
Actions:
View
Attachments on
bug 10493
: 10824 |
11341
|
11342