ldap/servers
by Nathan Kinder
ldap/servers/plugins/dna/dna.c | 467 ++++++++++++++++++++++++++++++-----------
1 file changed, 352 insertions(+), 115 deletions(-)
New commits:
commit a0b60b0b87c034f7f888b3ec0a86c4bca74f471d
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Wed Apr 28 17:12:29 2010 -0700
Bug 584497 - Allow DNA plugin to set same value on multiple attributes
This patch allows one to set multiple dnaType attributes for a single
DNA range. This allows the same value to be used for each dnaType
(such as ensuring the uidNumber and gidNumber are the same value
from the range when ading a posixAccount).
There are some differences with the way DNA works for multi-type
ranges. For a value to be generated from a multi-type range, the
magic value must be specified to indicate which attributes should
use the newly generated value. This allows a range to be shared
across different entry types (such as having a uidNumber/gidNumber
range that is used or posixAccount and posixGroup entries). A
multi-type range will not generate a value for missing attributes
as DNA does for single-type ranges.
Since a range can have multiple types, the internal ordering of
config structs had to be changed to order by scope only. It was
previously ordered by type and then scope, which allowed us to
easily detect if we had already generated a value for a given type.
This change required a number of helper functions to be added for
tracking and checking which types we have already generated values
for.
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
index 94c4ab3..dfa86c4 100644
--- a/ldap/servers/plugins/dna/dna.c
+++ b/ldap/servers/plugins/dna/dna.c
@@ -139,7 +139,7 @@ static Slapi_PluginDesc exop_pdesc = { DNA_EXOP_FEATURE_DESC,
struct configEntry {
PRCList list;
char *dn;
- char *type;
+ char **types;
char *prefix;
char *filter;
Slapi_Filter *slapi_filter;
@@ -252,6 +252,11 @@ static int dna_is_replica_bind_dn(char *range_dn, char *bind_dn);
static int dna_get_replica_bind_creds(char *range_dn, struct dnaServer *server,
char **bind_dn, char **bind_passwd,
char **bind_method, int *is_ssl, int *port);
+static int dna_list_contains_type(char **list, char *type);
+static int dna_list_contains_types(char **list, char **types);
+static void dna_list_remove_type(char **list, char *type);
+static int dna_is_multitype_range(struct configEntry *config_entry);
+static void dna_create_valcheck_filter(struct configEntry *config_entry, PRUint64 value, char **filter);
/**
*
@@ -667,6 +672,7 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
struct configEntry *config_entry;
PRCList *list;
int entry_added = 0;
+ int i = 0;
int ret = DNA_SUCCESS;
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
@@ -694,10 +700,8 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM,
"----------> dn [%s]\n", entry->dn);
- value = slapi_entry_attr_get_charptr(e, DNA_TYPE);
- if (value) {
- entry->type = value;
- } else {
+ entry->types = slapi_entry_attr_get_charray(e, DNA_TYPE);
+ if (entry->types == NULL) {
slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
"dna_parse_config_entry: The %s config "
"setting is required for range %s.\n",
@@ -706,8 +710,10 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
goto bail;
}
- slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM,
- "----------> %s [%s]\n", DNA_TYPE, entry->type);
+ for (i = 0; entry->types && entry->types[i]; i++) {
+ slapi_log_error(SLAPI_LOG_CONFIG, DNA_PLUGIN_SUBSYSTEM,
+ "----------> %s [%s]\n", DNA_TYPE, entry->types[i]);
+ }
value = slapi_entry_attr_get_charptr(e, DNA_NEXTVAL);
if (value) {
@@ -976,25 +982,17 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
}
/**
- * Finally add the entry to the list
- * we group by type then by filter
- * and finally sort by dn length with longer dn's
- * first - this allows the scope checking
- * code to be simple and quick and
- * cunningly linear
+ * Finally add the entry to the list.
+ * We sort by scope dn length with longer
+ * dn's first - this allows the scope
+ * checking code to be simple and quick and
+ * cunningly linear.
*/
if (!PR_CLIST_IS_EMPTY(dna_global_config)) {
list = PR_LIST_HEAD(dna_global_config);
while (list != dna_global_config) {
config_entry = (struct configEntry *) list;
- if (slapi_attr_type_cmp(config_entry->type, entry->type, 1))
- goto next;
-
- if (slapi_filter_compare(config_entry->slapi_filter,
- entry->slapi_filter))
- goto next;
-
if (slapi_dn_issuffix(entry->scope, config_entry->scope)) {
PR_INSERT_BEFORE(&(entry->list), list);
slapi_log_error(SLAPI_LOG_CONFIG,
@@ -1058,8 +1056,8 @@ dna_free_config_entry(struct configEntry ** entry)
slapi_ch_free_string(&e->dn);
}
- if (e->type)
- slapi_ch_free_string(&e->type);
+ if (e->types)
+ slapi_ch_array_free(e->types);
if (e->prefix)
slapi_ch_free_string(&e->prefix);
@@ -1770,10 +1768,9 @@ dna_first_free_value(struct configEntry *config_entry,
Slapi_Entry **entries = NULL;
Slapi_PBlock *pb = NULL;
LDAPControl **ctrls = NULL;
- char *attrs[2];
- char *filter;
+ char *filter = NULL;
char *prefix;
- char *type;
+ int multitype;
int result, status, filterlen;
PRUint64 tmpval, sval, i;
char *strval = NULL;
@@ -1785,31 +1782,26 @@ dna_first_free_value(struct configEntry *config_entry,
}
prefix = config_entry->prefix;
- type = config_entry->type;
tmpval = config_entry->nextval;
- attrs[0] = type;
- attrs[1] = NULL;
-
- /* We don't sort if we're using a prefix (non integer type). Instead,
- * we just search to see if the next value is free, and keep incrementing
- * until we find the next free value. */
- if (prefix) {
- /* The 7 below is for all of the filter characters "(&(=))"
- * plus the trailing \0. The 20 is for the maximum string
- * representation of a " NSPRIu64 ". */
- filterlen = strlen(config_entry->filter) +
- strlen(prefix) + strlen(type)
- + 7 + 20;
- filter = slapi_ch_malloc(filterlen);
- snprintf(filter, filterlen, "(&%s(%s=%s%" PRIu64 "))",
- config_entry->filter, type, prefix, tmpval);
+ if (dna_is_multitype_range(config_entry)) {
+ multitype = 1;
+ }
+
+ /* We don't sort if we're using a prefix (non integer type) or if this
+ * is a multi-type range. Instead, we just search to see if the next
+ * value is free, and keep incrementing until we find the next free value. */
+ if (prefix || multitype) {
+ /* This will allocate the filter string for us. */
+ dna_create_valcheck_filter(config_entry, tmpval, &filter);
} else {
+ /* This is a single-type range, so just use the first (only)
+ * type from the list. */
ctrls = (LDAPControl **)slapi_ch_calloc(2, sizeof(LDAPControl));
if (NULL == ctrls)
return LDAP_OPERATIONS_ERROR;
- ctrls[0] = dna_build_sort_control(config_entry->type);
+ ctrls[0] = dna_build_sort_control(config_entry->types[0]);
if (NULL == ctrls[0]) {
slapi_ch_free((void **)&ctrls);
return LDAP_OPERATIONS_ERROR;
@@ -1817,8 +1809,8 @@ dna_first_free_value(struct configEntry *config_entry,
filter = slapi_ch_smprintf("(&%s(&(%s>=%" NSPRIu64 ")(%s<=%" NSPRIu64 ")))",
config_entry->filter,
- type, tmpval,
- type, config_entry->maxval);
+ config_entry->types[0], tmpval,
+ config_entry->types[0], config_entry->maxval);
}
if (NULL == filter) {
@@ -1837,7 +1829,7 @@ dna_first_free_value(struct configEntry *config_entry,
slapi_search_internal_set_pb(pb, config_entry->scope,
LDAP_SCOPE_SUBTREE, filter,
- attrs, 0, ctrls,
+ config_entry->types, 0, ctrls,
NULL, getPluginID(), 0);
slapi_search_internal_pb(pb);
@@ -1857,17 +1849,17 @@ dna_first_free_value(struct configEntry *config_entry,
goto cleanup;
}
- if (prefix) {
+ if (prefix || multitype) {
/* The next value identified in the config entry has already
* been taken. We just iterate through the values until we
* (hopefully) find a free one. */
for (tmpval += config_entry->interval; tmpval <= config_entry->maxval;
tmpval += config_entry->interval) {
- /* filter is guaranteed to be big enough since we allocated
- * enough space to fit a string representation of any unsigned
- * 64-bit integer */
- snprintf(filter, filterlen, "(&%s(%s=%s%" PRIu64 "))",
- config_entry->filter, type, prefix, tmpval);
+ /* This will reuse the old memory for the previous filter. It is
+ * guaranteed to have enough space since the filter is the same
+ * aside from the assertion value (we allocated enough for the
+ * largest supported integer). */
+ dna_create_valcheck_filter(config_entry, tmpval, &filter);
/* clear out the pblock so we can re-use it */
slapi_free_search_results_internal(pb);
@@ -1875,7 +1867,7 @@ dna_first_free_value(struct configEntry *config_entry,
slapi_search_internal_set_pb(pb, config_entry->scope,
LDAP_SCOPE_SUBTREE, filter,
- attrs, 0, 0,
+ config_entry->types, 0, 0,
NULL, getPluginID(), 0);
slapi_search_internal_pb(pb);
@@ -1897,13 +1889,15 @@ dna_first_free_value(struct configEntry *config_entry,
}
}
} else {
- /* entries are sorted and filtered for value >= tval therefore if the
+ /* Entries are sorted and filtered for value >= tval therefore if the
* first one does not match tval it means that the value is free,
* otherwise we need to cycle through values until we find a mismatch,
- * the first mismatch is the first free pit */
+ * the first mismatch is the first free pit. This is guaranteed to
+ * be a single-type range, so we can just use the first (only)
+ * type from the list of types directly. */
sval = 0;
for (i = 0; NULL != entries[i]; i++) {
- strval = slapi_entry_attr_get_charptr(entries[i], type);
+ strval = slapi_entry_attr_get_charptr(entries[i], config_entry->types[0]);
errno = 0;
sval = strtoull(strval, 0, 0);
if (errno) {
@@ -2524,10 +2518,203 @@ bail:
return ret;
}
+/*
+ * dna_list_contains_type()
+ *
+ * Checks if a type is contained in a list of types.
+ * Returns 1 if the type is found, 0 otherwise.
+ */
+static int
+dna_list_contains_type(char **list, char *type)
+{
+ int ret = 0;
+ int i = 0;
+
+ if (list && type) {
+ for (i = 0; list[i]; i++) {
+ if (slapi_attr_types_equivalent(type, list[i])) {
+ ret = 1;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * dna_list_contains_types()
+ *
+ * Checks if all types in one list (types) are contained
+ * in another list of types (list). Returns 1 if all
+ * types are found, 0 otherwise.
+ */
+static int
+dna_list_contains_types(char **list, char **types)
+{
+ int ret = 1;
+ int i = 0;
+ int j = 0;
+
+ if (list && types) {
+ for (i = 0; types[i]; i++) {
+ int found = 0;
+
+ for (j = 0; list[j]; j++) {
+ if (slapi_attr_types_equivalent(types[i], list[i])) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ ret = 0;
+ break;
+ }
+ }
+ } else {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/*
+ * dna_list_remove_type()
+ *
+ * Removes a type from a list of types.
+ */
+static void
+dna_list_remove_type(char **list, char *type)
+{
+ int i = 0;
+ int found_type = 0;
+
+ if (list && type) {
+ /* Go through the list until we find the type that
+ * we want to remove. We simply free the type we
+ * want to remove and shift the remaining array
+ * elements down by one index. This will leave us
+ * with two NULL elements at the end of the list,
+ * but this should not cause any problems. */
+ for (i = 0; list[i]; i++) {
+ if (found_type) {
+ list[i] = list[i + 1];
+ } else if (slapi_attr_types_equivalent(type, list[i])) {
+ slapi_ch_free_string(&list[i]);
+ list[i] = list[i + 1];
+ found_type = 1;
+ }
+ }
+ }
+}
+
+/*
+ * dna_is_multitype_range()
+ *
+ * Returns 1 if the range has multiple types configured.
+ * Returns 0 otherwise.
+ */
+static int dna_is_multitype_range(struct configEntry *config_entry)
+{
+ int ret = 0;
+
+ if (config_entry && config_entry->types && config_entry->types[1]) {
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/*
+ * dna_create_valcheck_filter()
+ *
+ * Creates a filter string used to check if a value is free. If
+ * filter already holds a valid pointer, it is assumed to have enough
+ * space to hold the filter. This allows the same memory to be used
+ * over and over when you only want to change the assertion value.
+ * If filter contains a NULL pointer, a new string of the appropriate
+ * size will be allocated. The caller must free this when finished.
+ */
+static void
+dna_create_valcheck_filter(struct configEntry *config_entry, PRUint64 value, char **filter)
+{
+ int filterlen = 0;
+ int typeslen = 0;
+ int i = 0;
+ int bytes_out = 0;
+ int multitype = 0;
+
+ /* Just return if we didn't get an address for the filter. */
+ if (filter == NULL) {
+ return;
+ }
+
+ /* To determine the filter length, we add together the following:
+ *
+ * - the string length of the filter in the config
+ * - the string length sum of all configured types
+ * - 23 bytes for each type (20 for the max string
+ * representation of a NSPRIu64, 3 for "(=)"
+ * - 3 bytes for the beginning and end of the filter - "(&" and ")"
+ * - 3 bytes to OR together multiple types (if present) - "(|" and ")"
+ * - the string length of the prefix (if one is configured) for each type
+ * - 1 byte for the trailing \0
+ *
+ * The filter length should be the same every time if the config struct
+ * has not been changed. We need to calculate the filter length even
+ * if we are reusing memory since we have no other way of knowing the
+ * length used when it was originally allocated. We trust the caller
+ * to only reuse the pointer with the same config struct.
+ */
+ for (i = 0; config_entry->types && config_entry->types[i]; i++) {
+ typeslen += strlen(config_entry->types[i]);
+ }
+
+ if (i > 1) {
+ multitype = 1;
+ }
+
+ filterlen = strlen(config_entry->filter) + typeslen +
+ (i * 23) + 3 + 1 +
+ (config_entry->prefix ? (i * strlen(config_entry->prefix)) : 0) +
+ (multitype ? 3 : 0);
+
+ /* Allocate space for the filter if it hasn't been allocated yet. */
+ if (*filter == NULL) {
+ *filter = slapi_ch_malloc(filterlen);
+ }
+
+ /* Write out the beginning of the filter. If multiple types
+ * are configured, we need to OR together the search clauses
+ * for the types. */
+ if (multitype) {
+ bytes_out = snprintf(*filter, filterlen, "(&%s(|", config_entry->filter);
+ } else {
+ bytes_out = snprintf(*filter, filterlen, "(&%s", config_entry->filter);
+ }
+
+ /* Loop through the types and append each filter clause. */
+ for (i = 0; config_entry->types && config_entry->types[i]; i++) {
+ bytes_out += snprintf(*filter + bytes_out, filterlen - bytes_out,
+ "(%s=%s%" PRIu64 ")", config_entry->types[i],
+ config_entry->prefix ? config_entry->prefix : "",
+ value);
+ }
+
+ /* Append the end of the filter. We need an extra paren
+ * to close out the OR if we have multiple types. */
+ if (multitype) {
+ strncat(*filter, "))", filterlen - bytes_out);
+ } else {
+ strncat(*filter, ")", filterlen - bytes_out);
+ }
+}
+
/* for mods and adds:
where dn's are supplied, the closest in scope
- is used as long as the type and filter
- are identical - otherwise all matches count
+ is used as long as the type filter matches
+ and the type has not been generated yet.
*/
static int dna_pre_op(Slapi_PBlock * pb, int modtype)
@@ -2537,14 +2724,15 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
struct configEntry *config_entry = 0;
struct slapi_entry *e = 0;
Slapi_Entry *resulting_e = 0;
- char *last_type = 0;
char *value = 0;
- int generate = 0;
+ char **types_to_generate = NULL;
+ char **generated_types = NULL;
Slapi_Mods *smods = 0;
Slapi_Mod *smod = 0;
LDAPMod **mods;
int free_entry = 0;
char *errstr = NULL;
+ int i = 0;
int ret = 0;
slapi_log_error(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
@@ -2637,9 +2825,8 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
while (list != dna_global_config && LDAP_SUCCESS == ret) {
config_entry = (struct configEntry *) list;
- /* did we already service this type? */
- if (last_type) {
- if (!slapi_attr_type_cmp(config_entry->type, last_type, 1))
+ /* Did we already service all of these configured types? */
+ if (dna_list_contains_types(generated_types, config_entry->types)) {
goto next;
}
@@ -2670,18 +2857,33 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
if (LDAP_CHANGETYPE_ADD == modtype) {
- /* does attribute contain the magic value
- or is the type not there?
- */
- value =
- slapi_entry_attr_get_charptr(e, config_entry->type);
- if ((value
- && !slapi_UTF8CASECMP(config_entry->generate, value))
- || 0 == value) {
- generate = 1;
- }
+ if (config_entry->types && dna_is_multitype_range(config_entry)) {
+ /* For a multi-type range, we only generate a value
+ * for types where the magic value is set. We do not
+ * generate a value for missing types. */
+ for (i = 0; config_entry->types && config_entry->types[i]; i++) {
+ value = slapi_entry_attr_get_charptr(e, config_entry->types[i]);
+
+ if (value && !slapi_UTF8CASECMP(config_entry->generate, value)) {
+ slapi_ch_array_add(&types_to_generate,
+ slapi_ch_strdup(config_entry->types[i]));
+ }
- slapi_ch_free_string(&value);
+ slapi_ch_free_string(&value);
+ }
+ } else {
+ /* For a single type range, we generate the value if
+ * the magic value is set or if the type is missing. */
+ value = slapi_entry_attr_get_charptr(e, config_entry->types[0]);
+
+ if ((value && !slapi_UTF8CASECMP(config_entry->generate, value))
+ || 0 == value) {
+ slapi_ch_array_add(&types_to_generate,
+ slapi_ch_strdup(config_entry->types[0]));
+ }
+
+ slapi_ch_free_string(&value);
+ }
} else {
/* check mods for magic value */
Slapi_Mod *next_mod = slapi_mod_new();
@@ -2690,15 +2892,19 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
char *type = (char *)
slapi_mod_get_type(smod);
- if (slapi_attr_types_equivalent(type,
- config_entry->type)) {
+ /* See if the type matches any configured type. */
+ if (dna_list_contains_type(config_entry->types, type)) {
/* If all values are being deleted, we need to
- * generate a new value. */
- if (SLAPI_IS_MOD_DELETE(slapi_mod_get_operation(smod))) {
+ * generate a new value. We don't do this for
+ * multi-type ranges since they require the magic
+ * value to be specified to trigger generation. */
+ if (SLAPI_IS_MOD_DELETE(slapi_mod_get_operation(smod)) &&
+ !dna_is_multitype_range(config_entry)) {
int numvals = slapi_mod_get_num_values(smod);
if (numvals == 0) {
- generate = 1;
+ slapi_ch_array_add(&types_to_generate,
+ slapi_ch_strdup(type));
} else {
Slapi_Attr *attr = NULL;
int e_numvals = 0;
@@ -2707,7 +2913,8 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
if (attr) {
slapi_attr_get_numvalues(attr, &e_numvals);
if (numvals >= e_numvals) {
- generate = 1;
+ slapi_ch_array_add(&types_to_generate,
+ slapi_ch_strdup(type));
}
}
}
@@ -2715,14 +2922,17 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
/* This is either adding or replacing a value */
struct berval *bv = slapi_mod_get_first_value(smod);
- /* If generate is already set, a previous mod in
- * this same modify operation either removed all
- * values or set the magic value. It's possible
- * that this mod is adding a valid value, which
- * means we would not want to generate a new value.
- * It is safe to unset generate since it will be
- * reset here if necessary. */
- generate = 0;
+ /* If this type is already in the to be generated
+ * list, a previous mod in this same modify operation
+ * either removed all values or set the magic value.
+ * It's possible that this mod is adding a valid value,
+ * which means we would not want to generate a new value.
+ * It is safe to remove this type from the to be
+ * generated list since it will be re-added here if
+ * necessary. */
+ if (dna_list_contains_type(types_to_generate, type)) {
+ dna_list_remove_type(types_to_generate, type);
+ }
/* If we have a value, see if it's the magic value. */
if (bv) {
@@ -2731,13 +2941,16 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
if (!slapi_UTF8NCASECMP(bv->bv_val,
config_entry->generate,
len)) {
- generate = 1;
+ slapi_ch_array_add(&types_to_generate,
+ slapi_ch_strdup(type));
}
}
- } else {
+ } else if (!dna_is_multitype_range(config_entry)) {
/* This is a replace with no new values, so we need
- * to generate a new value. */
- generate = 1;
+ * to generate a new value if this is not a multi-type
+ * range. */
+ slapi_ch_array_add(&types_to_generate,
+ slapi_ch_strdup(type));
}
}
}
@@ -2754,25 +2967,27 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
* to see if a value exists for the managed type in the resulting
* entry. This will catch a modify operation that brings an entry
* into scope for a managed range, but doesn't supply a value for
- * the managed type.
- */
- if ((LDAP_CHANGETYPE_MODIFY == modtype) && !generate) {
+ * the managed type. We don't do this for multi-type ranges. */
+ if ((LDAP_CHANGETYPE_MODIFY == modtype) && (!types_to_generate ||
+ (types_to_generate && !types_to_generate[0])) &&
+ !dna_is_multitype_range(config_entry)) {
Slapi_Attr *attr = NULL;
- if (slapi_entry_attr_find(resulting_e, config_entry->type, &attr) != 0) {
- generate = 1;
+ if (slapi_entry_attr_find(resulting_e, config_entry->types[0], &attr) != 0) {
+ slapi_ch_array_add(&types_to_generate,
+ slapi_ch_strdup(config_entry->types[0]));
}
}
- if (generate) {
+ if (types_to_generate && types_to_generate[0]) {
char *new_value;
int len;
/* create the value to add */
ret = dna_get_next_value(config_entry, &value);
if (DNA_SUCCESS != ret) {
- errstr = slapi_ch_smprintf("Allocation of a new value for"
+ errstr = slapi_ch_smprintf("Allocation of a new value for range"
" %s failed! Unable to proceed.",
- config_entry->type);
+ config_entry->dn);
break;
}
@@ -2792,28 +3007,45 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
/* do the mod */
if (LDAP_CHANGETYPE_ADD == modtype) {
/* add - add to entry */
- slapi_entry_attr_set_charptr(e,
- config_entry->type,
- new_value);
+ for (i = 0; types_to_generate && types_to_generate[i]; i++) {
+ slapi_entry_attr_set_charptr(e,
+ types_to_generate[i],
+ new_value);
+ }
} else {
/* mod - add to mods */
- slapi_mods_add_string(smods,
- LDAP_MOD_REPLACE,
- config_entry->type, new_value);
+ for (i = 0; types_to_generate && types_to_generate[i]; i++) {
+ slapi_mods_add_string(smods,
+ LDAP_MOD_REPLACE,
+ types_to_generate[i], new_value);
+ }
}
- /* free up */
- slapi_ch_free_string(&value);
- slapi_ch_free_string(&new_value);
-
- /* make sure we don't generate for this
- * type again
+ /* Make sure we don't generate for this
+ * type again by keeping a list of types
+ * we have generated for already.
*/
if (LDAP_SUCCESS == ret) {
- last_type = config_entry->type;
+ if (generated_types == NULL) {
+ /* If we don't have a list of generated types yet,
+ * we can just use the types_to_generate list so
+ * we don't have to allocate anything. */
+ generated_types = types_to_generate;
+ types_to_generate = NULL;
+ } else {
+ /* Just reuse the elements out of types_to_generate for the
+ * generated types list to avoid allocating them again. */
+ for (i = 0; types_to_generate && types_to_generate[i]; ++i) {
+ slapi_ch_array_add(&generated_types, types_to_generate[i]);
+ types_to_generate[i] = NULL;
+ }
+ }
}
- generate = 0;
+ /* free up */
+ slapi_ch_free_string(&value);
+ slapi_ch_free_string(&new_value);
+ slapi_ch_array_free(types_to_generate);
}
next:
list = PR_NEXT_LINK(list);
@@ -2831,6 +3063,7 @@ static int dna_pre_op(Slapi_PBlock * pb, int modtype)
}
bail:
+ slapi_ch_array_free(generated_types);
if (free_entry && e)
slapi_entry_free(e);
@@ -3229,7 +3462,11 @@ void dna_dump_config()
void dna_dump_config_entry(struct configEntry * entry)
{
- printf("<---- type -----------> %s\n", entry->type);
+ int i = 0;
+
+ for (i = 0; entry->types && entry->types[i]; i++) {
+ printf("<---- type -----------> %s\n", entry->types[i]);
+ }
printf("<---- filter ---------> %s\n", entry->filter);
printf("<---- prefix ---------> %s\n", entry->prefix);
printf("<---- scope ----------> %s\n", entry->scope);
13 years, 1 month
Changes to 'refs/tags/389-ds-console-1.2.2'
by Richard Allen Megginson
Changes since the dawn of time:
Endi S. Dewata (3):
Bug 496863 - 'Construct' button creates incorrect referral urls
Resolves: bug 574098
Bug 563513 - New replication -> No changelong configured-msg
Nathan Kinder (19):
171941 - Adjusted the version number and branding. I had to modify the checkVersion method to deal with running in Console 1.0. I also cleaned up references to consolesdk in the Ant build files. They should be console instead since we dropped the consolesdk naming. The external and internal imports files were adjusted to pick up the new 1.0 Console component.
171941 - checkVersion was comparing versions with greater than when it should have been using greater than or equal to
177696 - Changed usage of enum keyword as a variable name for Java 1.5 compatibility
Bug(s) fixed: 181570
Resolves: 246513
Summary: Initial fedora-ds-console specfile.
Resolves: ?
Resolves: 250137
Resolves: 250145
Resolves: 204510
Resolves: 250636
Resolves: 252036
Add default ldapjdk path as well as a settable parameter
Fixed typo from last checkin
Use less restrictive version of Open Publication License for online help docs.
Resolves: 308221
Resolves: 333171
Resolves: 178247
Resolves: 379191
Noriko Hosoi (13):
Changed the ldapconsole package name to <brand>-ds-<version>.jar
Modified ant move syntax to support ant 1.6.2
[186105] Admin Server Makefile updates for Internal build
Resolves: #247215
Resolves: #248073
Resolves: #379191
Resolves: #386041
Resolves: #379191
Resolves: #379191
Resolves: #379191
Resolves: #379191
Resolves: #379191
Resolves: 178947
Rich Megginson (32):
Bug(s) fixed: 167761
allow the definition of the console location on the command line with different directory layouts than the default
Bug(s) fixed: 178478
The console now builds jar files in the format
bump version to 1.0.3
updated spec for Fedora DS 1.1 release
Resolves: bug 428357
Bump version to 1.1.2
this is for the 1.1.2 release
Resolves: bug 469261
Resolves: bug 469261
Resolves: bug 234948
Resolves: bug 452596
Resolves: bug 178947
Resolves: bug 177334
Resolves: bug 249120
Resolves: bug 238762
Resolves: bug 179193
Resolves: bug 179184
change version to 1.1.3
Resolves: bug 487831
Resolves: bug 481213
Resolves: bug 483660
Resolves: bug 483660
updated for 1.1.3
version must correspond to ds base version - 1.2.0
rename to 389
change mode of spec file to 644
added separate doc subpackage
update to version 1.2.1
Bug 586571 - DS Console shows escaped DNs
bump version to 1.2.2
foxworth (2):
Import initial source drop of Fedora DirectoryConsole
Import initial source drop of Fedora DirectoryConsole
13 years, 1 month
build.properties
by Richard Allen Megginson
build.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 2044ad9005c803116b972784c3b2eef5ed87a851
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Thu Apr 29 20:13:13 2010 -0600
bump version to 1.2.2
diff --git a/build.properties b/build.properties
index f0a2aa0..5961274 100755
--- a/build.properties
+++ b/build.properties
@@ -21,7 +21,7 @@
lang=en
ldapconsole.root=..
-ldapconsole.version=1.2.1
+ldapconsole.version=1.2.2
ldapconsole.gen.version=1.2
brand=389
ldapconsole.name=${brand}-ds-${ldapconsole.version}
13 years, 1 month
.gitignore src/com
by Richard Allen Megginson
.gitignore | 4
src/com/netscape/admin/dirserv/DSUtil.java | 171 ++++++++
src/com/netscape/admin/dirserv/browser/BasicNode.java | 5
src/com/netscape/admin/dirserv/node/DataRootResourceObject.java | 5
src/com/netscape/admin/dirserv/node/MappingNodeObject.java | 37 -
src/com/netscape/admin/dirserv/node/MappingTreeRootResourceObject.java | 5
src/com/netscape/admin/dirserv/node/SuffixResourceObject.java | 133 ++----
src/com/netscape/admin/dirserv/panel/BackendPanel.java | 18
src/com/netscape/admin/dirserv/panel/MappingNodeSettingPanel.java | 3
src/com/netscape/admin/dirserv/panel/MappingUtils.java | 207 +++++-----
src/com/netscape/admin/dirserv/panel/NewChainingInstancePanel.java | 8
src/com/netscape/admin/dirserv/panel/NewChainingPanel.java | 10
src/com/netscape/admin/dirserv/panel/NewLDBMPanel.java | 9
src/com/netscape/admin/dirserv/panel/NewMappingNodePanel.java | 9
src/com/netscape/admin/dirserv/panel/NewSuffixPanel.java | 3
src/com/netscape/admin/dirserv/panel/confirmDeleteSuffixPanel.java | 3
src/com/netscape/admin/dirserv/propedit/DSEntryPanel.java | 25 -
src/com/netscape/admin/dirserv/propedit/RenameDialog.java | 36 -
18 files changed, 380 insertions(+), 311 deletions(-)
New commits:
commit 1ce76be162d0ccd812511815e6176dfcd626ecea
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Thu Apr 29 16:10:43 2010 -0600
Bug 586571 - DS Console shows escaped DNs
https://bugzilla.redhat.com/show_bug.cgi?id=586571
Resolves: bug 586571
Bug Description: DS Console shows escaped DNs
Reviewed by: nhosoi (Thanks!)
Branch: HEAD
Fix Description: Changed the console to be aware of LDAPv3 escapes. The
console can now correctly read and display DN values that contain escapes,
and can correctly escape DNs sent to the server. The console will still
display the "raw" DN with the escapes in certain cases - for example, the
status area at the bottom of the window shows the raw DN for the entry
selected in the directory browser; the Advanced... editor will show the
raw DN in DN valued fields.
Platforms tested: RHEL5 x86_64
Flag Day: no
Doc impact: no
diff --git a/.gitignore b/.gitignore
index b25c15b..c9cd011 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,5 @@
*~
+.classpath
+.project
+*.patch
+bin
diff --git a/src/com/netscape/admin/dirserv/DSUtil.java b/src/com/netscape/admin/dirserv/DSUtil.java
index cf71b2c..6f0b3d1 100644
--- a/src/com/netscape/admin/dirserv/DSUtil.java
+++ b/src/com/netscape/admin/dirserv/DSUtil.java
@@ -26,6 +26,7 @@ import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.net.*;
+import java.text.CharacterIterator;
import java.text.SimpleDateFormat;
import java.text.Collator;
import java.text.ParsePosition;
@@ -2021,6 +2022,172 @@ public class DSUtil {
}
/**
+ * Returns the RDN value after unescaping any escaped characters.
+ * Can be a simple escape - a \ followed by any character -
+ * this will just remove the \ and leave the character in the
+ * result unescaped.
+ * Can be a hex escape - a \ followed by two hex digits - the
+ * \ will be removed and the two hex digits converted to a single
+ * char in the string.
+ * Note that this is different than netscape.ldap.LDAPDN#unEscapeRDN(java.lang.String
+ * in that this function will handle hex escapes.
+ * If the rdn value is bogus or otherwise cannot be parsed correctly, the original
+ * rdn value will be returned, with escapes if it had them.
+ * <P>
+ *
+ * @param rdnval the RDN value to unescape
+ * @return the unescaped RDN value or the original RDN value if there were errors
+ * @see netscape.ldap.LDAPDN#escapeRDN(java.lang.String)
+ */
+ public static String unEscapeRDNVal(String rdnval) {
+ StringBuffer copy = new StringBuffer();
+ CharacterIterator it = new StringCharacterIterator(rdnval);
+ for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
+ if (ch == '\\') {
+ ch = it.next();
+ if (ch == CharacterIterator.DONE) {
+ // bogus - escape at end of string
+ return rdnval;
+ }
+ int val1 = Character.digit(ch, 16);
+ if ((val1 >= 0) && (val1 < 16)) {
+ val1 = val1 * 16;
+ ch = it.next();
+ if (ch == CharacterIterator.DONE) {
+ // bogus - escape followed by only 1 hex digit
+ return rdnval;
+ }
+ int val2 = Character.digit(ch, 16);
+ if ((val2 < 0) || (val2 > 15)) {
+ return rdnval;
+ }
+ // must be a two digit hex code if we got here
+ ch = (char)(val1 + val2);
+ }
+ }
+ copy.append(ch);
+ }
+ return copy.toString();
+ }
+
+ /**
+ * Returns the RDN after unescaping any escaped characters.
+ * Can be a simple escape - a \ followed by any character -
+ * this will just remove the \ and leave the character in the
+ * result unescaped.
+ * Can be a hex escape - a \ followed by two hex digits - the
+ * \ will be removed and the two hex digits converted to a single
+ * char in the string.
+ * Note that this is different than netscape.ldap.LDAPDN#unEscapeRDN(java.lang.String
+ * in that this function will handle hex escapes.
+ * If the rdn is bogus or otherwise cannot be parsed correctly, the original
+ * rdn value will be returned, with escapes if it had them.
+ * <P>
+ *
+ * @param rdn the RDN to unescape
+ * @return the unescaped RDN or the original RDN if there were errors
+ * @see netscape.ldap.LDAPDN#escapeRDN(java.lang.String)
+ */
+ public static String unEscapeRDN(String rdn) {
+ RDN name = new RDN(rdn);
+ String[] vals = name.getValues();
+ if ( (vals == null) || (vals.length < 1) ) {
+ return rdn;
+ }
+ String[] types = name.getTypes();
+
+ StringBuffer rdnbuf = new StringBuffer();
+ for (int ii = 0; ii < vals.length; ++ii) {
+ if (rdnbuf.length() > 0) {
+ rdnbuf.append("+");
+ }
+ rdnbuf.append(types[ii] + "=" + unEscapeRDNVal(vals[ii]));
+ }
+
+ return rdnbuf.toString();
+ }
+
+ /**
+ * Returns the DN after unescaping any escaped characters.
+ * Can be a simple escape - a \ followed by any character -
+ * this will just remove the \ and leave the character in the
+ * result unescaped.
+ * Can be a hex escape - a \ followed by two hex digits - the
+ * \ will be removed and the two hex digits converted to a single
+ * char in the string.
+ * If the dn is bogus or otherwise cannot be parsed correctly, the original
+ * dn value will be returned, with escapes if it had them.
+ * <P>
+ *
+ * @param dn the DN to unescape
+ * @return the unescaped DN or the original DN if there were errors
+ */
+ public static String unEscapeDN(String dn) {
+ if ((dn == null) || (dn.equals(""))) {
+ return dn;
+ }
+ String[] rdns = LDAPDN.explodeDN(dn, false);
+ if ((rdns == null) || (rdns.length < 1)) {
+ return dn;
+ }
+ StringBuffer retdn = new StringBuffer();
+ for (int ii = 0; ii < rdns.length; ++ii) {
+ if (retdn.length() > 0) {
+ retdn.append(",");
+ }
+ retdn.append(unEscapeRDN(rdns[ii]));
+ }
+
+ return retdn.toString();
+ }
+
+ public static boolean[] DN_ESCAPE_CHARS = null;
+ static {
+ // get max val of DN.ESCAPED_CHAR
+ char maxval = 0;
+ for (char ii = 0; ii < DN.ESCAPED_CHAR.length; ++ii) {
+ if (maxval < DN.ESCAPED_CHAR[ii]) {
+ maxval = DN.ESCAPED_CHAR[ii];
+ }
+ }
+ // add the '='
+ if (maxval < '=') {
+ maxval = '=';
+ }
+ // create an array large enough to hold spaces
+ // for all values up to maxval
+ DN_ESCAPE_CHARS = new boolean[maxval+1];
+ // set default value to false
+ for (char ii = 0; ii < (int)maxval; ++ii) {
+ DN_ESCAPE_CHARS[ii] = false;
+ }
+ // set escape char vals to true
+ for (char ii = 0; ii < DN.ESCAPED_CHAR.length; ++ii) {
+ DN_ESCAPE_CHARS[DN.ESCAPED_CHAR[ii]] = true;
+ }
+ // add the equals sign
+ DN_ESCAPE_CHARS['='] = true;
+ }
+ /**
+ * Escape the given DN string value for use as an RDN value. Uses
+ * the \XX hex escapes.
+ * @param dnval value to escape for use as an RDN value
+ * @return the escaped string
+ */
+ public static String escapeDNVal(String dnval) {
+ StringBuffer copy = new StringBuffer();
+ CharacterIterator it = new StringCharacterIterator(dnval);
+ for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
+ if ((ch > 0) && (ch < DN_ESCAPE_CHARS.length) && DN_ESCAPE_CHARS[ch]) {
+ copy.append('\\');
+ copy.append(Integer.toHexString((int)ch).toUpperCase());
+ } else {
+ copy.append(ch);
+ }
+ }
+ return copy.toString();
+ }
+ /**
* This function was stolen from dsalib_dn.c. It checks the string
* for LDAPv2 style quoting e.g. o="foo, bar", c=US, a format which
* is now deprecated.
@@ -2050,7 +2217,7 @@ public class DSUtil {
return ret;
}
-
+
static public void checkForLDAPv2Quoting(String dn, JFrame frame,
String label) {
if (DNUsesLDAPv2Quoting(dn)) {
@@ -2878,7 +3045,7 @@ public class DSUtil {
}
return ret;
- }
+ }
// This the subdir where the DS online help is stored
public static final String HELP_DIRECTORY = "slapd";
diff --git a/src/com/netscape/admin/dirserv/browser/BasicNode.java b/src/com/netscape/admin/dirserv/browser/BasicNode.java
index a9d13de..c4910e0 100644
--- a/src/com/netscape/admin/dirserv/browser/BasicNode.java
+++ b/src/com/netscape/admin/dirserv/browser/BasicNode.java
@@ -23,6 +23,9 @@ import java.util.Vector;
import java.awt.Font;
import javax.swing.Icon;
import javax.swing.tree.DefaultMutableTreeNode;
+
+import com.netscape.admin.dirserv.DSUtil;
+
import netscape.ldap.util.DN;
import netscape.ldap.LDAPUrl;
@@ -205,7 +208,7 @@ class BasicNode extends DefaultMutableTreeNode {
else {
DN dnObj = new DN(dn);
if (dnObj.countRDNs() >= 1) {
- result = dnObj.explodeDN(true)[0];
+ result = DSUtil.unEscapeRDNVal(dnObj.explodeDN(true)[0]);
}
else {
result = "";
diff --git a/src/com/netscape/admin/dirserv/node/DataRootResourceObject.java b/src/com/netscape/admin/dirserv/node/DataRootResourceObject.java
index 9bfe29b..6c8006e 100644
--- a/src/com/netscape/admin/dirserv/node/DataRootResourceObject.java
+++ b/src/com/netscape/admin/dirserv/node/DataRootResourceObject.java
@@ -213,9 +213,8 @@ public class DataRootResourceObject extends DSResourceObject
false );
while( res.hasMoreElements() ) {
LDAPEntry entry = (LDAPEntry)res.nextElement();
- String name = entry.getDN();
- Debug.println( "Mapping node: " + name );
- name = MappingUtils.unQuote( LDAPDN.explodeDN(entry.getDN(),true)[0]);
+ String name = MappingUtils.getMappingNodeName(entry);
+ Debug.println( "Mapping node: dn=" + entry.getDN() + " name=" + name );
_isLeaf = false;
/* Add a node for each plugin */
SuffixResourceObject MappNode =
diff --git a/src/com/netscape/admin/dirserv/node/MappingNodeObject.java b/src/com/netscape/admin/dirserv/node/MappingNodeObject.java
index 3b0e703..87a6767 100644
--- a/src/com/netscape/admin/dirserv/node/MappingNodeObject.java
+++ b/src/com/netscape/admin/dirserv/node/MappingNodeObject.java
@@ -114,23 +114,18 @@ public class MappingNodeObject extends DSResourceObject
_model.fireChangeFeedbackCursor(null, FeedbackIndicator.FEEDBACK_WAIT );
LDAPConnection ldc = _model.getServerInfo().getLDAPConnection();
String psRDN = LDAPDN.explodeDN( _entry.getDN(), true)[0];
+ String filt = MappingUtils.getParentSearchFilter(psRDN);
LDAPSearchResults res =
ldc.search( "cn=mapping tree, cn=config",
ldc.SCOPE_ONE,
- // "((objectclass=nsMappingTree)" +
- "(nsslapd-parent-suffix=" +
- MappingUtils.Quote( psRDN ) +
- // ")"+
- ")",
+ filt,
null,
false );
- Debug.println( " *** ((objectclass=nsMappingTree)(nsslapd-parent-suffix=" +
- MappingUtils.Quote(psRDN) +")): res.getCount()=" + res.getCount());
+ Debug.println( " *** " + filt + ": res.getCount()=" + res.getCount());
while( res.hasMoreElements() ) {
LDAPEntry bentry = (LDAPEntry)res.nextElement();
- String name = bentry.getDN();
- Debug.println( "*** Mapping node: " + name );
- name = MappingUtils.unQuote(LDAPDN.explodeDN( bentry.getDN(), true)[0]);
+ String name = MappingUtils.getMappingNodeName(bentry);
+ Debug.println( "*** Mapping node: dn=" + bentry.getDN() + " name=" + name );
_isLeaf = false ;
/* Add a node for each Instance */
MappingNodeObject MapNode =
@@ -221,7 +216,7 @@ public class MappingNodeObject extends DSResourceObject
public boolean isLeaf() {
// return _isLeaf;
- return (isLeafMappingNode());
+ return MappingUtils.isLeafMappingNode(_model.getServerInfo().getLDAPConnection(), _entry);
}
/**
@@ -302,26 +297,6 @@ public class MappingNodeObject extends DSResourceObject
SECTION);
}
}
-
-
- private boolean isLeafMappingNode( ) {
- DN pDN = new DN( _entry.getDN() );
- String psRDN = LDAPDN.explodeDN( _entry.getDN(), true )[0];
- String filter = "nsslapd-parent-suffix=" + MappingUtils.Quote( psRDN );
- LDAPConnection ldc = _model.getServerInfo().getLDAPConnection();
- try {
- LDAPSearchResults res = ldc.search( CONFIG_MAPPING, ldc.SCOPE_ONE,
- filter, null, false);
- if (res == null || !res.hasMoreElements()) {
- return( true );
- } else {
- return( false );
- }
- } catch (LDAPException e) {
- Debug.println( "MappingNodeObject.isLeafMappingNode() :" + e );
- return( false );
- }
- }
private LDAPEntry _entry = null;
private boolean _isLeaf = false;
diff --git a/src/com/netscape/admin/dirserv/node/MappingTreeRootResourceObject.java b/src/com/netscape/admin/dirserv/node/MappingTreeRootResourceObject.java
index d6ac5d2..2943b26 100644
--- a/src/com/netscape/admin/dirserv/node/MappingTreeRootResourceObject.java
+++ b/src/com/netscape/admin/dirserv/node/MappingTreeRootResourceObject.java
@@ -103,9 +103,8 @@ public class MappingTreeRootResourceObject extends DSResourceObject
false );
while( res.hasMoreElements() ) {
LDAPEntry entry = (LDAPEntry)res.nextElement();
- String name = entry.getDN();
- Debug.println( "Mapping node: " + name );
- name = MappingUtils.unQuote( LDAPDN.explodeDN(entry.getDN(),true)[0]);
+ String name = MappingUtils.getMappingNodeName(entry);
+ Debug.println( "Mapping node: dn=" + entry.getDN() + " name=" + name );
_isLeaf = false;
/* Add a node for each plugin */
MappingNodeObject MappNode =
diff --git a/src/com/netscape/admin/dirserv/node/SuffixResourceObject.java b/src/com/netscape/admin/dirserv/node/SuffixResourceObject.java
index 65848ce..251da84 100644
--- a/src/com/netscape/admin/dirserv/node/SuffixResourceObject.java
+++ b/src/com/netscape/admin/dirserv/node/SuffixResourceObject.java
@@ -131,22 +131,19 @@ public class SuffixResourceObject extends DSResourceObject
private void addSuffix(){
- String psRDN = LDAPDN.explodeDN( _entry.getDN(), true)[0];
+ String suffix = MappingUtils.getMappingNodeSuffix(_entry);
+ String filter = MappingUtils.getParentSearchFilter(suffix);
try {
_model.fireChangeFeedbackCursor(null, FeedbackIndicator.FEEDBACK_WAIT );
LDAPConnection ldc = _model.getServerInfo().getLDAPConnection();
LDAPSearchResults res =
ldc.search( "cn=mapping tree, cn=config",
- ldc.SCOPE_ONE,
- "(nsslapd-parent-suffix=" +
- MappingUtils.Quote( psRDN ) +
- ")",
+ ldc.SCOPE_ONE, filter,
null,
false );
while( res.hasMoreElements() ) {
LDAPEntry bentry = (LDAPEntry)res.nextElement();
- String name = bentry.getDN();
- name = MappingUtils.unQuote(LDAPDN.explodeDN( bentry.getDN(), true)[0]);
+ String name = MappingUtils.getMappingNodeName(bentry);
_isLeaf = false ;
/* Add a node for each Instance */
SuffixResourceObject MapNode =
@@ -155,13 +152,13 @@ public class SuffixResourceObject extends DSResourceObject
}
} catch ( LDAPException e ) {
if( e.getLDAPResultCode() != e.NO_SUCH_OBJECT ) {
- String[] args_m = { psRDN , e.toString() };
+ String[] args_m = { suffix , e.toString() };
DSUtil.showErrorDialog( _model.getFrame(),
"error-find-subsuffix",
args_m,
SECTION);
Debug.println( "SuffixResourceObject.addSuffix: " +
- "psRDN: " + psRDN +
+ "suffix: " + suffix +
"Error: " + e.toString());
}
} finally {
@@ -180,12 +177,9 @@ public class SuffixResourceObject extends DSResourceObject
_model.fireChangeFeedbackCursor(null,
FeedbackIndicator.FEEDBACK_WAIT );
LDAPConnection ldc = _model.getServerInfo().getLDAPConnection();
- String psRDN = LDAPDN.explodeDN( _entry.getDN(), true)[0];
- psRDN = MappingUtils.escapeBackslash(psRDN);
- String dbFilter =
- "(&(objectclass=nsBackendInstance)" +
- "(nsslapd-suffix=" +
- MappingUtils.unQuote( psRDN )+ "))";
+ String suffix = MappingUtils.getMappingNodeSuffix(_entry);
+ String filter = MappingUtils.getSuffixSearchFilter(suffix, "nsslapd-suffix");
+ String dbFilter = "(&(objectclass=nsBackendInstance)" + filter + ")";
try {
LDAPSearchResults res =
@@ -229,7 +223,7 @@ public class SuffixResourceObject extends DSResourceObject
}
} catch ( LDAPException e ) {
if( e.getLDAPResultCode() != e.NO_SUCH_OBJECT ) {
- String[] args_m = { psRDN, e.toString() };
+ String[] args_m = { suffix, e.toString() };
DSUtil.showErrorDialog( _model.getFrame(),
"error-find-db",
args_m,
@@ -531,12 +525,10 @@ public class SuffixResourceObject extends DSResourceObject
}
private int delete_suffix(LDAPEntry node) {
- String dn2delete = node.getDN();
- String rdn2delete = (new DN(dn2delete)).explodeDN(true)[0];
- String[] args = { rdn2delete };
+ String suffix = MappingUtils.getMappingNodeSuffix(node);
confirmDeleteSuffixPanel child =
- new confirmDeleteSuffixPanel( _model, dn2delete );
+ new confirmDeleteSuffixPanel( _model, suffix );
SimpleDialog dlg =
new SimpleDialog( _model.getFrame(),
@@ -558,19 +550,19 @@ public class SuffixResourceObject extends DSResourceObject
StringBuffer sbDBLoc = new StringBuffer();
switch( resDiag ) {
case confirmDeleteSuffixPanel.ALL: {
- del_all_suffix( ldc, dn2delete, sbDBLoc);
+ del_all_suffix( ldc, suffix, node.getDN(), sbDBLoc);
break;
}
case confirmDeleteSuffixPanel.ONE:
LDAPAttribute dady_attr = node.getAttribute( "nsslapd-parent-suffix");
if( dady_attr == null) {
- del_1_suffix( ldc, dn2delete, null, true, sbDBLoc);
+ del_1_suffix( ldc, suffix, node.getDN(), null, true, sbDBLoc);
} else {
Enumeration en = dady_attr.getStringValues();
if ( en.hasMoreElements() ) {
- del_1_suffix( ldc, dn2delete,
- (String)en.nextElement(), true,
- sbDBLoc );
+ del_1_suffix( ldc, suffix,
+ node.getDN(), (String)en.nextElement(),
+ true, sbDBLoc );
}
}
break;
@@ -588,11 +580,10 @@ public class SuffixResourceObject extends DSResourceObject
private int del_all_suffix( LDAPConnection ldc,
String dn2delete ,
- StringBuffer sbDBLoc) {
- String rdn2delete = (new DN(dn2delete)).explodeDN(true)[0];
- String filter =
- "(&(objectclass=nsMappingTree)(nsslapd-parent-suffix=" +
- rdn2delete +"))";
+ String mndn, StringBuffer sbDBLoc) {
+ String filter = "(&(objectclass=nsMappingTree)" +
+ MappingUtils.getParentSearchFilter(dn2delete) +
+ ")";
try {
LDAPSearchResults res =
ldc.search( DSUtil.MAPPING_TREE_BASE_DN,
@@ -604,12 +595,12 @@ public class SuffixResourceObject extends DSResourceObject
while(( res != null ) && res.hasMoreElements()) {
Vector v = new Vector();
LDAPEntry entry = (LDAPEntry)res.nextElement();
- String dn2modify = entry.getDN();
- del_all_suffix( ldc, dn2modify, sbDBLoc );
+ String dn2modify = MappingUtils.getMappingNodeSuffix(entry);
+ del_all_suffix( ldc, dn2modify, entry.getDN(), sbDBLoc );
}
} catch( LDAPException e) {
if( e.getLDAPResultCode() != e.NO_SUCH_OBJECT ) {
- String[] args_m = { rdn2delete, e.toString() };
+ String[] args_m = { dn2delete, e.toString() };
DSUtil.showErrorDialog( _model.getFrame(),
"error-del-find-subsuffix",
args_m,
@@ -618,17 +609,16 @@ public class SuffixResourceObject extends DSResourceObject
}
}
- return( del_1_suffix( ldc, dn2delete, null, false, sbDBLoc));
+ return( del_1_suffix( ldc, dn2delete, mndn, null, false, sbDBLoc));
}
private int del_1_suffix(LDAPConnection ldc,
String dn2delete,
+ String mndn,
String dndady,
- boolean changeChildren,
- StringBuffer sbDBLoc) {
- String arg = (new DN(dn2delete)).explodeDN(true)[0];
- String[] dlg_arg = { arg };
+ boolean changeChildren, StringBuffer sbDBLoc) {
+ String[] dlg_arg = { dn2delete };
GenericProgressDialog dlg =
new GenericProgressDialog(_model.getFrame(),
true,
@@ -645,10 +635,10 @@ public class SuffixResourceObject extends DSResourceObject
erase_one_suffix task =
new erase_one_suffix( ldc,
dn2delete,
+ mndn,
dndady,
changeChildren,
- sbDBLoc,
- dlg );
+ sbDBLoc, dlg );
Thread th = new Thread(task);
th.start();
dlg.packAndShow();
@@ -661,36 +651,17 @@ public class SuffixResourceObject extends DSResourceObject
return( 1 );
}
-
- private boolean isLeafMappingNode( ) {
- DN pDN = new DN( _entry.getDN() );
- String psRDN = LDAPDN.explodeDN( _entry.getDN(), true )[0];
- String filter = "nsslapd-parent-suffix=" + MappingUtils.Quote( psRDN );
- LDAPConnection ldc = _model.getServerInfo().getLDAPConnection();
- try {
- LDAPSearchResults res = ldc.search( CONFIG_MAPPING, ldc.SCOPE_ONE,
- filter, null, false);
- if (res == null || !res.hasMoreElements()) {
- return( true );
- } else {
- return( false );
- }
- } catch (LDAPException e) {
- Debug.println( "SuffixResourceObject.isLeafMappingNode() : error :" + e );
- return( false );
- }
- }
-
class erase_one_suffix implements Runnable {
public erase_one_suffix(LDAPConnection ldc,
String dn2delete,
+ String mndn,
String dndady,
boolean changeChildren,
- StringBuffer sbDBLoc,
- GenericProgressDialog dlg ) {
+ StringBuffer sbDBLoc, GenericProgressDialog dlg ) {
_ldc = ldc;
_dn2delete = dn2delete;
+ _mndn = mndn;
_dndady = dndady;
_changeChildren = changeChildren;
_dlg = dlg;
@@ -701,11 +672,10 @@ public class SuffixResourceObject extends DSResourceObject
public void run() {
boolean everythingUnderControl = true;
if ( _changeChildren ) {
- String rdn2delete = (new DN(_dn2delete)).explodeDN(true)[0];
- rdn2delete = MappingUtils.escapeBackslash(rdn2delete);
- String filter =
- "(&(objectclass=nsMappingTree)(nsslapd-parent-suffix=" +
- rdn2delete +"))";
+ String filter = "(&(objectclass=nsMappingTree)" +
+ MappingUtils.getParentSearchFilter(_dn2delete) +
+ ")";
+ String suffix2delete = _dn2delete;
try {
LDAPSearchResults res =
_ldc.search( DSUtil.MAPPING_TREE_BASE_DN,
@@ -722,9 +692,9 @@ public class SuffixResourceObject extends DSResourceObject
if( _dndady == null ) {
attrs.add( LDAPModification.DELETE,
new LDAPAttribute( "nsslapd-parent-suffix",
- rdn2delete ));
+ suffix2delete ));
} else {
- rdn2delete = _dndady;
+ suffix2delete = _dndady;
attrs.add( LDAPModification.REPLACE,
new LDAPAttribute( "nsslapd-parent-suffix",
_dndady));
@@ -740,14 +710,14 @@ public class SuffixResourceObject extends DSResourceObject
SECTION);
Debug.println("SuffixResourceObject.del_1_suffix(): " +
- "rdn2 delete or mod = " + rdn2delete );
+ "rdn2 delete or mod = " + suffix2delete );
everythingUnderControl = false;
}
}
} catch(LDAPException e) {
if( e.getLDAPResultCode() != e.NO_SUCH_OBJECT ) {
- String[] args_m = { rdn2delete, e.toString() };
+ String[] args_m = { suffix2delete, e.toString() };
DSUtil.showErrorDialog( _model.getFrame(),
"error-del-find-subsuffix",
args_m,
@@ -763,8 +733,8 @@ public class SuffixResourceObject extends DSResourceObject
this._dlg.closeCallBack();
}
- if (!DSUtil.deleteTree ( _dn2delete, _ldc, false, _dlg )) {
- String[] args_m = { _dn2delete } ;
+ if (!DSUtil.deleteTree ( _mndn, _ldc, false, _dlg )) {
+ String[] args_m = { _mndn } ;
DSUtil.showErrorDialog( _model.getFrame(),
"error-remove",
args_m,
@@ -776,13 +746,11 @@ public class SuffixResourceObject extends DSResourceObject
// check suffix
this._dlg.stepCompleted(1);
- /* now get ride of all its database */
+ /* now get rid of all its database */
- String rdn2delete = (new DN(_dn2delete)).explodeDN(true)[0];
- rdn2delete = MappingUtils.escapeBackslash(rdn2delete);
- String filter =
- "(&(objectclass=nsBackendInstance)(nsslapd-suffix=" +
- MappingUtils.unQuote(rdn2delete) +"))";
+ String filter = "(&(objectclass=nsBackendInstance) " +
+ MappingUtils.getSuffixSearchFilter(_dn2delete, "nsslapd-suffix") +
+ ")";
try {
LDAPSearchResults res =
_ldc.search( DSUtil.PLUGIN_CONFIG_BASE_DN,
@@ -804,7 +772,7 @@ public class SuffixResourceObject extends DSResourceObject
}
} catch (LDAPException lde) {
if( lde.getLDAPResultCode() != lde.NO_SUCH_OBJECT ) {
- String[] args_m = { rdn2delete, lde.toString() };
+ String[] args_m = { _dn2delete, lde.toString() };
DSUtil.showErrorDialog( _model.getFrame(),
"error-del-find-subsuffix",
args_m,
@@ -826,8 +794,9 @@ public class SuffixResourceObject extends DSResourceObject
}
LDAPConnection _ldc;
- String _dn2delete;
- String _dndady;
+ String _dn2delete; // the suffix DN i.e. dc=example,dc=com
+ String _mndn; // the DN of the mapping tree node e.g. cn=dc\3Dexample\2Cdc\3Dcom,cn=mapping tree,cn=config
+ String _dndady; // the parent suffix, if any
boolean _changeChildren;
GenericProgressDialog _dlg;
StringBuffer _sbDBLoc;
diff --git a/src/com/netscape/admin/dirserv/panel/BackendPanel.java b/src/com/netscape/admin/dirserv/panel/BackendPanel.java
index cf02e5b..2d390f0 100644
--- a/src/com/netscape/admin/dirserv/panel/BackendPanel.java
+++ b/src/com/netscape/admin/dirserv/panel/BackendPanel.java
@@ -174,24 +174,6 @@ public class BackendPanel extends JPanel {
return null;
}
- public boolean setSelectedSuffix(String suffix) {
- if (_htSuffixAndBackends != null) {
- suffix = MappingUtils.unQuote(suffix);
- DN suffixDN = new DN(suffix);
- for (int i=0 ; i<_htSuffixAndBackends.size(); i++) {
- String key = String.valueOf(i);
- String currentSuffix = (String)(((Hashtable)(_htSuffixAndBackends.get(key))).get(SUFFIX_ATTR));
- currentSuffix = MappingUtils.unQuote(currentSuffix);
- DN currentSuffixDN = new DN(currentSuffix);
- if (currentSuffixDN.equals(suffixDN)) {
- _theChoice.setSelectedIndex(i);
- return true;
- }
- }
- }
- return false;
- }
-
public boolean setSelectedBackend(String backend) {
if (_htSuffixAndBackends != null) {
for (int i=0 ; i<_htSuffixAndBackends.size(); i++) {
diff --git a/src/com/netscape/admin/dirserv/panel/MappingNodeSettingPanel.java b/src/com/netscape/admin/dirserv/panel/MappingNodeSettingPanel.java
index dfe19c2..87bb2a1 100644
--- a/src/com/netscape/admin/dirserv/panel/MappingNodeSettingPanel.java
+++ b/src/com/netscape/admin/dirserv/panel/MappingNodeSettingPanel.java
@@ -93,7 +93,8 @@ public class MappingNodeSettingPanel extends BlankPanel
_myPanel.add( _NodeLabel, gbc );
_NodeText = new JLabel();
- _NodeText.setText( LDAPDN.explodeDN(_entry.getDN(),true)[0]);
+ String suffixval = MappingUtils.getMappingNodeName(_entry);
+ _NodeText.setText(suffixval);
gbc.gridx = 1;
gbc.anchor = gbc.WEST;
_myPanel.add( _NodeText, gbc );
diff --git a/src/com/netscape/admin/dirserv/panel/MappingUtils.java b/src/com/netscape/admin/dirserv/panel/MappingUtils.java
index 8910798..a9a2c03 100644
--- a/src/com/netscape/admin/dirserv/panel/MappingUtils.java
+++ b/src/com/netscape/admin/dirserv/panel/MappingUtils.java
@@ -38,6 +38,53 @@ public class MappingUtils {
private MappingUtils() {}
+ /**
+ * The mapping node name is the suffix DN. In the mapping tree entry,
+ * the values of the cn attribute hold the suffix DN. There are usually two
+ * values - the quoted or escaped value, and the unquoted value. We look
+ * for the first unquoted value and use that for the node name. If for some
+ * reason we could not find the cn attribute or a suitable value, assume the
+ * suffix is the value of the leftmost RDN in the entry DN.
+ * @param mnent - the mapping tree node entry
+ * @return the suffix to use as the name of the mapping tree node
+ */
+ static public String getMappingNodeName(LDAPEntry mnent) {
+ String cnvals[] = DSUtil.getAttrValues(mnent, "cn");
+ String suffixval = null;
+ for (int ii = 0; (cnvals != null) && (ii < cnvals.length); ++ii) {
+ if (!DSUtil.DNUsesLDAPv2Quoting(cnvals[ii])) {
+ suffixval = DSUtil.unEscapeDN(cnvals[ii]);
+ break;
+ }
+ }
+ if (suffixval == null) {
+ suffixval = DSUtil.unEscapeRDNVal(LDAPDN.explodeDN(mnent.getDN(),true)[0]);
+ }
+ return suffixval;
+ }
+
+ /**
+ * Given a mapping tree node entry, return the suffix that this represents.
+ * @param mnent - the mapping tree node entry
+ * @return the suffix represented by this mapping tree node
+ */
+ static public String getMappingNodeSuffix(LDAPEntry mnent) {
+ return getMappingNodeName(mnent);
+ }
+
+ static public String getSuffixSearchFilter(String suffix, String attrname) {
+ String normsuffix = LDAPDN.normalize(suffix);
+ return "(|(" + attrname + "=" + suffix + ")(" + attrname + "=" + Quote(suffix) + ")(" +
+ attrname + "=" + normsuffix + ")(" + attrname + "=" + Quote(normsuffix) + "))";
+ }
+
+ static public String getSuffixSearchFilter(String suffix) {
+ return getSuffixSearchFilter(suffix, "cn");
+ }
+ static public String getParentSearchFilter(String suffix) {
+ return getSuffixSearchFilter(suffix, "nsslapd-parent-suffix");
+ }
+
static public String[] getMappingNode(LDAPConnection ldc ) {
Vector v = new Vector(1);
@@ -51,8 +98,8 @@ public class MappingUtils {
false );
while( res.hasMoreElements() ) {
LDAPEntry bentry = (LDAPEntry)res.nextElement();
- String name = bentry.getDN();
- v.addElement(unQuote(LDAPDN.explodeDN(bentry.getDN(),true)[0]));
+ String name = getMappingNodeSuffix(bentry);
+ v.addElement(name);
}
} catch ( LDAPException e ) {
Debug.println(0, "NewMappingNodePanel.getMappingNode() " + e );
@@ -62,32 +109,12 @@ public class MappingUtils {
return mapList;
}
- static public String unQuote( String line ) {
- if (line != null) {
- if (line.length() > 0) {
- StringBuffer unquote_line = new StringBuffer();
-
- Character deb = new Character( line.charAt(0) );
- Character fin = new Character( line.charAt( line.length() - 1 ) );
- Character tag = new Character( '"' );
-
- if ( deb.compareTo(tag) == 0) {
- for (int i=1; i < (line.length() - 1); i++) {
- unquote_line.append(line.charAt(i));
- }
- } else {
- unquote_line.append( line );
- }
- return(unquote_line.toString());
- }
- return (new String(line));
- }
- return null;
- }
-
static public String Quote( String line ) {
+ if ((line == null) || (line.length() < 1)) {
+ return "\"\"";
+ }
StringBuffer quoted_line = new StringBuffer();
-
+
Character deb = new Character( line.charAt(0) );
Character tag = new Character( '"' );
@@ -101,51 +128,6 @@ public class MappingUtils {
return(quoted_line.toString());
}
- /**
- * Escape backslashes in RDNs for suffix search. E.g. to search for
- * "o=Abc\,Inc" as an attribute value it should be eacaped as
- * "o=Abc\\,Inc" in a search filter (nsslapd-suffix=o=Abc\\,Inc).
- */
- static public String escapeBackslash(String val) {
- if (val.indexOf('\\') < 0) {
- return val;
- }
- StringBuffer res = new StringBuffer();
- for (int i=0; i < val.length(); i++) {
- if (val.charAt(i) == '\\') {
- res.append('\\');
- }
- res.append(val.charAt(i));
- }
- return res.toString();
- }
-
- /**
- * Remove escape backslashes. This will be used when creating a suffix
- * to convert a RDN with escaped characters into an attribute value.
- *
- * E.g. the user wants to create a domain for "Abc, Inc". The domain
- * suffix DN must be input as "o=Abc\, Inc", but when the suffix entry
- * is created the corresponding attr value is "Abc, Inc".
- */
- static public String unescapeBackslash(String val) {
- if (val.indexOf('\\') < 0) {
- return val;
- }
- StringBuffer res = new StringBuffer();
- for (int i=0; i < val.length(); i++) {
- if (val.charAt(i) == '\\') {
- if (++i < val.length()) {
- res.append(val.charAt(i));
- }
- }
- else {
- res.append(val.charAt(i));
- }
- }
- return res.toString();
- }
-
static public String[] getBackendList(LDAPConnection ldc) {
if (ldc == null) {
return null;
@@ -226,7 +208,7 @@ public class MappingUtils {
return suffixes;
}
- /* Uses the bubble method to order the suffixes (the longuest goes first)*/
+ /* Uses the bubble method to order the suffixes (the longest goes first)*/
static public void orderSuffixes(String[] suffixes) {
if (suffixes==null) {
@@ -328,13 +310,13 @@ public class MappingUtils {
int index = values[i].indexOf(':');
if (index > 0) {
String suffix = values[i].substring(index+1);
- v.addElement(MappingUtils.unQuote(suffix));
+ v.addElement(suffix);
}
}
}
} else {
String suffix = DSUtil.getAttrValue(entry, SUFFIX_ATTR);
- v.addElement(MappingUtils.unQuote(suffix));
+ v.addElement(suffix);
}
}
} catch ( LDAPException e ) {
@@ -601,40 +583,23 @@ public class MappingUtils {
) {
int resDiag;
- StringBuffer cn2add = new StringBuffer();
-
// Check parms
if( (newNodeName == null) || (newNodeName.trim().length() == 0) ) {
return( false );
}
- // build the cn
- Character deb = new Character(newNodeName.charAt(0));
- Character fin = new Character(newNodeName.charAt(newNodeName.length() - 1));
- Character tag = new Character( '"' );
-
- if ( deb.compareTo(tag) != 0) {
- cn2add.append( '"' );
- }
-
- cn2add.append( newNodeName );
-
+ StringBuffer cn2add = new StringBuffer(newNodeName);
// Add the upperNode to the new node
if ( upperNode.compareTo( ROOT_MAPPING_NODE )!=0 ) {
cn2add.append( "," );
cn2add.append( upperNode );
}
+ // Building dn to add in mapping tree
+ // NOTE: we only need the escaped value in the DN - we use the
+ // "raw" value everywhere else
+ String dn2add = "cn=" + DSUtil.escapeDNVal(cn2add.toString()) + "," + CONFIG_MAPPING ;
- if ( fin.compareTo(tag) != 0) {
- cn2add.append( '"' );
- }
-
-
- // Building dn to add in mapping tree
- String dn2add = "cn=" + cn2add.toString() + "," + CONFIG_MAPPING ;
-
-
// Start LDAP job
LDAPAttributeSet attrs = new LDAPAttributeSet();
@@ -644,13 +609,14 @@ public class MappingUtils {
String state[] = { NStatus };
attrs.add( new LDAPAttribute( "nsslapd-state", state ));
- // Force a quoted value just to have a consistent display
+ // cn value is the "raw" suffix
+ // the server may also add the value from the RDN value from the DN
String mycn[] = { cn2add.toString() };
attrs.add( new LDAPAttribute( "cn", mycn ));
-
if ( upperNode.compareTo( ROOT_MAPPING_NODE ) != 0) {
- String dady[] = { Quote( upperNode.trim() ) };
+ // parent suffix is also the "raw" value, not escaped or quoted
+ String dady[] = { upperNode.trim() };
attrs.add( new LDAPAttribute( "nsslapd-parent-suffix", dady ));
}
@@ -905,6 +871,49 @@ public class MappingUtils {
}
+ public static boolean isLeafMappingNode(LDAPConnection ldc, LDAPEntry _entry) {
+ String suffix = MappingUtils.getMappingNodeSuffix(_entry);
+ String filter = MappingUtils.getParentSearchFilter(suffix);
+ // this node is a leaf if it is not the parent of another node
+ try {
+ LDAPSearchResults res = ldc.search( CONFIG_MAPPING, LDAPv3.SCOPE_ONE,
+ filter, null, false);
+ if ((res == null) || !res.hasMoreElements()) {
+ return( true );
+ } else {
+ return( false );
+ }
+ } catch (LDAPException e) {
+ Debug.println( "MappingNodeObject.isLeafMappingNode() :" + e );
+ return( false );
+ }
+ }
+
+ /**
+ * Given a suffix DN, return the corresponding mapping tree node DN
+ * @param ldc the LDAP connection
+ * @param suffix the suffix DN
+ * @return the DN of the mapping tree node corresponding to this suffix
+ */
+ public static String getMappingNodeForSuffix(LDAPConnection ldc, String suffix) {
+ String filter = getSuffixSearchFilter(suffix);
+ // this node is a leaf if it is not the parent of another node
+ String mndn = null;
+ try {
+ LDAPSearchResults res = ldc.search( CONFIG_MAPPING, LDAPv3.SCOPE_ONE,
+ filter, null, false);
+ if ((res == null) || !res.hasMoreElements()) {
+ Debug.println( "MappingNodeObject.getMappingNodeForSuffix() : " +
+ "no entries returned for filter " + filter );
+ } else {
+ LDAPEntry entry = (LDAPEntry)res.nextElement();
+ mndn = entry.getDN();
+ }
+ } catch (LDAPException e) {
+ Debug.println( "MappingNodeObject.getMappingNodeForSuffix() :" + e );
+ }
+ return mndn;
+ }
private final static String _section = "mappingtree";
public static final String CONFIG_BASEDN = "cn=plugins, cn=config" ;
diff --git a/src/com/netscape/admin/dirserv/panel/NewChainingInstancePanel.java b/src/com/netscape/admin/dirserv/panel/NewChainingInstancePanel.java
index 12c419f..4c62359 100644
--- a/src/com/netscape/admin/dirserv/panel/NewChainingInstancePanel.java
+++ b/src/com/netscape/admin/dirserv/panel/NewChainingInstancePanel.java
@@ -918,11 +918,6 @@ public class NewChainingInstancePanel extends BlankPanel
}
} else if ( _rbExistingNode.isSelected() ) {
// Add backend instance in selected Mapping Node
- String dn_instMapping = "cn=" +
- MappingUtils.Quote( (String) _comboMapping.getSelectedItem() ) +
- "," +
- CONFIG_MAPPING;
- Debug.println("okCallback updating :" + dn_instMapping);
LDAPModificationSet mods = new LDAPModificationSet();
LDAPAttribute backend_instMapping = new LDAPAttribute( "nsslapd-backend",
@@ -930,6 +925,9 @@ public class NewChainingInstancePanel extends BlankPanel
mods.add( LDAPModification.ADD, backend_instMapping );
_model.setWaitCursor( true );
LDAPConnection ldc = _model.getServerInfo().getLDAPConnection();
+ String dn_instMapping = MappingUtils.getMappingNodeForSuffix(ldc,
+ (String) _comboMapping.getSelectedItem());
+ Debug.println("okCallback updating :" + dn_instMapping);
try {
ldc.modify(dn_instMapping, mods );
} catch (LDAPException e) {
diff --git a/src/com/netscape/admin/dirserv/panel/NewChainingPanel.java b/src/com/netscape/admin/dirserv/panel/NewChainingPanel.java
index ad6bd8f..08a8277 100644
--- a/src/com/netscape/admin/dirserv/panel/NewChainingPanel.java
+++ b/src/com/netscape/admin/dirserv/panel/NewChainingPanel.java
@@ -102,11 +102,7 @@ public class NewChainingPanel extends BlankPanel
HostPanel.setLayout(HLbag);
- LDAPAttribute suffixCN = _entrySuffix.getAttribute("cn");
- if ( suffixCN != null ){
- _suffix = MappingUtils.unQuote( suffixCN.getStringValueArray()[0]);
- }
-
+ _suffix = MappingUtils.getMappingNodeSuffix(_entrySuffix);
_suffixLabel = makeJLabel( _section, "suffix-name" );
HLgbc.fill = HLgbc.NONE;
HLgbc.weightx = 0;
@@ -721,7 +717,7 @@ public class NewChainingPanel extends BlankPanel
}
}
- public int addChainingBackend(String _MappingNode ) {
+ public int addChainingBackend(String suffix ) {
String _instName = _instanceNameText.getText().trim();
getChainingLoc();
@@ -741,7 +737,7 @@ public class NewChainingPanel extends BlankPanel
attrs.add( new LDAPAttribute( "cn", cn_dbInst ) );
- String suffix_dbInstConfig[] = { _MappingNode };
+ String suffix_dbInstConfig[] = { suffix };
attrs.add( new LDAPAttribute ( "nsslapd-suffix", suffix_dbInstConfig ));
String nsBindDN = _bindDNText.getText();
diff --git a/src/com/netscape/admin/dirserv/panel/NewLDBMPanel.java b/src/com/netscape/admin/dirserv/panel/NewLDBMPanel.java
index 6d264ac..5535fec 100644
--- a/src/com/netscape/admin/dirserv/panel/NewLDBMPanel.java
+++ b/src/com/netscape/admin/dirserv/panel/NewLDBMPanel.java
@@ -83,10 +83,7 @@ public class NewLDBMPanel extends BlankPanel {
gbc.fill = gbc.HORIZONTAL;
grid.add( panel, gbc );
- LDAPAttribute suffixCN = _entrySuffix.getAttribute("cn");
- if ( suffixCN != null ){
- _suffix = MappingUtils.unQuote( suffixCN.getStringValueArray()[0]);
- }
+ _suffix = MappingUtils.getMappingNodeSuffix(_entrySuffix);
_suffixLabel = makeJLabel( _section, "suffix-name" );
gbc.gridwidth = 3;
gbc.fill = gbc.NONE;
@@ -309,7 +306,7 @@ public class NewLDBMPanel extends BlankPanel {
}
}
- public int addLDBMBackend(String _MappingNode ) {
+ public int addLDBMBackend(String suffix ) {
String _instName = _instanceNameText.getText().trim();
@@ -335,7 +332,7 @@ public class NewLDBMPanel extends BlankPanel {
attrs.add( new LDAPAttribute( "cn", cn_dbInst ) );
- String suffix_dbInstConfig[] = { _MappingNode };
+ String suffix_dbInstConfig[] = { suffix };
attrs.add( new LDAPAttribute ( "nsslapd-suffix", suffix_dbInstConfig ));
String cachesize_dbInstConfig[] = { "-1" };
diff --git a/src/com/netscape/admin/dirserv/panel/NewMappingNodePanel.java b/src/com/netscape/admin/dirserv/panel/NewMappingNodePanel.java
index 0243ab3..12a5f6d 100644
--- a/src/com/netscape/admin/dirserv/panel/NewMappingNodePanel.java
+++ b/src/com/netscape/admin/dirserv/panel/NewMappingNodePanel.java
@@ -218,11 +218,14 @@ public class NewMappingNodePanel extends BlankPanel {
if ( mapList != null ) {
int j =0;
_comboNewNodeMapping.addItem( ROOT_MAPPING_NODE );
+ String suffix = null;
+ if (_entry != null) {
+ suffix = MappingUtils.getMappingNodeSuffix(_entry);
+ }
for( int i = 0; i < mapList.length; i++ ) {
_comboNewNodeMapping.addItem( mapList[i] );
- if((_entry != null) &&
- ( mapList[i].compareTo(MappingUtils.unQuote(
- LDAPDN.explodeDN( _entry.getDN(), true )[0])) == 0)) {
+ if((suffix != null) &&
+ DSUtil.equalDNs(mapList[i], suffix)) {
j = i + 1;
}
diff --git a/src/com/netscape/admin/dirserv/panel/NewSuffixPanel.java b/src/com/netscape/admin/dirserv/panel/NewSuffixPanel.java
index 87bb368..ed88323 100644
--- a/src/com/netscape/admin/dirserv/panel/NewSuffixPanel.java
+++ b/src/com/netscape/admin/dirserv/panel/NewSuffixPanel.java
@@ -119,8 +119,7 @@ public class NewSuffixPanel extends BlankPanel implements SuiConstants {
Mapanel.add( _newSuffixText, Magbc );
if(! _isRoot ) {
- String dady = MappingUtils.unQuote( LDAPDN.explodeDN( _entry.getDN(),
- true )[0]);
+ String dady = MappingUtils.getMappingNodeSuffix(_entry);
_subordinationLabel = makeJLabel( _section,
"new-subordination" );
diff --git a/src/com/netscape/admin/dirserv/panel/confirmDeleteSuffixPanel.java b/src/com/netscape/admin/dirserv/panel/confirmDeleteSuffixPanel.java
index 7c61a5b..7b889f1 100644
--- a/src/com/netscape/admin/dirserv/panel/confirmDeleteSuffixPanel.java
+++ b/src/com/netscape/admin/dirserv/panel/confirmDeleteSuffixPanel.java
@@ -70,8 +70,7 @@ public class confirmDeleteSuffixPanel extends BlankPanel
_myPanel.setLayout(Mabag);
- DN dnObj = new DN(_dnSuffix2delete);
- String[] args = {dnObj.explodeDN(true)[0]};
+ String[] args = {_dnSuffix2delete};
_introLabel = new MultilineLabel(resource.getString( _section,
"intro-label", args ));
_introLabel.setLineWrap(false);
diff --git a/src/com/netscape/admin/dirserv/propedit/DSEntryPanel.java b/src/com/netscape/admin/dirserv/propedit/DSEntryPanel.java
index 06bba44..aff65a8 100644
--- a/src/com/netscape/admin/dirserv/propedit/DSEntryPanel.java
+++ b/src/com/netscape/admin/dirserv/propedit/DSEntryPanel.java
@@ -1414,21 +1414,11 @@ public class DSEntryPanel extends JPanel implements ActionListener,
String stringRDN = "";
for (int i=0; i < attributes.length ; i++) {
- /* We add the quotes if necessary*/
- if (values[i].indexOf(',') >= 0) {
- String unquotedValue = MappingUtils.unQuote(values[i]);
- if (i>0) {
- stringRDN = stringRDN + " + " + attributes[i]+"=\""+unquotedValue+"\"";
- } else {
- stringRDN = attributes[i]+"=\""+unquotedValue+"\"";
- }
- } else {
- if (i>0) {
- stringRDN = stringRDN + " + " +attributes[i]+"="+values[i];
- } else {
- stringRDN = attributes[i]+"="+values[i];
- }
- }
+ if (i>0) {
+ stringRDN = stringRDN + " + " +attributes[i]+"="+DSUtil.escapeDNVal(values[i]);
+ } else {
+ stringRDN = attributes[i]+"="+DSUtil.escapeDNVal(values[i]);
+ }
}
Debug.println("DSEntryPanel.updateDNValue: rdn = "+stringRDN);
@@ -1442,7 +1432,7 @@ public class DSEntryPanel extends JPanel implements ActionListener,
parentDN = new DN(stringRDN);
}
_dn = parentDN;
- String dn = stringRDN+", "+_dn.getParent();
+ String dn = stringRDN+","+_dn.getParent();
Debug.println("DSEntryPanel.updateDNValue: dn = "+dn);
if (dn != null) {
_dnLabel.setText("dn: "+dn);
@@ -1498,8 +1488,7 @@ public class DSEntryPanel extends JPanel implements ActionListener,
String currentValue = (String)en.nextElement();
/* Just in case we have quotes... */
if (value.equals(currentValue) ||
- MappingUtils.unescapeBackslash(value).equals(currentValue) ||
- value.equals('"'+currentValue+'"')) {
+ DSUtil.escapeDNVal(value).equals(currentValue)) {
typeWithValue = true;
break;
}
diff --git a/src/com/netscape/admin/dirserv/propedit/RenameDialog.java b/src/com/netscape/admin/dirserv/propedit/RenameDialog.java
index 40805c7..303ace3 100644
--- a/src/com/netscape/admin/dirserv/propedit/RenameDialog.java
+++ b/src/com/netscape/admin/dirserv/propedit/RenameDialog.java
@@ -209,21 +209,11 @@ class RenameDialog extends AbstractDialog implements TableUpdateListener {
private String getInitRdn() {
String rdn = "";
for (int i=0; i< _saveNamingAttributes.length; i++) {
- /* We add the quotes if necessary*/
- if (_saveNamingValues[i].indexOf(',') >= 0) {
- String unquotedValue = MappingUtils.unQuote(_saveNamingValues[i]);
- if (i>0) {
- rdn = rdn + " + " + _saveNamingAttributes[i]+"=\""+unquotedValue+"\"";
- } else {
- rdn = _saveNamingAttributes[i]+"=\""+unquotedValue+"\"";
- }
- } else {
- if (i>0) {
- rdn = rdn + " + " +_saveNamingAttributes[i]+"= "+_saveNamingValues[i];
- } else {
- rdn = _saveNamingAttributes[i]+"= "+_saveNamingValues[i];
- }
- }
+ if (i>0) {
+ rdn = rdn + " + " +_saveNamingAttributes[i]+"= "+DSUtil.escapeDNVal(_saveNamingValues[i]);
+ } else {
+ rdn = _saveNamingAttributes[i]+"= "+DSUtil.escapeDNVal(_saveNamingValues[i]);
+ }
}
return rdn;
}
@@ -237,20 +227,10 @@ class RenameDialog extends AbstractDialog implements TableUpdateListener {
for (int i=0; i< _namingAttributes.size(); i++) {
String namingAttribute = (String)_namingAttributes.elementAt(i);
String namingValue = (String)_namingValues.elementAt(i);
- /* We add the quotes if necessary*/
- if (namingValue.indexOf(',') >= 0) {
- String unquotedValue = MappingUtils.unQuote(namingValue);
- if (i>0) {
- rdn = rdn + " + " + namingAttribute+"=\""+unquotedValue+"\"";
- } else {
- rdn = namingAttribute+"=\""+unquotedValue+"\"";
- }
+ if (i>0) {
+ rdn = rdn + "+" +namingAttribute+"="+DSUtil.escapeDNVal(namingValue);
} else {
- if (i>0) {
- rdn = rdn + " + " +namingAttribute+"= "+namingValue;
- } else {
- rdn = namingAttribute+"= "+namingValue;
- }
+ rdn = namingAttribute+"="+DSUtil.escapeDNVal(namingValue);
}
}
return rdn;
13 years, 1 month
Branch 'Directory_Server_8_2_Branch' - ldap/ldif ldap/servers
by Noriko Hosoi
ldap/ldif/template-suffix-db.ldif.in | 1 +
ldap/servers/slapd/dn.c | 29 ++++++++++++++++++++++++-----
2 files changed, 25 insertions(+), 5 deletions(-)
New commits:
commit e7a81ddaa86b284d8eb29906e63e7841958f8ef1
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Apr 27 11:50:43 2010 -0700
574167 - An escaped space at the end of the RDN value is not
handled correctly
https://bugzilla.redhat.com/show_bug.cgi?id=574167
Bug Description: If a DN contains "\ " at the end of its RDN,
it's be converted to "\20" by slapi_dn_normalize_ext in the
add operation. But the following search returns ' ' (not
an escaped space).
Fix Description: When slapi_dn_normalize_ext was applied to a
string which contains "\20", it converted the string to ' '.
This fix changes the behaviour so that the string "\20" in
DN remains untouched.
Also, this patch includes a fix to add a default suffix value
with no double quotes in template-suffix-db.ldif.in. We keep
double quoted suffix for the backward compatibility.
diff --git a/ldap/ldif/template-suffix-db.ldif.in b/ldap/ldif/template-suffix-db.ldif.in
index 1b97826..1bcc5c2 100644
--- a/ldap/ldif/template-suffix-db.ldif.in
+++ b/ldap/ldif/template-suffix-db.ldif.in
@@ -21,6 +21,7 @@ dn: cn="%ds_suffix%",cn=mapping tree,cn=config
objectclass: top
objectclass: extensibleObject
objectclass: nsMappingTree
+cn: %ds_suffix%
cn: "%ds_suffix%"
nsslapd-state: backend
nsslapd-backend: %ds_bename%
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 4a40369..c3aaf4c 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -78,6 +78,7 @@ hexchar2int( char c )
}
#define ISBLANK(c) ((c) == ' ')
+#define ISBLANKSTR(s) (((*(s)) == '2') && (*((s)+1) == '0'))
#define ISSPACE(c) (ISBLANK(c) || ((c) == '\n') || ((c) == '\r')) /* XXX 518524 */
#define ISEQUAL(c) ((c) == '=')
@@ -444,6 +445,21 @@ substr_dn_normalize( char *dn, char *end )
return end;
}
+static int
+ISEOV(char *s, char *ends)
+{
+ char *p;
+ int rc = 1;
+ for (p = s; p && *p && p < ends; p++) {
+ if (SEPARATOR(*p)) {
+ return 1;
+ } else if (!ISBLANK(*p)) {
+ return 0; /* not the end of the value */
+ }
+ }
+ return 1;
+}
+
/*
* 1) Escaped NEEDSESCAPE chars (e.g., ',', '<', '=', etc.) are converted to
* ESC HEX HEX (e.g., \2C, \3C, \3D, etc.)
@@ -664,10 +680,13 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
s++;
}
}
- } else if (((state == INVALUE1ST) && (s+2 < ends) &&
- LEADNEEDSESCAPESTR(s+1)) ||
- ((state == INVALUE) && (s+2 < ends) &&
- NEEDSESCAPESTR(s+1))) {
+ } else if (((state == INVALUE1ST) &&
+ (s+2 < ends) && LEADNEEDSESCAPESTR(s+1)) ||
+ ((state == INVALUE) &&
+ (((s+2 < ends) && NEEDSESCAPESTR(s+1)) ||
+ (ISEOV(s+3, ends) && ISBLANKSTR(s+1))))) {
+ /* e.g., cn=abc\20 ,... */
+ /* ^ */
if (ISEQUALSTR(s+1)) {
if (NULL == subtypestart) {
/* e.g., cn=a\3Db\2Cc\3Dd */
@@ -933,7 +952,7 @@ bail:
if (*dest != src) {
slapi_ch_free_string(dest);
} else {
- *dest = NULL;
+ *dest = NULL;
}
*dest_len = 0;
} else if (rc > 0) {
13 years, 1 month
ldap/ldif ldap/servers
by Noriko Hosoi
ldap/ldif/template-suffix-db.ldif.in | 1 +
ldap/servers/slapd/dn.c | 29 ++++++++++++++++++++++++-----
2 files changed, 25 insertions(+), 5 deletions(-)
New commits:
commit 0501282a9042af77c20b793645a5b241082a08b5
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Apr 27 11:50:43 2010 -0700
574167 - An escaped space at the end of the RDN value is not
handled correctly
https://bugzilla.redhat.com/show_bug.cgi?id=574167
Bug Description: If a DN contains "\ " at the end of its RDN,
it's be converted to "\20" by slapi_dn_normalize_ext in the
add operation. But the following search returns ' ' (not
an escaped space).
Fix Description: When slapi_dn_normalize_ext was applied to a
string which contains "\20", it converted the string to ' '.
This fix changes the behaviour so that the string "\20" in
DN remains untouched.
Also, this patch includes a fix to add a default suffix value
with no double quotes in template-suffix-db.ldif.in. We keep
double quoted suffix for the backward compatibility.
diff --git a/ldap/ldif/template-suffix-db.ldif.in b/ldap/ldif/template-suffix-db.ldif.in
index 1b97826..1bcc5c2 100644
--- a/ldap/ldif/template-suffix-db.ldif.in
+++ b/ldap/ldif/template-suffix-db.ldif.in
@@ -21,6 +21,7 @@ dn: cn="%ds_suffix%",cn=mapping tree,cn=config
objectclass: top
objectclass: extensibleObject
objectclass: nsMappingTree
+cn: %ds_suffix%
cn: "%ds_suffix%"
nsslapd-state: backend
nsslapd-backend: %ds_bename%
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 743aa36..f30578f 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -78,6 +78,7 @@ hexchar2int( char c )
}
#define ISBLANK(c) ((c) == ' ')
+#define ISBLANKSTR(s) (((*(s)) == '2') && (*((s)+1) == '0'))
#define ISSPACE(c) (ISBLANK(c) || ((c) == '\n') || ((c) == '\r')) /* XXX 518524 */
#define ISEQUAL(c) ((c) == '=')
@@ -444,6 +445,21 @@ substr_dn_normalize( char *dn, char *end )
return end;
}
+static int
+ISEOV(char *s, char *ends)
+{
+ char *p;
+ int rc = 1;
+ for (p = s; p && *p && p < ends; p++) {
+ if (SEPARATOR(*p)) {
+ return 1;
+ } else if (!ISBLANK(*p)) {
+ return 0; /* not the end of the value */
+ }
+ }
+ return 1;
+}
+
/*
* 1) Escaped NEEDSESCAPE chars (e.g., ',', '<', '=', etc.) are converted to
* ESC HEX HEX (e.g., \2C, \3C, \3D, etc.)
@@ -664,10 +680,13 @@ slapi_dn_normalize_ext(char *src, size_t src_len, char **dest, size_t *dest_len)
s++;
}
}
- } else if (((state == INVALUE1ST) && (s+2 < ends) &&
- LEADNEEDSESCAPESTR(s+1)) ||
- ((state == INVALUE) && (s+2 < ends) &&
- NEEDSESCAPESTR(s+1))) {
+ } else if (((state == INVALUE1ST) &&
+ (s+2 < ends) && LEADNEEDSESCAPESTR(s+1)) ||
+ ((state == INVALUE) &&
+ (((s+2 < ends) && NEEDSESCAPESTR(s+1)) ||
+ (ISEOV(s+3, ends) && ISBLANKSTR(s+1))))) {
+ /* e.g., cn=abc\20 ,... */
+ /* ^ */
if (ISEQUALSTR(s+1)) {
if (NULL == subtypestart) {
/* e.g., cn=a\3Db\2Cc\3Dd */
@@ -933,7 +952,7 @@ bail:
if (*dest != src) {
slapi_ch_free_string(dest);
} else {
- *dest = NULL;
+ *dest = NULL;
}
*dest_len = 0;
} else if (rc > 0) {
13 years, 1 month
Branch 'Directory_Server_8_2_Branch' - 2 commits - ldap/servers
by Noriko Hosoi
ldap/servers/plugins/acl/acllas.c | 4 ++--
ldap/servers/plugins/acl/aclparse.c | 26 +++++++++++++++++++++++++-
2 files changed, 27 insertions(+), 3 deletions(-)
New commits:
commit ac26aed350efff609b721dd9d8fb0082ccdb4555
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Apr 27 10:31:49 2010 -0700
585905 - ACL with targattrfilters error crashes the server
https://bugzilla.redhat.com/show_bug.cgi?id=585905
Bug Description:
targattrfilters takes this format of value:
(targattrfilters="add=attr1:F1 && attr2:F2... &&
attrn:Fn,del=attr1:F1 && attr2:F2 ... && attrn:Fn")
The ACL plugin code had blindly expected the value contains
the operator "add" or "del" and '=' to concatenate the
attribute and filter pair. The plugin should have checked
the possibility that the value does not follow the format.
Fix Description:
If '=' is not included in the targattrfilters value, the
ACL parser returns ACL_SYNTAX_ERR. Also, adding a check
code for the returned pointer from strchr and strstr.
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 0c8d0fa..80fcfa0 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -291,6 +291,9 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
}
tmpstr = strchr(str, '=');
+ if (NULL == tmpstr) {
+ return ACL_SYNTAX_ERR;
+ }
tmpstr++;
__acl_strip_leading_space(&tmpstr);
@@ -777,6 +780,9 @@ normalize_nextACERule:
}
} else if ( 0 == strncmp ( s, DS_LAS_USERDN, 6)) {
p = strstr ( s, "=");
+ if (NULL == p) {
+ goto error;
+ }
p--;
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_USERDN;
@@ -840,6 +846,9 @@ normalize_nextACERule:
} else if ( 0 == strncmp ( s, DS_LAS_GROUPDN, 7)) {
p = strstr ( s, "=");
+ if (NULL == p) {
+ goto error;
+ }
p--;
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_GROUPDN;
@@ -860,6 +869,9 @@ normalize_nextACERule:
} else if ( 0 == strncmp ( s, DS_LAS_ROLEDN, 6)) {
p = strstr ( s, "=");
+ if (NULL == p) {
+ goto error;
+ }
p--;
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_ROLEDN;
@@ -1270,6 +1282,9 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
Targetattr *attr = NULL;
s = strchr (attr_val, '=');
+ if (NULL == s) {
+ return ACL_SYNTAX_ERR;
+ }
s++;
__acl_strip_leading_space(&s);
__acl_strip_trailing_space(s);
@@ -1695,6 +1710,9 @@ static int __acl__init_targetattrfilters( aci_t *aci, char *input_str) {
/* First, skip the "targetattrfilters" */
s = strchr (input_str, '=');
+ if (NULL == s) {
+ return ACL_SYNTAX_ERR;
+ }
s++; /* skip the = */
__acl_strip_leading_space(&s); /* skip to next significant character */
__acl_strip_trailing_space(s);
@@ -1720,6 +1738,9 @@ static int __acl__init_targetattrfilters( aci_t *aci, char *input_str) {
*/
s = strchr (str, '=');
+ if (NULL == s) {
+ return ACL_SYNTAX_ERR;
+ }
*s = '\0';
s++; /* skip the = */
__acl_strip_leading_space(&s); /* start of the first filter list */
@@ -1769,7 +1790,10 @@ static int __acl__init_targetattrfilters( aci_t *aci, char *input_str) {
if (str != NULL ){
__acl_strip_leading_space(&str);
- s = strchr (str, '=');
+ s = strchr (str, '=');
+ if (NULL == s) {
+ return ACL_SYNTAX_ERR;
+ }
*s = '\0';
s++;
__acl_strip_trailing_space(str);
commit c7fdf24cf58e7da5f5c297657e9e39ad1e72bbf4
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Apr 26 19:53:15 2010 -0600
Fix too few args for format warning in acllas
Removed unused format arguments from format string
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index 9fbd25b..12cefaf 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -3545,7 +3545,7 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
prefix_len = LDAPS_URL_prefix_len;
} else {
slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acllas__client_match_URL: url %s does not include ldap prefix: %s\n", url);
+ "acllas__client_match_URL: url %s does not have a recognized ldap protocol prefix\n", url);
return ACL_FALSE;
}
rawdn = url + prefix_len; /* ldap(s)://host:port/... or ldap(s):///... */
@@ -3560,7 +3560,7 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
size_t hostport_len = 0;
if (NULL == rawdn) {
slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acllas__client_match_URL: url %s does not include correct ldap prefix: %s\n", url);
+ "acllas__client_match_URL: url %s does not have a valid ldap protocol prefix\n", url);
return ACL_FALSE;
}
hostport_len = ++rawdn - tmpp; /* ldap(s)://host:port/... */
13 years, 1 month
ldap/servers
by Noriko Hosoi
ldap/servers/plugins/acl/aclparse.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
New commits:
commit b65b3c97847edefe8e9242e5bac294dd13e73234
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Apr 27 10:31:49 2010 -0700
585905 - ACL with targattrfilters error crashes the server
https://bugzilla.redhat.com/show_bug.cgi?id=585905
Bug Description:
targattrfilters takes this format of value:
(targattrfilters="add=attr1:F1 && attr2:F2... &&
attrn:Fn,del=attr1:F1 && attr2:F2 ... && attrn:Fn")
The ACL plugin code had blindly expected the value contains
the operator "add" or "del" and '=' to concatenate the
attribute and filter pair. The plugin should have checked
the possibility that the value does not follow the format.
Fix Description:
If '=' is not included in the targattrfilters value, the
ACL parser returns ACL_SYNTAX_ERR. Also, adding a check
code for the returned pointer from strchr and strstr.
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 0c8d0fa..80fcfa0 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -291,6 +291,9 @@ __aclp__parse_aci (char *str, aci_t *aci_item)
}
tmpstr = strchr(str, '=');
+ if (NULL == tmpstr) {
+ return ACL_SYNTAX_ERR;
+ }
tmpstr++;
__acl_strip_leading_space(&tmpstr);
@@ -777,6 +780,9 @@ normalize_nextACERule:
}
} else if ( 0 == strncmp ( s, DS_LAS_USERDN, 6)) {
p = strstr ( s, "=");
+ if (NULL == p) {
+ goto error;
+ }
p--;
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_USERDN;
@@ -840,6 +846,9 @@ normalize_nextACERule:
} else if ( 0 == strncmp ( s, DS_LAS_GROUPDN, 7)) {
p = strstr ( s, "=");
+ if (NULL == p) {
+ goto error;
+ }
p--;
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_GROUPDN;
@@ -860,6 +869,9 @@ normalize_nextACERule:
} else if ( 0 == strncmp ( s, DS_LAS_ROLEDN, 6)) {
p = strstr ( s, "=");
+ if (NULL == p) {
+ goto error;
+ }
p--;
if ( strncmp (p, "!=", 2) == 0)
aci_item->aci_type |= ACI_CONTAIN_NOT_ROLEDN;
@@ -1270,6 +1282,9 @@ __aclp__init_targetattr (aci_t *aci, char *attr_val)
Targetattr *attr = NULL;
s = strchr (attr_val, '=');
+ if (NULL == s) {
+ return ACL_SYNTAX_ERR;
+ }
s++;
__acl_strip_leading_space(&s);
__acl_strip_trailing_space(s);
@@ -1695,6 +1710,9 @@ static int __acl__init_targetattrfilters( aci_t *aci, char *input_str) {
/* First, skip the "targetattrfilters" */
s = strchr (input_str, '=');
+ if (NULL == s) {
+ return ACL_SYNTAX_ERR;
+ }
s++; /* skip the = */
__acl_strip_leading_space(&s); /* skip to next significant character */
__acl_strip_trailing_space(s);
@@ -1720,6 +1738,9 @@ static int __acl__init_targetattrfilters( aci_t *aci, char *input_str) {
*/
s = strchr (str, '=');
+ if (NULL == s) {
+ return ACL_SYNTAX_ERR;
+ }
*s = '\0';
s++; /* skip the = */
__acl_strip_leading_space(&s); /* start of the first filter list */
@@ -1769,7 +1790,10 @@ static int __acl__init_targetattrfilters( aci_t *aci, char *input_str) {
if (str != NULL ){
__acl_strip_leading_space(&str);
- s = strchr (str, '=');
+ s = strchr (str, '=');
+ if (NULL == s) {
+ return ACL_SYNTAX_ERR;
+ }
*s = '\0';
s++;
__acl_strip_trailing_space(str);
13 years, 1 month
ldap/servers
by Richard Allen Megginson
ldap/servers/plugins/acl/acllas.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
New commits:
commit 3155d9ce34ca1caec53762237815e4ed7bb59da6
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Apr 26 19:53:15 2010 -0600
Fix too few args for format warning in acllas
Removed unused format arguments from format string
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index 9fbd25b..12cefaf 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -3545,7 +3545,7 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
prefix_len = LDAPS_URL_prefix_len;
} else {
slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acllas__client_match_URL: url %s does not include ldap prefix: %s\n", url);
+ "acllas__client_match_URL: url %s does not have a recognized ldap protocol prefix\n", url);
return ACL_FALSE;
}
rawdn = url + prefix_len; /* ldap(s)://host:port/... or ldap(s):///... */
@@ -3560,7 +3560,7 @@ acllas__client_match_URL (struct acl_pblock *aclpb, char *n_clientdn, char *url
size_t hostport_len = 0;
if (NULL == rawdn) {
slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acllas__client_match_URL: url %s does not include correct ldap prefix: %s\n", url);
+ "acllas__client_match_URL: url %s does not have a valid ldap protocol prefix\n", url);
return ACL_FALSE;
}
hostport_len = ++rawdn - tmpp; /* ldap(s)://host:port/... */
13 years, 1 month
ldap/servers
by Richard Allen Megginson
ldap/servers/slapd/back-ldbm/ancestorid.c | 6 ++++++
1 file changed, 6 insertions(+)
New commits:
commit 4fa2ee84eb3dfdfd202585a59403195b408bbb8f
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Apr 26 17:26:00 2010 -0600
Bug 572018 - Upgrading from 1.2.5 to 1.2.6.a2 deletes userRoot
https://bugzilla.redhat.com/show_bug.cgi?id=572018
Resolves: bug 572018
Bug Description: Upgrading from 1.2.5 to 1.2.6.a2 deletes userRoot
Reviewed by: self
Branch: HEAD
Fix Description: According to the error message, the entry id cannot be
found in the id2entry file. The entry id comes from the parentid index,
which has just been created by the dn2rdn upgradedb process. The entryid
is the key in the parentid index. I'm not sure how this can happen -
either the parentid contains the id of an entry that does not exist, or
the entryid was somehow corrupted. I've added some additional debugging
statements to try to narrow this down.
Platforms tested: RHEL5 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/back-ldbm/ancestorid.c b/ldap/servers/slapd/back-ldbm/ancestorid.c
index 768dc6e..1337e03 100644
--- a/ldap/servers/slapd/back-ldbm/ancestorid.c
+++ b/ldap/servers/slapd/back-ldbm/ancestorid.c
@@ -464,6 +464,9 @@ static int ldbm_ancestorid_new_idl_create_index(backend *be)
while (1) {
ret = ldbm_parentid(be, txn, id, &parentid);
if (ret != 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, sourcefile,
+ "Error: ldbm_parentid on node index [" ID_FMT "] of [" ID_FMT "]\n",
+ nids, nodes->b_nids);
idl_free(children);
goto out;
}
@@ -552,6 +555,9 @@ static int ldbm_parentid(backend *be, DB_TXN *txn, ID id, ID *ppid)
ret = db->get(db, txn, &key, &data, 0);
if (ret != 0) {
ldbm_nasty(sourcefile,13110,ret);
+ slapi_log_error(SLAPI_LOG_FATAL, sourcefile,
+ "Error: unable to find entry id [" ID_FMT "] (original [" ID_FMT "])"
+ " in id2entry\n", stored_id, id);
goto out;
}
13 years, 1 month