From 89516c787c3fcd041a0867472382c37529339f71 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 16:14:28 -0400 Subject: - start adding an sch backend - start factoring out the backend logic where the sch and nis backends overlap --- src/Makefile.am | 21 +- src/back-nis.c | 11 +- src/back-sch.c | 1356 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/back-sch.h | 34 ++ src/back-shr.c | 1143 ++++++++++++++++++++++++++++++++++++++++++++++ src/disp-nis.c | 2 +- src/dummymap.c | 2 +- src/format.c | 87 +--- src/nis.c | 2 +- src/plug-nis.c | 2 +- src/plug-nis.h | 45 -- src/plug-sch.c | 113 +++++ 12 files changed, 2684 insertions(+), 134 deletions(-) create mode 100644 src/back-sch.c create mode 100644 src/back-sch.h create mode 100644 src/back-shr.c delete mode 100644 src/plug-nis.h create mode 100644 src/plug-sch.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 2ff593f..ee6bad1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,10 +6,12 @@ LIBWRAP = @LIBWRAP@ plugindir = $(libdir)/dirsrv/plugins dist_noinst_SCRIPTS = ypmaplist.py -plugin_LTLIBRARIES = nisserver-plugin.la +plugin_LTLIBRARIES = nisserver-plugin.la schemacompat-plugin.la nisserver_plugin_la_SOURCES = \ back-nis.c \ back-nis.h \ + back-shr.c \ + back-shr.h \ defs-nis.c \ defs-nis.h \ disp-nis.c \ @@ -21,13 +23,26 @@ nisserver_plugin_la_SOURCES = \ nis.c \ nis.h \ plug-nis.c \ - plug-nis.h \ + plugin.h \ portmap.c \ portmap.h \ wrap.c \ wrap.h nisserver_plugin_la_LIBADD = $(RUNTIME_LIBS) $(LIBWRAP) -lnsl $(LIBPTHREAD) +schemacompat_plugin_la_SOURCES = \ + back-sch.c \ + back-sch.h \ + back-shr.c \ + back-shr.h \ + format.c \ + format.h \ + map.c \ + map.h \ + plug-sch.c \ + plugin.h +schemacompat_plugin_la_LIBADD = $(RUNTIME_LIBS) $(LIBPTHREAD) + noinst_LTLIBRARIES = dummy-nis-plugin.la dummy_nis_plugin_la_SOURCES = \ disp-nis.c \ @@ -37,7 +52,7 @@ dummy_nis_plugin_la_SOURCES = \ nis.c \ nis.h \ plug-nis.c \ - plug-nis.h \ + plugin.h \ portmap.c \ portmap.h dummy_nis_plugin_la_LIBADD = $(RUNTIME_LIBS) -lnsl -lpthread diff --git a/src/back-nis.c b/src/back-nis.c index cde9c8a..a91c4f3 100644 --- a/src/back-nis.c +++ b/src/back-nis.c @@ -43,11 +43,12 @@ #include #endif +#include "backend.h" #include "back-nis.h" #include "defs-nis.h" #include "disp-nis.h" #include "format.h" -#include "plug-nis.h" +#include "plugin.h" #include "map.h" #define NIS_MAP_CONFIGURATION_FILTER "(&(objectClass=*)(" NIS_MAP_CONFIGURATION_BASE_ATTR "=*)(" NIS_MAP_CONFIGURATION_DOMAIN_ATTR "=*)(" NIS_MAP_CONFIGURATION_MAP_ATTR "=*))" @@ -63,13 +64,13 @@ struct backend_map_data { struct format_inref_attr **inref_attrs; }; -/* Read the name of the NIS master. */ +/* Read the name of the NIS master. Used by the map module on behalf of the + * NIS service logic. */ void backend_free_master_name(struct plugin_state *state, char *master) { free(master); } - int backend_read_master_name(struct plugin_state *state, char **master) { @@ -130,6 +131,8 @@ backend_free_strlist(char **strlist) free(strlist); } } + +/* Manipulate string lists. */ static char ** backend_dup_strlist_n(char **strlist, int n) { @@ -177,6 +180,7 @@ backend_dup_strlist(char **strlist) return backend_dup_strlist_n(strlist, i); } +/* Manipulate map data. */ static void backend_free_map_data_contents(void *data) { @@ -200,7 +204,6 @@ backend_free_map_data(void *data) backend_free_map_data_contents(data); free(data); } - static struct backend_map_data * backend_copy_map_data(const struct backend_map_data *data) { diff --git a/src/back-sch.c b/src/back-sch.c new file mode 100644 index 0000000..704e653 --- /dev/null +++ b/src/back-sch.c @@ -0,0 +1,1356 @@ +/* + * Copyright 2008 Red Hat, Inc. + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This Program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; if not, write to the + * + * Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111-1307 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#include +#include +#include +#include + +#ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H +#include +#include +#include +#else +#include +#endif + +#include +#include + +#ifdef HAVE_TCPD_H +#include +#endif + +#include "backend.h" +#include "back-sch.h" +#include "format.h" +#include "plugin.h" +#include "map.h" + +#define SCH_CONTAINER_CONFIGURATION_FILTER "(&(objectClass=*)(" SCH_CONTAINER_CONFIGURATION_BASE_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_GROUP_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_FILTER_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_ENTRY_FORMAT_ATTR "=*))" + +/* The data we ask the map cache to keep, for us, for each map. */ +struct backend_map_data { + struct plugin_state *state; + char *group, *container, **bases, *entry_filter, *entry_format; + char **ref_attrs; + struct format_inref_attr **inref_attrs; +}; + +/* Read the name of the NIS master. A dummy function for the schema + * compatibility plugin. */ +void +backend_free_master_name(struct plugin_state *state, char *master) +{ +} + +int +backend_read_master_name(struct plugin_state *state, char **master) +{ + *master = "localhost"; + return -1; +} + +/* Manipulate string lists. */ +static void +backend_free_strlist(char **strlist) +{ + if (strlist) { + free(strlist); + } +} +static char ** +backend_dup_strlist_n(char **strlist, int n) +{ + int i, l; + char **ret, *s; + /* Handle the NULL case. */ + if (strlist == NULL) { + return NULL; + } + /* No strings = no list. */ + if (n == 0) { + return NULL; + } + /* Count the amount of space needed for the strings. */ + for (i = 0, l = 0; i < n; i++) { + l += (strlen(strlist[i]) + 1); + } + /* Allocate space for the array of pointers (with NULL terminator) and + * then the string data. */ + ret = malloc(((n + 1) * sizeof(char *)) + l); + if (ret != NULL) { + /* Figure out where the string data will start. */ + s = (char *) ret; + s += ((n + 1) * sizeof(char *)); + for (i = 0; i < n; i++) { + /* Set the address of this string, copy the data + * around, and then prepare the address of the next + * string. */ + ret[i] = s; + strcpy(s, strlist[i]); + s += (strlen(strlist[i]) + 1); + } + /* NULL-terminate the array. */ + ret[i] = NULL; + } + return ret; +} +static char ** +backend_dup_strlist(char **strlist) +{ + int i; + for (i = 0; (strlist != NULL) && (strlist[i] != NULL); i++) { + continue; + } + return backend_dup_strlist_n(strlist, i); +} + +/* Manipulate a backend map configuration. */ +static void +backend_free_map_data_contents(void *data) +{ + struct backend_map_data *map_data = data; + if (map_data != NULL) { + free(map_data->group); + free(map_data->container); + free(map_data->bases); + format_free_attr_list(map_data->ref_attrs); + format_free_inref_attrs(map_data->inref_attrs); + free(map_data->entry_filter); + free(map_data->entry_format); + } +} +static void +backend_free_map_data(void *data) +{ + backend_free_map_data_contents(data); + free(data); +} +static struct backend_map_data * +backend_copy_map_data(const struct backend_map_data *data) +{ + struct backend_map_data *ret; + ret = malloc(sizeof(*ret)); + if (ret == NULL) { + return NULL; + } + ret->state = data->state; + ret->group = strdup(data->group); + ret->container = strdup(data->container); + ret->bases = backend_dup_strlist(data->bases); + ret->ref_attrs = data->ref_attrs ? + format_dup_attr_list(data->ref_attrs) : + NULL; + ret->inref_attrs = data->inref_attrs ? + format_dup_inref_attrs(data->inref_attrs) : + NULL; + ret->entry_filter = strdup(data->entry_filter); + ret->entry_format = strdup(data->entry_format); + if ((ret->group == NULL) || + (ret->container == NULL) || + (ret->bases == NULL) || + (ret->entry_filter == NULL) || + (ret->entry_format == NULL)) { + backend_free_map_data(ret); + return NULL; + } + return ret; +} + +/* Given a map-entry directory entry, determine a key, a value, and extra data + * to be stored in the map cache, and add them to the map cache. */ +static int +backend_map_config_entry_add_one_cb(Slapi_Entry *e, void *callback_data) +{ + struct backend_map_data *data; + char *ldif, *ndn, *plugin_id, *ndns[2]; + int i, j, k, n_key_sets; + data = callback_data; + plugin_id = data->state->plugin_desc->spd_id; + /* Pull out the NDN of this entry. */ + ndn = slapi_entry_get_ndn(e); + ndns[0] = ndn; + ndns[1] = NULL; + /* Pull out the keys and value for the entry. */ + ldif = format_get_data(data->state, e, data->group, data->container, + data->entry_format, NULL, + &data->ref_attrs, &data->inref_attrs); + /* If we actually generated a new entry for this entry, then set it, + * otherwise clear it in case there was one set before. */ + if (ldif == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, + "setting group/container/key/value " + "\"%s\"/\"%s\"/\"%s\"(\"%s\")=\"%s\"\n", + data->group, data->container, ndn, ndn, ldif); + map_data_set_entry(data->state, data->group, data->container, + ndn, NULL, ndns, -1, ldif, NULL, NULL); + } else { + slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, + "no value for %s, unsetting domain/map/id" + "\"%s\"/\"%s\"/(\"%s\")\n", + ndn, data->group, data->container, ndn); + map_data_unset_entry_id(data->state, + data->group, data->container, + ndn); + } + format_free_data(ldif); + return 0; +} + +static int +backend_map_config_entry_set_one_cb(Slapi_Entry *e, void *cbdata) +{ + backend_map_config_entry_add_one_cb(e, cbdata); + return 0; +} + +static void +backend_map_config_entry_set_one(Slapi_Entry *e, + struct backend_map_data *map_data) +{ + backend_map_config_entry_set_one_cb(e, map_data); +} + +static void +backend_map_config_entry_set_one_dn(struct plugin_state *state, const char *dn, + struct backend_map_data *map_data) +{ + Slapi_DN *sdn; + Slapi_Entry *entry; + sdn = slapi_sdn_new_dn_byval(dn); + if (sdn == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error parsing DN \"%s\"\n", dn); + return; + } else { + entry = NULL; + slapi_search_internal_get_entry(sdn, NULL, &entry, + state->plugin_identity); + if (entry == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "failure reading entry \"%s\"\n", dn); + } else { + backend_map_config_entry_set_one(entry, map_data); + slapi_entry_free(entry); + } + slapi_sdn_free(&sdn); + } +} + +/* Given an entry, read the map configuration for the given group and container + * name. */ +static void +backend_map_config_read_config(struct plugin_state *state, Slapi_Entry *e, + const char *group, const char *container, + struct backend_map_data *ret) +{ + char **bases, *entry_filter, *entry_format; + char **entrykey_formats, **keys_formats, *value_format, *actual_attr; + char *disallowed_chars; + char **use_bases, *use_entry_filter; + char **use_key_formats, **use_keys_formats; + char *use_value_format, *use_disallowed_chars; + const char *cvalue; + int i, j, disposition, buffer_flags, count; + Slapi_ValueSet *values; + Slapi_Value *value; + /* Read the values from the configuration entry. */ + bases = NULL; + if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_BASE_ATTR, + &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + count = slapi_valueset_count(values); + bases = malloc(sizeof(char *) * (count + 1)); + if (bases != NULL) { + i = 0; + for (j = slapi_valueset_first_value(values, &value); + j != -1; + j = slapi_valueset_next_value(values, j, &value)) { + cvalue = slapi_value_get_string(value); + bases[i++] = strdup(cvalue); + } + bases[i] = NULL; + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + entry_filter = NULL; + if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_FILTER_ATTR, + &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + i = slapi_valueset_first_value(values, &value); + if (i != -1) { + cvalue = slapi_value_get_string(value); + if (strlen(cvalue) > 1) { + if ((cvalue[0] != '(') || + (cvalue[strlen(cvalue) - 1] != ')')) { + entry_filter = malloc(strlen(cvalue) + + 3); + if (entry_filter != NULL) { + sprintf(entry_filter, "(%s)", + cvalue); + } + } + } + if (entry_filter == NULL) { + entry_filter = strdup(cvalue); + } + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + entry_format = NULL; + if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_ENTRY_FORMAT_ATTR, + &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + i = slapi_valueset_first_value(values, &value); + if (i != -1) { + cvalue = slapi_value_get_string(value); + entry_format = strdup(cvalue); + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + /* Populate the returned structure. */ + ret->state = state; + ret->group = strdup(group); + ret->container = strdup(container); + ret->bases = backend_dup_strlist(bases); + if (bases != NULL) { + for (i = 0; bases[i] != NULL; i++) { + free(bases[i]); + } + free(bases); + } + ret->entry_filter = entry_filter; + ret->entry_format = entry_format; + ret->ref_attrs = NULL; + ret->inref_attrs = NULL; +} + +/* Given a directory server entry which represents a container's configuration, + * set up and populate the container. */ +static int +backend_map_config_entry_add_one(struct plugin_state *state, Slapi_Entry *e, + const char *group, const char *container) +{ + Slapi_PBlock *pb; + int i; + struct backend_map_data cb_data, *map_cb_data; + + pb = slapi_pblock_new(); + backend_map_config_read_config(state, e, group, container, &cb_data); + map_cb_data = backend_copy_map_data(&cb_data); + backend_free_map_data_contents(&cb_data); + if (map_cb_data == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "incomplete container definition %s in %s " + "(2)\n", container, group); + slapi_pblock_destroy(pb); + return 0; + } + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "initializing container %s in %s (2)\n", + group, container); + map_data_set_map(state, group, container, FALSE, + map_cb_data, &backend_free_map_data); + map_data_clear_map(state, group, container); + /* Search under each base in turn, adding the matching directory + * entries to the containers. */ + for (i = 0; + (map_cb_data->bases != NULL) && (map_cb_data->bases[i] != NULL); + i++) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "searching '%s' for '%s'\n", + map_cb_data->bases[i], + map_cb_data->entry_filter); + slapi_search_internal_set_pb(pb, + map_cb_data->bases[i], + LDAP_SCOPE_SUB, + map_cb_data->entry_filter, + NULL, FALSE, + NULL, + NULL, + state->plugin_identity, + 0); + slapi_search_internal_callback_pb(pb, map_cb_data, + NULL, + backend_map_config_entry_add_one_cb, + NULL); + slapi_free_search_results_internal(pb); + } + /* Clean up. */ + slapi_pblock_destroy(pb); + return 0; +} + +/* Process a map configuration directory entry. Pull out the group and + * container names which are valid for this configuration and configure such a + * container for each in turn. */ +static int +backend_map_config_entry_add_cb(Slapi_Entry *e, void *callback_data) +{ + char **groups, **containers, *actual_attr; + const char *cvalue; + Slapi_ValueSet *values; + Slapi_Value *value; + int i, j, ret, disposition, buffer_flags, count; + struct plugin_state *state; + + state = callback_data; + groups = NULL; + if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_GROUP_ATTR, + &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + count = slapi_valueset_count(values); + groups = malloc(sizeof(char *) * (count + 1)); + if (groups != NULL) { + for (i = slapi_valueset_first_value(values, &value); + i != -1; + i = slapi_valueset_next_value(values, i, &value)) { + cvalue = slapi_value_get_string(value); + groups[i] = strdup(cvalue); + } + groups[count] = NULL; + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + containers = NULL; + if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR, + &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + count = slapi_valueset_count(values); + containers = malloc(sizeof(char *) * (count + 1)); + if (containers != NULL) { + for (i = slapi_valueset_first_value(values, &value); + i != -1; + i = slapi_valueset_next_value(values, i, &value)) { + cvalue = slapi_value_get_string(value); + containers[i] = strdup(cvalue); + } + containers[count] = NULL; + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + for (i = 0; (groups != NULL) && (groups[i] != NULL); i++) { + for (j = 0; + (containers != NULL) && (containers[j] != NULL); + j++) { + ret = backend_map_config_entry_add_one(state, e, + groups[i], + containers[j]); + } + } + if (groups != NULL) { + for (i = 0; (groups != NULL) && (groups[i] != NULL); i++) { + free(groups[i]); + } + free(groups); + } + if (containers != NULL) { + for (i = 0; + (containers != NULL) && (containers[i] != NULL); + i++) { + free(containers[i]); + } + free(containers); + } + return 0; +} + +/* Scan for the list of configured groups and containers. */ +void +backend_startup(struct plugin_state *state) +{ + Slapi_PBlock *pb; + + pb = slapi_pblock_new(); + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "searching \"%s\" for containers\n", + state->plugin_base); + slapi_search_internal_set_pb(pb, + state->plugin_base, + LDAP_SCOPE_ONE, + SCH_CONTAINER_CONFIGURATION_FILTER, + NULL, FALSE, + NULL, + NULL, + state->plugin_identity, + 0); + map_wrlock(); + slapi_search_internal_callback_pb(pb, state, + NULL, + backend_map_config_entry_add_cb, + NULL); + map_unlock(); + slapi_free_search_results_internal(pb); + slapi_pblock_destroy(pb); +} + +/* Process a map configuration directory entry. Pull out the domain and map + * names which are specified in the entry and delete each in turn. */ +static int +backend_map_config_entry_delete_cb(Slapi_Entry *e, void *callback_data) +{ + char **groups, **containers; + int i, j; + struct plugin_state *state; + + state = callback_data; + groups = slapi_entry_attr_get_charray(e, + SCH_CONTAINER_CONFIGURATION_GROUP_ATTR); + containers = slapi_entry_attr_get_charray(e, + SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR); + for (i = 0; (groups != NULL) && (groups[i] != NULL); i++) { + for (j = 0; + (containers != NULL) && (containers[j] != NULL); + j++) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "removing container %s in %s\n", + containers[j], groups[i]); + map_data_unset_map(state, groups[i], containers[j]); + } + } + slapi_ch_array_free(containers); + slapi_ch_array_free(groups); + return 0; +} + +/* Functions for passing information about a container's configuration to a + * caller. */ +struct backend_get_map_config_cb { + struct plugin_state *state; + char **bases; + char *entry_filter; +}; + +void +backend_free_map_config(char **bases, char *entry_filter) +{ + backend_free_strlist(bases); + free(entry_filter); +} + +static bool_t +backend_get_map_config_entry_cb(Slapi_Entry *e, void *callback_data) +{ + Slapi_ValueSet *values; + Slapi_Value *value; + struct backend_get_map_config_cb *cbdata; + char *actual_attr; + const char *cvalue; + int disposition, buffer_flags, i, count; + + cbdata = callback_data; + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "reading container configuration from \"%s\"\n", + slapi_entry_get_ndn(e)); + + values = NULL; + value = NULL; + if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_BASE_ATTR, + &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + count = slapi_valueset_count(values); + cbdata->bases = malloc(sizeof(char *) * (count + 1)); + if (cbdata->bases != NULL) { + for (i = slapi_valueset_first_value(values, &value); + i != -1; + i = slapi_valueset_next_value(values, i, &value)) { + cvalue = slapi_value_get_string(value); + cbdata->bases[i] = strdup(cvalue); + } + cbdata->bases[count] = NULL; + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_FILTER_ATTR, + &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + if (slapi_valueset_first_value(values, &value) != -1) { + cvalue = slapi_value_get_string(value); + if (cvalue != NULL) { + free(cbdata->entry_filter); + cbdata->entry_filter = strdup(cvalue); + } + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + + return TRUE; +} + +void +backend_get_map_config(struct plugin_state *state, + const char *group, const char *container, + char ***bases, char **entry_filter) +{ + Slapi_PBlock *pb; + char *filter; + char *attrs[] = {SCH_CONTAINER_CONFIGURATION_FILTER_ATTR, + SCH_CONTAINER_CONFIGURATION_BASE_ATTR, + NULL}; + const char *default_filter; + struct backend_get_map_config_cb cbdata; + + /* Build the search filter. */ + filter = malloc(strlen("(&(" + SCH_CONTAINER_CONFIGURATION_GROUP_ATTR "=)(" + SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR "=)" + "()") + + strlen(group) + strlen(container) + + strlen(SCH_CONTAINER_CONFIGURATION_FILTER) + 1); + if (filter == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "out of memory reading configuration for " + "\"%s\"/\"%s\"!\n", group, container); + return; + } + sprintf(filter, "(&(" + SCH_CONTAINER_CONFIGURATION_GROUP_ATTR "=%s)(" + SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR "=%s)(%s)", + group, container, SCH_CONTAINER_CONFIGURATION_FILTER); + + /* Perform the search. */ + pb = slapi_pblock_new(); + slapi_search_internal_set_pb(pb, + state->plugin_base, + LDAP_SCOPE_SUB, + filter, + attrs, FALSE, + NULL, + NULL, + state->plugin_identity, + 0); + cbdata.bases = NULL; + cbdata.state = state; + cbdata.entry_filter = NULL; + slapi_search_internal_callback_pb(pb, &cbdata, + NULL, + backend_get_map_config_entry_cb, + NULL); + + /* Return the results. */ + *bases = cbdata.bases; + *entry_filter = cbdata.entry_filter; + + /* Clean up. */ + slapi_pblock_destroy(pb); +} + +/* Our postoperation callbacks. */ + +/* Given a map configuration, return true if an entry corresponding to the + * entry is supposed to be in the container. */ +static bool_t +backend_entry_matches_map(struct backend_map_data *map_data, + Slapi_PBlock *pb, Slapi_Entry *e) +{ + Slapi_DN *base_sdn; + const Slapi_DN *entry_sdn; + Slapi_Filter *filter; + int i; + /* Decide if the directory server entry belongs in this map. That + * means that it must be contained by one of the bases of the map. */ + entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); + if (entry_sdn == NULL) { + return FALSE; + } else { + /* Check each base in turn. */ + for (i = 0; + (map_data->bases != NULL) && (map_data->bases[i] != NULL); + i++) { + base_sdn = slapi_sdn_new_dn_byval(map_data->bases[i]); + if (base_sdn == NULL) { + return FALSE; + } else { + if (slapi_sdn_scope_test(entry_sdn, + base_sdn, + LDAP_SCOPE_SUB) == 0) { + /* The entry is not contained by the + * base -- go on to try the next one. */ + slapi_sdn_free(&base_sdn); + continue; + } + /* The entry is contained by the base. */ + slapi_sdn_free(&base_sdn); + break; + } + } + /* If we ran out of bases to check, it doesn't match. */ + if ((map_data->bases == NULL) || (map_data->bases[i] == NULL)) { + return FALSE; + } + } + /* If it's contained by a search base, compare it to the filter. */ + filter = slapi_str2filter(map_data->entry_filter); + if (filter == NULL) { + return FALSE; + } else { + if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { + /* Didn't match -- return. */ + slapi_filter_free(filter, 1); + return FALSE; + } + slapi_filter_free(filter, 1); + } + return TRUE; +} + +/* Given an entry, return true if it describes a compatibility container. */ +static bool_t +backend_entry_is_a_map(struct plugin_state *state, + Slapi_PBlock *pb, Slapi_Entry *e) +{ + Slapi_DN *entry_sdn, *plugin_sdn; + Slapi_Filter *filter; + bool_t ret; + char configuration_filter[] = SCH_CONTAINER_CONFIGURATION_FILTER; + + /* First, just do the scope test. */ + entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); + if (entry_sdn == NULL) { + return FALSE; + } else { + plugin_sdn = slapi_sdn_new_dn_byval(state->plugin_base); + if (plugin_sdn == NULL) { + slapi_sdn_free(&entry_sdn); + return FALSE; + } + } + if (slapi_sdn_scope_test(entry_sdn, + plugin_sdn, + LDAP_SCOPE_ONE) == 0) { + /* Didn't match. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "entry \"%s\" is not a child of \"%s\"\n", + slapi_sdn_get_ndn(entry_sdn), + slapi_sdn_get_ndn(plugin_sdn)); + ret = FALSE; + } else { + ret = TRUE; + } + slapi_sdn_free(&plugin_sdn); + slapi_sdn_free(&entry_sdn); + /* If it's actually part of our configuration tree, check if it's a + * valid entry. */ + if (ret) { + filter = slapi_str2filter(configuration_filter); + if (filter != NULL) { + if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { + /* Didn't match. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "entry \"%s\" doesn't look " + "like a container " + "configuration " + "(didn't match filter " + "\"%s\")\n", + slapi_sdn_get_ndn(entry_sdn), + configuration_filter); + ret = FALSE; + } + slapi_filter_free(filter, 1); + } + } + return ret; +} + +/* Update any entries to which the passed-in entry in the passed-in map refers + * to, if the referred-to entry is in this map. Everybody got that? */ +struct backend_update_references_cbdata { + Slapi_PBlock *pb; + Slapi_Entry *e; +}; + +static bool_t +backend_update_references_cb(const char *domain, const char *map, bool_t secure, + void *backend_data, void *cbdata_ptr) +{ + struct plugin_state *state; + struct backend_map_data *map_data; + struct backend_update_references_cbdata *cbdata; + Slapi_DN *referred_to_sdn; + Slapi_ValueSet *values; + Slapi_Value *value; + char **ref_attrs, *actual_attr, *filter, *tndn; + struct format_inref_attr **inref_attrs; + const char *ndn, *dn; + int i, j, disposition, buffer_flags, filter_size, n_ref_attrs; + + map_data = backend_data; + cbdata = cbdata_ptr; + state = map_data->state; + + /* For every entry in this map which refers to this entry using + * a DN stored in an attribute, update that entry. */ + + /* Build a filter with all of these attributes and this entry's DN. */ + ref_attrs = map_data->ref_attrs; + for (i = 0; (ref_attrs != NULL) && (ref_attrs[i] != NULL); i++) { + continue; + } + n_ref_attrs = i; + if (n_ref_attrs > 0) { + filter_size = strlen("(&(|))") + + strlen(map_data->entry_filter) + + 1; + ndn = slapi_entry_get_ndn(cbdata->e); + tndn = format_escape_for_filter(ndn); + if (tndn == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error building filter for " + "updating entries\n"); + return TRUE; + } + for (i = 0; + (ref_attrs != NULL) && (ref_attrs[i] != NULL); + i++) { + filter_size += (strlen("(=)") + + strlen(ref_attrs[i]) + + strlen(ndn)); + } + filter = malloc(filter_size); + if (filter == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error building filter for " + "updating entries\n"); + free(tndn); + return TRUE; + } + sprintf(filter, "(&%s(|", map_data->entry_filter); + for (i = 0; + (ref_attrs != NULL) && (ref_attrs[i] != NULL); + i++) { + sprintf(filter + strlen(filter), + "(%s=%s)", ref_attrs[i], tndn); + } + strcat(filter, "))"); + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "searching for referrers using filter \"%s\"\n", + filter); + free(tndn); + /* Update any matching entry. */ + for (i = 0; + (map_data->bases != NULL) && (map_data->bases[i] != NULL); + i++) { + slapi_search_internal_set_pb(cbdata->pb, + map_data->bases[i], + LDAP_SCOPE_SUB, + filter, + NULL, FALSE, + NULL, + NULL, + state->plugin_identity, + 0); + slapi_search_internal_callback_pb(cbdata->pb, map_data, + NULL, + backend_map_config_entry_set_one_cb, + NULL); + } + free(filter); + } + + /* Allocate the DN we'll use to hold values for comparison. */ + referred_to_sdn = slapi_sdn_new(); + if (referred_to_sdn == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error updating entries referred to by %s\n", + slapi_entry_get_ndn(cbdata->e)); + return TRUE; + } + + /* For every directory entry to which this directory entry refers and + * which also has a corresponding entry in this map, update it. */ + inref_attrs = map_data->inref_attrs; + for (i = 0; (inref_attrs != NULL) && (inref_attrs[i] != NULL); i++) { + /* We're only processing inref attributes for this map. */ + if ((strcmp(inref_attrs[i]->domain, domain) != 0) || + (strcmp(inref_attrs[i]->map, map) != 0)) { + continue; + } + /* Extract the named attribute from the entry. */ + values = NULL; + if (slapi_vattr_values_get(cbdata->e, + inref_attrs[i]->attribute, + &values, &disposition, &actual_attr, + 0, &buffer_flags) != 0) { + continue; + } + /* For each value of this attributes.. */ + for (j = slapi_valueset_first_value(values, &value); + j != -1; + j = slapi_valueset_next_value(values, j, &value)) { + /* Pull out the value, which is a referred-to entry's + * DN. */ + dn = slapi_value_get_string(value); + if (dn == NULL) { + continue; + } + /* Normalize the DN. */ + slapi_sdn_set_dn_byref(referred_to_sdn, dn); + ndn = slapi_sdn_get_ndn(referred_to_sdn); + /* If the named entry corresponds to an entry that's + * already in this map. */ + if (map_data_check_entry(state, domain, map, ndn)) { + /* ...update it. */ + backend_map_config_entry_set_one_dn(state, ndn, + map_data); + } + } + slapi_vattr_values_free(&values, &actual_attr, + buffer_flags); + } + slapi_sdn_free(&referred_to_sdn); + return TRUE; +} + +static void +backend_update_references(struct plugin_state *state, Slapi_Entry *e) +{ + struct backend_update_references_cbdata cbdata; + cbdata.e = e; + cbdata.pb = slapi_pblock_new(); + if (!map_data_foreach_map(state, NULL, + backend_update_references_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error updating references for \"%s\"\n", + slapi_entry_get_ndn(cbdata.e)); + } + slapi_pblock_destroy(cbdata.pb); +} + +/* Add any map entries which correspond to a directory server entry in this + * map. */ + +struct backend_add_entry_cbdata { + struct plugin_state *state; + Slapi_PBlock *pb; + Slapi_Entry *e; + char *ndn; +}; + +static bool_t +backend_add_entry_cb(const char *domain, const char *map, bool_t secure, + void *backend_data, void *cbdata_ptr) +{ + struct backend_map_data *map_data; + struct backend_add_entry_cbdata *cbdata; + + map_data = backend_data; + cbdata = cbdata_ptr; + + /* If the entry doesn't match the map, skip it. */ + if (!backend_entry_matches_map(map_data, cbdata->pb, cbdata->e)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "entry \"%s\" does not belong in " + "\"%s\"/\"%s\"\n", + cbdata->ndn, domain, map); + return TRUE; + } + + /* Set the entry in the map which corresponds to this entry, or clear + * any that might if this entry doesn't have a key and value. */ + backend_map_config_entry_set_one(cbdata->e, map_data); + + return TRUE; +} + +static int +backend_add_cb(Slapi_PBlock *pb) +{ + struct backend_add_entry_cbdata cbdata; + + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_ADD_TARGET, &cbdata.ndn); + slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e); + cbdata.pb = pb; + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "added \"%s\"\n", cbdata.ndn); + + /* Check for NULL entries, indicative of a failure elsewhere (?). */ + if (cbdata.e == NULL) { + slapi_pblock_get(pb, SLAPI_ADD_EXISTING_DN_ENTRY, &cbdata.e); + if (cbdata.e == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "added entry is NULL\n"); + return 0; + } + } + + /* Add map entries which corresponded to this directory server + * entry. */ + map_wrlock(); + if (!map_data_foreach_map(cbdata.state, NULL, + backend_add_entry_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "error adding map entries corresponding to " + "\"%s\"\n", cbdata.ndn); + } + + /* If it's a map configuration entry, add and populate the maps it + * describes. */ + if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "new entry \"%s\" is a map\n", cbdata.ndn); + backend_map_config_entry_add_cb(cbdata.e, cbdata.state); + } + + /* Update entries which need to be updated in case this new entry + * refers to them. */ + backend_update_references(cbdata.state, cbdata.e); + + map_unlock(); + return 0; +} + +struct backend_modify_entry_cbdata { + struct plugin_state *state; + Slapi_PBlock *pb; + LDAPMod **mods; + Slapi_Entry *e_pre, *e_post; + char *ndn; +}; + +static bool_t +backend_modify_entry_cb(const char *domain, const char *map, bool_t secure, + void *backend_data, void *cbdata_ptr) +{ + struct backend_map_data *map_data; + struct backend_modify_entry_cbdata *cbdata; + + map_data = backend_data; + cbdata = cbdata_ptr; + + /* If the entry used to match the map, remove it. */ + if (backend_entry_matches_map(map_data, cbdata->pb, cbdata->e_pre)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "clearing group/container/id " + "\"%s\"/\"%s\"/(\"%s\")\n", + map_data->group, map_data->container, + cbdata->ndn); + map_data_unset_entry_id(cbdata->state, + map_data->group, map_data->container, + cbdata->ndn); + } + /* If the entry now matches the map, add it (or re-add it). */ + if (backend_entry_matches_map(map_data, cbdata->pb, cbdata->e_post)) { + /* Set the entry in the map which corresponds to this entry, or + * clear any that might if this entry doesn't have a key and + * value. */ + backend_map_config_entry_set_one(cbdata->e_post, map_data); + } + return TRUE; +} + +static int +backend_modify_cb(Slapi_PBlock *pb) +{ + Slapi_DN *sdn; + struct backend_modify_entry_cbdata cbdata; + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_MODIFY_TARGET, &cbdata.ndn); + slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &cbdata.mods); + slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); + slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); + cbdata.pb = pb; + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "modified \"%s\"\n", cbdata.ndn); + /* Check for NULL entries, indicative of a failure elsewhere (?). */ + if (cbdata.e_pre == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "pre-modify entry is NULL\n"); + return 0; + } + if (cbdata.e_post == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "post-modify entry is NULL\n"); + return 0; + } + /* Modify map entries which corresponded to this directory server + * entry. */ + map_wrlock(); + if (!map_data_foreach_map(cbdata.state, NULL, + backend_modify_entry_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "error modifying map entries corresponding to " + "\"%s\"\n", cbdata.ndn); + } + /* Update entries which need to be updated in case this entry + * no longer refers to them. */ + backend_update_references(cbdata.state, cbdata.e_pre); + /* Update entries which need to be updated in case this entry + * now refers to them. */ + backend_update_references(cbdata.state, cbdata.e_post); + /* If it's a map configuration entry, reconfigure, clear, and + * repopulate the map. */ + if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_pre)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "modified entry \"%s\" was a map\n", + cbdata.ndn); + backend_map_config_entry_delete_cb(cbdata.e_pre, cbdata.state); + } + if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_post)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "modified entry \"%s\" is now a map\n", + cbdata.ndn); + backend_map_config_entry_add_cb(cbdata.e_post, cbdata.state); + } + map_unlock(); + return 0; +} + +struct backend_modrdn_entry_cbdata { + struct plugin_state *state; + Slapi_PBlock *pb; + Slapi_Entry *e_pre, *e_post; + char *ndn_pre, *ndn_post; +}; + +static bool_t +backend_modrdn_entry_cb(const char *domain, const char *map, bool_t secure, + void *backend_data, void *cbdata_ptr) +{ + struct backend_map_data *map_data; + struct backend_modrdn_entry_cbdata *cbdata; + bool_t matched_pre, matched_post; + + map_data = backend_data; + cbdata = cbdata_ptr; + + matched_pre = backend_entry_matches_map(map_data, + cbdata->pb, cbdata->e_pre); + matched_post = backend_entry_matches_map(map_data, + cbdata->pb, cbdata->e_post); + + /* Now decide what to set, or unset, in this map. */ + if (matched_pre) { + /* If it was a match for the map, clear the entry. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "clearing group/container/id " + "\"%s\"/\"%s\"/(\"%s\")\n", + map_data->group, map_data->container, + cbdata->ndn_pre); + map_data_unset_entry_id(cbdata->state, + map_data->group, map_data->container, + cbdata->ndn_pre); + } + /* Set the entry in the map which corresponds to this entry, or clear + * any that might if this entry doesn't have a key and value. */ + if (matched_post) { + backend_map_config_entry_set_one(cbdata->e_post, map_data); + } + return TRUE; +} + +static int +backend_modrdn_cb(Slapi_PBlock *pb) +{ + struct backend_modrdn_entry_cbdata cbdata; + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); + slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); + cbdata.ndn_pre = slapi_entry_get_ndn(cbdata.e_pre); + cbdata.ndn_post = slapi_entry_get_ndn(cbdata.e_post); + cbdata.pb = pb; + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "renamed \"%s\" to \"%s\"\n", + cbdata.ndn_pre, cbdata.ndn_post); + /* Check for NULL entries, indicative of a failure elsewhere (?). */ + if (cbdata.e_pre == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "pre-modrdn entry is NULL\n"); + return 0; + } + if (cbdata.e_post == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "post-modrdn entry is NULL\n"); + return 0; + } + /* Modify map entries which corresponded to this directory server + * entry. */ + map_wrlock(); + if (!map_data_foreach_map(cbdata.state, NULL, + backend_modrdn_entry_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "error renaming map entries corresponding to " + "\"%s\"\n", cbdata.ndn_post); + } + /* If it's a map configuration entry, reconfigure, clear, and + * repopulate the map. */ + if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_pre)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "renamed entry \"%s\" was a map\n", + cbdata.e_pre); + backend_map_config_entry_delete_cb(cbdata.e_pre, cbdata.state); + } + if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_post)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "renamed entry \"%s\" is now a map\n", + cbdata.e_post); + backend_map_config_entry_add_cb(cbdata.e_post, cbdata.state); + } + map_unlock(); + return 0; +} + +/* Delete any map entries which correspond to a directory server entry in this + * map. */ + +struct backend_delete_entry_cbdata { + struct plugin_state *state; + Slapi_PBlock *pb; + Slapi_Entry *e; + char *ndn; +}; + +static bool_t +backend_delete_entry_cb(const char *group, const char *container, bool_t secure, + void *backend_data, void *cbdata_ptr) +{ + struct backend_map_data *map_data; + struct backend_delete_entry_cbdata *cbdata; + map_data = backend_data; + cbdata = cbdata_ptr; + /* If it was in the map, remove it. */ + if (backend_entry_matches_map(map_data, cbdata->pb, cbdata->e)) { + /* Remove this entry from the map. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "unsetting group/container/id" + "\"%s\"/\"%s\"=\"%s\"/\"%s\"/(\"%s\")\n", + group, container, + map_data->group, map_data->container, + cbdata->ndn); + map_data_unset_entry_id(cbdata->state, group, container, + cbdata->ndn); + } + return TRUE; +} + +/* Called by the server when a directory server entry is deleted. */ +static int +backend_delete_cb(Slapi_PBlock *pb) +{ + struct backend_delete_entry_cbdata cbdata; + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_DELETE_TARGET, &cbdata.ndn); + slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e); + cbdata.pb = pb; + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "deleted \"%s\"\n", cbdata.ndn); + /* Check for NULL entries, indicative of a failure elsewhere (?). */ + if (cbdata.e == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "deleted entry is NULL\n"); + return 0; + } + /* Remove map entries which corresponded to this directory server + * entry. */ + map_wrlock(); + if (!map_data_foreach_map(cbdata.state, NULL, + backend_delete_entry_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "error removing map entries corresponding to " + "\"%s\"\n", cbdata.ndn); + } + /* If it's a map configuration entry, remove the map. */ + if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "deleted entry \"%s\" is a map\n", cbdata.ndn); + backend_map_config_entry_delete_cb(cbdata.e, cbdata.state); + } + /* Update entries which need to be updated in case this entry no longer + * refers to them. */ + backend_update_references(cbdata.state, cbdata.e); + map_unlock(); + return 0; +} + +/* Set our post-op callbacks. */ +void +backend_init(Slapi_PBlock *pb, struct plugin_state *state) +{ + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "hooking up postoperation callbacks\n"); + if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN, + backend_add_cb) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up add callback\n"); + } + if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN, + backend_modify_cb) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up modify callback\n"); + } + if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, + backend_modrdn_cb) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up modrdn callback\n"); + } + if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, + backend_delete_cb) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up delete callback\n"); + } +} diff --git a/src/back-sch.h b/src/back-sch.h new file mode 100644 index 0000000..a97fc18 --- /dev/null +++ b/src/back-sch.h @@ -0,0 +1,34 @@ +/* + * Copyright 2008 Red Hat, Inc. + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This Program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; if not, write to the + * + * Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111-1307 USA + * + */ + +#ifndef back_nis_h +#define back_nis_h +struct plugin_state; +struct slapi_pblock; +int backend_read_master_name(struct plugin_state *state, char **master); +void backend_free_master_name(struct plugin_state *state, char *master); +void backend_startup(struct plugin_state *state); +void backend_init(struct slapi_pblock *pb, struct plugin_state *state); +void backend_get_map_config(struct plugin_state *state, + const char *domain, const char *map, + char ***bases, char **entry_filter); +void backend_free_map_config(char **bases, char *entry_filter); +#endif diff --git a/src/back-shr.c b/src/back-shr.c new file mode 100644 index 0000000..84f6a3b --- /dev/null +++ b/src/back-shr.c @@ -0,0 +1,1143 @@ +/* + * Copyright 2008 Red Hat, Inc. + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This Program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; if not, write to the + * + * Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111-1307 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#include +#include +#include +#include + +#ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H +#include +#include +#include +#else +#include +#endif + +#include +#include + +#ifdef HAVE_TCPD_H +#include +#endif + +#include "backend.h" +#include "back-shr.h" +#include "format.h" +#include "plugin.h" +#include "map.h" + +/* Read the name of this server. Used by the map module on behalf of the + * NIS service logic. */ +void +backend_shr_free_server_name(struct plugin_state *state, char *master) +{ + free(master); +} +int +backend_shr_read_server_name(struct plugin_state *state, char **master) +{ + Slapi_DN *config_dn; + Slapi_Entry *config; + Slapi_ValueSet *values; + Slapi_Value *value; + char *attrs[] = {"nsslapd-localhost", NULL}, *actual_attr; + const char *cvalue; + int disposition, buffer_flags; + *master = NULL; + /* Try to read our name from the top-level configuration node. */ + config_dn = slapi_sdn_new_dn_byval("cn=config"); + if (config_dn == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "backend_master_name: " + "error parsing \"cn=config\"\n"); + return -1; + } + config = NULL; + slapi_search_internal_get_entry(config_dn, attrs, &config, + state->plugin_identity); + if (config == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "backend_master_name: failure reading entry " + "\"cn=config\"\n"); + slapi_sdn_free(&config_dn); + return -1; + } + slapi_sdn_free(&config_dn); + /* Pull out the attribute. */ + if (slapi_vattr_values_get(config, attrs[0], &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + if (slapi_valueset_first_value(values, &value) == 0) { + cvalue = slapi_value_get_string(value); + if (cvalue != NULL) { + *master = strdup(cvalue); + } + } else { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "backend_master_name: no \"%s\" value " + "for \"cn=config\"", + attrs[0]); + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + slapi_entry_free(config); + return (*master != NULL) ? 0 : -1; +} + +/* Manipulate string lists. */ +void +backend_shr_free_strlist(char **strlist) +{ + if (strlist) { + free(strlist); + } +} +char ** +backend_shr_dup_strlist_n(char **strlist, int n) +{ + int i, l; + char **ret, *s; + /* Handle the NULL case. */ + if (strlist == NULL) { + return NULL; + } + /* No strings = no list. */ + if (n == 0) { + return NULL; + } + /* Count the amount of space needed for the strings. */ + for (i = 0, l = 0; i < n; i++) { + l += (strlen(strlist[i]) + 1); + } + /* Allocate space for the array of pointers (with NULL terminator) and + * then the string data. */ + ret = malloc(((n + 1) * sizeof(char *)) + l); + if (ret != NULL) { + /* Figure out where the string data will start. */ + s = (char *) ret; + s += ((n + 1) * sizeof(char *)); + for (i = 0; i < n; i++) { + /* Set the address of this string, copy the data + * around, and then prepare the address of the next + * string. */ + ret[i] = s; + strcpy(s, strlist[i]); + s += (strlen(strlist[i]) + 1); + } + /* NULL-terminate the array. */ + ret[i] = NULL; + } + return ret; +} +char ** +backend_shr_dup_strlist(char **strlist) +{ + int i; + for (i = 0; (strlist != NULL) && (strlist[i] != NULL); i++) { + continue; + } + return backend_shr_dup_strlist_n(strlist, i); +} +void +backend_shr_add_strlist(char ***strlist, const char *value) +{ + int i, elements, length; + char **ret, *p; + + length = strlen(value) + 1; + elements = 0; + if (*strlist != NULL) { + for (i = 0; (*strlist)[i] != NULL; i++) { + if (strcmp(value, (*strlist)[i]) == 0) { + return; + } + length += (strlen((*strlist)[i]) + 1); + elements++; + } + } + + ret = malloc(((elements + 2) * sizeof(char *)) + length); + if (ret != NULL) { + p = (char *) ret; + p += (elements + 2) * sizeof(char *); + for (i = 0; i < elements; i++) { + ret[i] = p; + strcpy(p, (*strlist)[i]); + p += (strlen((*strlist)[i]) + 1); + } + ret[i++] = p; + strcpy(p, value); + p += (strlen(value) + 1); + ret[i] = NULL; + backend_shr_free_strlist(*strlist); + } + *strlist = ret; +} + +/* Set or unset the entry using information in the callback data. */ +void +backend_shr_set_entry_one(Slapi_Entry *e, struct backend_set_data *set_data) +{ + backend_set_entry_one(e, set_data); +} +int +backend_shr_set_entry_one_cb(Slapi_Entry *e, void *set_data) +{ + backend_shr_set_entry_one(e, set_data); + return 0; +} + +/* Set or unset the named entry using information in the callback data. */ +void +backend_shr_set_config_entry_set_one_dn(struct plugin_state *state, + const char *dn, + struct backend_set_data *set_data) +{ + Slapi_DN *sdn; + Slapi_Entry *entry; + sdn = slapi_sdn_new_dn_byval(dn); + if (sdn == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error parsing DN \"%s\"\n", dn); + return; + } else { + entry = NULL; + slapi_search_internal_get_entry(sdn, NULL, &entry, + state->plugin_identity); + if (entry == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "failure reading entry \"%s\"\n", dn); + } else { + backend_shr_set_entry_one(entry, set_data); + slapi_entry_free(entry); + } + slapi_sdn_free(&sdn); + } +} + +/* Given a directory server entry which represents a set's configuration, set + * up and populate the set. */ +static void +backend_shr_set_config_free_config(void *cb_data) +{ + struct backend_set_data *set_data; + set_data = cb_data; + backend_set_config_free_config(backend_set_config_get_state(set_data), + set_data); + +} +int +backend_shr_set_config_entry_add_one(struct plugin_state *state, Slapi_Entry *e, + const char *group, const char *set) +{ + Slapi_PBlock *pb; + int i; + bool_t flag; + struct backend_set_data *set_data; + char **set_bases; + char *set_entry_filter; + + pb = slapi_pblock_new(); + flag = FALSE; + backend_set_config_read_config(state, e, group, set, &flag, &set_data); + set_bases = backend_set_config_get_bases(set_data); + set_entry_filter = backend_set_config_get_filter(set_data); + if (set_data == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "incomplete definition for %s in %s (2)\n", + set, group); + slapi_pblock_destroy(pb); + return 0; + } + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "initializing %s in %s, %s (2)\n", + set, group, flag ? "yes" : "no"); + map_data_set_map(state, group, set, flag, + set_data, &backend_shr_set_config_free_config); + map_data_clear_map(state, group, set); + /* Search under each base in turn, adding the matching directory + * entries to the set. */ + for (i = 0; (set_bases != NULL) && (set_bases[i] != NULL); i++) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "searching '%s' for '%s'\n", + set_bases[i], set_entry_filter); + slapi_search_internal_set_pb(pb, + set_bases[i], + LDAP_SCOPE_SUB, + set_entry_filter, + NULL, FALSE, + NULL, + NULL, + state->plugin_identity, + 0); + slapi_search_internal_callback_pb(pb, set_data, + NULL, + backend_set_config_entry_add_cb, + NULL); + slapi_free_search_results_internal(pb); + } + /* Clean up. */ + slapi_pblock_destroy(pb); + return 0; +} + +/* Scan for the list of configured groups and sets. */ +void +backend_shr_startup(struct plugin_state *state, const char *filter) +{ + Slapi_PBlock *pb; + + pb = slapi_pblock_new(); + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "searching under \"%s\" for configuration\n", + state->plugin_base); + slapi_search_internal_set_pb(pb, + state->plugin_base, + LDAP_SCOPE_ONE, + filter, + NULL, FALSE, + NULL, + NULL, + state->plugin_identity, + 0); + map_wrlock(); + slapi_search_internal_callback_pb(pb, state, + NULL, + backend_set_config_entry_add_cb, + NULL); + map_unlock(); + slapi_free_search_results_internal(pb); + slapi_pblock_destroy(pb); +} + +/* Process a set configuration directory entry. Pull out the group and set + * names which are specified in the entry and delete each in turn. */ +static int +backend_shr_set_config_entry_delete_cb(Slapi_Entry *e, void *callback_data, + const char *group_attr, + const char *set_attr) +{ + char **groups, **sets; + int i, j; + struct plugin_state *state; + + state = callback_data; + groups = slapi_entry_attr_get_charray(e, group_attr); + sets = slapi_entry_attr_get_charray(e, set_attr); + for (i = 0; (groups != NULL) && (groups[i] != NULL); i++) { + for (j = 0; (sets != NULL) && (sets[j] != NULL); j++) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "removing set %s in %s\n", + sets[j], groups[i]); + map_data_unset_map(state, groups[i], sets[j]); + } + } + slapi_ch_array_free(sets); + slapi_ch_array_free(groups); + return 0; +} + +struct backend_get_map_config_cb { + struct plugin_state *state; + char **bases; + char *entry_filter; +}; + +/* Used by the format functions to read set configuration. */ +void +backend_shr_free_set_config(char **bases, char *entry_filter) +{ + backend_shr_free_strlist(bases); + free(entry_filter); +} + +static bool_t +backend_shr_get_set_config_entry_cb(Slapi_Entry *e, void *callback_data, + const char *base_attr, + const char *filter_attr) +{ + Slapi_ValueSet *values; + Slapi_Value *value; + struct backend_get_map_config_cb *cbdata; + char *actual_attr; + const char *cvalue; + int disposition, buffer_flags, i, count; + + cbdata = callback_data; + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "reading set configuration from \"%s\"\n", + slapi_entry_get_ndn(e)); + + values = NULL; + value = NULL; + if (slapi_vattr_values_get(e, (char *) base_attr, &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + count = slapi_valueset_count(values); + cbdata->bases = malloc(sizeof(char *) * (count + 1)); + if (cbdata->bases != NULL) { + for (i = slapi_valueset_first_value(values, &value); + i != -1; + i = slapi_valueset_next_value(values, i, &value)) { + cvalue = slapi_value_get_string(value); + cbdata->bases[i] = strdup(cvalue); + } + cbdata->bases[count] = NULL; + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + if (slapi_vattr_values_get(e, (char *) filter_attr, &values, + &disposition, &actual_attr, + 0, &buffer_flags) == 0) { + if (slapi_valueset_first_value(values, &value) != -1) { + cvalue = slapi_value_get_string(value); + if (cvalue != NULL) { + free(cbdata->entry_filter); + cbdata->entry_filter = strdup(cvalue); + } + } + slapi_vattr_values_free(&values, &actual_attr, buffer_flags); + } + + return TRUE; +} + +/* Our postoperation callbacks. */ + +/* Given a map configuration, return true if the entry is supposed to be in the + * map. */ +bool_t +backend_shr_entry_matches_set(struct backend_set_data *set_data, + Slapi_PBlock *pb, Slapi_Entry *e) +{ + Slapi_DN *base_sdn; + const Slapi_DN *entry_sdn; + Slapi_Filter *filter; + char **set_bases; + char *set_filter; + int i; + /* Decide if the directory server entry belongs in this map. That + * means that it must be contained by one of the bases of the map. */ + entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); + if (entry_sdn == NULL) { + return FALSE; + } else { + /* Check each base in turn. */ + set_bases = backend_set_config_get_bases(set_data); + for (i = 0; + (set_bases != NULL) && (set_bases[i] != NULL); + i++) { + base_sdn = slapi_sdn_new_dn_byval(set_bases[i]); + if (base_sdn == NULL) { + return FALSE; + } else { + if (slapi_sdn_scope_test(entry_sdn, + base_sdn, + LDAP_SCOPE_SUB) == 0) { + /* The entry is not contained by the + * base -- go on to try the next one. */ + slapi_sdn_free(&base_sdn); + continue; + } + /* The entry is contained by the base. */ + slapi_sdn_free(&base_sdn); + break; + } + } + /* If we ran out of bases to check, it doesn't match. */ + if ((set_bases == NULL) || (set_bases[i] == NULL)) { + return FALSE; + } + } + /* If it's contained by a search base, compare it to the filter. */ + set_filter = backend_set_config_get_filter(set_data); + filter = slapi_str2filter(set_filter); + if (filter == NULL) { + return FALSE; + } else { + if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { + /* Didn't match -- return. */ + slapi_filter_free(filter, 1); + return FALSE; + } + slapi_filter_free(filter, 1); + } + return TRUE; +} + +/* Given an entry, return true if it describes a set. */ +bool_t +backend_shr_entry_is_a_set(struct plugin_state *state, + Slapi_PBlock *pb, Slapi_Entry *e, + const char *set_configuration_filter) +{ + Slapi_DN *entry_sdn, *plugin_sdn; + Slapi_Filter *filter; + bool_t ret; + + /* First, just do the scope test. */ + entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); + if (entry_sdn == NULL) { + return FALSE; + } else { + plugin_sdn = slapi_sdn_new_dn_byval(state->plugin_base); + if (plugin_sdn == NULL) { + slapi_sdn_free(&entry_sdn); + return FALSE; + } + } + if (slapi_sdn_scope_test(entry_sdn, + plugin_sdn, + LDAP_SCOPE_ONE) == 0) { + /* Didn't match. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "entry \"%s\" is not a child of \"%s\"\n", + slapi_sdn_get_ndn(entry_sdn), + slapi_sdn_get_ndn(plugin_sdn)); + ret = FALSE; + } else { + ret = TRUE; + } + slapi_sdn_free(&plugin_sdn); + slapi_sdn_free(&entry_sdn); + /* If it's actually part of our configuration tree, check if it's a + * valid entry. */ + if (ret) { + filter = slapi_str2filter((char *) set_configuration_filter); + if (filter != NULL) { + if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { + /* Didn't match. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "entry \"%s\" doesn't look " + "like a map configuration " + "(didn't match filter " + "\"%s\")\n", + slapi_sdn_get_ndn(entry_sdn), + set_configuration_filter); + ret = FALSE; + } + slapi_filter_free(filter, 1); + } + } + return ret; +} + +/* Update any entries to which the passed-in entry in the passed-in map refers + * to, if the referred-to entry is in this map. Everybody got that? */ +struct backend_shr_update_references_cbdata { + Slapi_PBlock *pb; + Slapi_Entry *e; +}; + +bool_t +backend_shr_update_references_cb(const char *group, const char *set, + bool_t flag, + void *backend_data, void *cbdata_ptr) +{ + struct plugin_state *state; + struct backend_set_data *set_data; + struct backend_shr_update_references_cbdata *cbdata; + Slapi_DN *referred_to_sdn; + Slapi_ValueSet *values; + Slapi_Value *value; + char **ref_attrs, *actual_attr, *filter, *tndn, **set_bases; + struct format_inref_attr **inref_attrs; + const char *ndn, *dn; + int i, j, disposition, buffer_flags, filter_size, n_ref_attrs; + + set_data = backend_data; + cbdata = cbdata_ptr; + state = backend_set_config_get_state(set_data); + + /* For every entry in this set which refers to this entry using + * a DN stored in an attribute, update that entry. */ + + /* Build a filter with all of these attributes and this entry's DN. */ + ref_attrs = backend_set_config_get_ref_attrs(set_data); + for (i = 0; (ref_attrs != NULL) && (ref_attrs[i] != NULL); i++) { + continue; + } + n_ref_attrs = i; + if (n_ref_attrs > 0) { + filter_size = strlen("(&(|))") + + strlen(backend_set_config_get_filter(set_data)) + + 1; + ndn = slapi_entry_get_ndn(cbdata->e); + tndn = format_escape_for_filter(ndn); + if (tndn == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error building filter for " + "updating entries\n"); + return TRUE; + } + for (i = 0; + (ref_attrs != NULL) && (ref_attrs[i] != NULL); + i++) { + filter_size += (strlen("(=)") + + strlen(ref_attrs[i]) + + strlen(ndn)); + } + filter = malloc(filter_size); + if (filter == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error building filter for " + "updating entries\n"); + free(tndn); + return TRUE; + } + sprintf(filter, "(&%s(|", + backend_set_config_get_filter(set_data)); + for (i = 0; + (ref_attrs != NULL) && (ref_attrs[i] != NULL); + i++) { + sprintf(filter + strlen(filter), + "(%s=%s)", ref_attrs[i], tndn); + } + strcat(filter, "))"); + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "searching for referrers using filter \"%s\"\n", + filter); + free(tndn); + /* Update any matching entry. */ + set_bases = backend_set_config_get_bases(set_data); + for (i = 0; + (set_bases != NULL) && (set_bases[i] != NULL); + i++) { + slapi_search_internal_set_pb(cbdata->pb, + set_bases[i], + LDAP_SCOPE_SUB, + filter, + NULL, FALSE, + NULL, + NULL, + state->plugin_identity, + 0); + slapi_search_internal_callback_pb(cbdata->pb, set_data, + NULL, + backend_shr_set_entry_one_cb, + NULL); + } + free(filter); + } + + /* Allocate the DN we'll use to hold values for comparison. */ + referred_to_sdn = slapi_sdn_new(); + if (referred_to_sdn == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error updating entries referred to by %s\n", + slapi_entry_get_ndn(cbdata->e)); + return TRUE; + } + + /* For every directory entry to which this directory entry refers and + * which also has a corresponding entry in this map, update it. */ + inref_attrs = backend_set_config_get_inref_attrs(set_data); + for (i = 0; (inref_attrs != NULL) && (inref_attrs[i] != NULL); i++) { + /* We're only processing inref attributes for this map. */ + if ((strcmp(inref_attrs[i]->domain, group) != 0) || + (strcmp(inref_attrs[i]->map, set) != 0)) { + continue; + } + /* Extract the named attribute from the entry. */ + values = NULL; + if (slapi_vattr_values_get(cbdata->e, + inref_attrs[i]->attribute, + &values, &disposition, &actual_attr, + 0, &buffer_flags) != 0) { + continue; + } + /* For each value of this attributes.. */ + for (j = slapi_valueset_first_value(values, &value); + j != -1; + j = slapi_valueset_next_value(values, j, &value)) { + /* Pull out the value, which is a referred-to entry's + * DN. */ + dn = slapi_value_get_string(value); + if (dn == NULL) { + continue; + } + /* Normalize the DN. */ + slapi_sdn_set_dn_byref(referred_to_sdn, dn); + ndn = slapi_sdn_get_ndn(referred_to_sdn); + /* If the named entry corresponds to an entry that's + * already in this map. */ + if (map_data_check_entry(state, group, set, ndn)) { + /* ...update it. */ + backend_shr_set_config_entry_set_one_dn(state, + ndn, + set_data); + } + } + slapi_vattr_values_free(&values, &actual_attr, + buffer_flags); + } + slapi_sdn_free(&referred_to_sdn); + return TRUE; +} + +void +backend_shr_update_references(struct plugin_state *state, Slapi_Entry *e) +{ + struct backend_shr_update_references_cbdata cbdata; + cbdata.e = e; + cbdata.pb = slapi_pblock_new(); + if (!map_data_foreach_map(state, NULL, + backend_shr_update_references_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "error updating references for \"%s\"\n", + slapi_entry_get_ndn(cbdata.e)); + } + slapi_pblock_destroy(cbdata.pb); +} + +/* Add any map entries which correspond to a directory server entry in this + * map. */ + +struct backend_add_entry_cbdata { + struct plugin_state *state; + Slapi_PBlock *pb; + Slapi_Entry *e; + char *ndn; +}; + +static bool_t +backend_shr_add_entry_cb(const char *group, const char *set, bool_t secure, + void *backend_data, void *cbdata_ptr) +{ + struct backend_set_data *set_data; + struct backend_add_entry_cbdata *cbdata; + + set_data = backend_data; + cbdata = cbdata_ptr; + + /* If the entry doesn't match the set, skip it. */ + if (!backend_shr_entry_matches_set(set_data, cbdata->pb, cbdata->e)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "entry \"%s\" does not belong in " + "\"%s\"/\"%s\"\n", + cbdata->ndn, group, set); + return TRUE; + } + + /* Set the entry in the map which corresponds to this entry, or clear + * any that might if this entry doesn't have a key and value. */ + backend_set_entry_one(cbdata->e, set_data); + + return TRUE; +} + +static int +backend_shr_add_cb(Slapi_PBlock *pb) +{ + struct backend_add_entry_cbdata cbdata; + + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_ADD_TARGET, &cbdata.ndn); + slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e); + cbdata.pb = pb; + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "added \"%s\"\n", cbdata.ndn); + + + /* Check for NULL entries, indicative of a failure elsewhere (?). */ + if (cbdata.e == NULL) { + slapi_pblock_get(pb, SLAPI_ADD_EXISTING_DN_ENTRY, &cbdata.e); + if (cbdata.e == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "added entry is NULL\n"); + return 0; + } + } + + /* Add map entries which corresponded to this directory server + * entry. */ + map_wrlock(); + if (!map_data_foreach_map(cbdata.state, NULL, + backend_shr_add_entry_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "error adding set entries corresponding to " + "\"%s\"\n", cbdata.ndn); + } + + /* If it's a map configuration entry, add and populate the maps it + * describes. */ + if (backend_entry_is_a_set(cbdata.state, pb, cbdata.e)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "new entry \"%s\" is a set\n", cbdata.ndn); + backend_set_config_entry_add_cb(cbdata.e, cbdata.state); + } + + /* Update entries which need to be updated in case this new entry + * refers to them. */ + backend_shr_update_references(cbdata.state, cbdata.e); + + map_unlock(); + return 0; +} + +struct backend_shr_modify_entry_cbdata { + struct plugin_state *state; + Slapi_PBlock *pb; + LDAPMod **mods; + Slapi_Entry *e_pre, *e_post; + char *ndn; +}; + +static bool_t +backend_shr_modify_entry_cb(const char *group, const char *set, bool_t flag, + void *backend_data, void *cbdata_ptr) +{ + struct backend_set_data *set_data; + struct backend_shr_modify_entry_cbdata *cbdata; + + set_data = backend_data; + cbdata = cbdata_ptr; + + /* If the entry used to match the map, remove it. */ + if (backend_shr_entry_matches_set(set_data, cbdata->pb, + cbdata->e_pre)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "clearing group/set/id " + "\"%s\"/\"%s\"/(\"%s\")\n", + backend_set_config_get_group(set_data), + backend_set_config_get_set(set_data), + cbdata->ndn); + map_data_unset_entry_id(cbdata->state, + backend_set_config_get_group(set_data), + backend_set_config_get_set(set_data), + cbdata->ndn); + } + /* If the entry now matches the map, add it (or re-add it). */ + if (backend_shr_entry_matches_set(set_data, cbdata->pb, + cbdata->e_post)) { + /* Set the entry in the set which corresponds to this entry, or + * remove any that might if this entry doesn't produce a useful + * value. */ + backend_shr_set_entry_one(cbdata->e_post, set_data); + } + return TRUE; +} + +static int +backend_shr_modify_cb(Slapi_PBlock *pb) +{ + Slapi_DN *sdn; + struct backend_shr_modify_entry_cbdata cbdata; + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_MODIFY_TARGET, &cbdata.ndn); + slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &cbdata.mods); + slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); + slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); + cbdata.pb = pb; + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "modified \"%s\"\n", cbdata.ndn); + /* Check for NULL entries, indicative of a failure elsewhere (?). */ + if (cbdata.e_pre == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "pre-modify entry is NULL\n"); + return 0; + } + if (cbdata.e_post == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "post-modify entry is NULL\n"); + return 0; + } + /* Modify map entries which corresponded to this directory server + * entry. */ + map_wrlock(); + if (!map_data_foreach_map(cbdata.state, NULL, + backend_shr_modify_entry_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "error modifying set entries corresponding to " + "\"%s\"\n", cbdata.ndn); + } + /* Update entries which need to be updated in case this entry + * no longer refers to them. */ + backend_shr_update_references(cbdata.state, cbdata.e_pre); + /* Update entries which need to be updated in case this entry + * now refers to them. */ + backend_shr_update_references(cbdata.state, cbdata.e_post); + /* If it's a map configuration entry, reconfigure, clear, and + * repopulate the map. */ + if (backend_entry_is_a_set(cbdata.state, pb, cbdata.e_pre)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "modified entry \"%s\" was a set\n", + cbdata.ndn); + backend_set_config_entry_delete_cb(cbdata.e_pre, cbdata.state); + } + if (backend_entry_is_a_set(cbdata.state, pb, cbdata.e_post)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "modified entry \"%s\" is now a set\n", + cbdata.ndn); + backend_set_config_entry_add_cb(cbdata.e_post, cbdata.state); + } + /* Lastly, if the entry is our own entry, re-read parameters. */ + sdn = slapi_sdn_new_dn_byref(cbdata.state->plugin_base); + if (sdn != NULL) { + if ((strcmp(slapi_entry_get_ndn(cbdata.e_pre), + slapi_sdn_get_ndn(sdn)) == 0) || + (strcmp(slapi_entry_get_ndn(cbdata.e_post), + slapi_sdn_get_ndn(sdn)) == 0)) { + backend_update_params(cbdata.state); + } + slapi_sdn_free(&sdn); + } + map_unlock(); + return 0; +} + +struct backend_shr_modrdn_entry_cbdata { + struct plugin_state *state; + Slapi_PBlock *pb; + Slapi_Entry *e_pre, *e_post; + char *ndn_pre, *ndn_post; +}; + +static bool_t +backend_shr_modrdn_entry_cb(const char *group, const char *set, bool_t secure, + void *backend_data, void *cbdata_ptr) +{ + struct backend_set_data *set_data; + struct backend_shr_modrdn_entry_cbdata *cbdata; + bool_t matched_pre, matched_post; + + set_data = backend_data; + cbdata = cbdata_ptr; + + /* Now decide what to set, or unset, in this map. */ + matched_pre = backend_shr_entry_matches_set(set_data, + cbdata->pb, + cbdata->e_pre); + if (matched_pre) { + /* If it was a match for the map, clear the entry. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "clearing group/set/id " + "\"%s\"/\"%s\"/(\"%s\")\n", + backend_set_config_get_group(set_data), + backend_set_config_get_set(set_data), + cbdata->ndn_pre); + map_data_unset_entry_id(cbdata->state, + backend_set_config_get_group(set_data), + backend_set_config_get_set(set_data), + cbdata->ndn_pre); + } + /* Set the entry in the map which corresponds to this entry, or clear + * any that might if this entry doesn't have a key and value. */ + matched_post = backend_shr_entry_matches_set(set_data, + cbdata->pb, + cbdata->e_post); + if (matched_post) { + backend_set_entry_one(cbdata->e_post, set_data); + } + return TRUE; +} + +static int +backend_shr_modrdn_cb(Slapi_PBlock *pb) +{ + struct backend_shr_modrdn_entry_cbdata cbdata; + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); + slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); + cbdata.ndn_pre = slapi_entry_get_ndn(cbdata.e_pre); + cbdata.ndn_post = slapi_entry_get_ndn(cbdata.e_post); + cbdata.pb = pb; + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "renamed \"%s\" to \"%s\"\n", + cbdata.ndn_pre, cbdata.ndn_post); + /* Check for NULL entries, indicative of a failure elsewhere (?). */ + if (cbdata.e_pre == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "pre-modrdn entry is NULL\n"); + return 0; + } + if (cbdata.e_post == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "post-modrdn entry is NULL\n"); + return 0; + } + /* Modify map entries which corresponded to this directory server + * entry. */ + map_wrlock(); + if (!map_data_foreach_map(cbdata.state, NULL, + backend_shr_modrdn_entry_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "error renaming map entries corresponding to " + "\"%s\"\n", cbdata.ndn_post); + } + /* If it's a set configuration entry, reconfigure, clear, and + * repopulate the set. */ + if (backend_entry_is_a_set(cbdata.state, pb, cbdata.e_pre)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "renamed entry \"%s\" was a set\n", + cbdata.e_pre); + backend_set_config_entry_delete_cb(cbdata.e_pre, cbdata.state); + } + if (backend_entry_is_a_set(cbdata.state, pb, cbdata.e_post)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "renamed entry \"%s\" is now a set\n", + cbdata.e_post); + backend_set_config_entry_add_cb(cbdata.e_post, cbdata.state); + } + map_unlock(); + return 0; +} + +/* Delete any map entries which correspond to a directory server entry in this + * map. */ + +struct backend_shr_delete_entry_cbdata { + struct plugin_state *state; + Slapi_PBlock *pb; + Slapi_Entry *e; + char *ndn; +}; +static bool_t +backend_shr_delete_entry_cb(const char *group, const char *set, bool_t flag, + void *backend_data, void *cbdata_ptr) +{ + struct backend_set_data *set_data; + struct backend_shr_delete_entry_cbdata *cbdata; + set_data = backend_data; + cbdata = cbdata_ptr; + /* If it was in the map, remove it. */ + if (backend_shr_entry_matches_set(set_data, cbdata->pb, cbdata->e)) { + /* Remove this entry from the set. */ + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "unsetting group/set/id" + "\"%s\"/\"%s\"=\"%s\"/\"%s\"/(\"%s\")\n", + group, set, + backend_set_config_get_group(set_data), + backend_set_config_get_set(set_data), + cbdata->ndn); + map_data_unset_entry_id(cbdata->state, group, set, cbdata->ndn); + } + return TRUE; +} + +/* Called by the server when a directory server entry is deleted. */ +static int +backend_shr_delete_cb(Slapi_PBlock *pb) +{ + struct backend_shr_delete_entry_cbdata cbdata; + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + slapi_pblock_get(pb, SLAPI_DELETE_TARGET, &cbdata.ndn); + slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e); + cbdata.pb = pb; + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "deleted \"%s\"\n", cbdata.ndn); + /* Check for NULL entries, indicative of a failure elsewhere (?). */ + if (cbdata.e == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "deleted entry is NULL\n"); + return 0; + } + /* Remove map entries which corresponded to this directory server + * entry. */ + map_wrlock(); + if (!map_data_foreach_map(cbdata.state, NULL, + backend_shr_delete_entry_cb, &cbdata)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "error removing entries corresponding to " + "\"%s\"\n", cbdata.ndn); + } + /* If it's a map configuration entry, remove the map. */ + if (backend_entry_is_a_set(cbdata.state, pb, cbdata.e)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "deleted entry \"%s\" is a set\n", cbdata.ndn); + backend_set_config_entry_delete_cb(cbdata.e, cbdata.state); + } + /* Update entries which need to be updated in case this entry no longer + * refers to them. */ + backend_shr_update_references(cbdata.state, cbdata.e); + map_unlock(); + return 0; +} + +/* Set our post-op callbacks. */ +void +backend_shr_postop_init(Slapi_PBlock *pb, struct plugin_state *state) +{ + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "hooking up postoperation callbacks\n"); + if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN, + backend_shr_add_cb) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up add callback\n"); + } + if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN, + backend_shr_modify_cb) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up modify callback\n"); + } + if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, + backend_shr_modrdn_cb) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up modrdn callback\n"); + } + if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, + backend_shr_delete_cb) != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "error hooking up delete callback\n"); + } +} diff --git a/src/disp-nis.c b/src/disp-nis.c index f2a6139..597254d 100644 --- a/src/disp-nis.c +++ b/src/disp-nis.c @@ -51,7 +51,7 @@ #include #include -#include "plug-nis.h" +#include "plugin.h" #include "disp-nis.h" #include "nis.h" #include "portmap.h" diff --git a/src/dummymap.c b/src/dummymap.c index 9eb0c0a..fc705d2 100644 --- a/src/dummymap.c +++ b/src/dummymap.c @@ -42,7 +42,7 @@ #include "disp-nis.h" #include "map.h" #include "nis.h" -#include "plug-nis.h" +#include "plugin.h" #include "portmap.h" struct entry { diff --git a/src/format.c b/src/format.c index 4734634..a17024d 100644 --- a/src/format.c +++ b/src/format.c @@ -42,8 +42,9 @@ #include #include "back-nis.h" +#include "back-shr.h" #include "format.h" -#include "plug-nis.h" +#include "plugin.h" #define DEFAULT_BUFFER_SIZE 0x1000 #define MAX_BUFFER_SIZE 0x100000 @@ -66,82 +67,12 @@ static int format_expand(struct plugin_state *state, char ** format_dup_attr_list(char **attr_list) { - int i, elements, length; - char **ret, *p; - length = 0; - elements = 0; - if (*attr_list != NULL) { - for (i = 0; attr_list[i] != NULL; i++) { - length += (strlen(attr_list[i]) + 1); - } - elements = i; - } - ret = malloc(((elements + 1) * sizeof(char *)) + length); - if (ret != NULL) { - p = (char *) ret; - p += (elements + 1) * sizeof(char *); - for (i = 0; i < elements; i++) { - ret[i] = p; - strcpy(p, attr_list[i]); - p += (strlen(attr_list[i]) + 1); - } - ret[i] = NULL; - } - return ret; -} -static char ** -format_dup_strlist(char **strlist) -{ - return format_dup_attr_list(strlist); + return backend_shr_dup_strlist(attr_list); } - -void -format_add_attr_list(char ***attr_list, const char *value) -{ - int i, elements, length; - char **ret, *p; - - length = strlen(value) + 1; - elements = 0; - if (*attr_list != NULL) { - for (i = 0; (*attr_list)[i] != NULL; i++) { - if (strcmp(value, (*attr_list)[i]) == 0) { - return; - } - length += (strlen((*attr_list)[i]) + 1); - elements++; - } - } - - ret = malloc(((elements + 2) * sizeof(char *)) + length); - if (ret != NULL) { - p = (char *) ret; - p += (elements + 2) * sizeof(char *); - for (i = 0; i < elements; i++) { - ret[i] = p; - strcpy(p, (*attr_list)[i]); - p += (strlen((*attr_list)[i]) + 1); - } - ret[i++] = p; - strcpy(p, value); - p += (strlen(value) + 1); - ret[i] = NULL; - format_free_attr_list(*attr_list); - } - *attr_list = ret; -} - void format_free_attr_list(char **attr_list) { - if (attr_list != NULL) { - free(attr_list); - } -} -static void -format_free_strlist(char **strlist) -{ - return format_free_attr_list(strlist); + return backend_shr_free_strlist(attr_list); } struct format_inref_attr ** @@ -249,7 +180,7 @@ format_free_choices(struct format_choice *choices) struct format_choice *next; while (choices != NULL) { next = choices->next; - format_free_strlist(choices->values); + backend_shr_free_strlist(choices->values); free(choices); choices = next; } @@ -290,7 +221,7 @@ format_add_choice(struct format_choice **choices, char *offset, char **values) choice = malloc(sizeof(*choice)); if (choice != NULL) { choice->offset = offset; - choice->values = format_dup_strlist(values); + choice->values = backend_shr_dup_strlist(values); choice->next = NULL; if (choice->values != NULL) { for (i = 0; choice->values[i] != NULL; i++) { @@ -573,7 +504,7 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, } /* Note that the attribute in this entry refers to other entries. */ if (ref_attrs != NULL) { - format_add_attr_list(ref_attrs, argv[1]); + backend_shr_add_strlist(ref_attrs, argv[1]); } /* Get the names of the reference attribute. */ if (slapi_vattr_values_get(e, argv[1], &ref_values, @@ -1406,7 +1337,7 @@ format_single(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, } } tmp_values[j] = NULL; - *values = format_dup_strlist(tmp_values); + *values = backend_shr_dup_strlist(tmp_values); for (i = 0; tmp_values[i] != NULL; i++) { free(tmp_values[i]); } @@ -1750,7 +1681,7 @@ format_expand_simple(struct plugin_state *state, * a note that any of these values would be fine at * this point in the output string. */ format_add_choice(outbuf_choices, outbuf, value_list); - format_free_strlist(value_list); + backend_shr_free_strlist(value_list); return 0; } } else { diff --git a/src/nis.c b/src/nis.c index 4c69f41..09b2588 100644 --- a/src/nis.c +++ b/src/nis.c @@ -47,7 +47,7 @@ #include "disp-nis.h" #include "map.h" #include "nis.h" -#include "plug-nis.h" +#include "plugin.h" /* Indicate whether or not we serve the specified domain. */ static void diff --git a/src/plug-nis.c b/src/plug-nis.c index 55c8b48..60acc08 100644 --- a/src/plug-nis.c +++ b/src/plug-nis.c @@ -56,7 +56,7 @@ #include "disp-nis.h" #include "map.h" #include "nis.h" -#include "plug-nis.h" +#include "plugin.h" #include "portmap.h" /* the module initialization function */ diff --git a/src/plug-nis.h b/src/plug-nis.h deleted file mode 100644 index ab46be1..0000000 --- a/src/plug-nis.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2008 Red Hat, Inc. - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This Program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this Program; if not, write to the - * - * Free Software Foundation, Inc. - * 59 Temple Place, Suite 330 - * Boston, MA 02111-1307 USA - * - */ - -#ifndef plug_nis_h -#define plug_nis_h - -#include "wrap.h" - -struct request_info; -struct securenet_info; - -struct plugin_state { - struct wrapped_thread *tid; - char *plugin_base; - Slapi_ComponentId *plugin_identity; - Slapi_PluginDesc *plugin_desc; - int pmap_client_socket; - int max_dgram_size, max_value_size; - struct request_info *request_info; - struct securenet_info *securenet_info; - int n_listeners; - struct { - int fd, port, pf, type; - } listener[4]; -}; - -#endif diff --git a/src/plug-sch.c b/src/plug-sch.c new file mode 100644 index 0000000..0149003 --- /dev/null +++ b/src/plug-sch.c @@ -0,0 +1,113 @@ +/* + * Copyright 2008 Red Hat, Inc. + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This Program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; if not, write to the + * + * Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111-1307 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef HAVE_TCPD_H +#include +#endif + +#ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H +#include +#include +#include +#else +#include +#endif + +#include "wrap.h" +#include "map.h" +#include "plugin.h" +#include "portmap.h" + +/* the module initialization function */ +static Slapi_PluginDesc +plugin_description = { + .spd_id = "schema-plugin", + .spd_vendor = "redhat.com", + .spd_version = PACKAGE_VERSION, + .spd_description = "Schema Compatibility Plugin", +}; + +/* Handle the part of startup that needs to be done before we drop privileges. + */ +static int +plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate) +{ + struct plugin_state *state = NULL; + + state = malloc(sizeof(*state)); + if (state == NULL) { + return -1; + } + memset(state, 0, sizeof(*state)); + state->plugin_base = NULL; + state->plugin_desc = &plugin_description; + slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &state->plugin_identity); + slapi_pblock_get(pb, SLAPI_TARGET_DN, &state->plugin_base); + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "init: target-dn is %s%s%s\n", + state->plugin_base ? "\"" : "", + state->plugin_base ? state->plugin_base : "NULL", + state->plugin_base ? "\"" : ""); + *lstate = state; + return 0; +} + +int +schema_compat_plugin_init(Slapi_PBlock *pb) +{ + struct plugin_state *state = NULL; + /* Allocate a memory pool and start listening for connections. */ + if (plugin_state_init(pb, &state) == -1) { + slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id, + "error setting up plugin\n"); + return -1; + } + /* Register the plugin with the server. */ + slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03); + slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, &plugin_description); + slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, state); + /* Let the backend do its setup. */ + map_init(pb, state); + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "registered plugin hooks\n"); + return 0; +} -- cgit From 91a5c2e9ef1e66d7c846a2f944b889f23ec92f11 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 16:56:51 -0400 Subject: - get schema compatibility linking correctly --- src/Makefile.am | 4 +- src/back-sch.c | 1043 ++++++++----------------------------------------------- src/back-shr.c | 14 +- 3 files changed, 150 insertions(+), 911 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index ee6bad1..442f3b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,7 +40,9 @@ schemacompat_plugin_la_SOURCES = \ map.c \ map.h \ plug-sch.c \ - plugin.h + plugin.h \ + wrap.c \ + wrap.h schemacompat_plugin_la_LIBADD = $(RUNTIME_LIBS) $(LIBPTHREAD) noinst_LTLIBRARIES = dummy-nis-plugin.la diff --git a/src/back-sch.c b/src/back-sch.c index 704e653..1e63c60 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -45,14 +45,15 @@ #include "backend.h" #include "back-sch.h" +#include "back-shr.h" #include "format.h" #include "plugin.h" #include "map.h" #define SCH_CONTAINER_CONFIGURATION_FILTER "(&(objectClass=*)(" SCH_CONTAINER_CONFIGURATION_BASE_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_GROUP_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_FILTER_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_ENTRY_FORMAT_ATTR "=*))" -/* The data we ask the map cache to keep, for us, for each map. */ -struct backend_map_data { +/* The data we ask the map cache to keep, for us, for each set. */ +struct backend_set_data { struct plugin_state *state; char *group, *container, **bases, *entry_filter, *entry_format; char **ref_attrs; @@ -73,86 +74,66 @@ backend_read_master_name(struct plugin_state *state, char **master) return -1; } -/* Manipulate string lists. */ -static void -backend_free_strlist(char **strlist) +/* Manipulate a backend map configuration. */ +struct plugin_state * +backend_set_config_get_state(struct backend_set_data *set_data) { - if (strlist) { - free(strlist); - } + return set_data->state; } -static char ** -backend_dup_strlist_n(char **strlist, int n) +char ** +backend_set_config_get_bases(struct backend_set_data *set_data) { - int i, l; - char **ret, *s; - /* Handle the NULL case. */ - if (strlist == NULL) { - return NULL; - } - /* No strings = no list. */ - if (n == 0) { - return NULL; - } - /* Count the amount of space needed for the strings. */ - for (i = 0, l = 0; i < n; i++) { - l += (strlen(strlist[i]) + 1); - } - /* Allocate space for the array of pointers (with NULL terminator) and - * then the string data. */ - ret = malloc(((n + 1) * sizeof(char *)) + l); - if (ret != NULL) { - /* Figure out where the string data will start. */ - s = (char *) ret; - s += ((n + 1) * sizeof(char *)); - for (i = 0; i < n; i++) { - /* Set the address of this string, copy the data - * around, and then prepare the address of the next - * string. */ - ret[i] = s; - strcpy(s, strlist[i]); - s += (strlen(strlist[i]) + 1); - } - /* NULL-terminate the array. */ - ret[i] = NULL; - } - return ret; + return set_data->bases; } -static char ** -backend_dup_strlist(char **strlist) +char * +backend_set_config_get_filter(struct backend_set_data *set_data) { - int i; - for (i = 0; (strlist != NULL) && (strlist[i] != NULL); i++) { - continue; - } - return backend_dup_strlist_n(strlist, i); + return set_data->entry_filter; +} +char * +backend_set_config_get_group(struct backend_set_data *set_data) +{ + return set_data->group; +} +char * +backend_set_config_get_set(struct backend_set_data *set_data) +{ + return set_data->container; +} +struct format_inref_attr ** +backend_set_config_get_inref_attrs(struct backend_set_data *set_data) +{ + return set_data->inref_attrs; +} +char ** +backend_set_config_get_ref_attrs(struct backend_set_data *set_data) +{ + return set_data->ref_attrs; } - -/* Manipulate a backend map configuration. */ static void -backend_free_map_data_contents(void *data) +backend_set_config_free_config_contents(void *data) { - struct backend_map_data *map_data = data; - if (map_data != NULL) { - free(map_data->group); - free(map_data->container); - free(map_data->bases); - format_free_attr_list(map_data->ref_attrs); - format_free_inref_attrs(map_data->inref_attrs); - free(map_data->entry_filter); - free(map_data->entry_format); + struct backend_set_data *set_data = data; + if (set_data != NULL) { + free(set_data->group); + free(set_data->container); + free(set_data->bases); + format_free_attr_list(set_data->ref_attrs); + format_free_inref_attrs(set_data->inref_attrs); + free(set_data->entry_filter); + free(set_data->entry_format); } } -static void -backend_free_map_data(void *data) +void +backend_set_config_free_config(struct backend_set_data *data) { - backend_free_map_data_contents(data); + backend_set_config_free_config_contents(data); free(data); } -static struct backend_map_data * -backend_copy_map_data(const struct backend_map_data *data) +static struct backend_set_data * +backend_copy_set_config(const struct backend_set_data *data) { - struct backend_map_data *ret; + struct backend_set_data *ret; ret = malloc(sizeof(*ret)); if (ret == NULL) { return NULL; @@ -160,7 +141,7 @@ backend_copy_map_data(const struct backend_map_data *data) ret->state = data->state; ret->group = strdup(data->group); ret->container = strdup(data->container); - ret->bases = backend_dup_strlist(data->bases); + ret->bases = backend_shr_dup_strlist(data->bases); ret->ref_attrs = data->ref_attrs ? format_dup_attr_list(data->ref_attrs) : NULL; @@ -174,100 +155,18 @@ backend_copy_map_data(const struct backend_map_data *data) (ret->bases == NULL) || (ret->entry_filter == NULL) || (ret->entry_format == NULL)) { - backend_free_map_data(ret); + backend_set_config_free_config(ret); return NULL; } return ret; } -/* Given a map-entry directory entry, determine a key, a value, and extra data - * to be stored in the map cache, and add them to the map cache. */ -static int -backend_map_config_entry_add_one_cb(Slapi_Entry *e, void *callback_data) -{ - struct backend_map_data *data; - char *ldif, *ndn, *plugin_id, *ndns[2]; - int i, j, k, n_key_sets; - data = callback_data; - plugin_id = data->state->plugin_desc->spd_id; - /* Pull out the NDN of this entry. */ - ndn = slapi_entry_get_ndn(e); - ndns[0] = ndn; - ndns[1] = NULL; - /* Pull out the keys and value for the entry. */ - ldif = format_get_data(data->state, e, data->group, data->container, - data->entry_format, NULL, - &data->ref_attrs, &data->inref_attrs); - /* If we actually generated a new entry for this entry, then set it, - * otherwise clear it in case there was one set before. */ - if (ldif == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, - "setting group/container/key/value " - "\"%s\"/\"%s\"/\"%s\"(\"%s\")=\"%s\"\n", - data->group, data->container, ndn, ndn, ldif); - map_data_set_entry(data->state, data->group, data->container, - ndn, NULL, ndns, -1, ldif, NULL, NULL); - } else { - slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, - "no value for %s, unsetting domain/map/id" - "\"%s\"/\"%s\"/(\"%s\")\n", - ndn, data->group, data->container, ndn); - map_data_unset_entry_id(data->state, - data->group, data->container, - ndn); - } - format_free_data(ldif); - return 0; -} - -static int -backend_map_config_entry_set_one_cb(Slapi_Entry *e, void *cbdata) -{ - backend_map_config_entry_add_one_cb(e, cbdata); - return 0; -} - -static void -backend_map_config_entry_set_one(Slapi_Entry *e, - struct backend_map_data *map_data) -{ - backend_map_config_entry_set_one_cb(e, map_data); -} - -static void -backend_map_config_entry_set_one_dn(struct plugin_state *state, const char *dn, - struct backend_map_data *map_data) -{ - Slapi_DN *sdn; - Slapi_Entry *entry; - sdn = slapi_sdn_new_dn_byval(dn); - if (sdn == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error parsing DN \"%s\"\n", dn); - return; - } else { - entry = NULL; - slapi_search_internal_get_entry(sdn, NULL, &entry, - state->plugin_identity); - if (entry == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "failure reading entry \"%s\"\n", dn); - } else { - backend_map_config_entry_set_one(entry, map_data); - slapi_entry_free(entry); - } - slapi_sdn_free(&sdn); - } -} - -/* Given an entry, read the map configuration for the given group and container - * name. */ -static void -backend_map_config_read_config(struct plugin_state *state, Slapi_Entry *e, +/* Given a configuration entry, read the map configuration for the given group + * and container name from the entry. */ +void +backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e, const char *group, const char *container, - struct backend_map_data *ret) + bool_t *flag, struct backend_set_data **pret) { char **bases, *entry_filter, *entry_format; char **entrykey_formats, **keys_formats, *value_format, *actual_attr; @@ -277,8 +176,10 @@ backend_map_config_read_config(struct plugin_state *state, Slapi_Entry *e, char *use_value_format, *use_disallowed_chars; const char *cvalue; int i, j, disposition, buffer_flags, count; + struct backend_set_data ret; Slapi_ValueSet *values; Slapi_Value *value; + /* Read the values from the configuration entry. */ bases = NULL; if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_BASE_ATTR, @@ -337,86 +238,71 @@ backend_map_config_read_config(struct plugin_state *state, Slapi_Entry *e, slapi_vattr_values_free(&values, &actual_attr, buffer_flags); } /* Populate the returned structure. */ - ret->state = state; - ret->group = strdup(group); - ret->container = strdup(container); - ret->bases = backend_dup_strlist(bases); - if (bases != NULL) { - for (i = 0; bases[i] != NULL; i++) { - free(bases[i]); + ret.state = state; + ret.group = strdup(group); + ret.container = strdup(container); + ret.bases = bases; + ret.entry_filter = entry_filter; + ret.entry_format = entry_format; + ret.ref_attrs = NULL; + ret.inref_attrs = NULL; + *pret = backend_copy_set_config(&ret); + free(ret.group); + free(ret.container); + if (ret.bases != NULL) { + for (i = 0; ret.bases[i] != NULL; i++) { + free(ret.bases[i]); } - free(bases); + free(ret.bases); } - ret->entry_filter = entry_filter; - ret->entry_format = entry_format; - ret->ref_attrs = NULL; - ret->inref_attrs = NULL; + free(ret.entry_filter); + free(ret.entry_format); } -/* Given a directory server entry which represents a container's configuration, - * set up and populate the container. */ -static int -backend_map_config_entry_add_one(struct plugin_state *state, Slapi_Entry *e, - const char *group, const char *container) +/* Given a map-entry directory entry, determine a key, a value, and extra data + * to be stored in the map cache, and add them to the map cache. */ +void +backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data) { - Slapi_PBlock *pb; - int i; - struct backend_map_data cb_data, *map_cb_data; - - pb = slapi_pblock_new(); - backend_map_config_read_config(state, e, group, container, &cb_data); - map_cb_data = backend_copy_map_data(&cb_data); - backend_free_map_data_contents(&cb_data); - if (map_cb_data == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "incomplete container definition %s in %s " - "(2)\n", container, group); - slapi_pblock_destroy(pb); - return 0; - } - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "initializing container %s in %s (2)\n", - group, container); - map_data_set_map(state, group, container, FALSE, - map_cb_data, &backend_free_map_data); - map_data_clear_map(state, group, container); - /* Search under each base in turn, adding the matching directory - * entries to the containers. */ - for (i = 0; - (map_cb_data->bases != NULL) && (map_cb_data->bases[i] != NULL); - i++) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "searching '%s' for '%s'\n", - map_cb_data->bases[i], - map_cb_data->entry_filter); - slapi_search_internal_set_pb(pb, - map_cb_data->bases[i], - LDAP_SCOPE_SUB, - map_cb_data->entry_filter, - NULL, FALSE, - NULL, - NULL, - state->plugin_identity, - 0); - slapi_search_internal_callback_pb(pb, map_cb_data, - NULL, - backend_map_config_entry_add_one_cb, - NULL); - slapi_free_search_results_internal(pb); + char *ldif, *ndn, *plugin_id, *ndns[2]; + int i, j, k, n_key_sets; + plugin_id = data->state->plugin_desc->spd_id; + /* Pull out the NDN of this entry. */ + ndn = slapi_entry_get_ndn(e); + ndns[0] = ndn; + ndns[1] = NULL; + /* Generate the LDIF for the entry. */ + ldif = format_get_data(data->state, e, data->group, data->container, + data->entry_format, NULL, + &data->ref_attrs, &data->inref_attrs); + /* If we actually generated a new entry for this entry, then set it, + * otherwise clear it in case there was one set before. */ + if (ldif == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, + "setting group/container/key/value " + "\"%s\"/\"%s\"/\"%s\"(\"%s\")=\"%s\"\n", + data->group, data->container, ndn, ndn, ldif); + map_data_set_entry(data->state, + data->group, data->container, ndn, + NULL, ndns, -1, ldif, + NULL, NULL); + } else { + slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, + "no value for %s, unsetting domain/map/id" + "\"%s\"/\"%s\"/(\"%s\")\n", + ndn, data->group, data->container, ndn); + map_data_unset_entry_id(data->state, + data->group, data->container, + ndn); } - /* Clean up. */ - slapi_pblock_destroy(pb); - return 0; + format_free_data(ldif); } -/* Process a map configuration directory entry. Pull out the group and +/* Process a set configuration directory entry. Pull out the group and * container names which are valid for this configuration and configure such a * container for each in turn. */ -static int -backend_map_config_entry_add_cb(Slapi_Entry *e, void *callback_data) +int +backend_set_config_entry_add_cb(Slapi_Entry *e, void *callback_data) { char **groups, **containers, *actual_attr; const char *cvalue; @@ -466,9 +352,9 @@ backend_map_config_entry_add_cb(Slapi_Entry *e, void *callback_data) for (j = 0; (containers != NULL) && (containers[j] != NULL); j++) { - ret = backend_map_config_entry_add_one(state, e, - groups[i], - containers[j]); + ret = backend_shr_set_config_entry_add_one(state, e, + groups[i], + containers[j]); } } if (groups != NULL) { @@ -488,68 +374,20 @@ backend_map_config_entry_add_cb(Slapi_Entry *e, void *callback_data) return 0; } -/* Scan for the list of configured groups and containers. */ -void -backend_startup(struct plugin_state *state) -{ - Slapi_PBlock *pb; - - pb = slapi_pblock_new(); - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "searching \"%s\" for containers\n", - state->plugin_base); - slapi_search_internal_set_pb(pb, - state->plugin_base, - LDAP_SCOPE_ONE, - SCH_CONTAINER_CONFIGURATION_FILTER, - NULL, FALSE, - NULL, - NULL, - state->plugin_identity, - 0); - map_wrlock(); - slapi_search_internal_callback_pb(pb, state, - NULL, - backend_map_config_entry_add_cb, - NULL); - map_unlock(); - slapi_free_search_results_internal(pb); - slapi_pblock_destroy(pb); -} - -/* Process a map configuration directory entry. Pull out the domain and map +/* Process a set configuration directory entry. Pull out the domain and map * names which are specified in the entry and delete each in turn. */ -static int -backend_map_config_entry_delete_cb(Slapi_Entry *e, void *callback_data) +int +backend_set_config_entry_delete_cb(Slapi_Entry *e, void *callback_data) { - char **groups, **containers; - int i, j; struct plugin_state *state; - state = callback_data; - groups = slapi_entry_attr_get_charray(e, - SCH_CONTAINER_CONFIGURATION_GROUP_ATTR); - containers = slapi_entry_attr_get_charray(e, - SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR); - for (i = 0; (groups != NULL) && (groups[i] != NULL); i++) { - for (j = 0; - (containers != NULL) && (containers[j] != NULL); - j++) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "removing container %s in %s\n", - containers[j], groups[i]); - map_data_unset_map(state, groups[i], containers[j]); - } - } - slapi_ch_array_free(containers); - slapi_ch_array_free(groups); - return 0; + return backend_shr_set_config_entry_delete(state, e, + SCH_CONTAINER_CONFIGURATION_GROUP_ATTR, + SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR); } -/* Functions for passing information about a container's configuration to a - * caller. */ +/* Functions for passing information about a container's configuration to the + * formatting functions. */ struct backend_get_map_config_cb { struct plugin_state *state; char **bases; @@ -559,7 +397,7 @@ struct backend_get_map_config_cb { void backend_free_map_config(char **bases, char *entry_filter) { - backend_free_strlist(bases); + backend_shr_free_strlist(bases); free(entry_filter); } @@ -674,68 +512,9 @@ backend_get_map_config(struct plugin_state *state, slapi_pblock_destroy(pb); } -/* Our postoperation callbacks. */ - -/* Given a map configuration, return true if an entry corresponding to the - * entry is supposed to be in the container. */ -static bool_t -backend_entry_matches_map(struct backend_map_data *map_data, - Slapi_PBlock *pb, Slapi_Entry *e) -{ - Slapi_DN *base_sdn; - const Slapi_DN *entry_sdn; - Slapi_Filter *filter; - int i; - /* Decide if the directory server entry belongs in this map. That - * means that it must be contained by one of the bases of the map. */ - entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); - if (entry_sdn == NULL) { - return FALSE; - } else { - /* Check each base in turn. */ - for (i = 0; - (map_data->bases != NULL) && (map_data->bases[i] != NULL); - i++) { - base_sdn = slapi_sdn_new_dn_byval(map_data->bases[i]); - if (base_sdn == NULL) { - return FALSE; - } else { - if (slapi_sdn_scope_test(entry_sdn, - base_sdn, - LDAP_SCOPE_SUB) == 0) { - /* The entry is not contained by the - * base -- go on to try the next one. */ - slapi_sdn_free(&base_sdn); - continue; - } - /* The entry is contained by the base. */ - slapi_sdn_free(&base_sdn); - break; - } - } - /* If we ran out of bases to check, it doesn't match. */ - if ((map_data->bases == NULL) || (map_data->bases[i] == NULL)) { - return FALSE; - } - } - /* If it's contained by a search base, compare it to the filter. */ - filter = slapi_str2filter(map_data->entry_filter); - if (filter == NULL) { - return FALSE; - } else { - if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { - /* Didn't match -- return. */ - slapi_filter_free(filter, 1); - return FALSE; - } - slapi_filter_free(filter, 1); - } - return TRUE; -} - /* Given an entry, return true if it describes a compatibility container. */ -static bool_t -backend_entry_is_a_map(struct plugin_state *state, +bool_t +backend_entry_is_a_set(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e) { Slapi_DN *entry_sdn, *plugin_sdn; @@ -743,7 +522,8 @@ backend_entry_is_a_map(struct plugin_state *state, bool_t ret; char configuration_filter[] = SCH_CONTAINER_CONFIGURATION_FILTER; - /* First, just do the scope test. */ + /* First, just do the scope test. The item should be a direct child of + * our plugin entry. */ entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); if (entry_sdn == NULL) { return FALSE; @@ -769,8 +549,9 @@ backend_entry_is_a_map(struct plugin_state *state, } slapi_sdn_free(&plugin_sdn); slapi_sdn_free(&entry_sdn); - /* If it's actually part of our configuration tree, check if it's a - * valid entry. */ + + /* If it's actually in our configuration tree, check if it's a valid + * entry. */ if (ret) { filter = slapi_str2filter(configuration_filter); if (filter != NULL) { @@ -793,564 +574,22 @@ backend_entry_is_a_map(struct plugin_state *state, return ret; } -/* Update any entries to which the passed-in entry in the passed-in map refers - * to, if the referred-to entry is in this map. Everybody got that? */ -struct backend_update_references_cbdata { - Slapi_PBlock *pb; - Slapi_Entry *e; -}; - -static bool_t -backend_update_references_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cbdata_ptr) -{ - struct plugin_state *state; - struct backend_map_data *map_data; - struct backend_update_references_cbdata *cbdata; - Slapi_DN *referred_to_sdn; - Slapi_ValueSet *values; - Slapi_Value *value; - char **ref_attrs, *actual_attr, *filter, *tndn; - struct format_inref_attr **inref_attrs; - const char *ndn, *dn; - int i, j, disposition, buffer_flags, filter_size, n_ref_attrs; - - map_data = backend_data; - cbdata = cbdata_ptr; - state = map_data->state; - - /* For every entry in this map which refers to this entry using - * a DN stored in an attribute, update that entry. */ - - /* Build a filter with all of these attributes and this entry's DN. */ - ref_attrs = map_data->ref_attrs; - for (i = 0; (ref_attrs != NULL) && (ref_attrs[i] != NULL); i++) { - continue; - } - n_ref_attrs = i; - if (n_ref_attrs > 0) { - filter_size = strlen("(&(|))") + - strlen(map_data->entry_filter) + - 1; - ndn = slapi_entry_get_ndn(cbdata->e); - tndn = format_escape_for_filter(ndn); - if (tndn == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error building filter for " - "updating entries\n"); - return TRUE; - } - for (i = 0; - (ref_attrs != NULL) && (ref_attrs[i] != NULL); - i++) { - filter_size += (strlen("(=)") + - strlen(ref_attrs[i]) + - strlen(ndn)); - } - filter = malloc(filter_size); - if (filter == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error building filter for " - "updating entries\n"); - free(tndn); - return TRUE; - } - sprintf(filter, "(&%s(|", map_data->entry_filter); - for (i = 0; - (ref_attrs != NULL) && (ref_attrs[i] != NULL); - i++) { - sprintf(filter + strlen(filter), - "(%s=%s)", ref_attrs[i], tndn); - } - strcat(filter, "))"); - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "searching for referrers using filter \"%s\"\n", - filter); - free(tndn); - /* Update any matching entry. */ - for (i = 0; - (map_data->bases != NULL) && (map_data->bases[i] != NULL); - i++) { - slapi_search_internal_set_pb(cbdata->pb, - map_data->bases[i], - LDAP_SCOPE_SUB, - filter, - NULL, FALSE, - NULL, - NULL, - state->plugin_identity, - 0); - slapi_search_internal_callback_pb(cbdata->pb, map_data, - NULL, - backend_map_config_entry_set_one_cb, - NULL); - } - free(filter); - } - - /* Allocate the DN we'll use to hold values for comparison. */ - referred_to_sdn = slapi_sdn_new(); - if (referred_to_sdn == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error updating entries referred to by %s\n", - slapi_entry_get_ndn(cbdata->e)); - return TRUE; - } - - /* For every directory entry to which this directory entry refers and - * which also has a corresponding entry in this map, update it. */ - inref_attrs = map_data->inref_attrs; - for (i = 0; (inref_attrs != NULL) && (inref_attrs[i] != NULL); i++) { - /* We're only processing inref attributes for this map. */ - if ((strcmp(inref_attrs[i]->domain, domain) != 0) || - (strcmp(inref_attrs[i]->map, map) != 0)) { - continue; - } - /* Extract the named attribute from the entry. */ - values = NULL; - if (slapi_vattr_values_get(cbdata->e, - inref_attrs[i]->attribute, - &values, &disposition, &actual_attr, - 0, &buffer_flags) != 0) { - continue; - } - /* For each value of this attributes.. */ - for (j = slapi_valueset_first_value(values, &value); - j != -1; - j = slapi_valueset_next_value(values, j, &value)) { - /* Pull out the value, which is a referred-to entry's - * DN. */ - dn = slapi_value_get_string(value); - if (dn == NULL) { - continue; - } - /* Normalize the DN. */ - slapi_sdn_set_dn_byref(referred_to_sdn, dn); - ndn = slapi_sdn_get_ndn(referred_to_sdn); - /* If the named entry corresponds to an entry that's - * already in this map. */ - if (map_data_check_entry(state, domain, map, ndn)) { - /* ...update it. */ - backend_map_config_entry_set_one_dn(state, ndn, - map_data); - } - } - slapi_vattr_values_free(&values, &actual_attr, - buffer_flags); - } - slapi_sdn_free(&referred_to_sdn); - return TRUE; -} - -static void -backend_update_references(struct plugin_state *state, Slapi_Entry *e) -{ - struct backend_update_references_cbdata cbdata; - cbdata.e = e; - cbdata.pb = slapi_pblock_new(); - if (!map_data_foreach_map(state, NULL, - backend_update_references_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error updating references for \"%s\"\n", - slapi_entry_get_ndn(cbdata.e)); - } - slapi_pblock_destroy(cbdata.pb); -} - -/* Add any map entries which correspond to a directory server entry in this - * map. */ - -struct backend_add_entry_cbdata { - struct plugin_state *state; - Slapi_PBlock *pb; - Slapi_Entry *e; - char *ndn; -}; - -static bool_t -backend_add_entry_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cbdata_ptr) -{ - struct backend_map_data *map_data; - struct backend_add_entry_cbdata *cbdata; - - map_data = backend_data; - cbdata = cbdata_ptr; - - /* If the entry doesn't match the map, skip it. */ - if (!backend_entry_matches_map(map_data, cbdata->pb, cbdata->e)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "entry \"%s\" does not belong in " - "\"%s\"/\"%s\"\n", - cbdata->ndn, domain, map); - return TRUE; - } - - /* Set the entry in the map which corresponds to this entry, or clear - * any that might if this entry doesn't have a key and value. */ - backend_map_config_entry_set_one(cbdata->e, map_data); - - return TRUE; -} - -static int -backend_add_cb(Slapi_PBlock *pb) -{ - struct backend_add_entry_cbdata cbdata; - - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); - slapi_pblock_get(pb, SLAPI_ADD_TARGET, &cbdata.ndn); - slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e); - cbdata.pb = pb; - slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, - "added \"%s\"\n", cbdata.ndn); - - /* Check for NULL entries, indicative of a failure elsewhere (?). */ - if (cbdata.e == NULL) { - slapi_pblock_get(pb, SLAPI_ADD_EXISTING_DN_ENTRY, &cbdata.e); - if (cbdata.e == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "added entry is NULL\n"); - return 0; - } - } - - /* Add map entries which corresponded to this directory server - * entry. */ - map_wrlock(); - if (!map_data_foreach_map(cbdata.state, NULL, - backend_add_entry_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "error adding map entries corresponding to " - "\"%s\"\n", cbdata.ndn); - } - - /* If it's a map configuration entry, add and populate the maps it - * describes. */ - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "new entry \"%s\" is a map\n", cbdata.ndn); - backend_map_config_entry_add_cb(cbdata.e, cbdata.state); - } - - /* Update entries which need to be updated in case this new entry - * refers to them. */ - backend_update_references(cbdata.state, cbdata.e); - - map_unlock(); - return 0; -} - -struct backend_modify_entry_cbdata { - struct plugin_state *state; - Slapi_PBlock *pb; - LDAPMod **mods; - Slapi_Entry *e_pre, *e_post; - char *ndn; -}; - -static bool_t -backend_modify_entry_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cbdata_ptr) -{ - struct backend_map_data *map_data; - struct backend_modify_entry_cbdata *cbdata; - - map_data = backend_data; - cbdata = cbdata_ptr; - - /* If the entry used to match the map, remove it. */ - if (backend_entry_matches_map(map_data, cbdata->pb, cbdata->e_pre)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "clearing group/container/id " - "\"%s\"/\"%s\"/(\"%s\")\n", - map_data->group, map_data->container, - cbdata->ndn); - map_data_unset_entry_id(cbdata->state, - map_data->group, map_data->container, - cbdata->ndn); - } - /* If the entry now matches the map, add it (or re-add it). */ - if (backend_entry_matches_map(map_data, cbdata->pb, cbdata->e_post)) { - /* Set the entry in the map which corresponds to this entry, or - * clear any that might if this entry doesn't have a key and - * value. */ - backend_map_config_entry_set_one(cbdata->e_post, map_data); - } - return TRUE; -} - -static int -backend_modify_cb(Slapi_PBlock *pb) -{ - Slapi_DN *sdn; - struct backend_modify_entry_cbdata cbdata; - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); - slapi_pblock_get(pb, SLAPI_MODIFY_TARGET, &cbdata.ndn); - slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &cbdata.mods); - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); - slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); - cbdata.pb = pb; - slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, - "modified \"%s\"\n", cbdata.ndn); - /* Check for NULL entries, indicative of a failure elsewhere (?). */ - if (cbdata.e_pre == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "pre-modify entry is NULL\n"); - return 0; - } - if (cbdata.e_post == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "post-modify entry is NULL\n"); - return 0; - } - /* Modify map entries which corresponded to this directory server - * entry. */ - map_wrlock(); - if (!map_data_foreach_map(cbdata.state, NULL, - backend_modify_entry_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "error modifying map entries corresponding to " - "\"%s\"\n", cbdata.ndn); - } - /* Update entries which need to be updated in case this entry - * no longer refers to them. */ - backend_update_references(cbdata.state, cbdata.e_pre); - /* Update entries which need to be updated in case this entry - * now refers to them. */ - backend_update_references(cbdata.state, cbdata.e_post); - /* If it's a map configuration entry, reconfigure, clear, and - * repopulate the map. */ - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_pre)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "modified entry \"%s\" was a map\n", - cbdata.ndn); - backend_map_config_entry_delete_cb(cbdata.e_pre, cbdata.state); - } - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_post)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "modified entry \"%s\" is now a map\n", - cbdata.ndn); - backend_map_config_entry_add_cb(cbdata.e_post, cbdata.state); - } - map_unlock(); - return 0; -} - -struct backend_modrdn_entry_cbdata { - struct plugin_state *state; - Slapi_PBlock *pb; - Slapi_Entry *e_pre, *e_post; - char *ndn_pre, *ndn_post; -}; - -static bool_t -backend_modrdn_entry_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cbdata_ptr) -{ - struct backend_map_data *map_data; - struct backend_modrdn_entry_cbdata *cbdata; - bool_t matched_pre, matched_post; - - map_data = backend_data; - cbdata = cbdata_ptr; - - matched_pre = backend_entry_matches_map(map_data, - cbdata->pb, cbdata->e_pre); - matched_post = backend_entry_matches_map(map_data, - cbdata->pb, cbdata->e_post); - - /* Now decide what to set, or unset, in this map. */ - if (matched_pre) { - /* If it was a match for the map, clear the entry. */ - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "clearing group/container/id " - "\"%s\"/\"%s\"/(\"%s\")\n", - map_data->group, map_data->container, - cbdata->ndn_pre); - map_data_unset_entry_id(cbdata->state, - map_data->group, map_data->container, - cbdata->ndn_pre); - } - /* Set the entry in the map which corresponds to this entry, or clear - * any that might if this entry doesn't have a key and value. */ - if (matched_post) { - backend_map_config_entry_set_one(cbdata->e_post, map_data); - } - return TRUE; -} - -static int -backend_modrdn_cb(Slapi_PBlock *pb) -{ - struct backend_modrdn_entry_cbdata cbdata; - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); - slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); - cbdata.ndn_pre = slapi_entry_get_ndn(cbdata.e_pre); - cbdata.ndn_post = slapi_entry_get_ndn(cbdata.e_post); - cbdata.pb = pb; - slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, - "renamed \"%s\" to \"%s\"\n", - cbdata.ndn_pre, cbdata.ndn_post); - /* Check for NULL entries, indicative of a failure elsewhere (?). */ - if (cbdata.e_pre == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "pre-modrdn entry is NULL\n"); - return 0; - } - if (cbdata.e_post == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "post-modrdn entry is NULL\n"); - return 0; - } - /* Modify map entries which corresponded to this directory server - * entry. */ - map_wrlock(); - if (!map_data_foreach_map(cbdata.state, NULL, - backend_modrdn_entry_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "error renaming map entries corresponding to " - "\"%s\"\n", cbdata.ndn_post); - } - /* If it's a map configuration entry, reconfigure, clear, and - * repopulate the map. */ - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_pre)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "renamed entry \"%s\" was a map\n", - cbdata.e_pre); - backend_map_config_entry_delete_cb(cbdata.e_pre, cbdata.state); - } - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_post)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "renamed entry \"%s\" is now a map\n", - cbdata.e_post); - backend_map_config_entry_add_cb(cbdata.e_post, cbdata.state); - } - map_unlock(); - return 0; -} - -/* Delete any map entries which correspond to a directory server entry in this - * map. */ - -struct backend_delete_entry_cbdata { - struct plugin_state *state; - Slapi_PBlock *pb; - Slapi_Entry *e; - char *ndn; -}; - -static bool_t -backend_delete_entry_cb(const char *group, const char *container, bool_t secure, - void *backend_data, void *cbdata_ptr) +/* Re-read plugin-wide settings that may have changed. Nothing to do. */ +void +backend_update_params(struct plugin_state *state) { - struct backend_map_data *map_data; - struct backend_delete_entry_cbdata *cbdata; - map_data = backend_data; - cbdata = cbdata_ptr; - /* If it was in the map, remove it. */ - if (backend_entry_matches_map(map_data, cbdata->pb, cbdata->e)) { - /* Remove this entry from the map. */ - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "unsetting group/container/id" - "\"%s\"/\"%s\"=\"%s\"/\"%s\"/(\"%s\")\n", - group, container, - map_data->group, map_data->container, - cbdata->ndn); - map_data_unset_entry_id(cbdata->state, group, container, - cbdata->ndn); - } - return TRUE; } -/* Called by the server when a directory server entry is deleted. */ -static int -backend_delete_cb(Slapi_PBlock *pb) +/* Populate our data. */ +void +backend_startup(struct plugin_state *state) { - struct backend_delete_entry_cbdata cbdata; - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); - slapi_pblock_get(pb, SLAPI_DELETE_TARGET, &cbdata.ndn); - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e); - cbdata.pb = pb; - slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, - "deleted \"%s\"\n", cbdata.ndn); - /* Check for NULL entries, indicative of a failure elsewhere (?). */ - if (cbdata.e == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "deleted entry is NULL\n"); - return 0; - } - /* Remove map entries which corresponded to this directory server - * entry. */ - map_wrlock(); - if (!map_data_foreach_map(cbdata.state, NULL, - backend_delete_entry_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "error removing map entries corresponding to " - "\"%s\"\n", cbdata.ndn); - } - /* If it's a map configuration entry, remove the map. */ - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "deleted entry \"%s\" is a map\n", cbdata.ndn); - backend_map_config_entry_delete_cb(cbdata.e, cbdata.state); - } - /* Update entries which need to be updated in case this entry no longer - * refers to them. */ - backend_update_references(cbdata.state, cbdata.e); - map_unlock(); - return 0; + backend_shr_startup(state, SCH_CONTAINER_CONFIGURATION_FILTER); } -/* Set our post-op callbacks. */ +/* Set up our post-op callbacks. */ void backend_init(Slapi_PBlock *pb, struct plugin_state *state) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "hooking up postoperation callbacks\n"); - if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN, - backend_add_cb) != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "error hooking up add callback\n"); - } - if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN, - backend_modify_cb) != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "error hooking up modify callback\n"); - } - if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, - backend_modrdn_cb) != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "error hooking up modrdn callback\n"); - } - if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, - backend_delete_cb) != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "error hooking up delete callback\n"); - } + backend_shr_postop_init(pb, state); } diff --git a/src/back-shr.c b/src/back-shr.c index 84f6a3b..2c6f358 100644 --- a/src/back-shr.c +++ b/src/back-shr.c @@ -250,8 +250,7 @@ backend_shr_set_config_free_config(void *cb_data) { struct backend_set_data *set_data; set_data = cb_data; - backend_set_config_free_config(backend_set_config_get_state(set_data), - set_data); + backend_set_config_free_config(set_data); } int @@ -344,16 +343,15 @@ backend_shr_startup(struct plugin_state *state, const char *filter) /* Process a set configuration directory entry. Pull out the group and set * names which are specified in the entry and delete each in turn. */ -static int -backend_shr_set_config_entry_delete_cb(Slapi_Entry *e, void *callback_data, - const char *group_attr, - const char *set_attr) +int +backend_shr_set_config_entry_delete(struct plugin_state *state, + Slapi_Entry *e, + const char *group_attr, + const char *set_attr) { char **groups, **sets; int i, j; - struct plugin_state *state; - state = callback_data; groups = slapi_entry_attr_get_charray(e, group_attr); sets = slapi_entry_attr_get_charray(e, set_attr); for (i = 0; (groups != NULL) && (groups[i] != NULL); i++) { -- cgit From 8331cdefa16c98e178aefc38cca254a72627aeab Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 17:03:24 -0400 Subject: - merge the backend-specific headers - start switching to using the shared implementations in back-nis --- src/Makefile.am | 4 +- src/back-nis.c | 573 +------------------------------------------------------- src/back-nis.h | 8 - src/back-sch.c | 2 +- src/format.c | 2 +- src/map.c | 2 +- 6 files changed, 9 insertions(+), 582 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 442f3b8..809fe04 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ dist_noinst_SCRIPTS = ypmaplist.py plugin_LTLIBRARIES = nisserver-plugin.la schemacompat-plugin.la nisserver_plugin_la_SOURCES = \ back-nis.c \ - back-nis.h \ + backend.h \ back-shr.c \ back-shr.h \ defs-nis.c \ @@ -32,7 +32,7 @@ nisserver_plugin_la_LIBADD = $(RUNTIME_LIBS) $(LIBWRAP) -lnsl $(LIBPTHREAD) schemacompat_plugin_la_SOURCES = \ back-sch.c \ - back-sch.h \ + backend.h \ back-shr.c \ back-shr.h \ format.c \ diff --git a/src/back-nis.c b/src/back-nis.c index a91c4f3..00b824e 100644 --- a/src/back-nis.c +++ b/src/back-nis.c @@ -44,7 +44,7 @@ #endif #include "backend.h" -#include "back-nis.h" +#include "back-shr.h" #include "defs-nis.h" #include "disp-nis.h" #include "format.h" @@ -1221,8 +1221,8 @@ backend_entry_matches_map(struct backend_map_data *map_data, } /* Given an entry, return true if it describes a NIS map. */ -static bool_t -backend_entry_is_a_map(struct plugin_state *state, +bool_t +backend_entry_is_a_set(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e) { Slapi_DN *entry_sdn, *plugin_sdn; @@ -1279,574 +1279,9 @@ backend_entry_is_a_map(struct plugin_state *state, return ret; } -/* Update any entries to which the passed-in entry in the passed-in map refers - * to, if the referred-to entry is in this map. Everybody got that? */ -struct backend_update_references_cbdata { - Slapi_PBlock *pb; - Slapi_Entry *e; -}; - -static bool_t -backend_update_references_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cbdata_ptr) -{ - struct plugin_state *state; - struct backend_map_data *map_data; - struct backend_update_references_cbdata *cbdata; - Slapi_DN *referred_to_sdn; - Slapi_ValueSet *values; - Slapi_Value *value; - char **ref_attrs, *actual_attr, *filter, *tndn; - struct format_inref_attr **inref_attrs; - const char *ndn, *dn; - int i, j, disposition, buffer_flags, filter_size, n_ref_attrs; - - map_data = backend_data; - cbdata = cbdata_ptr; - state = map_data->state; - - /* For every entry in this map which refers to this entry using - * a DN stored in an attribute, update that entry. */ - - /* Build a filter with all of these attributes and this entry's DN. */ - ref_attrs = map_data->ref_attrs; - for (i = 0; (ref_attrs != NULL) && (ref_attrs[i] != NULL); i++) { - continue; - } - n_ref_attrs = i; - if (n_ref_attrs > 0) { - filter_size = strlen("(&(|))") + - strlen(map_data->entry_filter) + - 1; - ndn = slapi_entry_get_ndn(cbdata->e); - tndn = format_escape_for_filter(ndn); - if (tndn == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error building filter for " - "updating entries\n"); - return TRUE; - } - for (i = 0; - (ref_attrs != NULL) && (ref_attrs[i] != NULL); - i++) { - filter_size += (strlen("(=)") + - strlen(ref_attrs[i]) + - strlen(ndn)); - } - filter = malloc(filter_size); - if (filter == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error building filter for " - "updating entries\n"); - free(tndn); - return TRUE; - } - sprintf(filter, "(&%s(|", map_data->entry_filter); - for (i = 0; - (ref_attrs != NULL) && (ref_attrs[i] != NULL); - i++) { - sprintf(filter + strlen(filter), - "(%s=%s)", ref_attrs[i], tndn); - } - strcat(filter, "))"); - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "searching for referrers using filter \"%s\"\n", - filter); - free(tndn); - /* Update any matching entry. */ - for (i = 0; - (map_data->bases != NULL) && (map_data->bases[i] != NULL); - i++) { - slapi_search_internal_set_pb(cbdata->pb, - map_data->bases[i], - LDAP_SCOPE_SUB, - filter, - NULL, FALSE, - NULL, - NULL, - state->plugin_identity, - 0); - slapi_search_internal_callback_pb(cbdata->pb, map_data, - NULL, - backend_map_config_entry_set_one_cb, - NULL); - } - free(filter); - } - - /* Allocate the DN we'll use to hold values for comparison. */ - referred_to_sdn = slapi_sdn_new(); - if (referred_to_sdn == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error updating entries referred to by %s\n", - slapi_entry_get_ndn(cbdata->e)); - return TRUE; - } - - /* For every directory entry to which this directory entry refers and - * which also has a corresponding entry in this map, update it. */ - inref_attrs = map_data->inref_attrs; - for (i = 0; (inref_attrs != NULL) && (inref_attrs[i] != NULL); i++) { - /* We're only processing inref attributes for this map. */ - if ((strcmp(inref_attrs[i]->domain, domain) != 0) || - (strcmp(inref_attrs[i]->map, map) != 0)) { - continue; - } - /* Extract the named attribute from the entry. */ - values = NULL; - if (slapi_vattr_values_get(cbdata->e, - inref_attrs[i]->attribute, - &values, &disposition, &actual_attr, - 0, &buffer_flags) != 0) { - continue; - } - /* For each value of this attributes.. */ - for (j = slapi_valueset_first_value(values, &value); - j != -1; - j = slapi_valueset_next_value(values, j, &value)) { - /* Pull out the value, which is a referred-to entry's - * DN. */ - dn = slapi_value_get_string(value); - if (dn == NULL) { - continue; - } - /* Normalize the DN. */ - slapi_sdn_set_dn_byref(referred_to_sdn, dn); - ndn = slapi_sdn_get_ndn(referred_to_sdn); - /* If the named entry corresponds to an entry that's - * already in this map. */ - if (map_data_check_entry(state, domain, map, ndn)) { - /* ...update it. */ - backend_map_config_entry_set_one_dn(state, ndn, - map_data); - } - } - slapi_vattr_values_free(&values, &actual_attr, - buffer_flags); - } - slapi_sdn_free(&referred_to_sdn); - return TRUE; -} - -static void -backend_update_references(struct plugin_state *state, Slapi_Entry *e) -{ - struct backend_update_references_cbdata cbdata; - cbdata.e = e; - cbdata.pb = slapi_pblock_new(); - if (!map_data_foreach_map(state, NULL, - backend_update_references_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error updating references for \"%s\"\n", - slapi_entry_get_ndn(cbdata.e)); - } - slapi_pblock_destroy(cbdata.pb); -} - -/* Add any map entries which correspond to a directory server entry in this - * map. */ - -struct backend_add_entry_cbdata { - struct plugin_state *state; - Slapi_PBlock *pb; - Slapi_Entry *e; - char *ndn; -}; - -static bool_t -backend_add_entry_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cbdata_ptr) -{ - struct backend_map_data *map_data; - struct backend_add_entry_cbdata *cbdata; - - map_data = backend_data; - cbdata = cbdata_ptr; - - /* If the entry doesn't match the map, skip it. */ - if (!backend_entry_matches_map(map_data, cbdata->pb, cbdata->e)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "entry \"%s\" does not belong in " - "\"%s\"/\"%s\"\n", - cbdata->ndn, domain, map); - return TRUE; - } - - /* Set the entry in the map which corresponds to this entry, or clear - * any that might if this entry doesn't have a key and value. */ - backend_map_config_entry_set_one(cbdata->e, map_data); - - return TRUE; -} - -static int -backend_add_cb(Slapi_PBlock *pb) -{ - struct backend_add_entry_cbdata cbdata; - - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); - slapi_pblock_get(pb, SLAPI_ADD_TARGET, &cbdata.ndn); - slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e); - cbdata.pb = pb; - slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, - "added \"%s\"\n", cbdata.ndn); - - /* Check for NULL entries, indicative of a failure elsewhere (?). */ - if (cbdata.e == NULL) { - slapi_pblock_get(pb, SLAPI_ADD_EXISTING_DN_ENTRY, &cbdata.e); - if (cbdata.e == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "added entry is NULL\n"); - return 0; - } - } - - /* Add map entries which corresponded to this directory server - * entry. */ - map_wrlock(); - if (!map_data_foreach_map(cbdata.state, NULL, - backend_add_entry_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "error adding map entries corresponding to " - "\"%s\"\n", cbdata.ndn); - } - - /* If it's a map configuration entry, add and populate the maps it - * describes. */ - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "new entry \"%s\" is a map\n", cbdata.ndn); - backend_map_config_entry_add_cb(cbdata.e, cbdata.state); - } - - /* Update entries which need to be updated in case this new entry - * refers to them. */ - backend_update_references(cbdata.state, cbdata.e); - - map_unlock(); - return 0; -} - -struct backend_modify_entry_cbdata { - struct plugin_state *state; - Slapi_PBlock *pb; - LDAPMod **mods; - Slapi_Entry *e_pre, *e_post; - char *ndn; -}; - -static bool_t -backend_modify_entry_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cbdata_ptr) -{ - struct backend_map_data *map_data; - struct backend_modify_entry_cbdata *cbdata; - - map_data = backend_data; - cbdata = cbdata_ptr; - - /* If the entry used to match the map, remove it. */ - if (backend_entry_matches_map(map_data, cbdata->pb, cbdata->e_pre)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "clearing domain/map/id " - "\"%s\"/\"%s\"/(\"%s\")\n", - map_data->domain, map_data->map, cbdata->ndn); - map_data_unset_entry_id(cbdata->state, - map_data->domain, map_data->map, - cbdata->ndn); - } - /* If the entry now matches the map, add it (or re-add it). */ - if (backend_entry_matches_map(map_data, cbdata->pb, cbdata->e_post)) { - /* Set the entry in the map which corresponds to this entry, or - * clear any that might if this entry doesn't have a key and - * value. */ - backend_map_config_entry_set_one(cbdata->e_post, map_data); - } - return TRUE; -} - -static int -backend_modify_cb(Slapi_PBlock *pb) -{ - Slapi_DN *sdn; - struct backend_modify_entry_cbdata cbdata; - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); - slapi_pblock_get(pb, SLAPI_MODIFY_TARGET, &cbdata.ndn); - slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &cbdata.mods); - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); - slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); - cbdata.pb = pb; - slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, - "modified \"%s\"\n", cbdata.ndn); - /* Check for NULL entries, indicative of a failure elsewhere (?). */ - if (cbdata.e_pre == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "pre-modify entry is NULL\n"); - return 0; - } - if (cbdata.e_post == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "post-modify entry is NULL\n"); - return 0; - } - /* Modify map entries which corresponded to this directory server - * entry. */ - map_wrlock(); - if (!map_data_foreach_map(cbdata.state, NULL, - backend_modify_entry_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "error modifying map entries corresponding to " - "\"%s\"\n", cbdata.ndn); - } - /* Update entries which need to be updated in case this entry - * no longer refers to them. */ - backend_update_references(cbdata.state, cbdata.e_pre); - /* Update entries which need to be updated in case this entry - * now refers to them. */ - backend_update_references(cbdata.state, cbdata.e_post); - /* If it's a map configuration entry, reconfigure, clear, and - * repopulate the map. */ - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_pre)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "modified entry \"%s\" was a map\n", - cbdata.ndn); - backend_map_config_entry_delete_cb(cbdata.e_pre, cbdata.state); - } - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_post)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "modified entry \"%s\" is now a map\n", - cbdata.ndn); - backend_map_config_entry_add_cb(cbdata.e_post, cbdata.state); - } - /* Lastly, if the entry is our own entry, re-read parameters. */ - sdn = slapi_sdn_new_dn_byref(cbdata.state->plugin_base); - if (sdn != NULL) { - if ((strcmp(slapi_entry_get_ndn(cbdata.e_pre), - slapi_sdn_get_ndn(sdn)) == 0) || - (strcmp(slapi_entry_get_ndn(cbdata.e_post), - slapi_sdn_get_ndn(sdn)) == 0)) { - backend_read_params(cbdata.state); - } - slapi_sdn_free(&sdn); - } - map_unlock(); - return 0; -} - -struct backend_modrdn_entry_cbdata { - struct plugin_state *state; - Slapi_PBlock *pb; - Slapi_Entry *e_pre, *e_post; - char *ndn_pre, *ndn_post; -}; - -static bool_t -backend_modrdn_entry_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cbdata_ptr) -{ - struct backend_map_data *map_data; - struct backend_modrdn_entry_cbdata *cbdata; - bool_t matched_pre, matched_post; - - map_data = backend_data; - cbdata = cbdata_ptr; - - matched_pre = backend_entry_matches_map(map_data, - cbdata->pb, cbdata->e_pre); - matched_post = backend_entry_matches_map(map_data, - cbdata->pb, cbdata->e_post); - - /* Now decide what to set, or unset, in this map. */ - if (matched_pre) { - /* If it was a match for the map, clear the entry. */ - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "clearing domain/map/id " - "\"%s\"/\"%s\"/(\"%s\")\n", - map_data->domain, map_data->map, - cbdata->ndn_pre); - map_data_unset_entry_id(cbdata->state, - map_data->domain, map_data->map, - cbdata->ndn_pre); - } - /* Set the entry in the map which corresponds to this entry, or clear - * any that might if this entry doesn't have a key and value. */ - if (matched_post) { - backend_map_config_entry_set_one(cbdata->e_post, map_data); - } - return TRUE; -} - -static int -backend_modrdn_cb(Slapi_PBlock *pb) -{ - struct backend_modrdn_entry_cbdata cbdata; - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); - slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); - cbdata.ndn_pre = slapi_entry_get_ndn(cbdata.e_pre); - cbdata.ndn_post = slapi_entry_get_ndn(cbdata.e_post); - cbdata.pb = pb; - slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, - "renamed \"%s\" to \"%s\"\n", - cbdata.ndn_pre, cbdata.ndn_post); - /* Check for NULL entries, indicative of a failure elsewhere (?). */ - if (cbdata.e_pre == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "pre-modrdn entry is NULL\n"); - return 0; - } - if (cbdata.e_post == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "post-modrdn entry is NULL\n"); - return 0; - } - /* Modify map entries which corresponded to this directory server - * entry. */ - map_wrlock(); - if (!map_data_foreach_map(cbdata.state, NULL, - backend_modrdn_entry_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "error renaming map entries corresponding to " - "\"%s\"\n", cbdata.ndn_post); - } - /* If it's a map configuration entry, reconfigure, clear, and - * repopulate the map. */ - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_pre)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "renamed entry \"%s\" was a map\n", - cbdata.e_pre); - backend_map_config_entry_delete_cb(cbdata.e_pre, cbdata.state); - } - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e_post)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "renamed entry \"%s\" is now a map\n", - cbdata.e_post); - backend_map_config_entry_add_cb(cbdata.e_post, cbdata.state); - } - map_unlock(); - return 0; -} - -/* Delete any map entries which correspond to a directory server entry in this - * map. */ - -struct backend_delete_entry_cbdata { - struct plugin_state *state; - Slapi_PBlock *pb; - Slapi_Entry *e; - char *ndn; -}; - -static bool_t -backend_delete_entry_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cbdata_ptr) -{ - struct backend_map_data *map_data; - struct backend_delete_entry_cbdata *cbdata; - map_data = backend_data; - cbdata = cbdata_ptr; - /* If it was in the map, remove it. */ - if (backend_entry_matches_map(map_data, cbdata->pb, cbdata->e)) { - /* Remove this entry from the map. */ - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "unsetting domain/map/id" - "\"%s\"/\"%s\"=\"%s\"/\"%s\"/(\"%s\")\n", - domain, map, - map_data->domain, map_data->map, - cbdata->ndn); - map_data_unset_entry_id(cbdata->state, domain, map, - cbdata->ndn); - } - return TRUE; -} - -/* Called by the server when a directory server entry is deleted. */ -static int -backend_delete_cb(Slapi_PBlock *pb) -{ - struct backend_delete_entry_cbdata cbdata; - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); - slapi_pblock_get(pb, SLAPI_DELETE_TARGET, &cbdata.ndn); - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e); - cbdata.pb = pb; - slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, - "deleted \"%s\"\n", cbdata.ndn); - /* Check for NULL entries, indicative of a failure elsewhere (?). */ - if (cbdata.e == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "deleted entry is NULL\n"); - return 0; - } - /* Remove map entries which corresponded to this directory server - * entry. */ - map_wrlock(); - if (!map_data_foreach_map(cbdata.state, NULL, - backend_delete_entry_cb, &cbdata)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "error removing map entries corresponding to " - "\"%s\"\n", cbdata.ndn); - } - /* If it's a map configuration entry, remove the map. */ - if (backend_entry_is_a_map(cbdata.state, pb, cbdata.e)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, - "deleted entry \"%s\" is a map\n", cbdata.ndn); - backend_map_config_entry_delete_cb(cbdata.e, cbdata.state); - } - /* Update entries which need to be updated in case this entry no longer - * refers to them. */ - backend_update_references(cbdata.state, cbdata.e); - map_unlock(); - return 0; -} - /* Set our post-op callbacks. */ void backend_init(Slapi_PBlock *pb, struct plugin_state *state) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "hooking up postoperation callbacks\n"); - if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN, - backend_add_cb) != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "error hooking up add callback\n"); - } - if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN, - backend_modify_cb) != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "error hooking up modify callback\n"); - } - if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, - backend_modrdn_cb) != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "error hooking up modrdn callback\n"); - } - if (slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, - backend_delete_cb) != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "error hooking up delete callback\n"); - } + backend_shr_postop_init(pb, state); } diff --git a/src/back-nis.h b/src/back-nis.h index a97fc18..1f9aa9c 100644 --- a/src/back-nis.h +++ b/src/back-nis.h @@ -23,12 +23,4 @@ #define back_nis_h struct plugin_state; struct slapi_pblock; -int backend_read_master_name(struct plugin_state *state, char **master); -void backend_free_master_name(struct plugin_state *state, char *master); -void backend_startup(struct plugin_state *state); -void backend_init(struct slapi_pblock *pb, struct plugin_state *state); -void backend_get_map_config(struct plugin_state *state, - const char *domain, const char *map, - char ***bases, char **entry_filter); -void backend_free_map_config(char **bases, char *entry_filter); #endif diff --git a/src/back-sch.c b/src/back-sch.c index 1e63c60..604d9ab 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -44,7 +44,7 @@ #endif #include "backend.h" -#include "back-sch.h" +#include "backend.h" #include "back-shr.h" #include "format.h" #include "plugin.h" diff --git a/src/format.c b/src/format.c index a17024d..c1482c6 100644 --- a/src/format.c +++ b/src/format.c @@ -41,7 +41,7 @@ #include -#include "back-nis.h" +#include "backend.h" #include "back-shr.h" #include "format.h" #include "plugin.h" diff --git a/src/map.c b/src/map.c index 385e590..5494886 100644 --- a/src/map.c +++ b/src/map.c @@ -40,7 +40,7 @@ #include -#include "back-nis.h" +#include "backend.h" #include "disp-nis.h" #include "map.h" #include "portmap.h" -- cgit From 3d8db6808b7b3707ff8958ff3c8ee9cdd69e3fd7 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 17:35:41 -0400 Subject: - add a data entry, not a map, to the map cache when we encounter entries at startup --- src/back-nis.c | 474 ++++++++++++++++----------------------------------------- src/back-shr.c | 6 +- 2 files changed, 139 insertions(+), 341 deletions(-) (limited to 'src') diff --git a/src/back-nis.c b/src/back-nis.c index 00b824e..5597255 100644 --- a/src/back-nis.c +++ b/src/back-nis.c @@ -54,7 +54,7 @@ #define NIS_MAP_CONFIGURATION_FILTER "(&(objectClass=*)(" NIS_MAP_CONFIGURATION_BASE_ATTR "=*)(" NIS_MAP_CONFIGURATION_DOMAIN_ATTR "=*)(" NIS_MAP_CONFIGURATION_MAP_ATTR "=*))" /* The data we ask the map cache to keep, for us, for each map. */ -struct backend_map_data { +struct backend_set_data { struct plugin_state *state; char *domain, *map, **bases, *entry_filter; char **key_formats, **keys_formats, *value_format; @@ -69,145 +69,77 @@ struct backend_map_data { void backend_free_master_name(struct plugin_state *state, char *master) { - free(master); + backend_shr_free_server_name(state, master); } int backend_read_master_name(struct plugin_state *state, char **master) { - Slapi_DN *config_dn; - Slapi_Entry *config; - Slapi_ValueSet *values; - Slapi_Value *value; - char *attrs[] = {"nsslapd-localhost", NULL}, *actual_attr; - const char *cvalue; - int disposition, buffer_flags; - *master = NULL; - /* Try to read our name from the top-level configuration node. */ - config_dn = slapi_sdn_new_dn_byval("cn=config"); - if (config_dn == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "backend_master_name: " - "error parsing \"cn=config\"\n"); - return -1; - } - config = NULL; - slapi_search_internal_get_entry(config_dn, attrs, &config, - state->plugin_identity); - if (config == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "backend_master_name: failure reading entry " - "\"cn=config\"\n"); - slapi_sdn_free(&config_dn); - return -1; - } - slapi_sdn_free(&config_dn); - /* Pull out the attribute. */ - if (slapi_vattr_values_get(config, attrs[0], &values, - &disposition, &actual_attr, - 0, &buffer_flags) == 0) { - if (slapi_valueset_first_value(values, &value) == 0) { - cvalue = slapi_value_get_string(value); - if (cvalue != NULL) { - *master = strdup(cvalue); - } - } else { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "backend_master_name: no \"%s\" value " - "for \"cn=config\"", - attrs[0]); - } - slapi_vattr_values_free(&values, &actual_attr, buffer_flags); - } - slapi_entry_free(config); - return (*master != NULL) ? 0 : -1; + return backend_shr_read_server_name(state, master); } -static void -backend_free_strlist(char **strlist) + +/* Manipulate map configuration data. */ +struct plugin_state * +backend_set_config_get_state(struct backend_set_data *set_data) { - if (strlist) { - free(strlist); - } + return set_data->state; } - -/* Manipulate string lists. */ -static char ** -backend_dup_strlist_n(char **strlist, int n) +char ** +backend_set_config_get_bases(struct backend_set_data *set_data) { - int i, l; - char **ret, *s; - /* Handle the NULL case. */ - if (strlist == NULL) { - return NULL; - } - /* No strings = no list. */ - if (n == 0) { - return NULL; - } - /* Count the amount of space needed for the strings. */ - for (i = 0, l = 0; i < n; i++) { - l += (strlen(strlist[i]) + 1); - } - /* Allocate space for the array of pointers (with NULL terminator) and - * then the string data. */ - ret = malloc(((n + 1) * sizeof(char *)) + l); - if (ret != NULL) { - /* Figure out where the string data will start. */ - s = (char *) ret; - s += ((n + 1) * sizeof(char *)); - for (i = 0; i < n; i++) { - /* Set the address of this string, copy the data - * around, and then prepare the address of the next - * string. */ - ret[i] = s; - strcpy(s, strlist[i]); - s += (strlen(strlist[i]) + 1); - } - /* NULL-terminate the array. */ - ret[i] = NULL; - } - return ret; + return set_data->bases; } -static char ** -backend_dup_strlist(char **strlist) +char * +backend_set_config_get_filter(struct backend_set_data *set_data) { - int i; - for (i = 0; (strlist != NULL) && (strlist[i] != NULL); i++) { - continue; - } - return backend_dup_strlist_n(strlist, i); + return set_data->entry_filter; +} +char * +backend_set_config_get_group(struct backend_set_data *set_data) +{ + return set_data->domain; +} +char * +backend_set_config_get_set(struct backend_set_data *set_data) +{ + return set_data->map; +} +struct format_inref_attr ** +backend_set_config_get_inref_attrs(struct backend_set_data *set_data) +{ + return set_data->inref_attrs; +} +char ** +backend_set_config_get_ref_attrs(struct backend_set_data *set_data) +{ + return set_data->ref_attrs; } - -/* Manipulate map data. */ static void -backend_free_map_data_contents(void *data) +backend_free_set_data_contents(void *data) { - struct backend_map_data *map_data = data; - if (map_data != NULL) { - free(map_data->domain); - free(map_data->map); - free(map_data->bases); - free(map_data->disallowed_chars); - format_free_attr_list(map_data->ref_attrs); - format_free_inref_attrs(map_data->inref_attrs); - free(map_data->entry_filter); - backend_free_strlist(map_data->key_formats); - backend_free_strlist(map_data->keys_formats); - free(map_data->value_format); + struct backend_set_data *set_data = data; + if (set_data != NULL) { + free(set_data->domain); + free(set_data->map); + free(set_data->bases); + free(set_data->disallowed_chars); + format_free_attr_list(set_data->ref_attrs); + format_free_inref_attrs(set_data->inref_attrs); + free(set_data->entry_filter); + backend_shr_free_strlist(set_data->key_formats); + backend_shr_free_strlist(set_data->keys_formats); + free(set_data->value_format); } } -static void -backend_free_map_data(void *data) +void +backend_set_config_free_config(struct backend_set_data *data) { - backend_free_map_data_contents(data); + backend_free_set_data_contents(data); free(data); } -static struct backend_map_data * -backend_copy_map_data(const struct backend_map_data *data) +static struct backend_set_data * +backend_copy_set_data(const struct backend_set_data *data) { - struct backend_map_data *ret; + struct backend_set_data *ret; ret = malloc(sizeof(*ret)); if (ret == NULL) { return NULL; @@ -215,7 +147,7 @@ backend_copy_map_data(const struct backend_map_data *data) ret->state = data->state; ret->domain = strdup(data->domain); ret->map = strdup(data->map); - ret->bases = backend_dup_strlist(data->bases); + ret->bases = backend_shr_dup_strlist(data->bases); ret->disallowed_chars = data->disallowed_chars ? strdup(data->disallowed_chars) : NULL; ret->ref_attrs = data->ref_attrs ? @@ -225,8 +157,8 @@ backend_copy_map_data(const struct backend_map_data *data) format_dup_inref_attrs(data->inref_attrs) : NULL; ret->entry_filter = strdup(data->entry_filter); - ret->key_formats = backend_dup_strlist(data->key_formats); - ret->keys_formats = backend_dup_strlist(data->keys_formats); + ret->key_formats = backend_shr_dup_strlist(data->key_formats); + ret->keys_formats = backend_shr_dup_strlist(data->keys_formats); ret->n_key_formats = data->n_key_formats; ret->n_keys_formats = data->n_keys_formats; ret->value_format = strdup(data->value_format); @@ -236,7 +168,7 @@ backend_copy_map_data(const struct backend_map_data *data) (ret->entry_filter == NULL) || ((ret->key_formats == NULL) && (ret->keys_formats == NULL)) || (ret->value_format == NULL)) { - backend_free_map_data(ret); + backend_set_config_free_config(ret); return NULL; } return ret; @@ -245,13 +177,11 @@ backend_copy_map_data(const struct backend_map_data *data) /* Given a map-entry directory entry, determine which keys it should have, * determine which value should be associated with those keys, and add them to * the map cache. */ -static int -backend_map_config_entry_add_one_cb(Slapi_Entry *e, void *callback_data) +void +backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data) { - struct backend_map_data *data; char **keys, ***key_sets, **all_keys, *value, *ndn, *plugin_id; int i, j, k, n_key_sets; - data = callback_data; plugin_id = data->state->plugin_desc->spd_id; /* Pull out the NDN of this entry. */ ndn = slapi_entry_get_ndn(e); @@ -285,7 +215,7 @@ backend_map_config_entry_add_one_cb(Slapi_Entry *e, void *callback_data) format_free_data(keys[k]); } free(keys); - return 0; + return; } } keys[j] = NULL; @@ -389,49 +319,6 @@ backend_map_config_entry_add_one_cb(Slapi_Entry *e, void *callback_data) } free(keys); } - return 0; -} - -static int -backend_map_config_entry_set_one_cb(Slapi_Entry *e, void *cbdata) -{ - backend_map_config_entry_add_one_cb(e, cbdata); - return 0; -} - -static void -backend_map_config_entry_set_one(Slapi_Entry *e, - struct backend_map_data *map_data) -{ - backend_map_config_entry_set_one_cb(e, map_data); -} - -static void -backend_map_config_entry_set_one_dn(struct plugin_state *state, const char *dn, - struct backend_map_data *map_data) -{ - Slapi_DN *sdn; - Slapi_Entry *entry; - sdn = slapi_sdn_new_dn_byval(dn); - if (sdn == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "error parsing DN \"%s\"\n", dn); - return; - } else { - entry = NULL; - slapi_search_internal_get_entry(sdn, NULL, &entry, - state->plugin_identity); - if (entry == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "failure reading entry \"%s\"\n", dn); - } else { - backend_map_config_entry_set_one(entry, map_data); - slapi_entry_free(entry); - } - slapi_sdn_free(&sdn); - } } /* @@ -500,13 +387,14 @@ backend_map_config_filter(const char *format, return ret; } -/* Given an entry, read the map configuration for the given domain and map - * name. */ -static void -backend_map_config_read_config(struct plugin_state *state, Slapi_Entry *e, +/* Given an entry, read the rest of the map configuration for the given domain + * and map name. */ +void +backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e, const char *domain, const char *map, - bool_t *secure, struct backend_map_data *ret) + bool_t *secure, struct backend_set_data **pret) { + struct backend_set_data ret; const char *default_filter, *default_key_format, *default_keys_format; const char *default_value_format, *default_disallowed_chars; char **bases, *entry_filter; @@ -655,21 +543,21 @@ backend_map_config_read_config(struct plugin_state *state, Slapi_Entry *e, default_filter, domain, map); use_key_formats = key_formats ? - backend_dup_strlist(key_formats) : + backend_shr_dup_strlist(key_formats) : default_key_format ? - backend_dup_strlist_n((char **) &default_key_format, - 1) : + backend_shr_dup_strlist_n((char **) &default_key_format, + 1) : NULL; use_keys_formats = keys_formats ? - backend_dup_strlist(keys_formats) : + backend_shr_dup_strlist(keys_formats) : default_keys_format ? - backend_dup_strlist_n((char **) &default_keys_format, - 1) : + backend_shr_dup_strlist_n((char **) &default_keys_format, + 1) : NULL; use_value_format = value_format ? strdup(value_format) : strdup(default_value_format); - use_bases = backend_dup_strlist(bases); + use_bases = backend_shr_dup_strlist(bases); use_disallowed_chars = disallowed_chars ? disallowed_chars : (default_disallowed_chars ? @@ -677,25 +565,25 @@ backend_map_config_read_config(struct plugin_state *state, Slapi_Entry *e, NULL); /* Free the values we read from the entry. */ free(value_format); - backend_free_strlist(key_formats); - backend_free_strlist(keys_formats); + backend_shr_free_strlist(key_formats); + backend_shr_free_strlist(keys_formats); free(entry_filter); - backend_free_strlist(bases); + backend_shr_free_strlist(bases); /* Populate the returned structure. */ - ret->state = state; - ret->domain = strdup(domain); - ret->map = strdup(map); - ret->bases = use_bases; - ret->disallowed_chars = use_disallowed_chars; - ret->entry_filter = use_entry_filter; - ret->key_formats = use_key_formats; - ret->n_key_formats = 0; - ret->keys_formats = use_keys_formats; - ret->n_keys_formats = 0; - ret->value_format = use_value_format; - ret->ref_attrs = NULL; - ret->inref_attrs = NULL; - ret->n_key_formats = 0; + ret.state = state; + ret.domain = strdup(domain); + ret.map = strdup(map); + ret.bases = use_bases; + ret.disallowed_chars = use_disallowed_chars; + ret.entry_filter = use_entry_filter; + ret.key_formats = use_key_formats; + ret.n_key_formats = 0; + ret.keys_formats = use_keys_formats; + ret.n_keys_formats = 0; + ret.value_format = use_value_format; + ret.ref_attrs = NULL; + ret.inref_attrs = NULL; + ret.n_key_formats = 0; for (i = 0; (use_key_formats != NULL) && (use_key_formats[i] != NULL); i++) { @@ -708,7 +596,7 @@ backend_map_config_read_config(struct plugin_state *state, Slapi_Entry *e, map, domain, use_entry_filter, use_key_formats[i], use_value_format); - ret->n_key_formats++; + ret.n_key_formats++; } for (i = 0; (use_keys_formats != NULL) && (use_keys_formats[i] != NULL); @@ -722,77 +610,24 @@ backend_map_config_read_config(struct plugin_state *state, Slapi_Entry *e, map, domain, use_entry_filter, use_keys_formats[i], use_value_format); - ret->n_keys_formats++; + ret.n_keys_formats++; } -} - -/* Given a directory server entry which represents a map's configuration, set - * up and populate the map. */ -static int -backend_map_config_entry_add_one(struct plugin_state *state, Slapi_Entry *e, - const char *domain, const char *map) -{ - Slapi_PBlock *pb; - int i; - bool_t secure; - struct backend_map_data cb_data, *map_cb_data; - - pb = slapi_pblock_new(); - secure = FALSE; - backend_map_config_read_config(state, e, domain, map, &secure, - &cb_data); - map_cb_data = backend_copy_map_data(&cb_data); - backend_free_map_data_contents(&cb_data); - if (map_cb_data == NULL) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "incomplete map definition %s in %s (2)\n", - map, domain); - slapi_pblock_destroy(pb); - return 0; - } - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "initializing map %s in %s, secure=%s (2)\n", - map, domain, secure ? "yes" : "no"); - map_data_set_map(state, domain, map, secure, - map_cb_data, &backend_free_map_data); - map_data_clear_map(state, domain, map); - /* Search under each base in turn, adding the matching directory - * entries to the NIS maps. */ - for (i = 0; - (map_cb_data->bases != NULL) && (map_cb_data->bases[i] != NULL); - i++) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "searching '%s' for '%s'\n", - map_cb_data->bases[i], - map_cb_data->entry_filter); - slapi_search_internal_set_pb(pb, - map_cb_data->bases[i], - LDAP_SCOPE_SUB, - map_cb_data->entry_filter, - NULL, FALSE, - NULL, - NULL, - state->plugin_identity, - 0); - slapi_search_internal_callback_pb(pb, map_cb_data, - NULL, - backend_map_config_entry_add_one_cb, - NULL); - slapi_free_search_results_internal(pb); - } - /* Clean up. */ - slapi_pblock_destroy(pb); - return 0; + *pret = backend_copy_set_data(&ret); + free(ret.domain); + free(ret.map); + backend_shr_free_strlist(ret.bases); + free(ret.disallowed_chars); + free(ret.entry_filter); + backend_shr_free_strlist(ret.key_formats); + backend_shr_free_strlist(ret.keys_formats); + free(ret.value_format); } /* Process a map configuration directory entry. Pull out the domain and map * names which are valid for this configuration and configure such a map for * each in turn. */ -static int -backend_map_config_entry_add_cb(Slapi_Entry *e, void *callback_data) +int +backend_set_config_entry_add_cb(Slapi_Entry *e, void *callback_data) { char **domains, **maps, *actual_attr; const char *cvalue; @@ -838,9 +673,9 @@ backend_map_config_entry_add_cb(Slapi_Entry *e, void *callback_data) } for (i = 0; (domains != NULL) && (domains[i] != NULL); i++) { for (j = 0; (maps != NULL) && (maps[j] != NULL); j++) { - ret = backend_map_config_entry_add_one(state, e, - domains[i], - maps[j]); + ret = backend_shr_set_config_entry_add_one(state, e, + domains[i], + maps[j]); } } if (domains != NULL) { @@ -859,8 +694,8 @@ backend_map_config_entry_add_cb(Slapi_Entry *e, void *callback_data) } /* Update/initialize parameters stored in the plugin's configuration entry. */ -static void -backend_read_params(struct plugin_state *state) +void +backend_update_params(struct plugin_state *state) { Slapi_DN *our_dn; Slapi_Entry *our_entry; @@ -882,7 +717,7 @@ backend_read_params(struct plugin_state *state) if (our_dn == NULL) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "backend_read_params: " + "backend_update_params: " "error parsing %s%s%s\n", state->plugin_base ? "\"" : "", state->plugin_base ? @@ -897,7 +732,7 @@ backend_read_params(struct plugin_state *state) if (our_entry == NULL) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "backend_read_params: failure reading entry " + "backend_update_params: failure reading entry " "\"%s\"\n", state->plugin_base); return; } @@ -920,7 +755,7 @@ backend_read_params(struct plugin_state *state) } slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "backend_read_params: " + "backend_update_params: " "setting max value " "size %u\n", state->max_value_size); @@ -935,7 +770,7 @@ backend_read_params(struct plugin_state *state) } slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "backend_read_params: " + "backend_update_params: " "setting max dgram " "size %u\n", state->max_dgram_size); @@ -965,7 +800,7 @@ backend_read_params(struct plugin_state *state) } else { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "backend_read_params: no \"%s\" value " + "backend_update_params: no \"%s\" value " "for \"%s\", using default\n", attrs[i], state->plugin_base); } @@ -973,64 +808,20 @@ backend_read_params(struct plugin_state *state) slapi_entry_free(our_entry); } -/* Scan for the list of configured domains and maps. */ -void -backend_startup(struct plugin_state *state) -{ - Slapi_PBlock *pb; - - backend_read_params(state); - - pb = slapi_pblock_new(); - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "searching \"%s\" for maps\n", state->plugin_base); - slapi_search_internal_set_pb(pb, - state->plugin_base, - LDAP_SCOPE_ONE, - NIS_MAP_CONFIGURATION_FILTER, - NULL, FALSE, - NULL, - NULL, - state->plugin_identity, - 0); - map_wrlock(); - slapi_search_internal_callback_pb(pb, state, - NULL, - backend_map_config_entry_add_cb, - NULL); - map_unlock(); - slapi_free_search_results_internal(pb); - slapi_pblock_destroy(pb); -} - /* Process a map configuration directory entry. Pull out the domain and map * names which are specified in the entry and delete each in turn. */ -static int -backend_map_config_entry_delete_cb(Slapi_Entry *e, void *callback_data) +int +backend_set_config_entry_delete_cb(Slapi_Entry *e, void *callback_data) { - char **domains, **maps; - int i, j; struct plugin_state *state; - state = callback_data; - domains = slapi_entry_attr_get_charray(e, - NIS_MAP_CONFIGURATION_DOMAIN_ATTR); - maps = slapi_entry_attr_get_charray(e, NIS_MAP_CONFIGURATION_MAP_ATTR); - for (i = 0; (domains != NULL) && (domains[i] != NULL); i++) { - for (j = 0; (maps != NULL) && (maps[j] != NULL); j++) { - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "removing map %s in %s\n", - maps[j], domains[i]); - map_data_unset_map(state, domains[i], maps[j]); - } - } - slapi_ch_array_free(maps); - slapi_ch_array_free(domains); - return 0; + return backend_shr_set_config_entry_delete(state, e, + NIS_MAP_CONFIGURATION_DOMAIN_ATTR, + NIS_MAP_CONFIGURATION_MAP_ATTR); } +/* Read enough of the map configuration for the formatting code to be able to + * resolver references correctly. */ struct backend_get_map_config_cb { struct plugin_state *state; char **bases; @@ -1040,7 +831,7 @@ struct backend_get_map_config_cb { void backend_free_map_config(char **bases, char *entry_filter) { - backend_free_strlist(bases); + backend_shr_free_strlist(bases); free(entry_filter); } @@ -1161,12 +952,10 @@ backend_get_map_config(struct plugin_state *state, free(filter); } -/* Our postoperation callbacks. */ - /* Given a map configuration, return true if the entry is supposed to be in the * map. */ -static bool_t -backend_entry_matches_map(struct backend_map_data *map_data, +bool_t +backend_entry_matches_set(struct backend_set_data *set_data, Slapi_PBlock *pb, Slapi_Entry *e) { Slapi_DN *base_sdn; @@ -1181,9 +970,9 @@ backend_entry_matches_map(struct backend_map_data *map_data, } else { /* Check each base in turn. */ for (i = 0; - (map_data->bases != NULL) && (map_data->bases[i] != NULL); + (set_data->bases != NULL) && (set_data->bases[i] != NULL); i++) { - base_sdn = slapi_sdn_new_dn_byval(map_data->bases[i]); + base_sdn = slapi_sdn_new_dn_byval(set_data->bases[i]); if (base_sdn == NULL) { return FALSE; } else { @@ -1201,12 +990,12 @@ backend_entry_matches_map(struct backend_map_data *map_data, } } /* If we ran out of bases to check, it doesn't match. */ - if ((map_data->bases == NULL) || (map_data->bases[i] == NULL)) { + if ((set_data->bases == NULL) || (set_data->bases[i] == NULL)) { return FALSE; } } /* If it's contained by a search base, compare it to the filter. */ - filter = slapi_str2filter(map_data->entry_filter); + filter = slapi_str2filter(set_data->entry_filter); if (filter == NULL) { return FALSE; } else { @@ -1279,7 +1068,14 @@ backend_entry_is_a_set(struct plugin_state *state, return ret; } -/* Set our post-op callbacks. */ +/* Scan for the list of configured domains and maps. */ +void +backend_startup(struct plugin_state *state) +{ + backend_shr_startup(state, NIS_MAP_CONFIGURATION_FILTER); +} + +/* Set up our post-op callbacks. */ void backend_init(Slapi_PBlock *pb, struct plugin_state *state) { diff --git a/src/back-shr.c b/src/back-shr.c index 2c6f358..26cfa30 100644 --- a/src/back-shr.c +++ b/src/back-shr.c @@ -279,7 +279,7 @@ backend_shr_set_config_entry_add_one(struct plugin_state *state, Slapi_Entry *e, } slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "initializing %s in %s, %s (2)\n", + "initializing %s in %s, flag=%s (2)\n", set, group, flag ? "yes" : "no"); map_data_set_map(state, group, set, flag, set_data, &backend_shr_set_config_free_config); @@ -302,7 +302,7 @@ backend_shr_set_config_entry_add_one(struct plugin_state *state, Slapi_Entry *e, 0); slapi_search_internal_callback_pb(pb, set_data, NULL, - backend_set_config_entry_add_cb, + backend_shr_set_entry_one_cb, NULL); slapi_free_search_results_internal(pb); } @@ -317,6 +317,8 @@ backend_shr_startup(struct plugin_state *state, const char *filter) { Slapi_PBlock *pb; + backend_update_params(state); + pb = slapi_pblock_new(); slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, -- cgit From 1dc540711014593ee1b3b2d55bc3f16f7173369b Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 17:38:27 -0400 Subject: - rename plugin.ldif to nis-plugin.ldif --- src/format.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/format.c b/src/format.c index c1482c6..f238194 100644 --- a/src/format.c +++ b/src/format.c @@ -751,8 +751,7 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, /* Retrieve the map-specific paramters. */ map_filter = NULL; map_bases = NULL; - backend_get_map_config(state, domain, argv[1], - &map_bases, &map_filter); + backend_get_map_config(state, domain, argv[1], &map_bases, &map_filter); if (map_filter == NULL) { map_filter = "(objectClass=*)"; } -- cgit From d9b4ec41885590e7a2d66c6d33229eb7a4eb2091 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 17:45:29 -0400 Subject: - use group/set nomenclature more widely --- src/back-shr.c | 4 +-- src/format.c | 104 ++++++++++++++++++++++++++++----------------------------- src/format.h | 2 +- 3 files changed, 55 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/back-shr.c b/src/back-shr.c index 26cfa30..f6384f9 100644 --- a/src/back-shr.c +++ b/src/back-shr.c @@ -673,8 +673,8 @@ backend_shr_update_references_cb(const char *group, const char *set, inref_attrs = backend_set_config_get_inref_attrs(set_data); for (i = 0; (inref_attrs != NULL) && (inref_attrs[i] != NULL); i++) { /* We're only processing inref attributes for this map. */ - if ((strcmp(inref_attrs[i]->domain, group) != 0) || - (strcmp(inref_attrs[i]->map, set) != 0)) { + if ((strcmp(inref_attrs[i]->group, group) != 0) || + (strcmp(inref_attrs[i]->set, set) != 0)) { continue; } /* Extract the named attribute from the entry. */ diff --git a/src/format.c b/src/format.c index f238194..70e8722 100644 --- a/src/format.c +++ b/src/format.c @@ -57,7 +57,7 @@ struct format_choice { static int format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *fmt, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, @@ -93,13 +93,13 @@ format_dup_inref_attrs(struct format_inref_attr **attrs) for (i = 0, j = 0; i < elements; i++) { ret[j] = malloc(sizeof(**attrs)); if (ret[j] != NULL) { - ret[j]->domain = - strdup(attrs[i]->domain); - ret[j]->map = strdup(attrs[i]->map); + ret[j]->group = + strdup(attrs[i]->group); + ret[j]->set = strdup(attrs[i]->set); ret[j]->attribute = strdup(attrs[i]->attribute); - if ((ret[j]->domain != NULL) && - (ret[j]->map != NULL) && + if ((ret[j]->group != NULL) && + (ret[j]->set != NULL) && (ret[j]->attribute != NULL)) { j++; } @@ -112,7 +112,7 @@ format_dup_inref_attrs(struct format_inref_attr **attrs) } void format_add_inref_attrs(struct format_inref_attr ***attrs, - const char *domain, const char *map, + const char *group, const char *set, const char *attribute) { struct format_inref_attr **ret; @@ -121,8 +121,8 @@ format_add_inref_attrs(struct format_inref_attr ***attrs, ret = NULL; if (*attrs != NULL) { for (i = 0; (*attrs)[i] != NULL; i++) { - if ((strcmp((*attrs)[i]->domain, domain) == 0) && - (strcmp((*attrs)[i]->map, map) == 0) && + if ((strcmp((*attrs)[i]->group, group) == 0) && + (strcmp((*attrs)[i]->set, set) == 0) && (strcmp((*attrs)[i]->attribute, attribute) == 0)) { return; } @@ -134,8 +134,8 @@ format_add_inref_attrs(struct format_inref_attr ***attrs, memcpy(ret, *attrs, elements * sizeof(**attrs)); ret[elements] = malloc(sizeof(**ret)); if (ret[elements] != NULL) { - ret[elements]->domain = strdup(domain); - ret[elements]->map = strdup(map); + ret[elements]->group = strdup(group); + ret[elements]->set = strdup(set); ret[elements]->attribute = strdup(attribute); ret[elements + 1] = NULL; } @@ -150,8 +150,8 @@ format_free_inref_attrs(struct format_inref_attr **attrs) int i; if (attrs != NULL) { for (i = 0; attrs[i] != NULL; i++) { - free(attrs[i]->domain); - free(attrs[i]->map); + free(attrs[i]->group); + free(attrs[i]->set); free(attrs[i]->attribute); free(attrs[i]); } @@ -302,7 +302,7 @@ format_parse_args(struct plugin_state *state, const char *args, /* Echo the parameter text. */ static int format_echo(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, char ***ref_attrs, struct format_inref_attr ***inref_attrs) @@ -342,7 +342,7 @@ format_echo(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, /* Choose the first value of the attribute in the entry. */ static int format_first(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, @@ -396,7 +396,7 @@ format_first(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, * joined by a separator given as the first argument. */ static int format_list(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, char ***ref_attrs, struct format_inref_attr ***inref_attrs) @@ -476,7 +476,7 @@ format_list(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, * argument, and create a list separated by the first argument. */ static int format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, @@ -703,7 +703,7 @@ format_referred_entry_cb(Slapi_Entry *e, void *callback_data) } static int format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, @@ -751,7 +751,7 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, /* Retrieve the map-specific paramters. */ map_filter = NULL; map_bases = NULL; - backend_get_map_config(state, domain, argv[1], &map_bases, &map_filter); + backend_get_map_config(state, group, argv[1], &map_bases, &map_filter); if (map_filter == NULL) { map_filter = "(objectClass=*)"; } @@ -759,12 +759,12 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "no search bases defined for \"%s\"/\"%s\"?\n", - domain, argv[1]); + group, argv[1]); } /* Note that the attribute in this map refers to this entry. */ if (inref_attrs != NULL) { - format_add_inref_attrs(inref_attrs, domain, argv[1], argv[2]); + format_add_inref_attrs(inref_attrs, group, argv[1], argv[2]); } tndn = format_escape_for_filter(slapi_entry_get_ndn(e)); @@ -826,7 +826,7 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, * first argument as a separator. */ static int format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, @@ -853,7 +853,7 @@ format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "merge: expanding ->%s<-\n", argv[i]); these_choices = NULL; - len = format_expand(state, pb, e, domain, map, + len = format_expand(state, pb, e, group, set, argv[i], disallowed, outbuf + ret + (count ? slen : 0), outbuf_len - (ret + (count ? slen : 0)), @@ -905,7 +905,7 @@ format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, static int format_match_generic(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, int min_args, int default_arg, const char *disallowed, char *outbuf, int outbuf_len, @@ -1073,13 +1073,13 @@ format_match_cb(const char *pattern, const char *value, char **argv) static int format_match(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, char ***ref_attrs, struct format_inref_attr ***inref_attrs) { - return format_match_generic(state, pb, e, domain, map, args, 2, 2, + return format_match_generic(state, pb, e, group, set, args, 2, 2, disallowed, outbuf, outbuf_len, outbuf_choices, ref_attrs, inref_attrs, @@ -1104,13 +1104,13 @@ format_regmatch_cb(const char *pattern, const char *value, char **argv) static int format_regmatch(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, char ***ref_attrs, struct format_inref_attr ***inref_attrs) { - return format_match_generic(state, pb, e, domain, map, args, 2, 2, + return format_match_generic(state, pb, e, group, set, args, 2, 2, disallowed, outbuf, outbuf_len, outbuf_choices, ref_attrs, inref_attrs, @@ -1228,13 +1228,13 @@ format_regsub_cb(const char *pattern, const char *value, char **argv) static int format_regsub(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, char ***ref_attrs, struct format_inref_attr ***inref_attrs) { - return format_match_generic(state, pb, e, domain, map, args, 3, 3, + return format_match_generic(state, pb, e, group, set, args, 3, 3, disallowed, outbuf, outbuf_len, outbuf_choices, ref_attrs, inref_attrs, @@ -1250,7 +1250,7 @@ format_lookup_fn(const char *fnname) const char *name; int (*fct_ptr)(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, @@ -1559,7 +1559,7 @@ format_trim_value(struct plugin_state *state, char *input, static int format_expand_simple(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *fmt, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, @@ -1663,7 +1663,7 @@ format_expand_simple(struct plugin_state *state, /* Supply the default value, expanding it if * needed. */ i = format_expand(state, pb, e, - domain, map, + group, set, default_value, NULL, outbuf, outbuf_len, outbuf_choices, @@ -1688,7 +1688,7 @@ format_expand_simple(struct plugin_state *state, if (alternate_value != NULL) { /* Supply the alternate value. */ i = format_expand(state, pb, e, - domain, map, alternate_value, NULL, + group, set, alternate_value, NULL, outbuf, outbuf_len, outbuf_choices, ref_attrs, inref_attrs); free(tmp); @@ -1725,7 +1725,7 @@ format_expand_simple(struct plugin_state *state, * specifier and evaluate it, otherwise return it. */ static int format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *fmt, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, @@ -1737,7 +1737,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *paramstart, *paramend; int (*formatfn)(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *args, const char *disallowed, char *outbuf, int outbuf_len, struct format_choice **outbuf_choices, @@ -1792,8 +1792,8 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, /* Expand the simple expression. */ used = format_expand_simple(state, pb, e, - domain, - map, + group, + set, subexp, disallowed, outbuf + j, @@ -1897,7 +1897,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, } /* Call the "function". */ used = (*formatfn)(state, pb, e, - domain, map, + group, set, params, disallowed, outbuf + j, outbuf_len - j, outbuf_choices, @@ -1951,7 +1951,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, static char * format_format(struct plugin_state *state, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *fmt, const char *disallowed, struct format_choice **choices, char ***ref_attrs, struct format_inref_attr ***inref_attrs) @@ -1976,7 +1976,7 @@ format_format(struct plugin_state *state, Slapi_Entry *e, return NULL; } - i = format_expand(state, pb, e, domain, map, + i = format_expand(state, pb, e, group, set, fmt, disallowed, buf, buflen, choices, ref_attrs, inref_attrs); @@ -2035,12 +2035,12 @@ format_free_data(char *data) } char * format_get_data(struct plugin_state *state, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *fmt, const char *disallowed, char ***ref_attrs, struct format_inref_attr ***inref_attrs) { - return format_format(state, e, domain, map, fmt, disallowed, + return format_format(state, e, group, set, fmt, disallowed, NULL, ref_attrs, inref_attrs); } @@ -2057,16 +2057,16 @@ format_free_data_set(char **data) } char ** format_get_data_set(struct plugin_state *state, Slapi_Entry *e, - const char *domain, const char *map, + const char *group, const char *set, const char *fmt, const char *disallowed, char ***ref_attrs, struct format_inref_attr ***inref_attrs) { struct format_choice *choices, *this_choice; char **ret, *template, *s; - int combinations, group, i, j, k, offset, length, template_len; + int combinations, groupsize, i, j, k, offset, length, template_len; choices = NULL; - template = format_format(state, e, domain, map, fmt, disallowed, + template = format_format(state, e, group, set, fmt, disallowed, &choices, ref_attrs, inref_attrs); if (template == NULL) { format_free_choices(choices); @@ -2092,14 +2092,14 @@ format_get_data_set(struct plugin_state *state, Slapi_Entry *e, /* Work out all of the results. */ for (i = 0, j = 0; i < combinations; i++) { /* First figure out how long this result will be. */ - group = combinations; + groupsize = combinations; length = template_len; for (this_choice = choices; this_choice != NULL; this_choice = this_choice->next) { /* Add the length of the value used here. */ - group /= this_choice->n_values; - s = this_choice->values[(i / group) % + groupsize /= this_choice->n_values; + s = this_choice->values[(i / groupsize) % this_choice->n_values]; length += strlen(s); } @@ -2111,7 +2111,7 @@ format_get_data_set(struct plugin_state *state, Slapi_Entry *e, /* Build the result's value. */ offset = 0; k = 0; - group = combinations; + groupsize = combinations; for (this_choice = choices; this_choice != NULL; this_choice = this_choice->next) { @@ -2122,8 +2122,8 @@ format_get_data_set(struct plugin_state *state, Slapi_Entry *e, memcpy(ret[j] + k, template + offset, length); k += length; offset += length; - group /= this_choice->n_values; - s = this_choice->values[(i / group) % + groupsize /= this_choice->n_values; + s = this_choice->values[(i / groupsize) % this_choice->n_values]; length = strlen(s); memcpy(ret[j] + k, s, length); diff --git a/src/format.h b/src/format.h index 54c795f..3fcf8f9 100644 --- a/src/format.h +++ b/src/format.h @@ -25,7 +25,7 @@ struct slapi_entry; struct plugin_state; struct format_inref_attr { - char *domain, *map, *attribute; + char *group, *set, *attribute; }; void format_free_attr_list(char **attr_list); -- cgit From 38fcfada8270bf022d7bedc884fda7de79478a33 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 17:48:57 -0400 Subject: - be more consisten about group/set nomenclature --- src/back-nis.c | 14 +++++++------- src/back-sch.c | 14 +++++++------- src/back-shr.c | 4 ++-- src/format.c | 8 ++++---- 4 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/back-nis.c b/src/back-nis.c index 5597255..8a394f9 100644 --- a/src/back-nis.c +++ b/src/back-nis.c @@ -822,25 +822,25 @@ backend_set_config_entry_delete_cb(Slapi_Entry *e, void *callback_data) /* Read enough of the map configuration for the formatting code to be able to * resolver references correctly. */ -struct backend_get_map_config_cb { +struct backend_get_set_config_cb { struct plugin_state *state; char **bases; char *entry_filter; }; void -backend_free_map_config(char **bases, char *entry_filter) +backend_free_set_config(char **bases, char *entry_filter) { backend_shr_free_strlist(bases); free(entry_filter); } static bool_t -backend_get_map_config_entry_cb(Slapi_Entry *e, void *callback_data) +backend_get_set_config_entry_cb(Slapi_Entry *e, void *callback_data) { Slapi_ValueSet *values; Slapi_Value *value; - struct backend_get_map_config_cb *cbdata; + struct backend_get_set_config_cb *cbdata; char *actual_attr; const char *cvalue; int disposition, buffer_flags, i, count; @@ -886,7 +886,7 @@ backend_get_map_config_entry_cb(Slapi_Entry *e, void *callback_data) } void -backend_get_map_config(struct plugin_state *state, +backend_get_set_config(struct plugin_state *state, const char *domain, const char *map, char ***bases, char **entry_filter) { @@ -897,7 +897,7 @@ backend_get_map_config(struct plugin_state *state, NULL}; const char *default_filter; bool_t map_secure; - struct backend_get_map_config_cb cbdata; + struct backend_get_set_config_cb cbdata; /* Build the search filter. */ filter = malloc(strlen("(&(" @@ -938,7 +938,7 @@ backend_get_map_config(struct plugin_state *state, cbdata.entry_filter = strdup(default_filter); slapi_search_internal_callback_pb(pb, &cbdata, NULL, - backend_get_map_config_entry_cb, + backend_get_set_config_entry_cb, NULL); /* Return the results. */ diff --git a/src/back-sch.c b/src/back-sch.c index 604d9ab..ed10afa 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -388,25 +388,25 @@ backend_set_config_entry_delete_cb(Slapi_Entry *e, void *callback_data) /* Functions for passing information about a container's configuration to the * formatting functions. */ -struct backend_get_map_config_cb { +struct backend_get_set_config_cb { struct plugin_state *state; char **bases; char *entry_filter; }; void -backend_free_map_config(char **bases, char *entry_filter) +backend_free_set_config(char **bases, char *entry_filter) { backend_shr_free_strlist(bases); free(entry_filter); } static bool_t -backend_get_map_config_entry_cb(Slapi_Entry *e, void *callback_data) +backend_get_set_config_entry_cb(Slapi_Entry *e, void *callback_data) { Slapi_ValueSet *values; Slapi_Value *value; - struct backend_get_map_config_cb *cbdata; + struct backend_get_set_config_cb *cbdata; char *actual_attr; const char *cvalue; int disposition, buffer_flags, i, count; @@ -454,7 +454,7 @@ backend_get_map_config_entry_cb(Slapi_Entry *e, void *callback_data) } void -backend_get_map_config(struct plugin_state *state, +backend_get_set_config(struct plugin_state *state, const char *group, const char *container, char ***bases, char **entry_filter) { @@ -464,7 +464,7 @@ backend_get_map_config(struct plugin_state *state, SCH_CONTAINER_CONFIGURATION_BASE_ATTR, NULL}; const char *default_filter; - struct backend_get_map_config_cb cbdata; + struct backend_get_set_config_cb cbdata; /* Build the search filter. */ filter = malloc(strlen("(&(" @@ -501,7 +501,7 @@ backend_get_map_config(struct plugin_state *state, cbdata.entry_filter = NULL; slapi_search_internal_callback_pb(pb, &cbdata, NULL, - backend_get_map_config_entry_cb, + backend_get_set_config_entry_cb, NULL); /* Return the results. */ diff --git a/src/back-shr.c b/src/back-shr.c index f6384f9..6af8883 100644 --- a/src/back-shr.c +++ b/src/back-shr.c @@ -370,7 +370,7 @@ backend_shr_set_config_entry_delete(struct plugin_state *state, return 0; } -struct backend_get_map_config_cb { +struct backend_get_set_config_cb { struct plugin_state *state; char **bases; char *entry_filter; @@ -391,7 +391,7 @@ backend_shr_get_set_config_entry_cb(Slapi_Entry *e, void *callback_data, { Slapi_ValueSet *values; Slapi_Value *value; - struct backend_get_map_config_cb *cbdata; + struct backend_get_set_config_cb *cbdata; char *actual_attr; const char *cvalue; int disposition, buffer_flags, i, count; diff --git a/src/format.c b/src/format.c index 70e8722..82dac70 100644 --- a/src/format.c +++ b/src/format.c @@ -751,7 +751,7 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, /* Retrieve the map-specific paramters. */ map_filter = NULL; map_bases = NULL; - backend_get_map_config(state, group, argv[1], &map_bases, &map_filter); + backend_get_set_config(state, group, argv[1], &map_bases, &map_filter); if (map_filter == NULL) { map_filter = "(objectClass=*)"; } @@ -772,7 +772,7 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "referred: out of memory\n"); - backend_free_map_config(map_bases, map_filter); + backend_free_set_config(map_bases, map_filter); slapi_pblock_destroy(local_pb); format_free_parsed_args(argv); return -ENOMEM; @@ -787,7 +787,7 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "referred: out of memory\n"); - backend_free_map_config(map_bases, map_filter); + backend_free_set_config(map_bases, map_filter); slapi_pblock_destroy(local_pb); format_free_parsed_args(argv); return -ENOMEM; @@ -816,7 +816,7 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, } free(tndn); - backend_free_map_config(map_bases, map_filter); + backend_free_set_config(map_bases, map_filter); slapi_pblock_destroy(local_pb); format_free_parsed_args(argv); return cbdata.ret ? cbdata.ret : cbdata.outbuf - outbuf; -- cgit From 3feea09ddbed94e96c12934e23f94071d804db0a Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 18:14:02 -0400 Subject: - take out the need for a backend to provide a matching test - start adding configuration for the schema plugin --- src/back-nis.c | 57 ------------------------------- src/back-shr.c | 103 +++++++++++++++++++++++++++++++-------------------------- src/back-shr.h | 49 +++++++++++++++++++++++++++ src/plug-sch.c | 2 +- 4 files changed, 106 insertions(+), 105 deletions(-) create mode 100644 src/back-shr.h (limited to 'src') diff --git a/src/back-nis.c b/src/back-nis.c index 8a394f9..aec9ce9 100644 --- a/src/back-nis.c +++ b/src/back-nis.c @@ -952,63 +952,6 @@ backend_get_set_config(struct plugin_state *state, free(filter); } -/* Given a map configuration, return true if the entry is supposed to be in the - * map. */ -bool_t -backend_entry_matches_set(struct backend_set_data *set_data, - Slapi_PBlock *pb, Slapi_Entry *e) -{ - Slapi_DN *base_sdn; - const Slapi_DN *entry_sdn; - Slapi_Filter *filter; - int i; - /* Decide if the directory server entry belongs in this map. That - * means that it must be contained by one of the bases of the map. */ - entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); - if (entry_sdn == NULL) { - return FALSE; - } else { - /* Check each base in turn. */ - for (i = 0; - (set_data->bases != NULL) && (set_data->bases[i] != NULL); - i++) { - base_sdn = slapi_sdn_new_dn_byval(set_data->bases[i]); - if (base_sdn == NULL) { - return FALSE; - } else { - if (slapi_sdn_scope_test(entry_sdn, - base_sdn, - LDAP_SCOPE_SUB) == 0) { - /* The entry is not contained by the - * base -- go on to try the next one. */ - slapi_sdn_free(&base_sdn); - continue; - } - /* The entry is contained by the base. */ - slapi_sdn_free(&base_sdn); - break; - } - } - /* If we ran out of bases to check, it doesn't match. */ - if ((set_data->bases == NULL) || (set_data->bases[i] == NULL)) { - return FALSE; - } - } - /* If it's contained by a search base, compare it to the filter. */ - filter = slapi_str2filter(set_data->entry_filter); - if (filter == NULL) { - return FALSE; - } else { - if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { - /* Didn't match -- return. */ - slapi_filter_free(filter, 1); - return FALSE; - } - slapi_filter_free(filter, 1); - } - return TRUE; -} - /* Given an entry, return true if it describes a NIS map. */ bool_t backend_entry_is_a_set(struct plugin_state *state, diff --git a/src/back-shr.c b/src/back-shr.c index 6af8883..acc010d 100644 --- a/src/back-shr.c +++ b/src/back-shr.c @@ -243,6 +243,52 @@ backend_shr_set_config_entry_set_one_dn(struct plugin_state *state, } } +/* Check if the given entry is somewhere beneath the NDN and matches the + * filter. */ +bool_t +backend_shr_entry_matches(Slapi_PBlock *pb, Slapi_Entry *e, + const char *containing_ndn, int scope, + const char *check_filter) +{ + struct plugin_state *state; + Slapi_DN *entry_sdn, *containing_sdn; + Slapi_Filter *filter; + bool_t ret; + + /* First, just do the scope test. The item should be a somewhere + * beneath the passed-in entry. */ + entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); + if (entry_sdn == NULL) { + return FALSE; + } else { + containing_sdn = slapi_sdn_new_ndn_byval(containing_ndn); + if (containing_sdn == NULL) { + slapi_sdn_free(&entry_sdn); + return FALSE; + } + } + if (slapi_sdn_scope_test(entry_sdn, containing_sdn, scope) == 0) { + ret = FALSE; + } else { + ret = TRUE; + } + slapi_sdn_free(&containing_sdn); + slapi_sdn_free(&entry_sdn); + + /* If it's actually in our configuration tree, check if it's a valid + * entry. */ + if (ret) { + filter = slapi_str2filter((char *) check_filter); + if (filter != NULL) { + if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { + ret = FALSE; + } + slapi_filter_free(filter, 1); + } + } + return ret; +} + /* Given a directory server entry which represents a set's configuration, set * up and populate the set. */ static void @@ -444,59 +490,22 @@ bool_t backend_shr_entry_matches_set(struct backend_set_data *set_data, Slapi_PBlock *pb, Slapi_Entry *e) { - Slapi_DN *base_sdn; - const Slapi_DN *entry_sdn; - Slapi_Filter *filter; char **set_bases; char *set_filter; int i; - /* Decide if the directory server entry belongs in this map. That - * means that it must be contained by one of the bases of the map. */ - entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); - if (entry_sdn == NULL) { - return FALSE; - } else { - /* Check each base in turn. */ - set_bases = backend_set_config_get_bases(set_data); - for (i = 0; - (set_bases != NULL) && (set_bases[i] != NULL); - i++) { - base_sdn = slapi_sdn_new_dn_byval(set_bases[i]); - if (base_sdn == NULL) { - return FALSE; - } else { - if (slapi_sdn_scope_test(entry_sdn, - base_sdn, - LDAP_SCOPE_SUB) == 0) { - /* The entry is not contained by the - * base -- go on to try the next one. */ - slapi_sdn_free(&base_sdn); - continue; - } - /* The entry is contained by the base. */ - slapi_sdn_free(&base_sdn); - break; - } - } - /* If we ran out of bases to check, it doesn't match. */ - if ((set_bases == NULL) || (set_bases[i] == NULL)) { - return FALSE; - } - } - /* If it's contained by a search base, compare it to the filter. */ + set_bases = backend_set_config_get_bases(set_data); set_filter = backend_set_config_get_filter(set_data); - filter = slapi_str2filter(set_filter); - if (filter == NULL) { - return FALSE; - } else { - if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { - /* Didn't match -- return. */ - slapi_filter_free(filter, 1); - return FALSE; + if (set_bases != NULL) { + for (i = 0; set_bases[i] != NULL; i++) { + if (backend_shr_entry_matches(pb, e, + set_bases[i], + LDAP_SCOPE_SUB, + set_filter)) { + return TRUE; + } } - slapi_filter_free(filter, 1); } - return TRUE; + return FALSE; } /* Given an entry, return true if it describes a set. */ diff --git a/src/back-shr.h b/src/back-shr.h new file mode 100644 index 0000000..2471676 --- /dev/null +++ b/src/back-shr.h @@ -0,0 +1,49 @@ +/* + * Copyright 2008 Red Hat, Inc. + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This Program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this Program; if not, write to the + * + * Free Software Foundation, Inc. + * 59 Temple Place, Suite 330 + * Boston, MA 02111-1307 USA + * + */ + +#ifndef back_shr_h +#define back_shr_h + +struct plugin_state; + +void backend_shr_free_server_name(struct plugin_state *state, char *master); +int backend_shr_read_server_name(struct plugin_state *state, char **master); + +void backend_shr_free_strlist(char **strlist); +char **backend_shr_dup_strlist_n(char **strlist, int n); +char **backend_shr_dup_strlist(char **strlist); +void backend_shr_add_strlist(char ***strlist, const char *item); + +void backend_shr_startup(struct plugin_state *state, const char *set_filter); +void backend_shr_postop_init(Slapi_PBlock *pb, struct plugin_state *state); + +bool_t backend_shr_entry_matches(Slapi_PBlock *pb, Slapi_Entry *e, + const char *containing_ndn, int scope, + const char *check_filter); +int backend_shr_set_config_entry_add_one(struct plugin_state *state, + Slapi_Entry *e, + const char *group_name, + const char *set_name); +int backend_shr_set_config_entry_delete(struct plugin_state *state, + Slapi_Entry *e, + const char *group_attr, + const char *set_attr); +#endif diff --git a/src/plug-sch.c b/src/plug-sch.c index 0149003..b406893 100644 --- a/src/plug-sch.c +++ b/src/plug-sch.c @@ -60,7 +60,7 @@ /* the module initialization function */ static Slapi_PluginDesc plugin_description = { - .spd_id = "schema-plugin", + .spd_id = "schema-compat-plugin", .spd_vendor = "redhat.com", .spd_version = PACKAGE_VERSION, .spd_description = "Schema Compatibility Plugin", -- cgit From 15fdeee0bab953ce506468806e326a99acae0e5a Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 18:17:39 -0400 Subject: - remove unused variables --- src/back-nis.c | 4 ++-- src/back-sch.c | 8 +------- src/back-shr.c | 1 - 3 files changed, 3 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/back-nis.c b/src/back-nis.c index aec9ce9..81248e3 100644 --- a/src/back-nis.c +++ b/src/back-nis.c @@ -387,8 +387,8 @@ backend_map_config_filter(const char *format, return ret; } -/* Given an entry, read the rest of the map configuration for the given domain - * and map name. */ +/* Given a map configuration entry and domain and map names, read the rest of + * the map configuration settings. */ void backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e, const char *domain, const char *map, diff --git a/src/back-sch.c b/src/back-sch.c index ed10afa..ad30ace 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -169,11 +169,7 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e, bool_t *flag, struct backend_set_data **pret) { char **bases, *entry_filter, *entry_format; - char **entrykey_formats, **keys_formats, *value_format, *actual_attr; - char *disallowed_chars; - char **use_bases, *use_entry_filter; - char **use_key_formats, **use_keys_formats; - char *use_value_format, *use_disallowed_chars; + char *actual_attr; const char *cvalue; int i, j, disposition, buffer_flags, count; struct backend_set_data ret; @@ -265,7 +261,6 @@ void backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data) { char *ldif, *ndn, *plugin_id, *ndns[2]; - int i, j, k, n_key_sets; plugin_id = data->state->plugin_desc->spd_id; /* Pull out the NDN of this entry. */ ndn = slapi_entry_get_ndn(e); @@ -463,7 +458,6 @@ backend_get_set_config(struct plugin_state *state, char *attrs[] = {SCH_CONTAINER_CONFIGURATION_FILTER_ATTR, SCH_CONTAINER_CONFIGURATION_BASE_ATTR, NULL}; - const char *default_filter; struct backend_get_set_config_cb cbdata; /* Build the search filter. */ diff --git a/src/back-shr.c b/src/back-shr.c index acc010d..c61451b 100644 --- a/src/back-shr.c +++ b/src/back-shr.c @@ -250,7 +250,6 @@ backend_shr_entry_matches(Slapi_PBlock *pb, Slapi_Entry *e, const char *containing_ndn, int scope, const char *check_filter) { - struct plugin_state *state; Slapi_DN *entry_sdn, *containing_sdn; Slapi_Filter *filter; bool_t ret; -- cgit From 7222241a931fc18b3c11643b394a4e81aa199775 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 18:29:23 -0400 Subject: - refactor the is-this-a-valid-set-definition logic - make building of either module a conditional, not yet controllable by the configure script --- src/Makefile.am | 10 +++++++++- src/back-shr.c | 54 +++--------------------------------------------------- 2 files changed, 12 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 809fe04..638f026 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,7 +6,15 @@ LIBWRAP = @LIBWRAP@ plugindir = $(libdir)/dirsrv/plugins dist_noinst_SCRIPTS = ypmaplist.py -plugin_LTLIBRARIES = nisserver-plugin.la schemacompat-plugin.la +plugin_LTLIBRARIES = +if NIS +plugin_LTLIBRARIES += nisserver-plugin.la +else +endif +if SCHEMA +plugin_LTLIBRARIES += schemacompat-plugin.la +endif + nisserver_plugin_la_SOURCES = \ back-nis.c \ backend.h \ diff --git a/src/back-shr.c b/src/back-shr.c index c61451b..bbae623 100644 --- a/src/back-shr.c +++ b/src/back-shr.c @@ -513,57 +513,9 @@ backend_shr_entry_is_a_set(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *set_configuration_filter) { - Slapi_DN *entry_sdn, *plugin_sdn; - Slapi_Filter *filter; - bool_t ret; - - /* First, just do the scope test. */ - entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e)); - if (entry_sdn == NULL) { - return FALSE; - } else { - plugin_sdn = slapi_sdn_new_dn_byval(state->plugin_base); - if (plugin_sdn == NULL) { - slapi_sdn_free(&entry_sdn); - return FALSE; - } - } - if (slapi_sdn_scope_test(entry_sdn, - plugin_sdn, - LDAP_SCOPE_ONE) == 0) { - /* Didn't match. */ - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "entry \"%s\" is not a child of \"%s\"\n", - slapi_sdn_get_ndn(entry_sdn), - slapi_sdn_get_ndn(plugin_sdn)); - ret = FALSE; - } else { - ret = TRUE; - } - slapi_sdn_free(&plugin_sdn); - slapi_sdn_free(&entry_sdn); - /* If it's actually part of our configuration tree, check if it's a - * valid entry. */ - if (ret) { - filter = slapi_str2filter((char *) set_configuration_filter); - if (filter != NULL) { - if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) { - /* Didn't match. */ - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "entry \"%s\" doesn't look " - "like a map configuration " - "(didn't match filter " - "\"%s\")\n", - slapi_sdn_get_ndn(entry_sdn), - set_configuration_filter); - ret = FALSE; - } - slapi_filter_free(filter, 1); - } - } - return ret; + return backend_shr_entry_matches(pb, e, + state->plugin_base, LDAP_SCOPE_ONE, + set_configuration_filter); } /* Update any entries to which the passed-in entry in the passed-in map refers -- cgit From 1889b058b5d1a55d81cff9e9b07f208150946c27 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jun 2008 18:34:19 -0400 Subject: - group data --- src/back-nis.c | 6 ++++-- src/back-sch.c | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/back-nis.c b/src/back-nis.c index 81248e3..67606f9 100644 --- a/src/back-nis.c +++ b/src/back-nis.c @@ -55,13 +55,15 @@ /* The data we ask the map cache to keep, for us, for each map. */ struct backend_set_data { + /* Common data. */ struct plugin_state *state; char *domain, *map, **bases, *entry_filter; + char **ref_attrs; + struct format_inref_attr **inref_attrs; + /* NIS-specific data. */ char **key_formats, **keys_formats, *value_format; int n_key_formats, n_keys_formats; char *disallowed_chars; - char **ref_attrs; - struct format_inref_attr **inref_attrs; }; /* Read the name of the NIS master. Used by the map module on behalf of the diff --git a/src/back-sch.c b/src/back-sch.c index ad30ace..ead2861 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -54,10 +54,13 @@ /* The data we ask the map cache to keep, for us, for each set. */ struct backend_set_data { + /* Common data. */ struct plugin_state *state; - char *group, *container, **bases, *entry_filter, *entry_format; + char *group, *container, **bases, *entry_filter; char **ref_attrs; struct format_inref_attr **inref_attrs; + /* Schema compatibility-specific data. */ + char *entry_format; }; /* Read the name of the NIS master. A dummy function for the schema -- cgit