diff options
| author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-07-30 17:37:35 -0400 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-07-30 17:37:35 -0400 |
| commit | 0566e2e2fbbeb82d383bf3e39c5a7014df315de0 (patch) | |
| tree | b31531b766755d90e7ab90c2a11092700378c883 /src | |
| parent | 76cfc37278eacc81a8d5656e381a7f265407a710 (diff) | |
| download | slapi-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.c | 484 |
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); } |
