diff options
| author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-05-12 17:57:06 -0400 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-05-12 17:57:06 -0400 |
| commit | a90652fce9126d42f5daf594c6c80418a48193ef (patch) | |
| tree | 7e94b643c9d131c11adb0adddf4871d28d5da86a /src | |
| parent | 96959aa8532d33f82476af0abf8cdee99d2c9b4b (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.c | 315 |
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; |
