|
|
eeac78 |
From 5f5f302e97560b05b154473f562410733e0b775b Mon Sep 17 00:00:00 2001
|
|
|
eeac78 |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
eeac78 |
Date: Tue, 28 Oct 2014 11:16:50 +0200
|
|
|
eeac78 |
Subject: [PATCH 2/2] schema-compat: support ID overrides in bind callback
|
|
|
eeac78 |
|
|
|
eeac78 |
If RDN of the bind DN is overridden within the ID view, rewrite the
|
|
|
eeac78 |
target to use original value of the uid attribute.
|
|
|
eeac78 |
|
|
|
eeac78 |
If original uid attribute is not available, fail the search and thus
|
|
|
eeac78 |
the whole bind request by claiming that bind DN does not exist.
|
|
|
eeac78 |
---
|
|
|
eeac78 |
src/back-sch-idview.c | 86 ++++++++++++++++++++++++++++++++++-----------------
|
|
|
eeac78 |
src/back-sch.c | 57 +++++++++++++++++++++++++++++-----
|
|
|
eeac78 |
src/back-sch.h | 4 +++
|
|
|
eeac78 |
3 files changed, 111 insertions(+), 36 deletions(-)
|
|
|
eeac78 |
|
|
|
eeac78 |
diff --git a/src/back-sch-idview.c b/src/back-sch-idview.c
|
|
|
eeac78 |
index a56a9e9..f1150cd 100644
|
|
|
eeac78 |
--- a/src/back-sch-idview.c
|
|
|
eeac78 |
+++ b/src/back-sch-idview.c
|
|
|
eeac78 |
@@ -290,21 +290,15 @@ idview_replace_target_dn(char **target, char **idview)
|
|
|
eeac78 |
}
|
|
|
eeac78 |
}
|
|
|
eeac78 |
|
|
|
eeac78 |
-static int
|
|
|
eeac78 |
-idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct berval *bval, struct backend_search_filter_config *config)
|
|
|
eeac78 |
+int
|
|
|
eeac78 |
+idview_replace_bval_by_override(const char *bval_usage, const char *attr_name,
|
|
|
eeac78 |
+ struct berval *bval, struct backend_search_cbdata *cbdata)
|
|
|
eeac78 |
{
|
|
|
eeac78 |
int res, i;
|
|
|
eeac78 |
- Slapi_Value *filter_val, *value, *anchor_val;
|
|
|
eeac78 |
+ Slapi_Value *attr_val, *value, *anchor_val;
|
|
|
eeac78 |
Slapi_Attr *anchor, *attr = NULL;
|
|
|
eeac78 |
- struct backend_search_cbdata *cbdata = (struct backend_search_cbdata *) config->callback_data;
|
|
|
eeac78 |
-
|
|
|
eeac78 |
- if (cbdata == NULL || cbdata->idview == NULL) {
|
|
|
eeac78 |
- return SLAPI_FILTER_SCAN_CONTINUE;
|
|
|
eeac78 |
- }
|
|
|
eeac78 |
-
|
|
|
eeac78 |
- if (filter_type == NULL || config->name == NULL) {
|
|
|
eeac78 |
- return SLAPI_FILTER_SCAN_CONTINUE;
|
|
|
eeac78 |
- }
|
|
|
eeac78 |
+ bool_t uid_override_found = FALSE;
|
|
|
eeac78 |
+ bool_t anchor_override_found = FALSE;
|
|
|
eeac78 |
|
|
|
eeac78 |
if (cbdata->overrides == NULL) {
|
|
|
eeac78 |
/* Only retrieve overrides for the view first time when neccessary */
|
|
|
eeac78 |
@@ -312,31 +306,34 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b
|
|
|
eeac78 |
}
|
|
|
eeac78 |
|
|
|
eeac78 |
if (cbdata->overrides == NULL) {
|
|
|
eeac78 |
- return SLAPI_FILTER_SCAN_CONTINUE;
|
|
|
eeac78 |
+ return 0;
|
|
|
eeac78 |
}
|
|
|
eeac78 |
|
|
|
eeac78 |
- filter_val = slapi_value_new_berval(bval);
|
|
|
eeac78 |
+ attr_val = slapi_value_new_berval(bval);
|
|
|
eeac78 |
+ slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id,
|
|
|
eeac78 |
+ "Searching for an override of the %s %s with %s=%*s from the overrides\n.",
|
|
|
eeac78 |
+ bval_usage, attr_name, attr_name, (int) bval->bv_len, bval->bv_val);
|
|
|
eeac78 |
|
|
|
eeac78 |
/* If filter contains an attribute name which is overridden in the view and filter value
|
|
|
eeac78 |
* corresponds to the override, replace the filter by (ipaAnchorUUID=...) from the override
|
|
|
eeac78 |
* to point to the original because otherwise an entry will not be found in the slapi-nis map */
|
|
|
eeac78 |
for(i=0; cbdata->overrides[i] != NULL; i++) {
|
|
|
eeac78 |
- res = slapi_entry_attr_find(cbdata->overrides[i], filter_type, &attr);
|
|
|
eeac78 |
+ res = slapi_entry_attr_find(cbdata->overrides[i], attr_name, &attr);
|
|
|
eeac78 |
if ((res == 0) && (attr != NULL)) {
|
|
|
eeac78 |
res = slapi_attr_first_value(attr, &value);
|
|
|
eeac78 |
- res = slapi_value_compare(attr, value, filter_val);
|
|
|
eeac78 |
+ res = slapi_value_compare(attr, value, attr_val);
|
|
|
eeac78 |
if (res == 0) {
|
|
|
eeac78 |
/* For uid overrides we should have ipaOriginalUID in the override */
|
|
|
eeac78 |
- if (strcasecmp(filter_type, "uid") == 0) {
|
|
|
eeac78 |
+ if (strcasecmp(attr_name, "uid") == 0) {
|
|
|
eeac78 |
res = slapi_entry_attr_find(cbdata->overrides[i], IPA_IDVIEWS_ATTR_ORIGINALUID, &anchor);
|
|
|
eeac78 |
if (res == 0) {
|
|
|
eeac78 |
res = slapi_attr_first_value(anchor, &anchor_val);
|
|
|
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 |
+ uid_override_found = TRUE;
|
|
|
eeac78 |
+ slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id,
|
|
|
eeac78 |
+ "Overriding the %s %s with %s=%*s from the override %s\n.",
|
|
|
eeac78 |
+ bval_usage, attr_name, attr_name, (int) bval->bv_len, bval->bv_val,
|
|
|
eeac78 |
slapi_entry_get_dn_const(cbdata->overrides[i]));
|
|
|
eeac78 |
break;
|
|
|
eeac78 |
}
|
|
|
eeac78 |
@@ -346,14 +343,13 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b
|
|
|
eeac78 |
res = slapi_entry_attr_find(cbdata->overrides[i], IPA_IDVIEWS_ATTR_ANCHORUUID, &anchor);
|
|
|
eeac78 |
if (res == 0) {
|
|
|
eeac78 |
res = slapi_attr_first_value(anchor, &anchor_val);
|
|
|
eeac78 |
- slapi_filter_changetype(filter, IPA_IDVIEWS_ATTR_ANCHORUUID);
|
|
|
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 |
+ anchor_override_found = TRUE;
|
|
|
eeac78 |
+ slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id,
|
|
|
eeac78 |
+ "Overriding the %s %s with %s=%*s from the override %s\n.",
|
|
|
eeac78 |
+ bval_usage, attr_name, IPA_IDVIEWS_ATTR_ANCHORUUID,
|
|
|
eeac78 |
+ (int) bval->bv_len, bval->bv_val,
|
|
|
eeac78 |
slapi_entry_get_dn_const(cbdata->overrides[i]));
|
|
|
eeac78 |
break;
|
|
|
eeac78 |
}
|
|
|
eeac78 |
@@ -362,7 +358,41 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b
|
|
|
eeac78 |
}
|
|
|
eeac78 |
}
|
|
|
eeac78 |
|
|
|
eeac78 |
- slapi_value_free(&filter_val);
|
|
|
eeac78 |
+ slapi_value_free(&attr_val);
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ if (uid_override_found) {
|
|
|
eeac78 |
+ return 1;
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ if (anchor_override_found) {
|
|
|
eeac78 |
+ return 2;
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ return 0;
|
|
|
eeac78 |
+}
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+static int
|
|
|
eeac78 |
+idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type,
|
|
|
eeac78 |
+ struct berval *bval, struct backend_search_filter_config *config)
|
|
|
eeac78 |
+{
|
|
|
eeac78 |
+ int res;
|
|
|
eeac78 |
+ struct backend_search_cbdata *cbdata = (struct backend_search_cbdata *) config->callback_data;
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ if (cbdata == NULL || cbdata->idview == NULL) {
|
|
|
eeac78 |
+ return SLAPI_FILTER_SCAN_CONTINUE;
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ if (filter_type == NULL || config->name == NULL) {
|
|
|
eeac78 |
+ return SLAPI_FILTER_SCAN_CONTINUE;
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ res = idview_replace_bval_by_override("filter", filter_type, bval, cbdata);
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ if (res == 2) {
|
|
|
eeac78 |
+ slapi_filter_changetype(filter, IPA_IDVIEWS_ATTR_ANCHORUUID);
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+
|
|
|
eeac78 |
+ config->override_found = (res != 0);
|
|
|
eeac78 |
|
|
|
eeac78 |
return SLAPI_FILTER_SCAN_CONTINUE;
|
|
|
eeac78 |
|
|
|
eeac78 |
diff --git a/src/back-sch.c b/src/back-sch.c
|
|
|
eeac78 |
index 27ac24f..2388d2f 100644
|
|
|
eeac78 |
--- a/src/back-sch.c
|
|
|
eeac78 |
+++ b/src/back-sch.c
|
|
|
eeac78 |
@@ -1631,7 +1631,6 @@ static void
|
|
|
eeac78 |
backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char **group, const char**set)
|
|
|
eeac78 |
{
|
|
|
eeac78 |
struct backend_locate_cbdata cbdata;
|
|
|
eeac78 |
- char *idview = NULL;
|
|
|
eeac78 |
|
|
|
eeac78 |
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state);
|
|
|
eeac78 |
if (cbdata.state->plugin_base == NULL) {
|
|
|
eeac78 |
@@ -1640,22 +1639,64 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char **
|
|
|
eeac78 |
return;
|
|
|
eeac78 |
}
|
|
|
eeac78 |
slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target);
|
|
|
eeac78 |
-#ifdef USE_IPA_IDVIEWS
|
|
|
eeac78 |
- idview_replace_target_dn(&cbdata.target, &idview);
|
|
|
eeac78 |
-#endif
|
|
|
eeac78 |
+
|
|
|
eeac78 |
cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
|
|
|
eeac78 |
cbdata.entry_data = NULL;
|
|
|
eeac78 |
cbdata.entry_group = NULL;
|
|
|
eeac78 |
cbdata.entry_set = NULL;
|
|
|
eeac78 |
map_data_foreach_map(cbdata.state, NULL, backend_locate_cb, &cbdata);
|
|
|
eeac78 |
+#ifdef USE_IPA_IDVIEWS
|
|
|
eeac78 |
+ /* In case nothing was found but we are operating on the ID override,
|
|
|
eeac78 |
+ * rebuild the target's RDN to use original attribute's value */
|
|
|
eeac78 |
+ if (cbdata.entry_data == NULL) {
|
|
|
eeac78 |
+ char *idview = NULL;
|
|
|
eeac78 |
+ char *target, *original_target;
|
|
|
eeac78 |
+ target = original_target = slapi_ch_strdup(cbdata.target);
|
|
|
eeac78 |
+ idview_replace_target_dn(&target, &idview);
|
|
|
eeac78 |
+ if (target != original_target) {
|
|
|
eeac78 |
+ slapi_ch_free_string(&original_target);
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+ if (idview != NULL) {
|
|
|
eeac78 |
+ char *rdnstr;
|
|
|
eeac78 |
+ char *val;
|
|
|
eeac78 |
+ struct berval bval;
|
|
|
eeac78 |
+ int res;
|
|
|
eeac78 |
+ struct backend_search_cbdata scbdata;
|
|
|
eeac78 |
+ Slapi_RDN *rdn = slapi_rdn_new_all_dn(target);
|
|
|
eeac78 |
+ if (rdn != NULL) {
|
|
|
eeac78 |
+ res = slapi_rdn_get_first(rdn, &rdnstr, &val;;
|
|
|
eeac78 |
+ if (res == 1) {
|
|
|
eeac78 |
+ bval.bv_len = strlen(val) + 1;
|
|
|
eeac78 |
+ bval.bv_val = slapi_ch_strdup(val);
|
|
|
eeac78 |
+ memset(&scbdata, 0, sizeof(scbdata));
|
|
|
eeac78 |
+ scbdata.idview = idview;
|
|
|
eeac78 |
+ scbdata.target = target;
|
|
|
eeac78 |
+ scbdata.pb = pb;
|
|
|
eeac78 |
+ scbdata.state = cbdata.state;
|
|
|
eeac78 |
+ scbdata.target_dn = slapi_sdn_new_dn_byval(target);
|
|
|
eeac78 |
+ res = idview_replace_bval_by_override("rdn", rdnstr, &bval, &scbdata);
|
|
|
eeac78 |
+ /* only accept uid overrides */
|
|
|
eeac78 |
+ if (res == 1) {
|
|
|
eeac78 |
+ slapi_rdn_remove_index(rdn, 1);
|
|
|
eeac78 |
+ slapi_rdn_add(rdn, "uid", bval.bv_val);
|
|
|
eeac78 |
+ slapi_sdn_free(&cbdata.target_dn);
|
|
|
eeac78 |
+ cbdata.target_dn = slapi_sdn_set_rdn(scbdata.target_dn, rdn);
|
|
|
eeac78 |
+ map_data_foreach_map(cbdata.state, NULL, backend_locate_cb, &cbdata);
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+ slapi_ber_bvdone(&bval);
|
|
|
eeac78 |
+ slapi_rdn_free(&rdn;;
|
|
|
eeac78 |
+ idview_free_overrides(&scbdata);
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+ slapi_ch_free_string(&target);
|
|
|
eeac78 |
+ slapi_ch_free_string(&idview);
|
|
|
eeac78 |
+ }
|
|
|
eeac78 |
+#endif
|
|
|
eeac78 |
*data = cbdata.entry_data;
|
|
|
eeac78 |
*group = cbdata.entry_group;
|
|
|
eeac78 |
*set = cbdata.entry_set;
|
|
|
eeac78 |
slapi_sdn_free(&cbdata.target_dn);
|
|
|
eeac78 |
- if (idview != NULL) {
|
|
|
eeac78 |
- slapi_ch_free_string(&cbdata.target);
|
|
|
eeac78 |
- }
|
|
|
eeac78 |
- slapi_ch_free_string(&idview);
|
|
|
eeac78 |
}
|
|
|
eeac78 |
|
|
|
eeac78 |
/* Check if the target DN is part of this group's tree. If it is, return an
|
|
|
eeac78 |
diff --git a/src/back-sch.h b/src/back-sch.h
|
|
|
eeac78 |
index 9f0b201..26e12d1 100644
|
|
|
eeac78 |
--- a/src/back-sch.h
|
|
|
eeac78 |
+++ b/src/back-sch.h
|
|
|
eeac78 |
@@ -131,6 +131,10 @@ void idview_process_overrides(struct backend_search_cbdata *cbdata,
|
|
|
eeac78 |
Slapi_Entry *entry);
|
|
|
eeac78 |
void idview_replace_target_dn(char **target, char **idview);
|
|
|
eeac78 |
void idview_replace_filter(struct backend_search_cbdata *cbdata);
|
|
|
eeac78 |
+/* Takes struct berval value of an attribute attr_name and replaces it with an override
|
|
|
eeac78 |
+ * Returns 0 if no override was found, 1 for 'uid' replacement, 2 for ipaAnchorUUID replacement */
|
|
|
eeac78 |
+int idview_replace_bval_by_override(const char *bval_usage, const char *attr_name,
|
|
|
eeac78 |
+ struct berval *bval, struct backend_search_cbdata *cbdata);
|
|
|
eeac78 |
#endif
|
|
|
eeac78 |
|
|
|
eeac78 |
#endif
|
|
|
eeac78 |
--
|
|
|
eeac78 |
2.1.0
|
|
|
eeac78 |
|