diff options
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/back-nis.c | 2 | ||||
-rw-r--r-- | src/back-sch.c | 7 | ||||
-rw-r--r-- | src/back-shr.c | 98 | ||||
-rw-r--r-- | src/back-shr.h | 5 | ||||
-rw-r--r-- | src/backend.h | 4 |
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; }; |