summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-30 17:37:35 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-07-30 17:37:35 -0400
commit0566e2e2fbbeb82d383bf3e39c5a7014df315de0 (patch)
treeb31531b766755d90e7ab90c2a11092700378c883 /src
parent76cfc37278eacc81a8d5656e381a7f265407a710 (diff)
downloadslapi-nis-0566e2e2fbbeb82d383bf3e39c5a7014df315de0.tar.gz
slapi-nis-0566e2e2fbbeb82d383bf3e39c5a7014df315de0.tar.xz
slapi-nis-0566e2e2fbbeb82d383bf3e39c5a7014df315de0.zip
- handle values-format, a la keys-format
- factor out code which retrieves key and keys lists so that it can be reused to pull up value data, too
Diffstat (limited to 'src')
-rw-r--r--src/back-nis.c484
1 files changed, 304 insertions, 180 deletions
diff --git a/src/back-nis.c b/src/back-nis.c
index b6fe86f..07fe0cd 100644
--- a/src/back-nis.c
+++ b/src/back-nis.c
@@ -59,8 +59,8 @@
struct backend_set_data {
struct backend_shr_set_data common;
/* NIS-specific data. */
- char **key_formats, **keys_formats, *value_format;
- int n_key_formats, n_keys_formats;
+ char **key_formats, **keys_formats, **value_formats, **values_formats;
+ int n_key_formats, n_keys_formats, n_value_formats, n_values_formats;
char *disallowed_chars;
};
@@ -92,7 +92,8 @@ backend_free_set_data_contents(void *data)
free(set_data->disallowed_chars);
backend_shr_free_strlist(set_data->key_formats);
backend_shr_free_strlist(set_data->keys_formats);
- free(set_data->value_format);
+ backend_shr_free_strlist(set_data->value_formats);
+ backend_shr_free_strlist(set_data->values_formats);
}
}
void
@@ -127,170 +128,238 @@ backend_copy_set_data(const struct backend_set_data *data)
ret->keys_formats = backend_shr_dup_strlist(data->keys_formats);
ret->n_key_formats = data->n_key_formats;
ret->n_keys_formats = data->n_keys_formats;
- ret->value_format = strdup(data->value_format);
+ ret->value_formats = backend_shr_dup_strlist(data->value_formats);
+ ret->values_formats = backend_shr_dup_strlist(data->values_formats);
+ ret->n_value_formats = data->n_value_formats;
+ ret->n_values_formats = data->n_values_formats;
if ((ret->common.group == NULL) ||
(ret->common.set == NULL) ||
(ret->common.bases == NULL) ||
(ret->common.entry_filter == NULL) ||
((ret->key_formats == NULL) && (ret->keys_formats == NULL)) ||
- (ret->value_format == NULL)) {
+ ((ret->value_formats == NULL) && (ret->values_formats == NULL))) {
backend_set_config_free_config(&ret->common);
return NULL;
}
return &ret->common;
}
-/* Given a map-entry directory entry, determine which keys it should have,
- * determine which value should be associated with those keys, and add them to
- * the map cache. */
-void
-backend_set_entry(Slapi_Entry *e, struct backend_set_data *data)
+/* Gather each single result gleaned by evaluating each value in
+ * single_formats, and each group of results by evaluating each value in
+ * group_formats, and merge them all together. */
+static void
+backend_free_gathered_data(char **all, unsigned int *all_lengths,
+ unsigned int n_singles,
+ char **singles,
+ unsigned int n_groups,
+ char ***groups, unsigned int **group_lengths)
{
- char **keys, ***key_sets, **all_keys, *value, *ndn, *plugin_id;
- int i, j, k, n_key_sets;
- unsigned int *key_lengths, **key_length_sets, *all_key_lengths;
- unsigned int value_len;
- plugin_id = data->common.state->plugin_desc->spd_id;
- /* Pull out the NDN of this entry. */
- ndn = slapi_entry_get_ndn(e);
- /* Pull out the keys and value for the entry. */
- if (data->n_key_formats > 0) {
- keys = malloc((data->n_key_formats + 1) * sizeof(char *));
- key_lengths = malloc((data->n_key_formats + 1) *
- sizeof(unsigned int));
- } else {
- keys = NULL;
- key_lengths = NULL;
- }
- if ((keys != NULL) && (key_lengths != NULL)) {
- for (i = 0, j = 0; i < data->n_key_formats; i++) {
- keys[j] = format_get_data(data->common.state, e,
- data->common.group,
- data->common.set,
- data->key_formats[i],
- data->disallowed_chars,
- &data->common.ref_attrs,
- &data->common.inref_attrs,
- &key_lengths[j]);
- if ((keys[j] != NULL) && (key_lengths[j] > 0)) {
- j++;
- } else {
- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id,
- "no key for %s, "
- "unsetting domain/map/id"
- "\"%s\"/\"%s\"/(\"%s\")\n",
- data->key_formats[i],
- 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]);
- }
- free(keys);
- return;
- }
- }
- keys[j] = NULL;
+ unsigned int i;
+ free(all);
+ free(all_lengths);
+ for (i = 0; i < n_singles; i++) {
+ format_free_data(singles[i]);
}
- if (data->n_keys_formats > 0) {
- key_sets = malloc((data->n_keys_formats + 1) * sizeof(char **));
- key_length_sets = malloc((data->n_keys_formats + 1) *
- sizeof(unsigned int *));
- } else {
- key_sets = NULL;
- key_length_sets = NULL;
+ free(singles);
+ for (i = 0; i < n_groups; i++) {
+ format_free_data_set(groups[i], group_lengths[i]);
}
- n_key_sets = 0;
- if (key_sets != NULL) {
- for (i = 0, j = 0; i < data->n_keys_formats; i++) {
- key_sets[j] = format_get_data_set(data->common.state, e,
- data->common.group,
- data->common.set,
- data->keys_formats[i],
- data->disallowed_chars,
- &data->common.ref_attrs,
- &data->common.inref_attrs,
- &key_length_sets[j]);
- if ((key_sets[j] != NULL) &&
- (key_length_sets[j] != NULL)) {
- j++;
- }
+ free(group_lengths);
+ free(groups);
+}
+static char **
+backend_gather_data(struct plugin_state *state, Slapi_Entry *e,
+ const char *domain, const char *map,
+ char **single_formats, char **group_formats,
+ const char *disallowed_chars,
+ char ***ref_attrs,
+ struct format_inref_attr ***inref_attrs,
+ unsigned int **ret_lengths,
+ unsigned int *ret_n_singles,
+ char ***ret_singles,
+ unsigned int *ret_n_groups,
+ char ****ret_groups,
+ unsigned int ***ret_group_lengths)
+{
+ char **ret, **singles, ***groups;
+ unsigned int i, j, k, n, n_singles, n_groups;
+ unsigned int *lengths, *single_lengths, **group_lengths;
+ if (single_formats != NULL) {
+ for (n_singles = 0;
+ single_formats[n_singles] != NULL;
+ n_singles++) {
+ continue;
+ }
+ singles = malloc(sizeof(singles[0]) * n_singles);
+ single_lengths = malloc(sizeof(single_lengths[0]) * n_singles);
+ if ((singles == NULL) || (single_lengths == NULL)) {
+ free(singles);
+ free(single_lengths);
+ n_singles = 0;
+ singles = NULL;
+ single_lengths = NULL;
}
- key_sets[j] = NULL;
- key_length_sets[j] = NULL;
- n_key_sets = j;
+ } else {
+ n_singles = 0;
+ singles = NULL;
+ single_lengths = NULL;
}
- value = format_get_data(data->common.state, e,
- data->common.group, data->common.set,
- data->value_format, data->disallowed_chars,
- &data->common.ref_attrs,
- &data->common.inref_attrs,
- &value_len);
- /* Build one big list of all of the keys and key sets. */
- k = 0;
- if (keys != NULL) {
- for (i = 0; keys[i] != NULL; i++) {
+ if (group_formats != NULL) {
+ for (n_groups = 0;
+ group_formats[n_groups] != NULL;
+ n_groups++) {
continue;
}
- k += i;
+ groups = malloc(sizeof(groups[0]) * n_groups);
+ group_lengths = malloc(sizeof(group_lengths[0]) * n_groups);
+ if ((groups == NULL) || (group_lengths == NULL)) {
+ free(groups);
+ free(group_lengths);
+ n_groups = 0;
+ groups = NULL;
+ group_lengths = NULL;
+ }
+ } else {
+ n_groups = 0;
+ groups = NULL;
+ group_lengths = NULL;
}
- if (key_sets != NULL) {
- for (i = 0; key_sets[i] != NULL; i++) {
- for (j = 0; key_sets[i][j] != NULL; j++) {
- continue;
+ n = 0;
+ for (i = 0; i < n_singles; i++) {
+ singles[i] = format_get_data(state, e, domain, map,
+ single_formats[i],
+ disallowed_chars,
+ ref_attrs, inref_attrs,
+ &single_lengths[i]);
+ if (singles[i] != NULL) {
+ n++;
+ } else {
+ /* If evaluating any of the single-value formats fails,
+ * then we should fail completely. */
+ for (j = 0; j < i; j++) {
+ format_free_data(singles[i]);
}
- k += j;
+ free(singles);
+ free(single_lengths);
+ free(groups);
+ free(group_lengths);
+ *ret_singles = NULL;
+ *ret_groups = NULL;
+ *ret_lengths = NULL;
+ return NULL;
}
}
- if (k > 0) {
- all_keys = malloc(sizeof(char *) * (k + 1));
- all_key_lengths = malloc(sizeof(unsigned int) * (k + 1));
- if ((all_keys != NULL) && (all_key_lengths != NULL)) {
- k = 0;
- if (keys != NULL) {
- for (i = 0; keys[i] != NULL; i++) {
- all_keys[k] = keys[i];
- all_key_lengths[k] = key_lengths[i];
- k++;
- }
+ for (i = 0; i < n_groups; i++) {
+ groups[i] = format_get_data_set(state, e, domain, map,
+ group_formats[i],
+ disallowed_chars,
+ ref_attrs, inref_attrs,
+ &group_lengths[i]);
+ if (groups[i] != NULL) {
+ for (j = 0; groups[i][j] != NULL; j++) {
+ n++;
}
- if (key_sets != NULL) {
- for (i = 0; key_sets[i] != NULL; i++) {
- for (j = 0;
- key_sets[i][j] != NULL;
- j++) {
- all_keys[k] = key_sets[i][j];
- all_key_lengths[k] =
- key_length_sets[i][j];
- k++;
- }
- }
+ }
+ }
+ ret = malloc((n + 1) * sizeof(char *));
+ lengths = malloc(n * sizeof(ret_lengths[0]));
+ if ((ret == NULL) || (ret_lengths == NULL)) {
+ free(ret);
+ free(lengths);
+ backend_free_gathered_data(NULL, NULL,
+ n_singles, singles,
+ n_groups, groups, group_lengths);
+ return NULL;
+ }
+ k = 0;
+ for (i = 0; i < n_singles; i++) {
+ ret[k] = singles[i];
+ lengths[k] = single_lengths[i];
+ k++;
+ }
+ for (i = 0; i < n_groups; i++) {
+ if (groups[i] != NULL) {
+ for (j = 0; groups[i][j] != NULL; j++) {
+ ret[k] = groups[i][j];
+ lengths[k] = group_lengths[i][j];
+ k++;
}
- all_keys[k] = NULL;
- all_key_lengths[k] = 0;
}
- } else {
- all_keys = NULL;
- all_key_lengths = NULL;
}
- /* If we actually generated a value, then set it, otherwise clear it in
- * case there was one set before. */
- if ((all_keys != NULL) && (value != NULL)) {
+ *ret_lengths = lengths;
+ *ret_n_singles = n_singles;
+ *ret_singles = singles;
+ *ret_n_groups = n_groups;
+ *ret_groups = groups;
+ *ret_group_lengths = group_lengths;
+ return ret;
+}
+
+/* Given a map-entry directory entry, determine which keys it should have,
+ * determine which value should be associated with those keys, and add them to
+ * the map cache. */
+void
+backend_set_entry(Slapi_Entry *e, struct backend_set_data *data)
+{
+ char **all_keys, **all_values, *ndn, *plugin_id;
+ char **key_singles, ***key_groups, **value_singles, ***value_groups;
+ unsigned int *all_key_lengths, *all_value_lengths;
+ unsigned int n_key_singles, n_key_groups, **key_group_lengths;
+ unsigned int n_value_singles, n_value_groups, **value_group_lengths;
+ int i, j, n_values;
+ plugin_id = data->common.state->plugin_desc->spd_id;
+ /* Pull out the NDN of this entry. */
+ ndn = slapi_entry_get_ndn(e);
+ /* Pull out the keys and value for the entry. */
+ all_keys = backend_gather_data(data->common.state, e,
+ data->common.group,
+ data->common.set,
+ data->key_formats,
+ data->keys_formats,
+ data->disallowed_chars,
+ &data->common.ref_attrs,
+ &data->common.inref_attrs,
+ &all_key_lengths,
+ &n_key_singles,
+ &key_singles,
+ &n_key_groups,
+ &key_groups,
+ &key_group_lengths);
+ all_values = backend_gather_data(data->common.state, e,
+ data->common.group,
+ data->common.set,
+ data->value_formats,
+ data->values_formats,
+ data->disallowed_chars,
+ &data->common.ref_attrs,
+ &data->common.inref_attrs,
+ &all_value_lengths,
+ &n_value_singles,
+ &value_singles,
+ &n_value_groups,
+ &value_groups,
+ &value_group_lengths);
+ /* If we actually generated keys and values, then set it, otherwise
+ * clear it in case there were some there before. */
+ if ((all_keys != NULL) && (all_values != NULL)) {
for (i = 0; all_keys[i] != NULL; i++) {
+ for (j = 0; all_values[j] != NULL; j++) {
+ continue;
+ }
+ n_values = j;
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id,
"setting domain/map/key/value "
"\"%s\"/\"%s\"/\"%s\"(\"%s\")="
"\"%.*s\"\n",
data->common.group, data->common.set,
- all_keys[i], ndn, value_len, value);
+ all_keys[i], ndn,
+ all_value_lengths[i % n_values],
+ all_values[i % n_values]);
}
map_data_set_entry(data->common.state,
data->common.group, data->common.set, ndn,
all_key_lengths, all_keys,
- value_len, value, NULL, NULL);
+ all_value_lengths, all_values, NULL, NULL);
} else {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id,
"no value for %s, unsetting domain/map/id"
@@ -299,23 +368,15 @@ backend_set_entry(Slapi_Entry *e, struct backend_set_data *data)
map_data_unset_entry(data->common.state,
data->common.group, data->common.set, ndn);
}
- format_free_data(value);
- free(all_key_lengths);
- free(all_keys);
- if (key_sets != NULL) {
- for (i = 0; key_sets[i] != NULL; i++) {
- format_free_data_set(key_sets[i], key_length_sets[i]);
- }
- free(key_sets);
- free(key_length_sets);
- }
- if (keys != NULL) {
- for (i = 0; i < data->n_key_formats; i++) {
- format_free_data(keys[i]);
- }
- free(keys);
- free(key_lengths);
- }
+ /* Clean up. */
+ backend_free_gathered_data(all_keys, all_key_lengths,
+ n_key_singles, key_singles,
+ n_key_groups, key_groups,
+ key_group_lengths);
+ backend_free_gathered_data(all_values, all_value_lengths,
+ n_value_singles, value_singles,
+ n_value_groups, value_groups,
+ value_group_lengths);
}
/*
@@ -394,18 +455,19 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
{
struct backend_set_data ret;
const char *default_filter, *default_key_format, *default_keys_format;
- const char *default_value_format, *default_disallowed_chars;
+ const char *default_value_format, *default_values_format;
+ const char *default_disallowed_chars;
char **bases, *entry_filter;
- char **key_formats, **keys_formats, *value_format;
+ char **key_formats, **keys_formats, **value_formats, **values_formats;
char *disallowed_chars;
char **use_bases, *use_entry_filter;
char **use_key_formats, **use_keys_formats;
- char *use_value_format, *use_disallowed_chars;
- int i;
+ char **use_value_formats, **use_values_formats, *use_disallowed_chars;
+ int i, j;
/* Read the hard-coded defaults for a map with this name. */
defaults_get_map_config(map, secure, &default_filter,
&default_key_format, &default_keys_format,
- &default_value_format,
+ &default_value_format, &default_values_format,
&default_disallowed_chars);
/* Read the values from the configuration entry. */
bases = backend_shr_get_vattr_strlist(state, e,
@@ -416,8 +478,10 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
NIS_MAP_CONFIGURATION_KEY_ATTR);
keys_formats = backend_shr_get_vattr_strlist(state, e,
NIS_MAP_CONFIGURATION_KEYS_ATTR);
- value_format = backend_shr_get_vattr_str(state, e,
- NIS_MAP_CONFIGURATION_VALUE_ATTR);
+ value_formats = backend_shr_get_vattr_strlist(state, e,
+ NIS_MAP_CONFIGURATION_VALUE_ATTR);
+ values_formats = backend_shr_get_vattr_strlist(state, e,
+ NIS_MAP_CONFIGURATION_VALUES_ATTR);
disallowed_chars = backend_shr_get_vattr_str(state, e,
NIS_MAP_CONFIGURATION_DISALLOWED_CHARS_ATTR);
*secure = backend_shr_get_vattr_boolean(state, e,
@@ -443,9 +507,18 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
backend_shr_dup_strlist_n((char **) &default_keys_format,
1) :
NULL;
- use_value_format = value_format ?
- strdup(value_format) :
- strdup(default_value_format);
+ use_value_formats = value_formats ?
+ backend_shr_dup_strlist_unless_empty(value_formats) :
+ default_value_format ?
+ backend_shr_dup_strlist_n((char **) &default_value_format,
+ 1) :
+ NULL;
+ use_values_formats = values_formats ?
+ backend_shr_dup_strlist_unless_empty(values_formats) :
+ default_values_format ?
+ backend_shr_dup_strlist_n((char **) &default_values_format,
+ 1) :
+ NULL;
use_bases = backend_shr_dup_strlist(bases);
use_disallowed_chars = disallowed_chars ?
strdup(disallowed_chars) :
@@ -454,7 +527,8 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
NULL);
/* Free the values we read from the entry. */
free(disallowed_chars);
- free(value_format);
+ backend_shr_free_strlist(value_formats);
+ backend_shr_free_strlist(values_formats);
backend_shr_free_strlist(key_formats);
backend_shr_free_strlist(keys_formats);
free(entry_filter);
@@ -472,33 +546,82 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
ret.n_key_formats = 0;
ret.keys_formats = use_keys_formats;
ret.n_keys_formats = 0;
- ret.value_format = use_value_format;
+ ret.value_formats = use_value_formats;
+ ret.n_value_formats = 0;
+ ret.values_formats = use_values_formats;
+ ret.n_values_formats = 0;
for (i = 0;
(use_key_formats != NULL) && (use_key_formats[i] != NULL);
i++) {
- slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc->spd_id,
- "initializing map %s in %s (3): "
- "filter \"%s\", "
- "key \"%s\", "
- "value \"%s\"\n",
- map, domain,
- use_entry_filter,
- use_key_formats[i], use_value_format);
+ for (j = 0;
+ (use_value_formats != NULL) &&
+ (use_value_formats[j] != NULL);
+ j++) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "initializing map %s in %s (3): "
+ "filter \"%s\", "
+ "key \"%s\", "
+ "value \"%s\"\n",
+ map, domain,
+ use_entry_filter,
+ use_key_formats[i],
+ use_value_formats[j]);
+ ret.n_value_formats++;
+ }
+ for (j = 0;
+ (use_values_formats != NULL) &&
+ (use_values_formats[j] != NULL);
+ j++) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "initializing map %s in %s (3): "
+ "filter \"%s\", "
+ "key \"%s\", "
+ "value \"%s\"\n",
+ map, domain,
+ use_entry_filter,
+ use_key_formats[i],
+ use_values_formats[j]);
+ ret.n_values_formats++;
+ }
ret.n_key_formats++;
}
for (i = 0;
(use_keys_formats != NULL) && (use_keys_formats[i] != NULL);
i++) {
- slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc->spd_id,
- "initializing map %s in %s (3): "
- "filter \"%s\", "
- "keys \"%s\", "
- "value \"%s\"\n",
- map, domain,
- use_entry_filter,
- use_keys_formats[i], use_value_format);
+ for (j = 0;
+ (use_value_formats != NULL) &&
+ (use_value_formats[j] != NULL);
+ j++) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "initializing map %s in %s (3): "
+ "filter \"%s\", "
+ "keys \"%s\", "
+ "value \"%s\"\n",
+ map, domain,
+ use_entry_filter,
+ use_keys_formats[i],
+ use_value_formats[j]);
+ ret.n_value_formats++;
+ }
+ for (j = 0;
+ (use_values_formats != NULL) &&
+ (use_values_formats[j] != NULL);
+ j++) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "initializing map %s in %s (3): "
+ "filter \"%s\", "
+ "keys \"%s\", "
+ "value \"%s\"\n",
+ map, domain,
+ use_entry_filter,
+ use_keys_formats[i],
+ use_values_formats[j]);
+ ret.n_values_formats++;
+ }
ret.n_keys_formats++;
}
*pret = backend_copy_set_data(&ret);
@@ -509,7 +632,8 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
free(ret.common.entry_filter);
backend_shr_free_strlist(ret.key_formats);
backend_shr_free_strlist(ret.keys_formats);
- free(ret.value_format);
+ backend_shr_free_strlist(ret.value_formats);
+ backend_shr_free_strlist(ret.values_formats);
}
/* Process a map configuration directory entry. Pull out the domain and map
@@ -708,7 +832,7 @@ backend_get_set_config(struct plugin_state *state,
backend_get_set_config_entry_cb,
NULL);
defaults_get_map_config(map, &map_secure, &default_filter,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
if (cbdata.entry_filter == NULL) {
cbdata.entry_filter = strdup(default_filter);
}