summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-05-12 17:57:06 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-05-12 17:57:06 -0400
commita90652fce9126d42f5daf594c6c80418a48193ef (patch)
tree7e94b643c9d131c11adb0adddf4871d28d5da86a /src
parent96959aa8532d33f82476af0abf8cdee99d2c9b4b (diff)
- factor out checking if an entry would be considered part of a given map
- get this working right, finally - update map entries on modify
Diffstat (limited to 'src')
-rw-r--r--src/backend.c315
1 files changed, 229 insertions, 86 deletions
diff --git a/src/backend.c b/src/backend.c
index 6e9bf1e..7ac8a9e 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -18,7 +18,7 @@
#include "defaults.h"
/* The data we ask the map cache to keep, for us, for each map. */
-struct backend_map_entry_cb_data {
+struct backend_map_data {
struct plugin_state *state;
char *domain, *map, **bases, *filter, *key_attr, *value_fmt;
};
@@ -61,24 +61,24 @@ backend_dup_strlist(char **strlist)
}
static void
-backend_free_cb_data(void *data)
+backend_free_map_data(void *data)
{
- struct backend_map_entry_cb_data *cb_data = data;
- if (cb_data != NULL) {
- free(cb_data->domain);
- free(cb_data->map);
- free(cb_data->bases);
- free(cb_data->filter);
- free(cb_data->key_attr);
- free(cb_data->value_fmt);
- free(cb_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->filter);
+ free(map_data->key_attr);
+ free(map_data->value_fmt);
+ free(map_data);
}
}
-static struct backend_map_entry_cb_data *
-backend_copy_cb_data(const struct backend_map_entry_cb_data *data)
+static struct backend_map_data *
+backend_copy_cb_data(const struct backend_map_data *data)
{
- struct backend_map_entry_cb_data *ret;
+ struct backend_map_data *ret;
ret = malloc(sizeof(*ret));
if (ret == NULL) {
return NULL;
@@ -96,7 +96,7 @@ backend_copy_cb_data(const struct backend_map_entry_cb_data *data)
(ret->filter == NULL) ||
(ret->key_attr == NULL) ||
(ret->value_fmt == NULL)) {
- backend_free_cb_data(ret);
+ backend_free_map_data(ret);
return NULL;
} return ret;
}
@@ -107,7 +107,7 @@ backend_copy_cb_data(const struct backend_map_entry_cb_data *data)
static int
backend_map_entry_cb(Slapi_Entry *e, void *callback_data)
{
- struct backend_map_entry_cb_data *data;
+ struct backend_map_data *data;
char *key, *value, *dn, **visited_dn;
int i, j;
data = callback_data;
@@ -116,7 +116,7 @@ backend_map_entry_cb(Slapi_Entry *e, void *callback_data)
/* Pull out the value format string and generate the value. XXX */
value = slapi_entry_attr_get_charptr(e, data->value_fmt);
/* Pull together the DN of this entry and the others we peeked at. */
- dn = slapi_entry_get_dn(e);
+ dn = slapi_entry_get_ndn(e);
visited_dn = NULL;
/* If we actually generated a value, then set it for all keys. */
if ((key != NULL) && (value != NULL)) {
@@ -226,7 +226,7 @@ backend_map_config_entry(struct plugin_state *state, Slapi_Entry *e,
char *entry_filter, *use_entry_filter, *key_attribute, *value_attribute;
char *use_key_attribute, *use_value_attribute;
char *use_attrs[3]; /* XXX */
- struct backend_map_entry_cb_data cb_data;
+ struct backend_map_data cb_data;
pb = slapi_pblock_new();
/* Read the NIS entry search base, entry search filter, and the names
@@ -268,7 +268,7 @@ backend_map_config_entry(struct plugin_state *state, Slapi_Entry *e,
map, domain);
map_data_set_map(state, domain, map,
backend_copy_cb_data(&cb_data),
- &backend_free_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. */
@@ -359,45 +359,30 @@ backend_startup(struct plugin_state *state)
}
/* Our postoperation callbacks. */
-
-/* Add any map entries which correspond to a directory server entry in this
- * map. */
-struct backend_add_entry_cbdata {
- Slapi_PBlock *pb;
- Slapi_Entry *e;
- char *dn;
-};
-
static PRBool
-backend_add_entry_cb(const char *domain, const char *map, void *backend_data,
- void *cbdata_ptr)
+backend_entry_matches_map(struct backend_map_data *map_data, Slapi_Entry *e)
{
- Slapi_DN *base_sdn, *entry_sdn;
+ Slapi_DN *base_sdn;
+ const Slapi_DN *entry_sdn;
Slapi_Filter *filter;
- char *dn, **visited_dn, *key, *value;
int i;
- struct backend_map_entry_cb_data *data;
- struct backend_add_entry_cbdata *cbdata;
-
- data = backend_data;
- cbdata = cbdata_ptr;
- dn = cbdata->dn;
/* 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_byval(dn);
+ entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e));
if (entry_sdn == NULL) {
- /* XXX */
+ return PR_FALSE;
} else {
/* Check each base in turn. */
for (i = 0;
- (data->bases != NULL) && (data->bases[i] != NULL);
+ (map_data->bases != NULL) && (map_data->bases[i] != NULL);
i++) {
- base_sdn = slapi_sdn_new_ndn_byval(data->bases[i]);
+ base_sdn = slapi_sdn_new_dn_byval(map_data->bases[i]);
if (base_sdn == NULL) {
- /* XXX */
+ return PR_FALSE;
} else {
- if (slapi_sdn_issuffix(entry_sdn,
- base_sdn) != 0) {
+ 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);
@@ -408,57 +393,93 @@ backend_add_entry_cb(const char *domain, const char *map, void *backend_data,
break;
}
}
- slapi_sdn_free(&entry_sdn);
/* If we ran out of bases to check, it doesn't match. */
- if ((data->bases == NULL) || (data->bases[i] == NULL)) {
- return PR_TRUE;
+ if ((map_data->bases == NULL) || (map_data->bases[i] == NULL)) {
+ return PR_FALSE;
}
}
/* If it's contained by a search base, compare it to the filter. */
- filter = slapi_str2filter(data->filter);
+ filter = slapi_str2filter(map_data->filter);
if (filter == NULL) {
- /* XXX */
+ return PR_FALSE;
} else {
- if (slapi_filter_test(cbdata->pb, cbdata->e, filter, 0) != 0) {
+ if (slapi_filter_test_simple(e, filter) != 0) {
/* Didn't match -- return. */
slapi_filter_free(filter, 1);
- return PR_TRUE;
+ return PR_FALSE;
}
slapi_filter_free(filter, 1);
}
- /* It's contained by the search base and it matches the filter, so add
- * it to the map. */
+ return PR_TRUE;
+}
+
+/* Add any map entries which correspond to a directory server entry in this
+ * map. */
+
+struct backend_add_entry_cbdata {
+ Slapi_PBlock *pb;
+ Slapi_Entry *e;
+ char *dn;
+};
+
+static PRBool
+backend_add_entry_cb(const char *domain, const char *map, void *backend_data,
+ void *cbdata_ptr)
+{
+ Slapi_DN *base_sdn, *entry_sdn;
+ Slapi_Filter *filter;
+ char **visited_dn, *key, *value;
+ 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->e)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ map_data->state->plugin_desc->spd_id,
+ "entry \"%s\" does not belong in "
+ "\"%s\"/\"%s\"\n",
+ cbdata->dn, domain, map);
+ map_data_unset_entry_id(map_data->state,
+ map_data->domain, map_data->map,
+ cbdata->dn);
+ return PR_TRUE;
+ }
+
/* Pull out the name of the attribute which holds the key. */
- key = slapi_entry_attr_get_charptr(cbdata->e, data->key_attr);
+ key = slapi_entry_attr_get_charptr(cbdata->e, map_data->key_attr);
/* Pull out the value format string and generate the value. XXX */
- value = slapi_entry_attr_get_charptr(cbdata->e, data->value_fmt);
+ value = slapi_entry_attr_get_charptr(cbdata->e, map_data->value_fmt);
/* Pull together the DN of this entry and the others we peeked at. */
visited_dn = NULL;
+
/* If we actually generated a value, then set it for all keys. */
if ((key != NULL) && (value != NULL)) {
/* For each key, set the value. */
slapi_log_error(SLAPI_LOG_PLUGIN,
- data->state->plugin_desc->spd_id,
+ map_data->state->plugin_desc->spd_id,
"setting domain/map/key/value "
"\"%s\"/\"%s\"/\"%s\"(\"%s\")=\"%s\"\n",
domain, map,
- key, dn, value);
- map_data_set_entry(data->state, domain, map,
- dn, (const char **) visited_dn,
+ key, cbdata->dn, value);
+ map_data_set_entry(map_data->state, domain, map,
+ cbdata->dn, (const char **) visited_dn,
-1, key,
-1, value);
} else {
slapi_log_error(SLAPI_LOG_PLUGIN,
- data->state->plugin_desc->spd_id,
- "no value for %s\n", dn);
+ map_data->state->plugin_desc->spd_id,
+ "no value for \"%s\"\n", cbdata->dn);
slapi_log_error(SLAPI_LOG_PLUGIN,
- data->state->plugin_desc->spd_id,
+ map_data->state->plugin_desc->spd_id,
"unsetting domain/map/id"
"\"%s\"/\"%s\"/(\"%s\")\n",
- data->domain, data->map, dn);
- map_data_unset_entry_id(data->state,
- data->domain, data->map,
- dn);
+ map_data->domain, map_data->map, cbdata->dn);
+ map_data_unset_entry_id(map_data->state,
+ map_data->domain, map_data->map,
+ cbdata->dn);
}
slapi_ch_free_string(&value);
slapi_ch_free_string(&key);
@@ -488,43 +509,163 @@ backend_add_cb(Slapi_PBlock *pb)
return 0;
}
+struct backend_modify_entry_cbdata {
+ Slapi_PBlock *pb;
+ LDAPMod **mods;
+ Slapi_Entry *e;
+ char *dn;
+};
+
+static PRBool
+backend_modify_entry_cb(const char *domain, const char *map, void *backend_data,
+ void *cbdata_ptr)
+{
+ Slapi_DN *base_sdn, *entry_sdn;
+ Slapi_Filter *filter;
+ char **visited_dn, *key, *value;
+ struct backend_map_data *map_data;
+ struct backend_modify_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->e)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ map_data->state->plugin_desc->spd_id,
+ "clearing domain/map/id "
+ "\"%s\"/\"%s\"/(\"%s\")\n",
+ map_data->domain, map_data->map, cbdata->dn);
+ map_data_unset_entry_id(map_data->state,
+ map_data->domain, map_data->map,
+ cbdata->dn);
+ } else {
+ /* Pull out the name of the attribute which holds the key. */
+ key = slapi_entry_attr_get_charptr(cbdata->e,
+ map_data->key_attr);
+ /* Pull out the value format string and generate the value. XXX
+ * */
+ value = slapi_entry_attr_get_charptr(cbdata->e,
+ map_data->value_fmt);
+ /* Pull together the DN of this entry and the others we peeked
+ * at. */
+ visited_dn = NULL;
+ /* If we actually generated a value, then set it for all keys.
+ * */
+ if ((key != NULL) && (value != NULL)) {
+ /* For each key, set the value. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ map_data->state->plugin_desc->spd_id,
+ "setting domain/map/key/value "
+ "\"%s\"/\"%s\"/\"%s\"(\"%s\")=\"%s\"\n",
+ domain, map,
+ key, cbdata->dn, value);
+ map_data_set_entry(map_data->state, domain, map,
+ cbdata->dn,
+ (const char **) visited_dn,
+ -1, key,
+ -1, value);
+ } else {
+ if (key == NULL) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ map_data->state->plugin_desc->spd_id,
+ "no key for \"%s\"\n",
+ cbdata->dn);
+ }
+ if (value == NULL) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ map_data->state->plugin_desc->spd_id,
+ "no value for \"%s\"\n",
+ cbdata->dn);
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ map_data->state->plugin_desc->spd_id,
+ "unsetting domain/map/id"
+ "\"%s\"/\"%s\"/(\"%s\")\n",
+ map_data->domain, map_data->map,
+ cbdata->dn);
+ map_data_unset_entry_id(map_data->state,
+ map_data->domain, map_data->map,
+ cbdata->dn);
+ }
+ slapi_ch_free_string(&value);
+ slapi_ch_free_string(&key);
+ }
+ return PR_TRUE;
+}
+
int
backend_modify_cb(Slapi_PBlock *pb)
{
struct plugin_state *state;
- char *dn, *id;
+ struct backend_modify_entry_cbdata cbdata;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
- slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
- slapi_pblock_get(pb, SLAPI_TARGET_UNIQUEID, &id);
+ slapi_pblock_get(pb, SLAPI_MODIFY_TARGET, &cbdata.dn);
+ slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &cbdata.mods);
+ slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e);
+ cbdata.pb = pb;
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "modified \"%s\" (\"%s\")\n", dn, id);
+ "modified \"%s\"\n", cbdata.dn);
+ /* Modify map entries which corresponded to this directory server
+ * entry. */
+ if (!map_data_foreach_map(state, NULL,
+ backend_modify_entry_cb, &cbdata)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error modifying map entries corresponding to "
+ "\"%s\"\n", cbdata.dn);
+ }
+ /* If it's a map configuration entry, reconfigure, clear, and
+ * repopulate the map. XXX */
return 0;
}
+struct backend_modrdn_entry_cbdata {
+ Slapi_PBlock *pb;
+ char *new_superior;
+ char *new_rdn;
+ char *dn;
+};
+
int
backend_modrdn_cb(Slapi_PBlock *pb)
{
struct plugin_state *state;
- char *dn, *id;
+ struct backend_modrdn_entry_cbdata cbdata;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
- slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
- slapi_pblock_get(pb, SLAPI_TARGET_UNIQUEID, &id);
+ slapi_pblock_get(pb, SLAPI_MODRDN_TARGET, &cbdata.dn);
+ slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &cbdata.new_rdn);
+ slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR, &cbdata.new_superior);
+ cbdata.pb = pb;
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "renamed \"%s\" (\"%s\")\n", dn, id);
+ "renamed \"%s\" to \"%s\" under \"%s\"\n",
+ cbdata.dn, cbdata.new_rdn, cbdata.new_superior);
return 0;
}
/* Delete any map entries which correspond to a directory server entry in this
* map. */
+
+struct backend_delete_entry_cbdata {
+ Slapi_PBlock *pb;
+ char *dn;
+};
+
static PRBool
backend_delete_entry_cb(const char *domain, const char *map, void *backend_data,
- void *cbdata)
+ void *cbdata_ptr)
{
- char *dn;
- struct backend_map_entry_cb_data *data;
- data = backend_data;
- dn = cbdata;
- map_data_unset_entry_id(data->state, domain, map, dn);
+ struct backend_map_data *map_data;
+ struct backend_delete_entry_cbdata *cbdata;
+ map_data = backend_data;
+ cbdata = cbdata_ptr;
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ map_data->state->plugin_desc->spd_id,
+ "unsetting domain/map/id"
+ "\"%s\"/\"%s\"=\"%s\"/\"%s\"/(\"%s\")\n",
+ domain, map,
+ map_data->domain, map_data->map,
+ cbdata->dn);
+ map_data_unset_entry_id(map_data->state, domain, map, cbdata->dn);
return PR_TRUE;
}
@@ -533,17 +674,19 @@ int
backend_delete_cb(Slapi_PBlock *pb)
{
struct plugin_state *state;
- char *dn;
+ struct backend_delete_entry_cbdata cbdata;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
- slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
+ slapi_pblock_get(pb, SLAPI_DELETE_TARGET, &cbdata.dn);
+ cbdata.pb = pb;
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "deleted \"%s\" (\"%s\")\n", dn);
+ "deleted \"%s\"\n", cbdata.dn);
/* Remove map entries which corresponded to this directory server
* entry. */
- if (!map_data_foreach_map(state, NULL, backend_delete_entry_cb, dn)) {
+ if (!map_data_foreach_map(state, NULL,
+ backend_delete_entry_cb, &cbdata)) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error removing map entries corresponding to "
- "\"%s\"\n", dn);
+ "\"%s\"\n", cbdata.dn);
}
/* If it's a map configuration entry, remove the map. XXX */
return 0;