summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@dahyabhai.net>2013-09-12 14:23:19 -0400
committerNalin Dahyabhai <nalin@dahyabhai.net>2013-09-12 14:23:19 -0400
commiteb43fd14cbe47e014139838200f31e01e1fc8a10 (patch)
tree70c9add1f306d56a93e364381766f279a11cc609
parent9e552ca19a67a54aaebc60a0aaa48756013be957 (diff)
downloadslapi-nis-eb43fd14cbe47e014139838200f31e01e1fc8a10.tar.gz
slapi-nis-eb43fd14cbe47e014139838200f31e01e1fc8a10.tar.xz
slapi-nis-eb43fd14cbe47e014139838200f31e01e1fc8a10.zip
Add schema-compat-ignore-subtree
Add a schema-compat-ignore-subtree configuration option, listing parts of the DIT that we should never look at, neither as source entries nor as random other entries which contain data which might be pulled in as part of computing the contents of compat entries.
-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;
};