summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-30 18:35:47 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-30 18:35:47 -0400
commitb28a5836fd7234bfffe702b095b657036d3f9230 (patch)
treee1bb5feba64ff730a2c8b1623e1906356ffad32a /src
parent053e390a31ba40149cd5238c19d90c974df9e0ac (diff)
parent1889b058b5d1a55d81cff9e9b07f208150946c27 (diff)
downloadslapi-nis-b28a5836fd7234bfffe702b095b657036d3f9230.tar.gz
slapi-nis-b28a5836fd7234bfffe702b095b657036d3f9230.tar.xz
slapi-nis-b28a5836fd7234bfffe702b095b657036d3f9230.zip
Merge branch 'schema-compat'
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am33
-rw-r--r--src/back-nis.c1113
-rw-r--r--src/back-nis.h8
-rw-r--r--src/back-sch.c592
-rw-r--r--src/back-sch.h (renamed from src/plug-nis.h)35
-rw-r--r--src/back-shr.c1103
-rw-r--r--src/back-shr.h49
-rw-r--r--src/disp-nis.c2
-rw-r--r--src/dummymap.c2
-rw-r--r--src/format.c200
-rw-r--r--src/format.h2
-rw-r--r--src/map.c2
-rw-r--r--src/nis.c2
-rw-r--r--src/plug-nis.c2
-rw-r--r--src/plug-sch.c113
15 files changed, 2115 insertions, 1143 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 2ff593f..638f026 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,10 +6,20 @@ LIBWRAP = @LIBWRAP@
plugindir = $(libdir)/dirsrv/plugins
dist_noinst_SCRIPTS = ypmaplist.py
-plugin_LTLIBRARIES = nisserver-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 \
- back-nis.h \
+ backend.h \
+ back-shr.c \
+ back-shr.h \
defs-nis.c \
defs-nis.h \
disp-nis.c \
@@ -21,13 +31,28 @@ 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 \
+ backend.h \
+ back-shr.c \
+ back-shr.h \
+ format.c \
+ format.h \
+ map.c \
+ map.h \
+ plug-sch.c \
+ plugin.h \
+ wrap.c \
+ wrap.h
+schemacompat_plugin_la_LIBADD = $(RUNTIME_LIBS) $(LIBPTHREAD)
+
noinst_LTLIBRARIES = dummy-nis-plugin.la
dummy_nis_plugin_la_SOURCES = \
disp-nis.c \
@@ -37,7 +62,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..67606f9 100644
--- a/src/back-nis.c
+++ b/src/back-nis.c
@@ -43,168 +43,105 @@
#include <tcpd.h>
#endif
-#include "back-nis.h"
+#include "backend.h"
+#include "back-shr.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 "=*))"
/* The data we ask the map cache to keep, for us, for each map. */
-struct backend_map_data {
+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. */
+/* 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);
+ 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;
}
-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;
}
-
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;
@@ -212,7 +149,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 ?
@@ -222,8 +159,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);
@@ -233,7 +170,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;
@@ -242,13 +179,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);
@@ -282,7 +217,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;
@@ -386,49 +321,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);
- }
}
/*
@@ -497,13 +389,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 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,
- 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;
@@ -652,21 +545,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 ?
@@ -674,25 +567,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++) {
@@ -705,7 +598,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);
@@ -719,77 +612,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++;
- }
-}
-
-/* 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;
+ ret.n_keys_formats++;
+ }
+ *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;
@@ -835,9 +675,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) {
@@ -856,8 +696,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;
@@ -879,7 +719,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 ?
@@ -894,7 +734,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;
}
@@ -917,7 +757,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);
@@ -932,7 +772,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);
@@ -962,7 +802,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);
}
@@ -970,83 +810,39 @@ 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);
}
-struct backend_get_map_config_cb {
+/* Read enough of the map configuration for the formatting code to be able to
+ * resolver references correctly. */
+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_free_strlist(bases);
+ 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;
@@ -1092,7 +888,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)
{
@@ -1103,7 +899,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("(&("
@@ -1144,7 +940,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. */
@@ -1158,68 +954,9 @@ 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,
- 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 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;
@@ -1276,574 +1013,16 @@ 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)
+/* Scan for the list of configured domains and maps. */
+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, NIS_MAP_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-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
new file mode 100644
index 0000000..ead2861
--- /dev/null
+++ b/src/back-sch.c
@@ -0,0 +1,592 @@
+/*
+ * 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 <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H
+#include <nspr.h>
+#include <nss.h>
+#include <dirsrv/slapi-plugin.h>
+#else
+#include <slapi-plugin.h>
+#endif
+
+#include <rpc/xdr.h>
+#include <rpcsvc/yp_prot.h>
+
+#ifdef HAVE_TCPD_H
+#include <tcpd.h>
+#endif
+
+#include "backend.h"
+#include "backend.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 set. */
+struct backend_set_data {
+ /* Common data. */
+ struct plugin_state *state;
+ 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
+ * 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 a backend map configuration. */
+struct plugin_state *
+backend_set_config_get_state(struct backend_set_data *set_data)
+{
+ return set_data->state;
+}
+char **
+backend_set_config_get_bases(struct backend_set_data *set_data)
+{
+ return set_data->bases;
+}
+char *
+backend_set_config_get_filter(struct backend_set_data *set_data)
+{
+ 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;
+}
+static void
+backend_set_config_free_config_contents(void *data)
+{
+ 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);
+ }
+}
+void
+backend_set_config_free_config(struct backend_set_data *data)
+{
+ backend_set_config_free_config_contents(data);
+ free(data);
+}
+static struct backend_set_data *
+backend_copy_set_config(const struct backend_set_data *data)
+{
+ struct backend_set_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_shr_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_set_config_free_config(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+/* 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,
+ bool_t *flag, struct backend_set_data **pret)
+{
+ char **bases, *entry_filter, *entry_format;
+ char *actual_attr;
+ 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,
+ &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 = 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(ret.bases);
+ }
+ free(ret.entry_filter);
+ free(ret.entry_format);
+}
+
+/* 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)
+{
+ char *ldif, *ndn, *plugin_id, *ndns[2];
+ 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);
+ }
+ format_free_data(ldif);
+}
+
+/* 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. */
+int
+backend_set_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_shr_set_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;
+}
+
+/* Process a set configuration directory entry. Pull out the domain and map
+ * names which are specified in the entry and delete each in turn. */
+int
+backend_set_config_entry_delete_cb(Slapi_Entry *e, void *callback_data)
+{
+ struct plugin_state *state;
+ state = callback_data;
+ 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 the
+ * formatting functions. */
+struct backend_get_set_config_cb {
+ struct plugin_state *state;
+ char **bases;
+ char *entry_filter;
+};
+
+void
+backend_free_set_config(char **bases, char *entry_filter)
+{
+ backend_shr_free_strlist(bases);
+ free(entry_filter);
+}
+
+static bool_t
+backend_get_set_config_entry_cb(Slapi_Entry *e, void *callback_data)
+{
+ Slapi_ValueSet *values;
+ Slapi_Value *value;
+ struct backend_get_set_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_set_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};
+ struct backend_get_set_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_set_config_entry_cb,
+ NULL);
+
+ /* Return the results. */
+ *bases = cbdata.bases;
+ *entry_filter = cbdata.entry_filter;
+
+ /* Clean up. */
+ slapi_pblock_destroy(pb);
+}
+
+/* Given an entry, return true if it describes a compatibility container. */
+bool_t
+backend_entry_is_a_set(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. 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;
+ } 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 in 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;
+}
+
+/* Re-read plugin-wide settings that may have changed. Nothing to do. */
+void
+backend_update_params(struct plugin_state *state)
+{
+}
+
+/* Populate our data. */
+void
+backend_startup(struct plugin_state *state)
+{
+ backend_shr_startup(state, SCH_CONTAINER_CONFIGURATION_FILTER);
+}
+
+/* Set up our post-op callbacks. */
+void
+backend_init(Slapi_PBlock *pb, struct plugin_state *state)
+{
+ backend_shr_postop_init(pb, state);
+}
diff --git a/src/plug-nis.h b/src/back-sch.h
index ab46be1..a97fc18 100644
--- a/src/plug-nis.h
+++ b/src/back-sch.h
@@ -19,27 +19,16 @@
*
*/
-#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];
-};
-
+#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..bbae623
--- /dev/null
+++ b/src/back-shr.c
@@ -0,0 +1,1103 @@
+/*
+ * 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 <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H
+#include <nspr.h>
+#include <nss.h>
+#include <dirsrv/slapi-plugin.h>
+#else
+#include <slapi-plugin.h>
+#endif
+
+#include <rpc/xdr.h>
+#include <rpcsvc/yp_prot.h>
+
+#ifdef HAVE_TCPD_H
+#include <tcpd.h>
+#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);
+ }
+}
+
+/* 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)
+{
+ 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
+backend_shr_set_config_free_config(void *cb_data)
+{
+ struct backend_set_data *set_data;
+ set_data = cb_data;
+ backend_set_config_free_config(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, 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);
+ 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_shr_set_entry_one_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;
+
+ backend_update_params(state);
+
+ 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. */
+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;
+
+ 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_set_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_set_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)
+{
+ char **set_bases;
+ char *set_filter;
+ int i;
+ set_bases = backend_set_config_get_bases(set_data);
+ set_filter = backend_set_config_get_filter(set_data);
+ 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;
+ }
+ }
+ }
+ return FALSE;
+}
+
+/* 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)
+{
+ 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
+ * 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]->group, group) != 0) ||
+ (strcmp(inref_attrs[i]->set, 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/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/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 <rpc/pmap_clnt.h>
#include <rpcsvc/yp_prot.h>
-#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..82dac70 100644
--- a/src/format.c
+++ b/src/format.c
@@ -41,9 +41,10 @@
#include <rpcsvc/yp.h>
-#include "back-nis.h"
+#include "backend.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
@@ -56,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,
@@ -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 **
@@ -162,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++;
}
@@ -181,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;
@@ -190,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;
}
@@ -203,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;
}
@@ -219,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]);
}
@@ -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++) {
@@ -371,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)
@@ -411,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,
@@ -465,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)
@@ -545,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,
@@ -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,
@@ -772,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,
@@ -820,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_set_config(state, group, argv[1], &map_bases, &map_filter);
if (map_filter == NULL) {
map_filter = "(objectClass=*)";
}
@@ -829,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));
@@ -842,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;
@@ -857,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;
@@ -886,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;
@@ -896,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,
@@ -923,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)),
@@ -975,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,
@@ -1143,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,
@@ -1174,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,
@@ -1298,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,
@@ -1320,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,
@@ -1406,7 +1336,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]);
}
@@ -1629,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,
@@ -1733,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,
@@ -1750,7 +1680,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 {
@@ -1758,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);
@@ -1795,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,
@@ -1807,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,
@@ -1862,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,
@@ -1967,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,
@@ -2021,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)
@@ -2046,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);
@@ -2105,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);
}
@@ -2127,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);
@@ -2162,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);
}
@@ -2181,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) {
@@ -2192,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);
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 <rpc/rpc.h>
-#include "back-nis.h"
+#include "backend.h"
#include "disp-nis.h"
#include "map.h"
#include "portmap.h"
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-sch.c b/src/plug-sch.c
new file mode 100644
index 0000000..b406893
--- /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 <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <rpcsvc/yp_prot.h>
+
+#ifdef HAVE_TCPD_H
+#include <tcpd.h>
+#endif
+
+#ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H
+#include <nspr.h>
+#include <nss.h>
+#include <dirsrv/slapi-plugin.h>
+#else
+#include <slapi-plugin.h>
+#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-compat-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;
+}