Add schema-compat-relevant-subtree
Add a schema-compat-relevant-subtree configuration option, listing the
only parts of the DIT that we should ever look at, either as source
entries or as other entries which contain data which might be pulled in
as part of computing the contents of compat entries.
This is more or less the whitelist to schema-compat-ignore-subtree's
blacklist.
Nalin Dahyabhai
10 years ago
465 | 465 | schbaseattr=schema-compat-search-base |
466 | 466 | AC_DEFINE_UNQUOTED(SCH_CONTAINER_CONFIGURATION_BASE_ATTR,"$schbaseattr", |
467 | 467 | [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.]) |
468 | schignoreattr=schema-compat-ignore-subtree | |
469 | AC_DEFINE_UNQUOTED(SCH_CONTAINER_CONFIGURATION_IGNORE_SUBTREES_ATTR,"$schignoreattr", | |
468 | schignoresubtreeattr=schema-compat-ignore-subtree | |
469 | AC_DEFINE_UNQUOTED(SCH_CONTAINER_CONFIGURATION_IGNORE_SUBTREES_ATTR,"$schignoresubtreeattr", | |
470 | 470 | [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.]) |
471 | schrelevantsubtreeattr=schema-compat-relevant-subtree | |
472 | AC_DEFINE_UNQUOTED(SCH_CONTAINER_CONFIGURATION_RELEVANT_SUBTREES_ATTR,"$schrelevantsubtreeattr", | |
473 | [Define to name of the attribute which lists the only subtrees which are relevant when locating entries and reading data to be used for constructing entries for a given container.]) | |
471 | 474 | schfilterattr=schema-compat-search-filter |
472 | 475 | AC_DEFINE_UNQUOTED(SCH_CONTAINER_CONFIGURATION_FILTER_ATTR,"$schfilterattr", |
473 | 476 | [Define to name of the attribute which holds the filter for selecting entries to be used for constructing entries for a given container.]) |
120 | 120 | ret->common.set = strdup(data->common.set); |
121 | 121 | ret->common.bases = backend_shr_dup_strlist(data->common.bases); |
122 | 122 | ret->common.entry_filter = strdup(data->common.entry_filter); |
123 | ret->common.relevant_subtrees = NULL; | |
123 | 124 | ret->common.ignore_subtrees = NULL; |
124 | 125 | ret->common.rel_attrs = data->common.rel_attrs ? |
125 | 126 | format_dup_attr_list(data->common.rel_attrs) : |
604 | 605 | ret.common.set = strdup(map); |
605 | 606 | ret.common.bases = use_bases; |
606 | 607 | ret.common.entry_filter = use_entry_filter; |
608 | ret.common.relevant_subtrees = NULL; | |
607 | 609 | ret.common.ignore_subtrees = NULL; |
608 | 610 | ret.common.rel_attrs = NULL; |
609 | 611 | ret.common.rel_attr_list = NULL; |
705 | 707 | free(ret.common.group); |
706 | 708 | free(ret.common.set); |
707 | 709 | backend_shr_free_strlist(ret.common.bases); |
710 | backend_shr_free_sdnlist(ret.common.relevant_subtrees); | |
708 | 711 | free(ret.disallowed_chars); |
709 | 712 | free(ret.common.entry_filter); |
710 | 713 | backend_shr_free_strlist(ret.key_formats); |
78 | 78 | free(set_data->common.group); |
79 | 79 | free(set_data->common.set); |
80 | 80 | free(set_data->common.bases); |
81 | backend_shr_free_sdnlist(set_data->common.relevant_subtrees); | |
81 | 82 | backend_shr_free_sdnlist(set_data->common.ignore_subtrees); |
82 | 83 | format_free_attr_list(set_data->common.rel_attrs); |
83 | 84 | free(set_data->common.rel_attr_list); |
110 | 111 | ret->common.group = strdup(data->common.group); |
111 | 112 | ret->common.set = strdup(data->common.set); |
112 | 113 | ret->common.bases = backend_shr_dup_strlist(data->common.bases); |
114 | ret->common.relevant_subtrees = backend_shr_dup_sdnlist(data->common.relevant_subtrees); | |
113 | 115 | ret->common.ignore_subtrees = backend_shr_dup_sdnlist(data->common.ignore_subtrees); |
114 | 116 | ret->common.rel_attrs = data->common.rel_attrs ? |
115 | 117 | format_dup_attr_list(data->common.rel_attrs) : |
161 | 163 | bool_t check_access; |
162 | 164 | struct backend_set_data ret; |
163 | 165 | Slapi_DN *tmp_sdn; |
164 | const Slapi_DN **ignore_subtrees; | |
166 | const Slapi_DN **relevant_subtrees, **ignore_subtrees; | |
165 | 167 | |
166 | 168 | /* Read the values from the configuration entry. */ |
167 | 169 | bases = backend_shr_get_vattr_strlist(state, e, |
168 | 170 | SCH_CONTAINER_CONFIGURATION_BASE_ATTR); |
171 | relevant_subtrees = backend_shr_get_vattr_sdnlist(state, e, | |
172 | SCH_CONTAINER_CONFIGURATION_RELEVANT_SUBTREES_ATTR); | |
169 | 173 | ignore_subtrees = backend_shr_get_vattr_sdnlist(state, e, |
170 | 174 | SCH_CONTAINER_CONFIGURATION_IGNORE_SUBTREES_ATTR); |
171 | 175 | entry_filter = backend_shr_get_vattr_filter(state, e, |
188 | 192 | slapi_sdn_free(&tmp_sdn); |
189 | 193 | ret.common.set = strdup(container); |
190 | 194 | ret.common.bases = bases; |
195 | ret.common.relevant_subtrees = relevant_subtrees; | |
191 | 196 | ret.common.ignore_subtrees = ignore_subtrees; |
192 | 197 | ret.common.entry_filter = entry_filter; |
193 | 198 | ret.common.rel_attrs = NULL; |
253 | 258 | free(ret.common.group); |
254 | 259 | free(ret.common.set); |
255 | 260 | backend_shr_free_strlist(ret.common.bases); |
261 | backend_shr_free_sdnlist(ret.common.relevant_subtrees); | |
256 | 262 | backend_shr_free_sdnlist(ret.common.ignore_subtrees); |
257 | 263 | free(ret.common.entry_filter); |
258 | 264 | slapi_sdn_free(&ret.container_sdn); |
316 | 316 | { |
317 | 317 | int i; |
318 | 318 | for (i = 0; (sdnlist != NULL) && (sdnlist[i] != NULL); i++) { |
319 | slapi_sdn_free(&sdnlist[i]); | |
319 | slapi_sdn_free((Slapi_DN **) &sdnlist[i]); | |
320 | 320 | sdnlist[i] = NULL; |
321 | 321 | } |
322 | 322 | free(sdnlist); |
790 | 790 | backend_shr_entry_matches_set(struct backend_shr_set_data *set_data, |
791 | 791 | Slapi_PBlock *pb, Slapi_Entry *e) |
792 | 792 | { |
793 | const Slapi_DN **ignore_subtrees; | |
793 | const Slapi_DN **relevant_subtrees, **ignore_subtrees; | |
794 | 794 | char **set_bases; |
795 | 795 | char *set_filter; |
796 | 796 | int i; |
797 | 797 | |
798 | relevant_subtrees = set_data->relevant_subtrees; | |
798 | 799 | ignore_subtrees = set_data->ignore_subtrees; |
799 | 800 | set_bases = set_data->bases; |
800 | 801 | set_filter = set_data->entry_filter; |
806 | 807 | LDAP_SCOPE_SUBTREE) != 0) { |
807 | 808 | return FALSE; |
808 | 809 | } |
810 | } | |
811 | } | |
812 | if (relevant_subtrees != NULL) { | |
813 | for (i = 0; relevant_subtrees[i] != NULL; i++) { | |
814 | if (slapi_sdn_scope_test(slapi_entry_get_sdn_const(e), | |
815 | relevant_subtrees[i], | |
816 | LDAP_SCOPE_SUBTREE) != 0) { | |
817 | break; | |
818 | } | |
819 | } | |
820 | if (relevant_subtrees[i] == NULL) { | |
821 | /* Non-empty list, but no match. */ | |
822 | return FALSE; | |
809 | 823 | } |
810 | 824 | } |
811 | 825 | |
1010 | 1024 | /* Yeah, we're done here. */ |
1011 | 1025 | return TRUE; |
1012 | 1026 | } |
1027 | } | |
1028 | } | |
1029 | if (set_data->relevant_subtrees != NULL) { | |
1030 | for (i = 0; set_data->relevant_subtrees[i] != NULL; i++) { | |
1031 | if (slapi_sdn_scope_test(slapi_entry_get_sdn_const(cbdata->e), | |
1032 | set_data->relevant_subtrees[i], | |
1033 | LDAP_SCOPE_SUBTREE) != 0) { | |
1034 | break; | |
1035 | } | |
1036 | } | |
1037 | if (set_data->relevant_subtrees[i] == NULL) { | |
1038 | /* Non-empty list, but no match. */ | |
1039 | return TRUE; | |
1013 | 1040 | } |
1014 | 1041 | } |
1015 | 1042 |
45 | 45 | /* Configuration flag indicating whether or not we try to skip |
46 | 46 | * recomputing data in this map. */ |
47 | 47 | unsigned int skip_uninteresting_updates:1; |
48 | /* Subtrees under which all of the contents that we care about will be | |
49 | * stored. Other locaoins will be silently ignored. */ | |
50 | const struct slapi_dn **relevant_subtrees; | |
48 | 51 | /* Subtrees under which we ignore contents. */ |
49 | 52 | const struct slapi_dn **ignore_subtrees; |
50 | 53 | struct backend_set_data *self; |