summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-03 13:47:01 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-03 13:47:01 -0400
commitbe91b0030506410a0c8239ca977c5e1ba4c5d78f (patch)
tree7348d48adf1fa11d13a5ff3b1d10f47f589d4936 /src
parentd0bd372e6602d68a948521950a52650619f5d1c6 (diff)
parentafeacf387f97ca097a856612d94f01e695fb1a9c (diff)
Merge branch 'master' of git.fedoraproject.org:/git/slapi-nis
Diffstat (limited to 'src')
-rw-r--r--src/back-nis.c108
-rw-r--r--src/back-nis.h26
-rw-r--r--src/back-sch.c687
-rw-r--r--src/back-sch.h34
-rw-r--r--src/back-shr.c63
-rw-r--r--src/back-shr.h8
-rw-r--r--src/backend.h28
-rw-r--r--src/dummymap.c17
-rw-r--r--src/format.c168
-rw-r--r--src/map.c65
-rw-r--r--src/map.h24
-rw-r--r--src/nis.c14
-rw-r--r--src/plug-sch.c54
13 files changed, 946 insertions, 350 deletions
diff --git a/src/back-nis.c b/src/back-nis.c
index ced47db..63d5a44 100644
--- a/src/back-nis.c
+++ b/src/back-nis.c
@@ -142,7 +142,7 @@ backend_copy_set_data(const struct backend_set_data *data)
* determine which value should be associated with those keys, and add them to
* the map cache. */
void
-backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data)
+backend_set_entry(Slapi_Entry *e, struct backend_set_data *data)
{
char **keys, ***key_sets, **all_keys, *value, *ndn, *plugin_id;
int i, j, k, n_key_sets;
@@ -174,10 +174,10 @@ backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data)
data->key_formats[i],
data->common.group,
data->common.set, ndn);
- map_data_unset_entry_id(data->common.state,
- data->common.group,
- data->common.set,
- ndn);
+ map_data_unset_entry(data->common.state,
+ data->common.group,
+ data->common.set,
+ ndn);
for (k = 0; k < j; k++) {
format_free_data(keys[k]);
}
@@ -271,9 +271,8 @@ backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data)
"no value for %s, unsetting domain/map/id"
"\"%s\"/\"%s\"/(\"%s\")\n",
ndn, data->common.group, data->common.set, ndn);
- map_data_unset_entry_id(data->common.state,
- data->common.group, data->common.set,
- ndn);
+ map_data_unset_entry(data->common.state,
+ data->common.group, data->common.set, ndn);
}
format_free_data(value);
free(all_keys);
@@ -643,9 +642,9 @@ backend_set_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_shr_set_config_entry_add_one(state, e,
- domains[i],
- maps[j]);
+ ret = backend_shr_set_config_entry_add(state, e,
+ domains[i],
+ maps[j]);
}
}
if (domains != NULL) {
@@ -801,7 +800,13 @@ struct backend_get_set_config_cb {
void
backend_free_set_config(char **bases, char *entry_filter)
{
- backend_shr_free_strlist(bases);
+ int i;
+ if (bases != NULL) {
+ for (i = 0; bases[i] != NULL; i++) {
+ free(bases[i]);
+ }
+ free(bases);
+ }
free(entry_filter);
}
@@ -813,7 +818,7 @@ backend_get_set_config_entry_cb(Slapi_Entry *e, void *callback_data)
struct backend_get_set_config_cb *cbdata;
char *actual_attr;
const char *cvalue;
- int disposition, buffer_flags, i, count;
+ int disposition, buffer_flags, i, count, len;
cbdata = callback_data;
slapi_log_error(SLAPI_LOG_PLUGIN,
@@ -846,7 +851,19 @@ backend_get_set_config_entry_cb(Slapi_Entry *e, void *callback_data)
cvalue = slapi_value_get_string(value);
if (cvalue != NULL) {
free(cbdata->entry_filter);
- cbdata->entry_filter = strdup(cvalue);
+ cbdata->entry_filter = NULL;
+ if ((cvalue[0] != '(') ||
+ (cvalue[strlen(cvalue) - 1] != ')')) {
+ len = strlen(cvalue) + 3;
+ cbdata->entry_filter = malloc(len);
+ if (cbdata->entry_filter != NULL) {
+ sprintf(cbdata->entry_filter,
+ "(%s)", cvalue);
+ }
+ }
+ if (cbdata->entry_filter == NULL) {
+ cbdata->entry_filter = strdup(cvalue);
+ }
}
}
slapi_vattr_values_free(&values, &actual_attr, buffer_flags);
@@ -922,63 +939,12 @@ backend_get_set_config(struct plugin_state *state,
free(filter);
}
-/* Given an entry, return true if it describes a NIS map. */
-bool_t
-backend_entry_is_a_set(struct plugin_state *state,
- Slapi_PBlock *pb, Slapi_Entry *e)
+/* Given an entry, return the filter which will match a container entry beneath
+ * the plugin's configuration entry. */
+const char *
+backend_entry_get_set_config_entry_filter(void)
{
- Slapi_DN *entry_sdn, *plugin_sdn;
- Slapi_Filter *filter;
- bool_t ret;
- char map_configuration_filter[] = NIS_MAP_CONFIGURATION_FILTER;
-
- /* First, just do the scope test. */
- entry_sdn = slapi_sdn_new_ndn_byref(slapi_entry_get_ndn(e));
- if (entry_sdn == NULL) {
- return FALSE;
- } else {
- plugin_sdn = slapi_sdn_new_dn_byval(state->plugin_base);
- if (plugin_sdn == NULL) {
- slapi_sdn_free(&entry_sdn);
- return FALSE;
- }
- }
- if (slapi_sdn_scope_test(entry_sdn,
- plugin_sdn,
- LDAP_SCOPE_ONE) == 0) {
- /* Didn't match. */
- slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc->spd_id,
- "entry \"%s\" is not a child of \"%s\"\n",
- slapi_sdn_get_ndn(entry_sdn),
- slapi_sdn_get_ndn(plugin_sdn));
- ret = FALSE;
- } else {
- ret = TRUE;
- }
- slapi_sdn_free(&plugin_sdn);
- slapi_sdn_free(&entry_sdn);
- /* If it's actually part of our configuration tree, check if it's a
- * valid entry. */
- if (ret) {
- filter = slapi_str2filter(map_configuration_filter);
- if (filter != NULL) {
- if (slapi_vattr_filter_test(pb, e, filter, 0) != 0) {
- /* Didn't match. */
- slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc->spd_id,
- "entry \"%s\" doesn't look "
- "like a map configuration "
- "(didn't match filter "
- "\"%s\")\n",
- slapi_sdn_get_ndn(entry_sdn),
- NIS_MAP_CONFIGURATION_FILTER);
- ret = FALSE;
- }
- slapi_filter_free(filter, 1);
- }
- }
- return ret;
+ return NIS_MAP_CONFIGURATION_FILTER;
}
/* Scan for the list of configured domains and maps. */
@@ -992,5 +958,7 @@ backend_startup(struct plugin_state *state)
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");
backend_shr_postop_init(pb, state);
}
diff --git a/src/back-nis.h b/src/back-nis.h
deleted file mode 100644
index 1f9aa9c..0000000
--- a/src/back-nis.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2008 Red Hat, Inc.
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this Program; if not, write to the
- *
- * Free Software Foundation, Inc.
- * 59 Temple Place, Suite 330
- * Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef back_nis_h
-#define back_nis_h
-struct plugin_state;
-struct slapi_pblock;
-#endif
diff --git a/src/back-sch.c b/src/back-sch.c
index c141551..29216c8 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -50,15 +50,20 @@
#include "plugin.h"
#include "map.h"
-#define SCH_CONTAINER_CONFIGURATION_FILTER "(&(objectClass=*)(" SCH_CONTAINER_CONFIGURATION_GROUP_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_BASE_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_FILTER_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_RDN_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_ATTR_ATTR "=*))"
+#define SCH_CONTAINER_CONFIGURATION_FILTER "(&(objectClass=*)(" SCH_CONTAINER_CONFIGURATION_GROUP_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_BASE_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_FILTER_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_RDN_ATTR "=*))"
/* The data we ask the map cache to keep, for us, for each set. */
struct backend_set_data {
struct backend_shr_set_data common;
/* Schema compatibility-specific data. */
- char *container_dn;
+ Slapi_DN *container_sdn;
char *rdn_format;
char **attribute_format;
+ bool_t check_access;
+};
+struct backend_entry_data {
+ Slapi_DN *original_entry_dn;
+ Slapi_Entry *e;
};
/* Read the name of the NIS master. A dummy function for the schema
@@ -87,6 +92,7 @@ backend_set_config_free_config_contents(void *data)
format_free_attr_list(set_data->common.ref_attrs);
format_free_inref_attrs(set_data->common.inref_attrs);
free(set_data->common.entry_filter);
+ slapi_sdn_free(&set_data->container_sdn);
free(set_data->rdn_format);
backend_shr_free_strlist(set_data->attribute_format);
}
@@ -117,14 +123,15 @@ backend_copy_set_config(const struct backend_set_data *data)
format_dup_inref_attrs(data->common.inref_attrs) :
NULL;
ret->common.entry_filter = strdup(data->common.entry_filter);
- ret->container_dn = strdup(data->container_dn);
+ ret->container_sdn = slapi_sdn_dup(data->container_sdn);
ret->rdn_format = strdup(data->rdn_format);
ret->attribute_format = backend_shr_dup_strlist(data->attribute_format);
+ ret->check_access = data->check_access;
if ((ret->common.group == NULL) ||
(ret->common.set == NULL) ||
(ret->common.bases == NULL) ||
(ret->common.entry_filter == NULL) ||
- (ret->container_dn == NULL)) {
+ (ret->container_sdn == NULL)) {
backend_set_config_free_config(&ret->common);
return NULL;
}
@@ -138,7 +145,8 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
const char *group, const char *container,
bool_t *flag, struct backend_shr_set_data **pret)
{
- char **bases, *entry_filter, **attributes, *rdn_format;
+ char **bases, *entry_filter, **attributes, *rdn_format, *dn;
+ bool_t check_access;
char *actual_attr;
const char *cvalue;
int i, j, disposition, buffer_flags, count;
@@ -203,6 +211,25 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
}
slapi_vattr_values_free(&values, &actual_attr, buffer_flags);
}
+ check_access = TRUE;
+ if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_ACCESS_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);
+ /* FIXME: use nl_langinfo(YESEXPR) here? */
+ if ((strcasecmp(cvalue, "yes") == 0) ||
+ (strcasecmp(cvalue, "on") == 0) ||
+ (strcasecmp(cvalue, "1") == 0)) {
+ check_access = TRUE;
+ } else {
+ check_access = FALSE;
+ }
+ }
+ slapi_vattr_values_free(&values, &actual_attr, buffer_flags);
+ }
attributes = NULL;
if (slapi_vattr_values_get(e, SCH_CONTAINER_CONFIGURATION_ATTR_ATTR,
&values,
@@ -230,9 +257,11 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
ret.common.entry_filter = entry_filter;
ret.common.ref_attrs = NULL;
ret.common.inref_attrs = NULL;
- ret.container_dn = slapi_dn_plus_rdn(ret.common.group, ret.common.set);
+ dn = slapi_dn_plus_rdn(ret.common.group, ret.common.set);
+ ret.container_sdn = slapi_sdn_new_dn_passin(dn);
ret.rdn_format = rdn_format;
ret.attribute_format = attributes;
+ ret.check_access = check_access;
*pret = backend_copy_set_config(&ret);
free(ret.common.group);
free(ret.common.set);
@@ -243,7 +272,7 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
free(ret.common.bases);
}
free(ret.common.entry_filter);
- slapi_ch_free((void **) &ret.container_dn);
+ slapi_sdn_free(&ret.container_sdn);
if (ret.attribute_format != NULL) {
for (i = 0; ret.attribute_format[i] != NULL; i++) {
free(ret.attribute_format[i]);
@@ -253,16 +282,44 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
free(ret.rdn_format);
}
+/* Create and destroy entry-specific data. */
+static struct backend_entry_data *
+backend_entry_make_entry_data(Slapi_DN *original_entry_dn, Slapi_Entry *e)
+{
+ struct backend_entry_data *ret;
+ ret = malloc(sizeof(*ret));
+ if (ret != NULL) {
+ ret->original_entry_dn = slapi_sdn_dup(original_entry_dn);
+ ret->e = e;
+ } else {
+ slapi_entry_free(e);
+ }
+ return ret;
+}
+static void
+backend_entry_free_entry_data(void *p)
+{
+ struct backend_entry_data *data;
+ data = p;
+ slapi_entry_free(data->e);
+ slapi_sdn_free(&data->original_entry_dn);
+ free(data);
+}
+
/* 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)
+backend_set_entry(Slapi_Entry *e, struct backend_set_data *data)
{
char *dn, *rdn, *ndn, *ldif, *plugin_id, *keys[2], **ava, *val;
+ const char *rdnstr;
int len, i, j;
Slapi_Entry *entry;
+ Slapi_DN *e_dn;
+ Slapi_RDN *srdn;
plugin_id = data->common.state->plugin_desc->spd_id;
+ e_dn = slapi_entry_get_sdn(e);
ndn = slapi_entry_get_ndn(e);
/* Generate the RDN for the entry. */
rdn = format_get_data(data->common.state, e,
@@ -272,7 +329,7 @@ backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data)
&data->common.inref_attrs);
/* Now build the entry itself, and set the DN first. */
entry = slapi_entry_alloc();
- dn = slapi_dn_plus_rdn(data->container_dn, rdn);
+ dn = slapi_dn_plus_rdn(slapi_sdn_get_ndn(data->container_sdn), rdn);
slapi_entry_set_dn(entry, dn); /* NOTE: the entry now owns the dn */
/* Iterate through the set of attributes. */
if (data->attribute_format != NULL) {
@@ -287,7 +344,7 @@ backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data)
if (ava != NULL) {
for (j = 0; ava[j] != NULL; j++) {
val = strchr(ava[j], '=');
- if (val != NULL) {
+ if ((val != NULL) && (val[1] != '\0')) {
*val = '\0';
slapi_entry_add_string(entry,
ava[j],
@@ -303,38 +360,52 @@ backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *data)
if (!slapi_entry_rdn_values_present(entry)) {
slapi_entry_add_rdn_values(entry);
}
- /* Perform a schema check. */
if (slapi_entry_schema_check(NULL, entry) != 0) {
slapi_entry_add_string(entry,
"objectClass", "extensibleObject");
}
- /* Produce some LDIF. */
+ /* Clean up some LDIF. */
ldif = slapi_entry2str(entry, &len);
+ /* Recreate the entry. */
+ slapi_entry_free(entry);
+ entry = slapi_str2entry(ldif,
+ SLAPI_STR2ENTRY_REMOVEDUPVALS |
+ SLAPI_STR2ENTRY_ADDRDNVALS |
+ SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES |
+ SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF);
+ slapi_ch_free((void **) &ldif);
+ /* Normalize the RDN, so that we can use it as a key. */
+ srdn = slapi_rdn_new_sdn(slapi_entry_get_sdn(entry));
+ if (srdn != NULL) {
+ rdnstr = slapi_rdn_get_rdn(srdn);
+ } else {
+ rdnstr = NULL;
+ }
/* If we actually generated a useful new entry for this entry, then set
* it, otherwise clear it in case there was one set before. */
- if ((rdn != NULL) && (ldif != NULL)) {
+ if ((rdnstr != NULL) && (slapi_entry_get_ndn(entry) != NULL)) {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id,
"setting group/container/key/value "
"\"%s\"/\"%s\"/\"%s\"(\"%s\")=\"%s\"\n",
data->common.group, data->common.set,
- rdn, ndn, ldif);
- keys[0] = rdn;
+ rdn, ndn, slapi_entry_get_ndn(entry));
+ keys[0] = (char *) rdnstr;
keys[1] = NULL;
map_data_set_entry(data->common.state,
data->common.group, data->common.set, ndn,
- NULL, keys, len, ldif,
- NULL, NULL);
+ NULL, keys, -1, slapi_entry_get_ndn(entry),
+ backend_entry_make_entry_data(e_dn, entry),
+ backend_entry_free_entry_data);
} else {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id,
"no value for %s, unsetting domain/map/id"
"\"%s\"/\"%s\"/(\"%s\")\n",
ndn, data->common.group, data->common.set, ndn);
- map_data_unset_entry_id(data->common.state,
- data->common.group, data->common.set,
- ndn);
+ map_data_unset_entry(data->common.state,
+ data->common.group, data->common.set, ndn);
slapi_entry_free(entry);
}
- slapi_ch_free((void **) &ldif);
+ slapi_rdn_free(&srdn);
format_free_data(rdn);
}
@@ -392,9 +463,9 @@ backend_set_config_entry_add_cb(Slapi_Entry *e, void *callback_data)
for (j = 0;
(containers != NULL) && (containers[j] != NULL);
j++) {
- ret = backend_shr_set_config_entry_add_one(state, e,
- groups[i],
- containers[j]);
+ ret = backend_shr_set_config_entry_add(state, e,
+ groups[i],
+ containers[j]);
}
}
if (groups != NULL) {
@@ -437,7 +508,13 @@ struct backend_get_set_config_cb {
void
backend_free_set_config(char **bases, char *entry_filter)
{
- backend_shr_free_strlist(bases);
+ int i;
+ if (bases != NULL) {
+ for (i = 0; bases[i] != NULL; i++) {
+ free(bases[i]);
+ }
+ free(bases);
+ }
free(entry_filter);
}
@@ -449,7 +526,7 @@ backend_get_set_config_entry_cb(Slapi_Entry *e, void *callback_data)
struct backend_get_set_config_cb *cbdata;
char *actual_attr;
const char *cvalue;
- int disposition, buffer_flags, i, count;
+ int disposition, buffer_flags, i, count, len;
cbdata = callback_data;
slapi_log_error(SLAPI_LOG_PLUGIN,
@@ -484,7 +561,19 @@ backend_get_set_config_entry_cb(Slapi_Entry *e, void *callback_data)
cvalue = slapi_value_get_string(value);
if (cvalue != NULL) {
free(cbdata->entry_filter);
- cbdata->entry_filter = strdup(cvalue);
+ cbdata->entry_filter = NULL;
+ if ((cvalue[0] != '(') ||
+ (cvalue[strlen(cvalue) - 1] != ')')) {
+ len = strlen(cvalue) + 3;
+ cbdata->entry_filter = malloc(len);
+ if (cbdata->entry_filter != NULL) {
+ sprintf(cbdata->entry_filter,
+ "(%s)", cvalue);
+ }
+ }
+ if (cbdata->entry_filter == NULL) {
+ cbdata->entry_filter = strdup(cvalue);
+ }
}
}
slapi_vattr_values_free(&values, &actual_attr, buffer_flags);
@@ -509,7 +598,7 @@ backend_get_set_config(struct plugin_state *state,
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) {
@@ -521,7 +610,7 @@ backend_get_set_config(struct plugin_state *state,
}
sprintf(filter, "(&("
SCH_CONTAINER_CONFIGURATION_GROUP_ATTR "=%s)("
- SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR "=%s)(%s)",
+ SCH_CONTAINER_CONFIGURATION_CONTAINER_ATTR "=%s)%s)",
group, container, SCH_CONTAINER_CONFIGURATION_FILTER);
/* Perform the search. */
@@ -551,105 +640,507 @@ backend_get_set_config(struct plugin_state *state,
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)
+/* Given an entry, return the filter which will match a container entry beneath
+ * the plugin's configuration entry. */
+const char *
+backend_entry_get_set_config_entry_filter(void)
+{
+ return SCH_CONTAINER_CONFIGURATION_FILTER;
+}
+
+/* Re-read plugin-wide settings that may have changed. Nothing to do. */
+void
+backend_update_params(struct plugin_state *state)
{
- Slapi_DN *entry_sdn, *plugin_sdn;
+}
+
+/* Intercept a search request, and if it belongs to one of our compatibility
+ * trees, answer from our cache before letting the default database have a
+ * crack at it. */
+struct backend_search_cbdata {
+ Slapi_PBlock *pb;
+ struct plugin_state *state;
+ char *target, *strfilter, **attrs;
+ int scope, sizelimit, timelimit, attrsonly;
+ bool_t check_access;
+ Slapi_DN *target_dn;
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;
+
+ bool_t answer;
+ int result;
+ const char *matched, *text;
+ int n_entries;
+};
+static bool_t
+backend_search_entry_cb(const char *domain, const char *map, bool_t secure,
+ const char *key, unsigned int key_len,
+ const char *value, unsigned int value_len,
+ const char *id, int key_index,
+ void *backend_data, void *cb_data)
+{
+ Slapi_DN *sdn;
+ struct backend_search_cbdata *cbdata;
+ struct backend_entry_data *entry_data;
+ int result;
+
+ cbdata = cb_data;
+ entry_data = backend_data;
+ sdn = slapi_entry_get_sdn(entry_data->e);
+ /* We've already done the scope check, so just check the entry against
+ * the filter. */
+ result = slapi_filter_test(cbdata->pb, entry_data->e,
+ cbdata->filter, cbdata->check_access);
+ switch (result) {
+ case -1:
+ /* Not a match. */
+ break;
+ case 0:
+ /* Match. Return the entry. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ cbdata->state->plugin_desc->spd_id,
+ "search matched %s\n",
+ slapi_sdn_get_ndn(sdn));
+ slapi_send_ldap_search_entry(cbdata->pb, entry_data->e, NULL,
+ cbdata->attrs, cbdata->attrsonly);
+ cbdata->n_entries++;
+ break;
+ default:
+ /* Return an LDAP error. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ cbdata->state->plugin_desc->spd_id,
+ "search got error %d checking %s\n",
+ result, slapi_sdn_get_ndn(sdn));
+ cbdata->answer = TRUE;
+ if (cbdata->result == 0) {
+ cbdata->result = result;
}
+ break;
}
- 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;
+ return TRUE;
+}
+static bool_t
+backend_search_set_cb(const char *group, const char *set, bool_t flag,
+ void *backend_data, void *cb_data)
+{
+ struct backend_search_cbdata *cbdata;
+ struct backend_set_data *set_data;
+ Slapi_Entry *set_entry;
+ int result;
+ const char *ndn;
+
+ cbdata = cb_data;
+ set_data = backend_data;
+ cbdata->check_access = set_data->check_access;
+ /* Check the set itself. */
+ if (slapi_sdn_scope_test(set_data->container_sdn, cbdata->target_dn,
+ cbdata->scope)) {
+ set_entry = slapi_entry_alloc();
+ slapi_entry_add_string(set_entry,
+ "objectClass", "extensibleObject");
+ slapi_entry_set_sdn(set_entry, set_data->container_sdn);
+ if (!slapi_entry_rdn_values_present(set_entry)) {
+ slapi_entry_add_rdn_values(set_entry);
+ }
+ ndn = slapi_sdn_get_ndn(set_data->container_sdn);
+ result = slapi_filter_test(cbdata->pb, set_entry,
+ cbdata->filter,
+ cbdata->check_access);
+ switch (result) {
+ case -1:
+ /* Not a match. */
+ break;
+ case 0:
+ /* Match. Return the entry. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ cbdata->state->plugin_desc->spd_id,
+ "search matched %s\n", ndn);
+ slapi_send_ldap_search_entry(cbdata->pb, set_entry,
+ NULL, cbdata->attrs,
+ cbdata->attrsonly);
+ cbdata->n_entries++;
+ break;
+ default:
+ /* Return an LDAP error. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ cbdata->state->plugin_desc->spd_id,
+ "search got error %d checking %s\n",
+ result, ndn);
+ cbdata->answer = TRUE;
+ if (cbdata->result == 0) {
+ cbdata->result = result;
}
- slapi_filter_free(filter, 1);
+ break;
}
+ slapi_entry_free(set_entry);
}
- return ret;
+ /* Now scope-check the set's contents so that we only do it once. */
+ switch (cbdata->scope) {
+ case LDAP_SCOPE_BASE:
+ /* If the container is not the parent of the target, then we're
+ * done with this set. */
+ if (slapi_sdn_isparent(set_data->container_sdn,
+ cbdata->target_dn) != 1) {
+ return TRUE;
+ }
+ break;
+ case LDAP_SCOPE_ONE:
+ /* If it's not a scope=one search of this set, then we're done
+ * with this set. */
+ if (slapi_sdn_compare(set_data->container_sdn,
+ cbdata->target_dn) != 0) {
+ return TRUE;
+ }
+ break;
+ case LDAP_SCOPE_SUB:
+ /* If the search suffix is not a suffix of the set and it's not
+ * the set itself, then we're done with this set. */
+ if ((slapi_sdn_compare(set_data->container_sdn,
+ cbdata->target_dn) != 0) &&
+ (slapi_sdn_issuffix(set_data->container_sdn,
+ cbdata->target_dn) != 1)) {
+ return TRUE;
+ }
+ break;
+ }
+ /* Walk the set of entries in this set. */
+ map_data_foreach_entry_id(cbdata->state, group, set, NULL,
+ backend_search_entry_cb, cbdata);
+ return TRUE;
}
-/* Re-read plugin-wide settings that may have changed. Nothing to do. */
-void
-backend_update_params(struct plugin_state *state)
+static bool_t
+backend_search_group_cb(const char *group, void *cb_data)
{
+ struct backend_search_cbdata *cbdata;
+ Slapi_DN *group_dn;
+ Slapi_Entry *group_entry;
+ int result;
+
+ cbdata = cb_data;
+ /* Check the group itself. */
+ group_dn = slapi_sdn_new_dn_byref(group);
+ if (slapi_sdn_scope_test(group_dn, cbdata->target_dn, cbdata->scope)) {
+ group_entry = slapi_entry_alloc();
+ slapi_entry_add_string(group_entry,
+ "objectClass", "extensibleObject");
+ slapi_entry_set_sdn(group_entry, group_dn);
+ if (!slapi_entry_rdn_values_present(group_entry)) {
+ slapi_entry_add_rdn_values(group_entry);
+ }
+ result = slapi_filter_test(cbdata->pb, group_entry,
+ cbdata->filter,
+ cbdata->check_access);
+ switch (result) {
+ case -1:
+ /* Not a match. */
+ break;
+ case 0:
+ /* Match. Return the entry. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ cbdata->state->plugin_desc->spd_id,
+ "search matched %s\n", group);
+ slapi_send_ldap_search_entry(cbdata->pb, group_entry,
+ NULL, cbdata->attrs,
+ cbdata->attrsonly);
+ cbdata->n_entries++;
+ break;
+ default:
+ /* Return an LDAP error. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ cbdata->state->plugin_desc->spd_id,
+ "search got error %d checking %s\n",
+ result, group);
+ cbdata->answer = TRUE;
+ if (cbdata->result == 0) {
+ cbdata->result = result;
+ }
+ break;
+ }
+ slapi_entry_free(group_entry);
+ }
+ /* Now check the group's sets and their contents. */
+ map_data_foreach_map(cbdata->state, group,
+ backend_search_set_cb, cbdata);
+ /* If the search is confined to this group, we need to send the result
+ * ourselves. */
+ if (slapi_sdn_scope_test(cbdata->target_dn, group_dn, LDAP_SCOPE_SUB)) {
+ cbdata->answer = TRUE;
+ }
+ slapi_sdn_free(&group_dn);
+ return TRUE;
}
static int
backend_search_cb(Slapi_PBlock *pb)
{
- return 0;
+ struct backend_search_cbdata cbdata;
+ cbdata.pb = pb;
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state);
+ slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &cbdata.target);
+ cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
+ slapi_pblock_get(pb, SLAPI_SEARCH_SCOPE, &cbdata.scope);
+ slapi_pblock_get(pb, SLAPI_SEARCH_SIZELIMIT, &cbdata.sizelimit);
+ slapi_pblock_get(pb, SLAPI_SEARCH_TIMELIMIT, &cbdata.timelimit);
+ slapi_pblock_get(pb, SLAPI_SEARCH_FILTER, &cbdata.filter);
+ slapi_pblock_get(pb, SLAPI_SEARCH_STRFILTER, &cbdata.strfilter);
+ slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &cbdata.attrs);
+ slapi_pblock_get(pb, SLAPI_SEARCH_ATTRSONLY, &cbdata.attrsonly);
+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id,
+ "searching from \"%s\" for \"%s\" with scope %d\n",
+ cbdata.target, cbdata.strfilter, cbdata.scope);
+ cbdata.answer = FALSE;
+ cbdata.result = 0;
+ cbdata.matched = "";
+ cbdata.text = "";
+ cbdata.n_entries = 0;
+ map_rdlock();
+ map_data_foreach_domain(cbdata.state, backend_search_group_cb, &cbdata);
+ map_unlock();
+ slapi_sdn_free(&cbdata.target_dn);
+ if (cbdata.answer) {
+ slapi_send_ldap_result(cbdata.pb, cbdata.result,
+ (char *) cbdata.matched,
+ (char *) cbdata.text,
+ cbdata.n_entries, NULL);
+ }
+ return cbdata.answer ? -1 : 0;
+}
+
+/* Locate the entry for a given DN. */
+struct backend_locate_cbdata {
+ struct plugin_state *state;
+ char *target;
+ Slapi_DN *target_dn;
+
+ struct backend_entry_data *entry_data;
+};
+/* Check if the target DN is an entry in this container's set of entries. If
+ * it is, pull the entry's data out and save it. */
+static bool_t
+backend_locate_cb(const char *group, const char *set, bool_t flag,
+ void *backend_set_data, void *cb_data)
+{
+ struct backend_locate_cbdata *cbdata;
+ struct backend_set_data *set_data;
+ struct backend_entry_data *entry_data;
+ Slapi_RDN *rdn;
+ const char *rdnstr, *ndn, *original_dn;
+ unsigned int ndnlen;
+
+ cbdata = cb_data;
+ set_data = backend_set_data;
+ /* Check if the target DN looks like it would be part of this set. */
+ if (slapi_sdn_scope_test(cbdata->target_dn, set_data->container_sdn,
+ LDAP_SCOPE_ONE)) {
+ /* Pull out the RDN and check for an entry which is using the
+ * RDN as a key. */
+ rdn = slapi_rdn_new_sdn(cbdata->target_dn);
+ if (rdn != NULL) {
+ rdnstr = slapi_rdn_get_rdn(rdn);
+ if (map_match(cbdata->state, group, set, &flag,
+ strlen(rdnstr), rdnstr,
+ &ndnlen, &ndn,
+ &original_dn, (void **) &entry_data)) {
+ if (entry_data != NULL) {
+ cbdata->entry_data = entry_data;
+ }
+ }
+ slapi_rdn_free(&rdn);
+ }
+ }
+ return TRUE;
+}
+static void
+backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data)
+{
+ struct backend_locate_cbdata cbdata;
+
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state);
+ slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target);
+ cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
+ cbdata.entry_data = NULL;
+ map_data_foreach_map(cbdata.state, NULL, backend_locate_cb, &cbdata);
+ *data = cbdata.entry_data;
+ slapi_sdn_free(&cbdata.target_dn);
+}
+
+/* Check if the target DN is part of this group's tree. If it is, return an
+ * insufficient-access error. */
+struct backend_group_check_scope_cbdata {
+ struct plugin_state *state;
+ const char *target;
+ Slapi_DN *target_dn;
+ bool_t ours;
+};
+static bool_t
+backend_group_check_scope_cb(const char *group, void *cb_data)
+{
+ struct backend_group_check_scope_cbdata *cbdata;
+ Slapi_DN *group_dn;
+
+ cbdata = cb_data;
+ group_dn = slapi_sdn_new_dn_byref(group);
+ if (slapi_sdn_scope_test(cbdata->target_dn, group_dn, LDAP_SCOPE_SUB)) {
+ cbdata->ours = TRUE;
+ }
+ slapi_sdn_free(&group_dn);
+ return TRUE;
+}
+static bool_t
+backend_check_scope(struct plugin_state *state, const char *target)
+{
+ struct backend_group_check_scope_cbdata cbdata;
+
+ cbdata.state = state;
+ cbdata.target = target;
+ cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
+ cbdata.ours = FALSE;
+ map_rdlock();
+ map_data_foreach_domain(cbdata.state, backend_group_check_scope_cb,
+ &cbdata);
+ map_unlock();
+ slapi_sdn_free(&cbdata.target_dn);
+ return cbdata.ours;
}
+static bool_t
+backend_check_scope_pb(Slapi_PBlock *pb)
+{
+ struct plugin_state *state;
+ char *target;
-/* Populate our data. */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
+ slapi_pblock_get(pb, SLAPI_TARGET_DN, &target);
+ return backend_check_scope(state, target);
+}
+static int
+backend_write_cb(Slapi_PBlock *pb)
+{
+ int ret;
+ map_rdlock();
+ if (backend_check_scope_pb(pb)) {
+ slapi_send_ldap_result(pb, LDAP_INSUFFICIENT_ACCESS,
+ NULL, NULL, 0, NULL);
+ ret = -1;
+ } else {
+ ret = 0;
+ }
+ map_unlock();
+ return ret;
+}
+static int
+backend_bind_cb(Slapi_PBlock *pb)
+{
+ struct backend_entry_data *data;
+ int ret;
+ struct berval ref;
+ struct berval *urls[] = {&ref, NULL};
+ const char *ndn;
+
+ map_rdlock();
+ backend_locate(pb, &data);
+ if (data != NULL) {
+ ndn = slapi_sdn_get_ndn(data->original_entry_dn);
+ ref.bv_len = strlen("ldap:///") + strlen(ndn);
+ ref.bv_val = malloc(ref.bv_len + 1);
+ if (ref.bv_val != NULL) {
+ sprintf(ref.bv_val, "ldap:///%s", ndn);
+ slapi_send_ldap_result(pb, LDAP_REFERRAL,
+ NULL, NULL, 0, urls);
+ free(ref.bv_val);
+ } else {
+ slapi_send_ldap_result(pb, LDAP_BUSY,
+ NULL, NULL, 0, NULL);
+ }
+ ret = -1;
+ } else {
+ if (backend_check_scope_pb(pb)) {
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS,
+ NULL, NULL, 0, NULL);
+ ret = -1;
+ } else {
+ ret = 0;
+ }
+ }
+ map_unlock();
+ return ret;
+}
+static int
+backend_compare_cb(Slapi_PBlock *pb)
+{
+ int ret;
+ map_rdlock();
+ if (backend_check_scope_pb(pb)) {
+ slapi_send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM,
+ NULL, NULL, 0, NULL);
+ ret = -1;
+ } else {
+ ret = 0;
+ }
+ map_unlock();
+ return ret;
+}
+
+/* Populate our data cache. */
void
backend_startup(struct plugin_state *state)
{
backend_shr_startup(state, SCH_CONTAINER_CONFIGURATION_FILTER);
}
-static void
-backend_preop_init(Slapi_PBlock *pb, struct plugin_state *state)
+void
+backend_init_preop(Slapi_PBlock *pb, struct plugin_state *state)
{
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "hooking up preoperation callbacks\n");
+ /* Intercept bind requests and return a referral or failure for entries
+ * that we're managing. */
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_BIND_FN,
+ backend_bind_cb) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error hooking up bind callback\n");
+ }
+ /* Intercept compare requests and return the right data. */
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_COMPARE_FN,
+ backend_compare_cb) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error hooking up bind callback\n");
+ }
+ /* Intercept search requests and return the right data. */
if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_SEARCH_FN,
backend_search_cb) != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"error hooking up search callback\n");
}
+ /* Intercept write requests and return an insufficient-access error for
+ * attempts to write to anything we're managing. */
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ADD_FN,
+ backend_write_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_PRE_MODIFY_FN,
+ backend_write_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_PRE_MODRDN_FN,
+ backend_write_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_PRE_DELETE_FN,
+ backend_write_cb) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error hooking up delete callback\n");
+ }
+ /* We don't hook abandonment requests. */
+ /* We don't hook unbind requests. */
}
-static void
-backend_postop_init(Slapi_PBlock *pb, struct plugin_state *state)
-{
- backend_shr_postop_init(pb, state);
-}
-/* Set up our callbacks. */
+
void
-backend_init(Slapi_PBlock *pb, struct plugin_state *state)
+backend_init_postop(Slapi_PBlock *pb, struct plugin_state *state)
{
- backend_preop_init(pb, state);
- backend_postop_init(pb, state);
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "hooking up postoperation callbacks\n");
+ backend_shr_postop_init(pb, state);
}
diff --git a/src/back-sch.h b/src/back-sch.h
deleted file mode 100644
index a97fc18..0000000
--- a/src/back-sch.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2008 Red Hat, Inc.
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this Program; if not, write to the
- *
- * Free Software Foundation, Inc.
- * 59 Temple Place, Suite 330
- * Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef 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
index 4b6701c..15bc7f6 100644
--- a/src/back-shr.c
+++ b/src/back-shr.c
@@ -202,14 +202,14 @@ backend_shr_add_strlist(char ***strlist, const char *value)
/* 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_shr_set_entry(Slapi_Entry *e, struct backend_set_data *set_data)
{
- backend_set_entry_one(e, set_data);
+ backend_set_entry(e, set_data);
}
int
-backend_shr_set_entry_one_cb(Slapi_Entry *e, void *set_data)
+backend_shr_set_entry_cb(Slapi_Entry *e, void *set_data)
{
- backend_shr_set_entry_one(e, set_data);
+ backend_shr_set_entry(e, set_data);
return 0;
}
@@ -236,7 +236,7 @@ backend_shr_set_config_entry_set_one_dn(struct plugin_state *state,
state->plugin_desc->spd_id,
"failure reading entry \"%s\"\n", dn);
} else {
- backend_shr_set_entry_one(entry, set_data);
+ backend_shr_set_entry(entry, set_data);
slapi_entry_free(entry);
}
slapi_sdn_free(&sdn);
@@ -299,8 +299,8 @@ backend_shr_set_config_free_config(void *cb_data)
}
int
-backend_shr_set_config_entry_add_one(struct plugin_state *state, Slapi_Entry *e,
- const char *group, const char *set)
+backend_shr_set_config_entry_add(struct plugin_state *state, Slapi_Entry *e,
+ const char *group, const char *set)
{
Slapi_PBlock *pb;
int i;
@@ -347,7 +347,7 @@ backend_shr_set_config_entry_add_one(struct plugin_state *state, Slapi_Entry *e,
0);
slapi_search_internal_callback_pb(pb, set_data,
NULL,
- backend_shr_set_entry_one_cb,
+ backend_shr_set_entry_cb,
NULL);
slapi_free_search_results_internal(pb);
}
@@ -508,14 +508,13 @@ backend_shr_entry_matches_set(struct backend_shr_set_data *set_data,
}
/* Given an entry, return true if it describes a set. */
-bool_t
+static bool_t
backend_shr_entry_is_a_set(struct plugin_state *state,
- Slapi_PBlock *pb, Slapi_Entry *e,
- const char *set_configuration_filter)
+ Slapi_PBlock *pb, Slapi_Entry *e)
{
return backend_shr_entry_matches(pb, e,
state->plugin_base, LDAP_SCOPE_ONE,
- set_configuration_filter);
+ backend_entry_get_set_config_entry_filter());
}
/* Update any entries to which the passed-in entry in the passed-in map refers
@@ -611,7 +610,7 @@ backend_shr_update_references_cb(const char *group, const char *set,
0);
slapi_search_internal_callback_pb(cbdata->pb, set_data,
NULL,
- backend_shr_set_entry_one_cb,
+ backend_shr_set_entry_cb,
NULL);
}
free(filter);
@@ -721,7 +720,7 @@ backend_shr_add_entry_cb(const char *group, const char *set, bool_t secure,
/* 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->self);
+ backend_set_entry(cbdata->e, set_data->self);
return TRUE;
}
@@ -763,7 +762,7 @@ backend_shr_add_cb(Slapi_PBlock *pb)
/* 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)) {
+ if (backend_shr_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);
@@ -806,10 +805,10 @@ backend_shr_modify_entry_cb(const char *group, const char *set, bool_t flag,
set_data->group,
set_data->set,
cbdata->ndn);
- map_data_unset_entry_id(cbdata->state,
- set_data->group,
- set_data->set,
- cbdata->ndn);
+ map_data_unset_entry(cbdata->state,
+ set_data->group,
+ set_data->set,
+ 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,
@@ -817,7 +816,7 @@ backend_shr_modify_entry_cb(const char *group, const char *set, bool_t flag,
/* 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->self);
+ backend_shr_set_entry(cbdata->e_post, set_data->self);
}
return TRUE;
}
@@ -866,14 +865,14 @@ backend_shr_modify_cb(Slapi_PBlock *pb)
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)) {
+ if (backend_shr_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)) {
+ if (backend_shr_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",
@@ -926,10 +925,10 @@ backend_shr_modrdn_entry_cb(const char *group, const char *set, bool_t secure,
set_data->group,
set_data->set,
cbdata->ndn_pre);
- map_data_unset_entry_id(cbdata->state,
- set_data->group,
- set_data->set,
- cbdata->ndn_pre);
+ map_data_unset_entry(cbdata->state,
+ set_data->group,
+ set_data->set,
+ 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. */
@@ -937,7 +936,7 @@ backend_shr_modrdn_entry_cb(const char *group, const char *set, bool_t secure,
cbdata->pb,
cbdata->e_post);
if (matched_post) {
- backend_set_entry_one(cbdata->e_post, set_data->self);
+ backend_set_entry(cbdata->e_post, set_data->self);
}
return TRUE;
}
@@ -980,14 +979,14 @@ backend_shr_modrdn_cb(Slapi_PBlock *pb)
}
/* 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)) {
+ if (backend_shr_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)) {
+ if (backend_shr_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",
@@ -1024,7 +1023,7 @@ backend_shr_delete_entry_cb(const char *group, const char *set, bool_t flag,
"\"%s\"/\"%s\"=\"%s\"/\"%s\"/(\"%s\")\n",
group, set, set_data->group, set_data->set,
cbdata->ndn);
- map_data_unset_entry_id(cbdata->state, group, set, cbdata->ndn);
+ map_data_unset_entry(cbdata->state, group, set, cbdata->ndn);
}
return TRUE;
}
@@ -1058,7 +1057,7 @@ backend_shr_delete_cb(Slapi_PBlock *pb)
"\"%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)) {
+ if (backend_shr_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);
@@ -1075,8 +1074,6 @@ backend_shr_delete_cb(Slapi_PBlock *pb)
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,
diff --git a/src/back-shr.h b/src/back-shr.h
index 2471676..f477362 100644
--- a/src/back-shr.h
+++ b/src/back-shr.h
@@ -38,10 +38,10 @@ 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_add(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,
diff --git a/src/backend.h b/src/backend.h
index 5924d78..bd44fc7 100644
--- a/src/backend.h
+++ b/src/backend.h
@@ -1,3 +1,24 @@
+/*
+ * 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 backend_h
#define backend_h
struct backend_set_data;
@@ -16,6 +37,8 @@ struct backend_shr_set_data {
/* Startup/initialization functions called through the map. */
void backend_startup(struct plugin_state *state);
void backend_init(struct slapi_pblock *pb, struct plugin_state *state);
+void backend_init_preop(struct slapi_pblock *pb, struct plugin_state *state);
+void backend_init_postop(struct slapi_pblock *pb, struct plugin_state *state);
/* Read the server's name. */
int backend_read_master_name(struct plugin_state *state, char **master);
@@ -29,13 +52,12 @@ void backend_get_set_config(struct plugin_state *state,
void backend_free_set_config(char **bases, char *entry_filter);
/* Check if an entry is a set configuration, and add or remove one. */
-bool_t backend_entry_is_a_set(struct plugin_state *state,
- Slapi_PBlock *pb, Slapi_Entry *e);
+const char *backend_entry_get_set_config_entry_filter(void);
int backend_set_config_entry_add_cb(Slapi_Entry *e, void *callback_data);
int backend_set_config_entry_delete_cb(Slapi_Entry *e, void *callback_data);
/* Set an entry in a set. */
-void backend_set_entry_one(Slapi_Entry *e, struct backend_set_data *set_data);
+void backend_set_entry(Slapi_Entry *e, struct backend_set_data *set_data);
/* Read and free set configurations. */
void backend_set_config_read_config(struct plugin_state *state,
diff --git a/src/dummymap.c b/src/dummymap.c
index fc705d2..2687ab3 100644
--- a/src/dummymap.c
+++ b/src/dummymap.c
@@ -192,8 +192,9 @@ map_find_entries(const char *domain, const char *map)
bool_t
map_match(struct plugin_state *state,
const char *domain, const char *map, bool_t *secure,
- unsigned int key_len, char *key,
- unsigned int *value_len, char **value, const char **id)
+ unsigned int key_len, const char *key,
+ unsigned int *value_len, const char **value,
+ const char **id, void **backend_data)
{
struct entry *entries;
int i;
@@ -213,6 +214,9 @@ map_match(struct plugin_state *state,
*value = entries[i].value;
*value_len = strlen(entries[i].value);
*id = entries[i].key;
+ if (backend_data != NULL) {
+ *backend_data = NULL;
+ }
return TRUE;
}
@@ -220,9 +224,9 @@ bool_t
map_match_id(struct plugin_state *state,
const char *domain, const char *map, bool_t *secure,
const char *in_id, unsigned int in_index,
- unsigned int *key_len, char **key,
- unsigned int *value_len, char **value,
- const char **id)
+ unsigned int *key_len, const char **key,
+ unsigned int *value_len, const char **value,
+ const char **id, void **backend_data)
{
struct entry *entries;
int i;
@@ -246,6 +250,9 @@ map_match_id(struct plugin_state *state,
*value = entries[i].value;
*value_len = strlen(entries[i].value);
*id = entries[i].id;
+ if (backend_data != NULL) {
+ *backend_data = NULL;
+ }
return TRUE;
}
diff --git a/src/format.c b/src/format.c
index 82dac70..2b20305 100644
--- a/src/format.c
+++ b/src/format.c
@@ -490,36 +490,60 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
int disposition, ref_disposition, buffer_flags, ref_buffer_flags;
char **argv, *attrs[3], *actual_attr, *actual_ref_attr;
const char *sep, *cvalue, *cref;
+ char *ref_attr, *target_attr, **choices;
ret = format_parse_args(state, args, &argc, &argv);
if (ret != 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"deref: error parsing arguments\n");
return -EINVAL;
}
- if (argc < 3) {
- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "deref: requires 3 arguments\n");
- format_free_parsed_args(argv);
- return -EINVAL;
+ if (outbuf_choices == NULL) {
+ if (argc != 3) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "deref: requires 3 arguments\n");
+ format_free_parsed_args(argv);
+ return -EINVAL;
+ }
+ sep = argv[0];
+ ref_attr = argv[1];
+ target_attr = argv[2];
+ } else {
+ if (argc != 2) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "deref: requires 2 arguments\n");
+ format_free_parsed_args(argv);
+ return -EINVAL;
+ }
+ sep = NULL;
+ ref_attr = argv[0];
+ target_attr = argv[1];
}
/* Note that the attribute in this entry refers to other entries. */
if (ref_attrs != NULL) {
- backend_shr_add_strlist(ref_attrs, argv[1]);
+ backend_shr_add_strlist(ref_attrs, ref_attr);
}
/* Get the names of the reference attribute. */
- if (slapi_vattr_values_get(e, argv[1], &ref_values,
+ if (slapi_vattr_values_get(e, ref_attr, &ref_values,
&ref_disposition, &actual_ref_attr,
0, &ref_buffer_flags) != 0) {
/* No references. */
format_free_parsed_args(argv);
- return 0;
+ if (outbuf_choices == NULL) {
+ return 0;
+ } else {
+ return -ENOENT;
+ }
}
/* Retrieve these attributes from the referred-to entries. */
- attrs[0] = argv[1];
- attrs[1] = argv[2];
+ attrs[0] = ref_attr;
+ attrs[1] = target_attr;
attrs[2] = NULL;
/* Iterate through the names of the referred-to entries. */
+ ret = 0;
count = 0;
+ choices = NULL;
for (i = slapi_valueset_first_value(ref_values, &ref_value);
i != -1;
i = slapi_valueset_next_value(ref_values, i, &ref_value)) {
@@ -547,9 +571,13 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
slapi_sdn_free(&refdn);
continue;
}
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "deref: reading \"%s\" from \"%s\"\n",
+ target_attr, slapi_sdn_get_ndn(refdn));
slapi_sdn_free(&refdn);
/* Pull out the attribute from the referred-to entry. */
- if (slapi_vattr_values_get(ref, argv[2], &values,
+ if (slapi_vattr_values_get(ref, target_attr, &values,
&disposition, &actual_attr,
0, &buffer_flags) != 0) {
slapi_entry_free(ref);
@@ -580,10 +608,15 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
if (len == 0) {
continue;
}
+ /* If we're keeping a list of choices, just add it to
+ * the list of values we've retrieved and keep going. */
+ if (outbuf_choices != NULL) {
+ backend_shr_add_strlist(&choices, cvalue);
+ continue;
+ }
/* If we need to, add the separator. */
if (count > 0) {
/* Get the length of the separator. */
- sep = argv[0];
slen = strlen(sep);
/* Check if there's space for the separator. */
if (ret + len + slen > outbuf_len) {
@@ -616,6 +649,16 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
&actual_ref_attr,
ref_buffer_flags);
format_free_parsed_args(argv);
+ if (outbuf_choices != NULL) {
+ if (choices != NULL) {
+ /* Return the values we found. */
+ format_add_choice(outbuf_choices, outbuf, choices);
+ backend_shr_free_strlist(choices);
+ } else {
+ /* Return a no-result error. */
+ ret = -ENOENT;
+ }
+ }
return ret;
}
@@ -628,6 +671,8 @@ struct format_referred_cbdata {
char *attr, *separator;
char *outbuf;
int outbuf_len;
+ struct format_choice **outbuf_choices;
+ char **choices;
int count;
int ret;
};
@@ -673,8 +718,14 @@ format_referred_entry_cb(Slapi_Entry *e, void *callback_data)
slapi_log_error(SLAPI_LOG_PLUGIN,
cbdata->state->plugin_desc->spd_id,
"referred: got value \"%s\"\n", cvalue);
- slen = strlen(cbdata->separator);
+ /* If we're keeping a list of choices, just add it to the list
+ * of values we've retrieved and keep going. */
+ if (cbdata->outbuf_choices != NULL) {
+ backend_shr_add_strlist(&cbdata->choices, cvalue);
+ continue;
+ }
/* Check if there's space for the value. */
+ slen = strlen(cbdata->separator);
if (len + (cbdata->count ? slen : 0) > cbdata->outbuf_len) {
slapi_log_error(SLAPI_LOG_PLUGIN,
cbdata->state->plugin_desc->spd_id,
@@ -711,8 +762,8 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
{
int i, ret, argc;
Slapi_PBlock *local_pb;
- char **argv, *attrs[2], *filter, *tndn;
- char *map_filter, **map_bases;
+ char **argv, *attrs[2], *filter, *tndn, *sep, *attr, *other_attr;
+ char *other_set, *set_filter, **set_bases, *use_filter;
struct format_referred_cbdata cbdata;
ret = format_parse_args(state, args, &argc, &argv);
@@ -721,15 +772,34 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
"referred: error parsing arguments\n");
return -EINVAL;
}
- if (argc < 4) {
- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "referred: requires 4 arguments\n");
- format_free_parsed_args(argv);
- return -EINVAL;
+ if (outbuf_choices == NULL) {
+ if (argc != 4) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "referred: requires 4 arguments\n");
+ format_free_parsed_args(argv);
+ return -EINVAL;
+ }
+ sep = argv[0];
+ other_set = argv[1];
+ other_attr = argv[2];
+ attr = argv[3];
+ } else {
+ if (argc != 3) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "referred: requires 3 arguments\n");
+ format_free_parsed_args(argv);
+ return -EINVAL;
+ }
+ sep = NULL;
+ other_set = argv[0];
+ other_attr = argv[1];
+ attr = argv[2];
}
/* Build the attribute list. */
- attrs[0] = argv[3];
+ attrs[0] = attr;
attrs[1] = NULL;
/* Set up to search for matches. */
@@ -741,30 +811,31 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return -ENOMEM;
}
cbdata.state = state;
- cbdata.attr = argv[3];
- cbdata.separator = argv[0];
+ cbdata.attr = attr;
+ cbdata.separator = sep;
cbdata.outbuf = outbuf;
cbdata.outbuf_len = outbuf_len;
+ cbdata.outbuf_choices = outbuf_choices;
+ cbdata.choices = NULL;
cbdata.count = 0;
cbdata.ret = 0;
/* Retrieve the map-specific paramters. */
- map_filter = NULL;
- map_bases = NULL;
- backend_get_set_config(state, group, argv[1], &map_bases, &map_filter);
- if (map_filter == NULL) {
- map_filter = "(objectClass=*)";
- }
- if (map_bases == NULL) {
+ set_filter = NULL;
+ set_bases = NULL;
+ backend_get_set_config(state, group, other_set,
+ &set_bases, &set_filter);
+ if (set_bases == NULL) {
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
"no search bases defined for \"%s\"/\"%s\"?\n",
- group, argv[1]);
+ group, other_set);
}
/* Note that the attribute in this map refers to this entry. */
if (inref_attrs != NULL) {
- format_add_inref_attrs(inref_attrs, group, argv[1], argv[2]);
+ format_add_inref_attrs(inref_attrs, group,
+ other_set, other_attr);
}
tndn = format_escape_for_filter(slapi_entry_get_ndn(e));
@@ -772,30 +843,31 @@ 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_set_config(map_bases, map_filter);
+ backend_free_set_config(set_bases, set_filter);
slapi_pblock_destroy(local_pb);
format_free_parsed_args(argv);
return -ENOMEM;
}
/* Now just search through the entries used for the map. */
- for (i = 0; (map_bases != NULL) && (map_bases[i] != NULL); i++) {
+ use_filter = set_filter ? set_filter : "(objectClass=*)";
+ for (i = 0; (set_bases != NULL) && (set_bases[i] != NULL); i++) {
/* Build the search filter. */
- filter = malloc(strlen(map_filter) + strlen(argv[2]) +
+ filter = malloc(strlen(use_filter) + strlen(other_attr) +
strlen(tndn) + 7);
if (filter == NULL) {
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
"referred: out of memory\n");
- backend_free_set_config(map_bases, map_filter);
+ backend_free_set_config(set_bases, set_filter);
slapi_pblock_destroy(local_pb);
format_free_parsed_args(argv);
return -ENOMEM;
}
- sprintf(filter, "(&(%s=%s)%s)", argv[2], tndn, map_filter);
+ sprintf(filter, "(&(%s=%s)%s)", other_attr, tndn, use_filter);
/* Set up the search. */
slapi_search_internal_set_pb(local_pb,
- map_bases[i], LDAP_SCOPE_SUB,
+ set_bases[i], LDAP_SCOPE_SUB,
filter, attrs, FALSE,
NULL, NULL,
state->plugin_identity, 0);
@@ -803,7 +875,7 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
"searching under \"%s\" for \"%s\"\n",
- map_bases[i], filter);
+ set_bases[i], filter);
slapi_search_internal_callback_pb(local_pb, &cbdata,
NULL,
format_referred_entry_cb,
@@ -816,7 +888,19 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
}
free(tndn);
- backend_free_set_config(map_bases, map_filter);
+ if (outbuf_choices != NULL) {
+ if (cbdata.choices != NULL) {
+ /* Return the values we found. */
+ format_add_choice(outbuf_choices, outbuf,
+ cbdata.choices);
+ backend_shr_free_strlist(cbdata.choices);
+ } else {
+ /* Return a no-result error. */
+ cbdata.ret = -ENOENT;
+ }
+ }
+
+ backend_free_set_config(set_bases, set_filter);
slapi_pblock_destroy(local_pb);
format_free_parsed_args(argv);
return cbdata.ret ? cbdata.ret : cbdata.outbuf - outbuf;
@@ -2086,6 +2170,10 @@ format_get_data_set(struct plugin_state *state, Slapi_Entry *e,
}
combinations *= this_choice->n_values;
}
+ if (combinations == 0) {
+ format_free_choices(choices);
+ return NULL;
+ }
template_len = strlen(template);
ret = malloc((combinations + 1) * sizeof(char *));
if (ret != NULL) {
diff --git a/src/map.c b/src/map.c
index 6f95e61..75d5bc9 100644
--- a/src/map.c
+++ b/src/map.c
@@ -47,7 +47,7 @@
#include "wrap.h"
/* The singleton for the cache. */
-struct {
+static struct {
char *master;
struct domain {
char *name;
@@ -228,7 +228,8 @@ map_data_find_map_entry_id(struct plugin_state *state,
* returns FALSE, then we abort and return FALSE, otherwise we return TRUE. */
static bool_t
map_data_foreach_entry(struct plugin_state *state,
- bool_t all, const char *id,
+ const char *domain_name, const char *map_name,
+ const char *id,
bool_t (*fn)(const char *domain, const char *map,
bool_t secure,
const char *key, unsigned int key_len,
@@ -245,14 +246,21 @@ map_data_foreach_entry(struct plugin_state *state,
struct map_entry *entry;
for (i = 0; i < map_data.n_domains; i++) {
domain = &map_data.domains[i];
+ if ((domain_name != NULL) &&
+ (strcmp(domain_name, domain->name) != 0)) {
+ continue;
+ }
for (j = 0; j < domain->n_maps; j++) {
map = &domain->maps[j];
+ if ((map_name != NULL) &&
+ (strcmp(map_name, map->name) != 0)) {
+ continue;
+ }
for (entry = map->entries;
entry != NULL;
entry = entry->next) {
- if (all ||
- ((id != NULL) &&
- (strcmp(id, entry->id) == 0))) {
+ if ((id == NULL) ||
+ (strcmp(id, entry->id) == 0)) {
for (k = 0; k < entry->n_keys; k++) {
if (!(*fn)(domain->name,
map->name,
@@ -276,7 +284,8 @@ map_data_foreach_entry(struct plugin_state *state,
/* Iterate over every entry which matches the corresponding ID. */
bool_t
-map_data_foreach_entry_id(struct plugin_state *state, const char *id,
+map_data_foreach_entry_id(struct plugin_state *state,
+ const char *domain, const char *map, const char *id,
bool_t (*fn)(const char *domain, const char *map,
bool_t secure,
const char *key,
@@ -287,7 +296,23 @@ map_data_foreach_entry_id(struct plugin_state *state, const char *id,
void *backend_data, void *cbdata),
void *cbdata)
{
- return map_data_foreach_entry(state, FALSE, id, fn, cbdata);
+ return map_data_foreach_entry(state, domain, map, id, fn, cbdata);
+}
+
+/* Iterate over all domains, calling the callback with information about the
+ * domain. */
+bool_t
+map_data_foreach_domain(struct plugin_state *state,
+ bool_t (*fn)(const char *domain, void *cbdata),
+ void *cbdata)
+{
+ int i, j;
+ for (i = 0; i < map_data.n_domains; i++) {
+ if (!(*fn)(map_data.domains[i].name, cbdata)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
}
/* Iterate over all maps, calling the callback with information about the map
@@ -398,9 +423,9 @@ bool_t
map_match(struct plugin_state *state,
const char *domain_name, const char *map_name,
bool_t *secure,
- unsigned int key_len, char *key,
- unsigned int *value_len, char **value,
- const char **id)
+ unsigned int key_len, const char *key,
+ unsigned int *value_len, const char **value,
+ const char **id, void **backend_data)
{
struct map *map;
struct map_entry *entry;
@@ -416,6 +441,9 @@ map_match(struct plugin_state *state,
*value_len = entry->value_len;
*value = entry->value;
*id = entry->id;
+ if (backend_data != NULL) {
+ *backend_data = entry->backend_data;
+ }
return TRUE;
}
@@ -424,9 +452,9 @@ map_match_id(struct plugin_state *state,
const char *domain_name, const char *map_name,
bool_t *secure,
const char *in_id, unsigned int in_key_index,
- unsigned int *key_len, char **key,
- unsigned int *value_len, char **value,
- const char **id)
+ unsigned int *key_len, const char **key,
+ unsigned int *value_len, const char **value,
+ const char **id, void **backend_data)
{
struct map *map;
struct map_entry *entry;
@@ -450,6 +478,9 @@ map_match_id(struct plugin_state *state,
*value_len = entry->value_len;
*value = entry->value;
*id = entry->id;
+ if (backend_data != NULL) {
+ *backend_data = entry->backend_data;
+ }
return TRUE;
}
@@ -827,10 +858,10 @@ map_data_unset_map_entry(struct plugin_state *state,
/* Remove the entry from the map which matches the passed-in ID. */
void
-map_data_unset_entry_id(struct plugin_state *state,
- const char *domain_name,
- const char *map_name,
- const char *id)
+map_data_unset_entry(struct plugin_state *state,
+ const char *domain_name,
+ const char *map_name,
+ const char *id)
{
struct map *map;
struct map_entry *entry;
diff --git a/src/map.h b/src/map.h
index 6a8e4a5..e7d0f52 100644
--- a/src/map.h
+++ b/src/map.h
@@ -37,14 +37,15 @@ bool_t map_supports_map(struct plugin_state *state,
bool_t *secure);
bool_t map_match(struct plugin_state *state,
const char *domain, const char *map, bool_t *secure,
- unsigned int key_len, char *key,
- unsigned int *value_len, char **value, const char **id);
+ unsigned int key_len, const char *key,
+ unsigned int *value_len, const char **value,
+ const char **id, void **backend_data);
bool_t map_match_id(struct plugin_state *state,
const char *domain, const char *map, bool_t *secure,
const char *id_in, unsigned int id_index,
- unsigned int *key_len, char **key,
- unsigned int *value_len, char **value,
- const char **id);
+ unsigned int *key_len, const char **key,
+ unsigned int *value_len, const char **value,
+ const char **id, void **backend_data);
bool_t map_first(struct plugin_state *state,
const char *domain, const char *map, bool_t *secure,
unsigned int *first_key_len, char **first_key,
@@ -73,9 +74,9 @@ void map_data_set_map(struct plugin_state *state,
const char *domain_name, const char *map_name,
bool_t secure,
void *backend_data, void (*free_backend_data)(void *p));
-void map_data_unset_entry_id(struct plugin_state *state,
- const char *domain_name, const char *map_name,
- const char *id);
+void map_data_unset_entry(struct plugin_state *state,
+ const char *domain_name, const char *map_name,
+ const char *id);
void map_data_set_entry(struct plugin_state *state,
const char *domain_name, const char *map_name,
const char *id,
@@ -85,7 +86,9 @@ void map_data_set_entry(struct plugin_state *state,
bool_t map_data_check_entry(struct plugin_state *state,
const char *domain_name, const char *map_name,
const char *id);
-bool_t map_data_foreach_entry_id(struct plugin_state *state, const char *id,
+bool_t map_data_foreach_entry_id(struct plugin_state *state,
+ const char *domain, const char *map,
+ const char *id,
bool_t (*fn)(const char *domain,
const char *map,
bool_t secure,
@@ -97,6 +100,9 @@ bool_t map_data_foreach_entry_id(struct plugin_state *state, const char *id,
void *backend_data,
void *cbdata),
void *cbdata);
+bool_t map_data_foreach_domain(struct plugin_state *state,
+ bool_t (*fn)(const char *domain, void *cbdata),
+ void *cbdata);
bool_t map_data_foreach_map(struct plugin_state *state, const char *domain_name,
bool_t (*fn)(const char *domain,
const char *map,
diff --git a/src/nis.c b/src/nis.c
index 09b2588..3100977 100644
--- a/src/nis.c
+++ b/src/nis.c
@@ -106,8 +106,8 @@ nis_match(struct plugin_state *state,
req_key.keydat.keydat_len,
req_key.keydat.keydat_val,
&reply_val->valdat.valdat_len,
- &reply_val->valdat.valdat_val,
- &entry_id) &&
+ (const char **) &reply_val->valdat.valdat_val,
+ &entry_id, NULL) &&
(map_secure ? client_secure : TRUE)) {
reply_val->status = YP_TRUE;
slapi_log_error(SLAPI_LOG_PLUGIN,
@@ -217,8 +217,8 @@ nis_next(struct plugin_state *state,
req_key.keydat.keydat_len,
req_key.keydat.keydat_val,
&reply_key_val->valdat.valdat_len,
- &reply_key_val->valdat.valdat_val,
- &entry_id) &&
+ (const char **) &reply_key_val->valdat.valdat_val,
+ &entry_id, NULL) &&
(map_secure ? client_secure : TRUE)) {
/* Have data for this key, but not the next. */
reply_key_val->status = YP_NOMORE;
@@ -660,10 +660,10 @@ nis_all(struct plugin_state *state,
cookie->id,
cookie->key_index,
&reply_key->keydat_len,
- &reply_key->keydat_val,
+ (const char **) &reply_key->keydat_val,
&reply_val->valdat_len,
- &reply_val->valdat_val,
- &entry_id) &&
+ (const char **) &reply_val->valdat_val,
+ &entry_id, NULL) &&
(map_secure ? client_secure : TRUE);
entry_key_index = cookie->key_index;
if (found) {
diff --git a/src/plug-sch.c b/src/plug-sch.c
index fdb819a..6bd8f33 100644
--- a/src/plug-sch.c
+++ b/src/plug-sch.c
@@ -58,14 +58,19 @@
#include "portmap.h"
#include "wrap.h"
+#define PLUGIN_ID "schema-compat-plugin"
+#define PLUGIN_PREOP_ID PLUGIN_ID "-preop"
+#define PLUGIN_POSTOP_ID PLUGIN_ID "-postop"
+
/* the module initialization function */
static Slapi_PluginDesc
plugin_description = {
- .spd_id = "schema-compat-plugin",
+ .spd_id = PLUGIN_ID,
.spd_vendor = "redhat.com",
.spd_version = PACKAGE_VERSION,
.spd_description = "Schema Compatibility Plugin",
};
+static struct plugin_state *global_plugin_state;
/* Handle the part of startup that needs to be done before we drop privileges.
*/
@@ -99,15 +104,38 @@ plugin_startup(Slapi_PBlock *pb)
struct plugin_state *state;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
slapi_pblock_get(pb, SLAPI_TARGET_DN, &state->plugin_base);
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "startup: target-dn is %s%s%s\n",
+ state->plugin_base ? "\"" : "",
+ state->plugin_base ? state->plugin_base : "NULL",
+ state->plugin_base ? "\"" : "");
backend_startup(state);
return 0;
}
+static int
+schema_compat_plugin_init_preop(Slapi_PBlock *pb)
+{
+ 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, global_plugin_state);
+ backend_init_preop(pb, global_plugin_state);
+ return 0;
+}
+static int
+schema_compat_plugin_init_postop(Slapi_PBlock *pb)
+{
+ 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, global_plugin_state);
+ backend_init_postop(pb, global_plugin_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. */
+ /* Allocate a memory pool. */
if (plugin_state_init(pb, &state) == -1) {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
"error setting up plugin\n");
@@ -120,8 +148,26 @@ schema_compat_plugin_init(Slapi_PBlock *pb)
slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, state);
/* Let the backend do its setup. */
map_init(pb, state);
- backend_init(pb, state);
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "registered plugin hooks\n");
+ "registered plugin\n");
+ /* Register the sub-plugins. */
+ global_plugin_state = state;
+ if (slapi_register_plugin("preoperation", TRUE,
+ "schema_compat_plugin_init_preop",
+ schema_compat_plugin_init_preop,
+ PLUGIN_PREOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering preoperation plugin\n");
+ }
+ if (slapi_register_plugin("postoperation", TRUE,
+ "schema_compat_plugin_init_postop",
+ schema_compat_plugin_init_postop,
+ PLUGIN_POSTOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering postoperation plugin\n");
+ }
+ global_plugin_state = NULL;
return 0;
}