|
|
eeac78 |
From 79391fda05fba164af577bd0e08a2807643b7b48 Mon Sep 17 00:00:00 2001
|
|
|
eeac78 |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
eeac78 |
Date: Tue, 28 Oct 2014 10:09:47 +0200
|
|
|
eeac78 |
Subject: [PATCH 1/2] ID views: ignore searches for views outside the subtrees
|
|
|
eeac78 |
of schema-compat sets
|
|
|
eeac78 |
|
|
|
eeac78 |
schema-compat plugin may provide multiple disjoint subtrees which
|
|
|
eeac78 |
can be used to request overridden entries by prefixing the subtree
|
|
|
eeac78 |
suffix with a
|
|
|
eeac78 |
|
|
|
eeac78 |
cn=<name of view>,cn=views,<subtree suffix>
|
|
|
eeac78 |
|
|
|
eeac78 |
As subtrees may be disjoint, we cannot rely on the common suffix. Thus,
|
|
|
eeac78 |
any attempt to replace target DN and update filter terms must only be
|
|
|
eeac78 |
done once we are sure the search will be done in the subtree.
|
|
|
eeac78 |
|
|
|
eeac78 |
This optimization prevents mistakenly changing the search filter when
|
|
|
eeac78 |
FreeIPA and SSSD search for the ID overrides themselves, as the same
|
|
|
eeac78 |
structure of the target DN is used for cn=views,cn=accounts,$SUFFIX
|
|
|
eeac78 |
subtree in FreeIPA. This subtree is never handled by slapi-nis and
|
|
|
eeac78 |
should be ignored.
|
|
|
eeac78 |
|
|
|
eeac78 |
https://bugzilla.redhat.com/show_bug.cgi?id=1157989
|
|
|
eeac78 |
---
|
|
|
eeac78 |
src/back-sch-idview.c | 11 +++++--
|
|
|
eeac78 |
src/back-sch.c | 81 +++++++++++++++++++++++++++++++++++++++++++++------
|
|
|
eeac78 |
2 files changed, 81 insertions(+), 11 deletions(-)
|
|
|
eeac78 |
|
|
|
eeac78 |
diff --git a/src/back-sch-idview.c b/src/back-sch-idview.c
|
|
|
eeac78 |
index 5a2b450..a56a9e9 100644
|
|
|
eeac78 |
--- a/src/back-sch-idview.c
|
|
|
eeac78 |
+++ b/src/back-sch-idview.c
|
|
|
eeac78 |
@@ -334,6 +334,10 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b
|
|
|
eeac78 |
slapi_ber_bvdone(bval);
|
|
|
eeac78 |
slapi_ber_bvcpy(bval, slapi_value_get_berval(anchor_val));
|
|
|
eeac78 |
config->override_found = TRUE;
|
|
|
eeac78 |
+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id,
|
|
|
eeac78 |
+ "Overriding the filter %s with %s=%*s from the override %s\n.",
|
|
|
eeac78 |
+ filter_type, filter_type, bval->bv_len, bval->bv_val,
|
|
|
eeac78 |
+ slapi_entry_get_dn_const(cbdata->overrides[i]));
|
|
|
eeac78 |
break;
|
|
|
eeac78 |
}
|
|
|
eeac78 |
}
|
|
|
eeac78 |
@@ -346,6 +350,11 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b
|
|
|
eeac78 |
slapi_ber_bvdone(bval);
|
|
|
eeac78 |
slapi_ber_bvcpy(bval, slapi_value_get_berval(anchor_val));
|
|
|
eeac78 |
config->override_found = TRUE;
|
|
|
eeac78 |
+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id,
|
|
|
eeac78 |
+ "Overriding the filter %s with %s=%*s from the override %s\n.",
|
|
|
eeac78 |
+ filter_type, IPA_IDVIEWS_ATTR_ANCHORUUID,
|
|
|
eeac78 |
+ bval->bv_len, bval->bv_val,
|
|
|
eeac78 |
+ slapi_entry_get_dn_const(cbdata->overrides[i]));
|
|
|
eeac78 |
break;
|
|
|
eeac78 |
}
|
|
|
eeac78 |
|
|
|
eeac78 |
@@ -366,8 +375,6 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b
|
|
|
eeac78 |
*
|
|
|
eeac78 |
* Note that in reality we don't use original value of the uid/cn attribue. Instead, we use ipaAnchorUUID
|
|
|
eeac78 |
* to refer to the original entry. */
|
|
|
eeac78 |
-extern char *
|
|
|
eeac78 |
-slapi_filter_to_string( const struct slapi_filter *f, char *buf, size_t bufsize );
|
|
|
eeac78 |
void
|
|
|
eeac78 |
idview_replace_filter(struct backend_search_cbdata *cbdata)
|
|
|
eeac78 |
{
|
|
|
eeac78 |
diff --git a/src/back-sch.c b/src/back-sch.c
|
|
|
eeac78 |
index 27d5101..27ac24f 100644
|
|
|
eeac78 |
--- a/src/back-sch.c
|
|
|
eeac78 |
+++ b/src/back-sch.c
|
|
|
eeac78 |
@@ -1166,6 +1166,44 @@ backend_search_set_cb(const char *group, const char *set, bool_t flag,
|
|
|
eeac78 |
return TRUE;
|
|
|
eeac78 |
}
|
|
|
eeac78 |
|
|
|
eeac78 |
+/* Routines to search if a target DN is within any of the sets we handle */
|
|
|
eeac78 |
+static bool_t
|
|
|
eeac78 |
+backend_search_find_set_dn_in_group_cb(const char *group, const char *set, bool_t flag,
|
|
|
eeac78 |
+ void *backend_data, void *cb_data)
|
|
|
eeac78 |
+{
|
|
|
eeac78 |
+ struct backend_search_cbdata *cbdata;
|
|
|
eeac78 |
+ struct backend_set_data *set_data;
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ cbdata = cb_data;
|
|
|
eeac78 |
+ set_data = backend_data;
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ if (slapi_sdn_scope_test(cbdata->target_dn,
|
|
|
eeac78 |
+ set_data->container_sdn,
|
|
|
eeac78 |
+ cbdata->scope) == 1) {
|
|
|
eeac78 |
+ cbdata->answer = TRUE;
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ if (slapi_sdn_compare(set_data->container_sdn,
|
|
|
eeac78 |
+ cbdata->target_dn) == 0) {
|
|
|
eeac78 |
+ cbdata->answer = TRUE;
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ return TRUE;
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+}
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+static bool_t
|
|
|
eeac78 |
+backend_search_find_set_dn_cb(const char *group, void *cb_data)
|
|
|
eeac78 |
+{
|
|
|
eeac78 |
+ struct backend_search_cbdata *cbdata;
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ cbdata = cb_data;
|
|
|
eeac78 |
+ map_data_foreach_map(cbdata->state, group,
|
|
|
eeac78 |
+ backend_search_find_set_dn_in_group_cb, cb_data);
|
|
|
eeac78 |
+ return TRUE;
|
|
|
eeac78 |
+}
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+/* Routines to find out the set that has the same group as requested */
|
|
|
eeac78 |
static bool_t
|
|
|
eeac78 |
backend_search_find_set_data_in_group_cb(const char *group, const char *set, bool_t flag,
|
|
|
eeac78 |
void *backend_data, void *cb_data)
|
|
|
eeac78 |
@@ -1340,9 +1378,6 @@ backend_search_cb(Slapi_PBlock *pb)
|
|
|
eeac78 |
"searching from \"%s\" for \"%s\" with scope %d%s\n",
|
|
|
eeac78 |
cbdata.target, cbdata.strfilter, cbdata.scope,
|
|
|
eeac78 |
backend_sch_scope_as_string(cbdata.scope));
|
|
|
eeac78 |
-#ifdef USE_IPA_IDVIEWS
|
|
|
eeac78 |
- idview_replace_target_dn(&cbdata.target, &cbdata.idview);
|
|
|
eeac78 |
-#endif
|
|
|
eeac78 |
cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
|
|
|
eeac78 |
/* Check if there's a backend handling this search. */
|
|
|
eeac78 |
if (!slapi_be_exist(cbdata.target_dn)) {
|
|
|
eeac78 |
@@ -1351,19 +1386,47 @@ backend_search_cb(Slapi_PBlock *pb)
|
|
|
eeac78 |
"slapi_be_exists(\"%s\") = 0, "
|
|
|
eeac78 |
"ignoring search\n", cbdata.target);
|
|
|
eeac78 |
slapi_sdn_free(&cbdata.target_dn);
|
|
|
eeac78 |
+ return 0;
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+#ifdef USE_IPA_IDVIEWS
|
|
|
eeac78 |
+ /* We may have multiple disjoint trees in the sets, search if the target matches any of them
|
|
|
eeac78 |
+ * as in general there don't have to be a single subtree (cn=compat,$SUFFIX) for all trees to easily
|
|
|
eeac78 |
+ * detect the ID view use. Unless the ID view is within the set we control, don't consider the override */
|
|
|
eeac78 |
+ map_data_foreach_domain(cbdata.state, backend_search_find_set_dn_cb, &cbdata);
|
|
|
eeac78 |
+ if (cbdata.answer == FALSE) {
|
|
|
eeac78 |
+ idview_replace_target_dn(&cbdata.target, &cbdata.idview);
|
|
|
eeac78 |
if (cbdata.idview != NULL) {
|
|
|
eeac78 |
- slapi_ch_free_string(&cbdata.target);
|
|
|
eeac78 |
+ slapi_sdn_free(&cbdata.target_dn);
|
|
|
eeac78 |
+ /* Perform another check, now for rewritten DN */
|
|
|
eeac78 |
+ cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
|
|
|
eeac78 |
+ map_data_foreach_domain(cbdata.state, backend_search_find_set_dn_cb, &cbdata);
|
|
|
eeac78 |
+ /* Rewritten DN might still be outside of our trees */
|
|
|
eeac78 |
+ if (cbdata.answer == TRUE) {
|
|
|
eeac78 |
+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id,
|
|
|
eeac78 |
+ "Use of ID view '%s' is detected, searching from \"%s\" "
|
|
|
eeac78 |
+ "for \"%s\" with scope %d%s. Filter may get overridden later.\n",
|
|
|
eeac78 |
+ cbdata.idview, cbdata.target, cbdata.strfilter, cbdata.scope,
|
|
|
eeac78 |
+ backend_sch_scope_as_string(cbdata.scope));
|
|
|
eeac78 |
+ } else {
|
|
|
eeac78 |
+ slapi_sdn_free(&cbdata.target_dn);
|
|
|
eeac78 |
+ slapi_ch_free_string(&cbdata.target);
|
|
|
eeac78 |
+ slapi_ch_free_string(&cbdata.idview);
|
|
|
eeac78 |
+ slapi_log_error(SLAPI_LOG_PLUGIN,
|
|
|
eeac78 |
+ cbdata.state->plugin_desc->spd_id,
|
|
|
eeac78 |
+ "The search base didn't match any of the containers, "
|
|
|
eeac78 |
+ "ignoring search\n");
|
|
|
eeac78 |
+ return 0;
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
}
|
|
|
eeac78 |
- slapi_ch_free_string(&cbdata.idview);
|
|
|
eeac78 |
-#ifdef USE_IPA_IDVIEWS
|
|
|
eeac78 |
- idview_free_overrides(&cbdata);
|
|
|
eeac78 |
-#endif
|
|
|
eeac78 |
- return 0;
|
|
|
eeac78 |
}
|
|
|
eeac78 |
+ cbdata.answer = FALSE;
|
|
|
eeac78 |
+#endif
|
|
|
eeac78 |
|
|
|
eeac78 |
/* Walk the list of groups. */
|
|
|
eeac78 |
wrap_inc_call_level();
|
|
|
eeac78 |
#ifdef USE_IPA_IDVIEWS
|
|
|
eeac78 |
+ /* Filter replacement requires increased call level as we may fetch overrides and thus come back here */
|
|
|
eeac78 |
idview_replace_filter(&cbdata);
|
|
|
eeac78 |
#endif
|
|
|
eeac78 |
if (map_rdlock() == 0) {
|
|
|
eeac78 |
--
|
|
|
eeac78 |
2.1.0
|
|
|
eeac78 |
|