summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac3
-rw-r--r--src/back-nis.c2
-rw-r--r--src/back-sch.c7
-rw-r--r--src/back-shr.c98
-rw-r--r--src/back-shr.h5
-rw-r--r--src/backend.h4
6 files changed, 118 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 37ccbf3..0d05c1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -466,6 +466,9 @@ AC_DEFINE_UNQUOTED(SCH_CONTAINER_CONFIGURATION_ACCESS_ATTR,"$checkaciattr",
schbaseattr=schema-compat-search-base
AC_DEFINE_UNQUOTED(SCH_CONTAINER_CONFIGURATION_BASE_ATTR,"$schbaseattr",
[Define to name of the attribute which lists the containers to search when locating entries to be used for constructing entries for a given container.])
+schignoreattr=schema-compat-ignore-subtree
+AC_DEFINE_UNQUOTED(SCH_CONTAINER_CONFIGURATION_IGNORE_SUBTREES_ATTR,"$schignoreattr",
+ [Define to name of the attribute which lists the subtrees to ignore when locating entries and reading data to be used for constructing entries for a given container.])
schfilterattr=schema-compat-search-filter
AC_DEFINE_UNQUOTED(SCH_CONTAINER_CONFIGURATION_FILTER_ATTR,"$schfilterattr",
[Define to name of the attribute which holds the filter for selecting entries to be used for constructing entries for a given container.])
diff --git a/src/back-nis.c b/src/back-nis.c
index df5df3f..f747f49 100644
--- a/src/back-nis.c
+++ b/src/back-nis.c
@@ -121,6 +121,7 @@ backend_copy_set_data(const struct backend_set_data *data)
ret->common.set = strdup(data->common.set);
ret->common.bases = backend_shr_dup_strlist(data->common.bases);
ret->common.entry_filter = strdup(data->common.entry_filter);
+ ret->common.ignore_subtrees = NULL;
ret->common.rel_attrs = data->common.rel_attrs ?
format_dup_attr_list(data->common.rel_attrs) :
NULL;
@@ -604,6 +605,7 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
ret.common.set = strdup(map);
ret.common.bases = use_bases;
ret.common.entry_filter = use_entry_filter;
+ ret.common.ignore_subtrees = NULL;
ret.common.rel_attrs = NULL;
ret.common.rel_attr_list = NULL;
ret.common.rel_attrs_list = NULL;
diff --git a/src/back-sch.c b/src/back-sch.c
index c33e708..047f2dc 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -79,6 +79,7 @@ backend_set_config_free_config_contents(void *data)
free(set_data->common.group);
free(set_data->common.set);
free(set_data->common.bases);
+ backend_shr_free_sdnlist(set_data->common.ignore_subtrees);
format_free_attr_list(set_data->common.rel_attrs);
free(set_data->common.rel_attr_list);
format_free_attr_list(set_data->common.ref_attrs);
@@ -110,6 +111,7 @@ backend_copy_set_config(const struct backend_set_data *data)
ret->common.group = strdup(data->common.group);
ret->common.set = strdup(data->common.set);
ret->common.bases = backend_shr_dup_strlist(data->common.bases);
+ ret->common.ignore_subtrees = backend_shr_dup_sdnlist(data->common.ignore_subtrees);
ret->common.rel_attrs = data->common.rel_attrs ?
format_dup_attr_list(data->common.rel_attrs) :
NULL;
@@ -160,10 +162,13 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
bool_t check_access;
struct backend_set_data ret;
Slapi_DN *tmp_sdn;
+ const Slapi_DN **ignore_subtrees;
/* Read the values from the configuration entry. */
bases = backend_shr_get_vattr_strlist(state, e,
SCH_CONTAINER_CONFIGURATION_BASE_ATTR);
+ ignore_subtrees = backend_shr_get_vattr_sdnlist(state, e,
+ SCH_CONTAINER_CONFIGURATION_IGNORE_SUBTREES_ATTR);
entry_filter = backend_shr_get_vattr_filter(state, e,
SCH_CONTAINER_CONFIGURATION_FILTER_ATTR);
rdn_format = backend_shr_get_vattr_str(state, e,
@@ -184,6 +189,7 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
slapi_sdn_free(&tmp_sdn);
ret.common.set = strdup(container);
ret.common.bases = bases;
+ ret.common.ignore_subtrees = ignore_subtrees;
ret.common.entry_filter = entry_filter;
ret.common.rel_attrs = NULL;
ret.common.rel_attr_list = NULL;
@@ -248,6 +254,7 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
free(ret.common.group);
free(ret.common.set);
backend_shr_free_strlist(ret.common.bases);
+ backend_shr_free_sdnlist(ret.common.ignore_subtrees);
free(ret.common.entry_filter);
slapi_sdn_free(&ret.container_sdn);
backend_shr_free_strlist(ret.attribute_format);
diff --git a/src/back-shr.c b/src/back-shr.c
index 5b7c6ec..cabd01c 100644
--- a/src/back-shr.c
+++ b/src/back-shr.c
@@ -284,6 +284,44 @@ backend_shr_set_entry_cb(Slapi_Entry *e, void *callback_data)
backend_shr_set_entry(cbdata->pb, e, cbdata->set_data);
return 0;
}
+static const Slapi_DN **
+backend_shr_dup_sdnlist_n(const Slapi_DN **sdnlist, int n)
+{
+ const Slapi_DN **ret;
+ int i;
+ /* Handle the NULL case. */
+ if (sdnlist == NULL) {
+ return NULL;
+ }
+ /* No DNs = no list. */
+ if (n == 0) {
+ return NULL;
+ }
+ ret = calloc(n + 1, sizeof(ret[0]));
+ for (i = 0; (sdnlist[i] != NULL) && (i < n); i++) {
+ ret[i] = slapi_sdn_dup(sdnlist[i]);
+ }
+ return ret;
+}
+const Slapi_DN **
+backend_shr_dup_sdnlist(const Slapi_DN **sdnlist)
+{
+ int i;
+ for (i = 0; (sdnlist != NULL) && (sdnlist[i] != NULL); i++) {
+ continue;
+ }
+ return backend_shr_dup_sdnlist_n(sdnlist, i);
+}
+void
+backend_shr_free_sdnlist(const Slapi_DN **sdnlist)
+{
+ int i;
+ for (i = 0; (sdnlist != NULL) && (sdnlist[i] != NULL); i++) {
+ slapi_sdn_free(&sdnlist[i]);
+ sdnlist[i] = NULL;
+ }
+ free(sdnlist);
+}
/* Set or unset the named entry using information in the callback data. */
static void
@@ -569,6 +607,38 @@ backend_shr_get_vattr_boolean(struct plugin_state *state,
return ret;
}
+const Slapi_DN **
+backend_shr_get_vattr_sdnlist(struct plugin_state *state,
+ Slapi_Entry *e, const char *attribute)
+{
+ Slapi_ValueSet *values;
+ Slapi_Value *value;
+ int disposition, buffer_flags;
+ char *actual_attr;
+ const Slapi_DN **ret;
+ int i, j;
+ ret = NULL;
+ if (slapi_vattr_values_get(e, (char *) attribute,
+ &values, &disposition, &actual_attr,
+ 0, &buffer_flags) == 0) {
+ ret = malloc(sizeof(ret[0]) *
+ (slapi_valueset_count(values) + 1));
+ if (ret != NULL) {
+ j = 0;
+ for (i = slapi_valueset_first_value(values, &value);
+ i != -1;
+ i = slapi_valueset_next_value(values, i, &value)) {
+ if (slapi_value_get_length(value) > 0) {
+ ret[j++] = slapi_sdn_new_dn_byval(slapi_value_get_string(value));
+ }
+ }
+ ret[j] = NULL;
+ }
+ slapi_vattr_values_free(&values, &actual_attr, buffer_flags);
+ }
+ return ret;
+}
+
/* Scan for the list of configured groups and sets. */
void
backend_shr_startup(struct plugin_state *state,
@@ -721,11 +791,25 @@ static bool_t
backend_shr_entry_matches_set(struct backend_shr_set_data *set_data,
Slapi_PBlock *pb, Slapi_Entry *e)
{
+ const Slapi_DN **ignore_subtrees;
char **set_bases;
char *set_filter;
int i;
+
+ ignore_subtrees = set_data->ignore_subtrees;
set_bases = set_data->bases;
set_filter = set_data->entry_filter;
+
+ if (ignore_subtrees != NULL) {
+ for (i = 0; ignore_subtrees[i] != NULL; i++) {
+ if (slapi_sdn_scope_test(slapi_entry_get_sdn_const(e),
+ ignore_subtrees[i],
+ LDAP_SCOPE_SUBTREE) != 0) {
+ return FALSE;
+ }
+ }
+ }
+
if (set_bases != NULL) {
for (i = 0; set_bases[i] != NULL; i++) {
if (backend_shr_entry_matches(pb, e,
@@ -736,6 +820,7 @@ backend_shr_entry_matches_set(struct backend_shr_set_data *set_data,
}
}
}
+
return FALSE;
}
@@ -916,6 +1001,19 @@ backend_shr_update_references_cb(const char *group, const char *set,
cbdata = cbdata_ptr;
state = set_data->state;
+ /* Check if this entry is in one of the areas we've been specifically
+ * told to ignore. */
+ if (set_data->ignore_subtrees != NULL) {
+ for (i = 0; set_data->ignore_subtrees[i] != NULL; i++) {
+ if (slapi_sdn_scope_test(slapi_entry_get_sdn_const(cbdata->e),
+ set_data->ignore_subtrees[i],
+ LDAP_SCOPE_SUBTREE) != 0) {
+ /* Yeah, we're done here. */
+ return TRUE;
+ }
+ }
+ }
+
/* If the entry didn't change any attributes which are at all relevant
* to this map, then we don't need to recompute anything. */
if (set_data->skip_uninteresting_updates &&
diff --git a/src/back-shr.h b/src/back-shr.h
index 9b2eda9..83c049d 100644
--- a/src/back-shr.h
+++ b/src/back-shr.h
@@ -33,6 +33,8 @@ char **backend_shr_dup_strlist_n(char **strlist, int n);
char **backend_shr_dup_strlist(char **strlist);
char **backend_shr_dup_strlist_unless_empty(char **strlist);
void backend_shr_add_strlist(char ***strlist, const char *item);
+const Slapi_DN **backend_shr_dup_sdnlist(const Slapi_DN **sdnlist);
+void backend_shr_free_sdnlist(const Slapi_DN **sdnlist);
void backend_shr_startup(struct plugin_state *state,
Slapi_PBlock *pb, const char *set_filter);
@@ -53,6 +55,9 @@ int backend_shr_set_config_entry_delete(struct plugin_state *state,
const char *set_attr);
char **backend_shr_get_vattr_strlist(struct plugin_state *state,
Slapi_Entry *e, const char *attribute);
+const Slapi_DN ** backend_shr_get_vattr_sdnlist(struct plugin_state *state,
+ Slapi_Entry *e,
+ const char *attribute);
char *backend_shr_get_vattr_str(struct plugin_state *state,
Slapi_Entry *e, const char *attribute);
unsigned int backend_shr_get_vattr_uint(struct plugin_state *state,
diff --git a/src/backend.h b/src/backend.h
index c8f053d..be6693d 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -45,7 +45,9 @@ struct backend_shr_set_data {
struct format_ref_attr_list **ref_attr_list, **inref_attr_list;
/* Configuration flag indicating whether or not we try to skip
* recomputing data in this map. */
- int skip_uninteresting_updates:1;
+ unsigned int skip_uninteresting_updates:1;
+ /* Subtrees under which we ignore contents. */
+ const struct slapi_dn **ignore_subtrees;
struct backend_set_data *self;
};