ldap/servers
by Noriko Hosoi
ldap/servers/slapd/pw.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 6ada149c42dbcce727662927129ae55832def5a0
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Mar 21 16:44:16 2011 -0700
Bug 681015 - RFE: allow fine grained password policy duration attributes in days, hours, minutes, as well
https://bugzilla.redhat.com/show_bug.cgi?id=681015
Description: passwordLockoutDuration attribute is not working
with the fine grain password policy. The code to parse the
value of passwordlockoutduration was missing. This patch
adds it.
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
index 2992623..7c6210b 100644
--- a/ldap/servers/slapd/pw.c
+++ b/ldap/servers/slapd/pw.c
@@ -1673,7 +1673,7 @@ new_passwdPolicy(Slapi_PBlock *pb, char *dn)
else
if (!strcasecmp(attr_name, "passwordlockoutduration")) {
if ((sval = attr_get_present_values(attr))) {
- pwdpolicy->pw_lockduration = slapi_value_get_long(*sval);
+ pwdpolicy->pw_lockduration = slapi_value_get_timelong(*sval);
}
}
else
13 years, 1 month
Branch '389-ds-base-1.2.8' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/back-ldbm/import-threads.c | 52 ++++++++++++++++--
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 24 +++++++-
ldap/servers/slapd/entry.c | 75 ++++++++++++++++++++++++--
ldap/servers/slapd/rdn.c | 36 ++++++++++++
ldap/servers/slapd/slap.h | 3 +
ldap/servers/slapd/slapi-plugin.h | 7 ++
6 files changed, 189 insertions(+), 8 deletions(-)
New commits:
commit 2ba240b48dbae4a49d194f7a4ebc59fb0ad3d908
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Mar 17 11:21:19 2011 -0700
Bug 684996 - Exported tombstone cannot be imported correctly
https://bugzilla.redhat.com/show_bug.cgi?id=684996
Description: When nsslapd-subtree-rename-switch is on,
a tombstone entry has a special RDN which looks like this:
nsuniqueid=042d8081-...-ca8fe9f7,<original_leaf_rdn>
This special format was not treated properly.
This patch adds the code to handle the special tombstone
RDN, where an internal entry has the above RDN and points
the correct parent entry.
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index d743baa..df070a3 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
@@ -2136,11 +2136,11 @@ import_foreman(void *param)
goto error;
}
- if (! slapi_entry_flag_is_set(fi->entry->ep_entry,
- SLAPI_ENTRY_FLAG_TOMBSTONE)) {
+ if (entryrdn_get_switch() ||
+ !slapi_entry_flag_is_set(fi->entry->ep_entry,
+ SLAPI_ENTRY_FLAG_TOMBSTONE)) {
/*
- * Only check for a parent and add to the entry2dn index if
- * the entry is not a tombstone.
+ * Only check for a parent and add to the entry2dn index
*/
if (job->flags & FLAG_ABORT) {
goto error;
@@ -2865,6 +2865,50 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
job->fifo.c_bsize = 0;
backentry_free(&old_ep);
}
+ /* Is subtree-rename on? And is this a tombstone?
+ * If so, need a special treatment */
+ if (entryrdn_get_switch() &&
+ (ep->ep_entry->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE)) {
+ char *tombstone_rdn =
+ slapi_ch_strdup(slapi_entry_get_dn_const(ep->ep_entry));
+ if ((0 == PL_strncasecmp(tombstone_rdn, SLAPI_ATTR_UNIQUEID,
+ sizeof(SLAPI_ATTR_UNIQUEID) - 1)) &&
+ /* dn starts with "nsuniqueid=" */
+ (NULL == PL_strstr(tombstone_rdn, RUV_STORAGE_ENTRY_UNIQUEID))) {
+ /* and this is not an RUV */
+ char *sepp = PL_strchr(tombstone_rdn, ',');
+ /* dn looks like this:
+ * nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser,o=abc.com
+ * create a new srdn for the original dn
+ * uid=tuser,o=abc.com
+ */
+ if (sepp) {
+ Slapi_RDN mysrdn = {0};
+ if (slapi_rdn_init_all_dn(&mysrdn, sepp + 1)) {
+ slapi_log_error(SLAPI_LOG_FATAL, "bulk_import_queue",
+ "Failed to convert DN %s to RDN\n", sepp + 1);
+ slapi_ch_free_string(&tombstone_rdn);
+ /* entry is released in the frontend on failure*/
+ backentry_clear_entry(ep);
+ backentry_free( &ep ); /* release the backend wrapper */
+ PR_Unlock(job->wire_lock);
+ return -1;
+ }
+ sepp = PL_strchr(sepp + 1, ',');
+ if (sepp) {
+ Slapi_RDN *srdn = slapi_entry_get_srdn(ep->ep_entry);
+ /* nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser, */
+ /* ^ */
+ *sepp = '\0';
+ slapi_rdn_replace_rdn(&mysrdn, tombstone_rdn);
+ slapi_rdn_done(srdn);
+ slapi_entry_set_srdn(ep->ep_entry, &mysrdn);
+ slapi_rdn_done(&mysrdn);
+ }
+ }
+ }
+ slapi_ch_free_string(&tombstone_rdn);
+ }
newesize = (slapi_entry_size(ep->ep_entry) + sizeof(struct backentry));
if (newesize > job->fifo.bsize) { /* entry too big */
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index ccad8e6..fd7934a 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -254,6 +254,28 @@ int add_op_attrs(Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *ep,
slapi_sdn_set_dn_byval(&sdn, pdn);
err = entryrdn_index_read(be, &sdn, &pid, NULL);
slapi_sdn_done(&sdn);
+ if (DB_NOTFOUND == err) {
+ /*
+ * Could be a tombstone. E.g.,
+ * nsuniqueid=042d8081-..-ca8fe9f7,uid=tuser,o=abc,com
+ * If so, need to get the grandparent of the leaf.
+ */
+ if (slapi_entry_flag_is_set(ep->ep_entry,
+ SLAPI_ENTRY_FLAG_TOMBSTONE)) {
+ char *ppdn = slapi_dn_parent(pdn);
+ slapi_ch_free_string(&pdn);
+ if (NULL == ppdn) {
+ if (NULL != status) {
+ *status = IMPORT_ADD_OP_ATTRS_NO_PARENT;
+ goto next;
+ }
+ }
+ pdn = ppdn;
+ slapi_sdn_set_dn_byval(&sdn, pdn);
+ err = entryrdn_index_read(be, &sdn, &pid, NULL);
+ slapi_sdn_done(&sdn);
+ }
+ }
if (err) {
if (DB_NOTFOUND != err && 1 != err) {
LDAPDebug1Arg( LDAP_DEBUG_ANY, "database error %d\n", err );
@@ -291,7 +313,7 @@ int add_op_attrs(Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *ep,
*status = IMPORT_ADD_OP_ATTRS_NO_PARENT;
}
}
-
+next:
/* Get rid of attributes you're not allowed to specify yourself */
slapi_entry_delete_values( ep->ep_entry, hassubordinates, NULL );
slapi_entry_delete_values( ep->ep_entry, numsubordinates, NULL );
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index 33ac468..9e0b57f 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -61,6 +61,9 @@
#define DELETED_VALUE_STRING ";deleted"
#define DELETED_VALUE_STRSIZE 8 /* sizeof(";deleted") */
+/* a helper function to set special rdn to a tombstone entry */
+static int _entry_set_tombstone_rdn(Slapi_Entry *e, char *normdn);
+
/*
* An attribute name is of the form 'basename[;option]'.
* The state informaion is encoded in options. For example:
@@ -519,6 +522,18 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
/* release read lock of name2asi, per-entry lock */
attr_syntax_unlock_read();
+ /* If this is a tombstone, it requires a special treatment for rdn. */
+ if (e->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE) {
+ /* tombstone */
+ if (_entry_set_tombstone_rdn(e, slapi_entry_get_dn_const(e))) {
+ LDAPDebug1Arg( LDAP_DEBUG_TRACE, "str2entry_fast: "
+ "tombstone entry has badly formatted dn: %s\n",
+ slapi_entry_get_dn_const(e) );
+ slapi_entry_free( e ); e = NULL;
+ goto done;
+ }
+ }
+
/* check to make sure there was a dn: line */
if ( slapi_entry_get_dn_const(e)==NULL ) {
if (!(SLAPI_STR2ENTRY_INCLUDE_VERSION_STR & flags))
@@ -807,7 +822,7 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
normdn = slapi_create_dn_string("%s", rawdn);
if (NULL == normdn) {
LDAPDebug1Arg(LDAP_DEBUG_TRACE,
- "str2entry_fast: Invalid DN: %s\n", rawdn);
+ "str2entry_dupcheck: Invalid DN: %s\n", rawdn);
slapi_entry_free( e );
if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
csn_free(&attributedeletioncsn);
@@ -1221,6 +1236,17 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
/* release read lock of name2asi, per-entry lock */
attr_syntax_unlock_read();
+ /* If this is a tombstone, it requires a special treatment for rdn. */
+ if (e->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE) {
+ /* tombstone */
+ if (_entry_set_tombstone_rdn(e, slapi_entry_get_dn_const(e))) {
+ LDAPDebug1Arg( LDAP_DEBUG_TRACE, "str2entry_dupcheck: "
+ "tombstone entry has badly formatted dn: %s\n",
+ slapi_entry_get_dn_const(e) );
+ slapi_entry_free( e ); e = NULL;
+ goto free_and_return;
+ }
+ }
/* Add the RDN values, if asked, and if not already present */
if ( flags & SLAPI_STR2ENTRY_ADDRDNVALS ) {
@@ -1974,8 +2000,8 @@ slapi_entry_size(Slapi_Entry *e)
if (e->e_uniqueid) size += strlen(e->e_uniqueid) + 1;
if (e->e_dncsnset) size += csnset_size(e->e_dncsnset);
if (e->e_maxcsn) size += sizeof( CSN );
- size += slapi_dn_size(&e->e_sdn); /* covers rdn format,
- since (rdn length < dn length) */
+ size += slapi_dn_size(&e->e_sdn);
+ size += slapi_rdn_get_size(&e->e_srdn);
size += slapi_attrlist_size(e->e_attrs);
if (e->e_deleted_attrs) size += slapi_attrlist_size(e->e_deleted_attrs);
if (e->e_virtual_attrs) size += slapi_attrlist_size(e->e_virtual_attrs);
@@ -3830,3 +3856,46 @@ out:
return rval;
}
+
+/* a helper function to set special rdn to a tombstone entry */
+/* Since this a tombstone, it requires a special treatment for rdn*/
+static int
+_entry_set_tombstone_rdn(Slapi_Entry *e, char *normdn)
+{
+ int rc = 0;
+ char *tombstone_rdn = slapi_ch_strdup(normdn);
+ if ((0 == PL_strncasecmp(tombstone_rdn, SLAPI_ATTR_UNIQUEID,
+ sizeof(SLAPI_ATTR_UNIQUEID) - 1)) &&
+ (NULL == PL_strstr(tombstone_rdn, RUV_STORAGE_ENTRY_UNIQUEID))) {
+ /* dn starts with "nsuniqueid=" and this is not an RUV */
+ char *sepp = PL_strchr(tombstone_rdn, ',');
+ /* dn looks like this:
+ * nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser,o=abc.com
+ * create a new srdn for the original dn
+ * uid=tuser,o=abc.com
+ */
+ if (sepp) {
+ Slapi_RDN mysrdn = {0};
+ rc = slapi_rdn_init_all_dn(&mysrdn, sepp + 1);
+ if (rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "str2entry",
+ "Failed to convert DN %s to RDN\n", sepp + 1);
+ goto bail;
+ }
+ sepp = PL_strchr(sepp + 1, ',');
+ if (sepp) {
+ Slapi_RDN *srdn = slapi_entry_get_srdn(e);
+ /* nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser, */
+ /* ^ */
+ *sepp = '\0';
+ slapi_rdn_replace_rdn(&mysrdn, tombstone_rdn);
+ slapi_rdn_done(srdn);
+ slapi_entry_set_srdn(e, &mysrdn);
+ slapi_rdn_done(&mysrdn);
+ }
+ }
+ }
+bail:
+ slapi_ch_free_string(&tombstone_rdn);
+ return rc;
+}
diff --git a/ldap/servers/slapd/rdn.c b/ldap/servers/slapd/rdn.c
index 39b40bd..e8b7915 100644
--- a/ldap/servers/slapd/rdn.c
+++ b/ldap/servers/slapd/rdn.c
@@ -997,3 +997,39 @@ slapi_rdn_partial_dup(Slapi_RDN *from, Slapi_RDN **to, int rdnidx)
(*to)->all_nrdns = charray_dup(&(from->all_nrdns[rdnidx]));
return 0;
}
+
+size_t
+slapi_rdn_get_size(Slapi_RDN *srdn)
+{
+ size_t sz = 0;
+ char **ptr;
+
+ if (!srdn) {
+ goto bail;
+ }
+ sz = sizeof(Slapi_RDN);
+ if (srdn->rdn) {
+ sz += strlen(srdn->rdn) + 1;
+ }
+ if (srdn->nrdn) {
+ sz += strlen(srdn->nrdn) + 1;
+ }
+ if (srdn->rdns) {
+ for (ptr = srdn->rdns; ptr && *ptr; ptr++) {
+ sz += strlen(*ptr) + 1;
+ }
+ }
+ if (srdn->all_rdns) {
+ for (ptr = srdn->all_rdns; ptr && *ptr; ptr++) {
+ sz += strlen(*ptr) + 1;
+ }
+ }
+ if (srdn->all_nrdns) {
+ for (ptr = srdn->all_nrdns; ptr && *ptr; ptr++) {
+ sz += strlen(*ptr) + 1;
+ }
+ }
+bail:
+ return sz;
+}
+
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index a19e5c8..b3728d3 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -2259,4 +2259,7 @@ extern char *attr_dataversion;
#define LDAP_VIRTUAL_LIST_VIEW_ERROR 0x4C /* 76 */
#endif
+/* copied from replication/repl5.h */
+#define RUV_STORAGE_ENTRY_UNIQUEID "ffffffff-ffffffff-ffffffff-ffffffff"
+
#endif /* _slap_h_ */
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 8613c60..f0be0a6 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -3071,6 +3071,13 @@ int slapi_rdn_replace_rdn(Slapi_RDN *srdn, char *new_rdn);
*/
int slapi_rdn_partial_dup(Slapi_RDN *from, Slapi_RDN **to, int idx);
+/**
+ * Return the size of the RDN
+ *
+ * \param srdn A pointer to Slapi_RDN to calculate the size
+ * \return The size of the given RDN.
+ */
+size_t slapi_rdn_get_size(Slapi_RDN *srdn);
/*
* utility routines for dealing with DNs
13 years, 1 month
6 commits - ldap/servers
by Nathan Kinder
ldap/servers/slapd/entry.c | 6 +++---
ldap/servers/slapd/mapping_tree.c | 2 +-
ldap/servers/slapd/schema.c | 2 +-
ldap/servers/slapd/vattr.c | 8 ++++----
4 files changed, 9 insertions(+), 9 deletions(-)
New commits:
commit 9d5d73c6b617a4caddd36cbe0085995930b928e0
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Thu Mar 17 09:32:01 2011 -0700
Bug 688341 - (cov#10702) Fix Coverity code maintainability issues
We are computing the size of memory needed by using the incorrect
pointer type.
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index 898fe93..c511d1f 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -1535,7 +1535,7 @@ add_internal_mapping_tree_node(const char *subtree, Slapi_Backend *be, mapping_t
{
Slapi_DN *dn;
mapping_tree_node *node;
- backend ** be_list = (backend **) slapi_ch_malloc(sizeof(backend **));
+ backend ** be_list = (backend **) slapi_ch_malloc(sizeof(backend *));
be_list[0] = be;
commit dcedbebf2db08be32c7ee4aad722f51d2c0d78ee
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Thu Mar 17 09:24:49 2011 -0700
Bug 688341 - (cov#10703) Fix Coverity code maintainability issues
We are computing the size of memory needed by using the incorrect
pointer type.
diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
index 72f98f8..e221096 100644
--- a/ldap/servers/slapd/vattr.c
+++ b/ldap/servers/slapd/vattr.c
@@ -1704,9 +1704,9 @@ int vattr_call_sp_get_batch_values(vattr_sp_handle *handle, vattr_context *c, Sl
else
{
/* make our args look like the simple non-batched case */
- *results = (Slapi_ValueSet**)slapi_ch_calloc(2, sizeof(*results)); /* 2 for null terminated list */
+ *results = (Slapi_ValueSet**)slapi_ch_calloc(2, sizeof(**results)); /* 2 for null terminated list */
*type_name_disposition = (int *)slapi_ch_calloc(2, sizeof(*type_name_disposition));
- *actual_type_name = (char**)slapi_ch_calloc(2, sizeof(*actual_type_name));
+ *actual_type_name = (char**)slapi_ch_calloc(2, sizeof(**actual_type_name));
ret =((handle->sp->sp_get_fn)(handle,c,e,*type,*results,*type_name_disposition,*actual_type_name,flags,buffer_flags, hint));
if (ret)
commit 1c4d25369dd749a13a71f60af4c3d43326e9e4a0
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Thu Mar 17 09:17:22 2011 -0700
Bug 688341 - (cov#10704,10705) Fix Coverity code maintainability issues
We are computing the size of memory needed by using the incorrect
pointer type.
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index ceea429..c628ba5 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -2419,11 +2419,11 @@ slapi_entry_vattrcache_find_values_and_type_ex( const Slapi_Entry *e,
char *vattr_type=NULL;
r= SLAPI_ENTRY_VATTR_RESOLVED_EXISTS;
- *results = (Slapi_ValueSet**)slapi_ch_calloc(1, sizeof(*results));
+ *results = (Slapi_ValueSet**)slapi_ch_calloc(1, sizeof(**results));
**results = valueset_dup(&(tmp_attr->a_present_values));
*actual_type_name =
- (char**)slapi_ch_malloc(sizeof(*actual_type_name));
+ (char**)slapi_ch_malloc(sizeof(**actual_type_name));
slapi_attr_get_type( tmp_attr, &vattr_type );
**actual_type_name = slapi_ch_strdup(vattr_type);
commit 5004279ad887abc9d2164c06f13d669731e94853
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Thu Mar 17 08:45:22 2011 -0700
Bug 688341 - (cov#10706,10707) Fix Coverity code maintainability issues
We are calling computing the size of memory needed by calculating
the number of pointers to put in the array, but we are not using
the correct pointer type.
diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
index 4957132..72f98f8 100644
--- a/ldap/servers/slapd/vattr.c
+++ b/ldap/servers/slapd/vattr.c
@@ -983,9 +983,9 @@ int slapi_vattr_namespace_values_get_sp(vattr_context *c,
if(attr_count > 0)
{
- *results = (Slapi_ValueSet**)slapi_ch_calloc(1, sizeof(*results) * attr_count);
+ *results = (Slapi_ValueSet**)slapi_ch_calloc(1, sizeof(**results) * attr_count);
*type_name_disposition = (int *)slapi_ch_malloc(sizeof(**type_name_disposition) * attr_count);
- *actual_type_name = (char**)slapi_ch_malloc(sizeof(*actual_type_name) * attr_count);
+ *actual_type_name = (char**)slapi_ch_malloc(sizeof(**actual_type_name) * attr_count);
/* For attributes which are in the entry, we just need to get to the Slapi_Attr structure and yank out the slapi_value_set
structure. We either return a pointer directly to it, or we copy it, depending upon whether the caller asked us to try to
commit 8786f0e05e2cc6a2f31b22357e9c7d269d186ccd
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Wed Mar 16 14:38:11 2011 -0700
Bug 688341 - (cov#10708) Fix Coverity code maintainability issues
We are calling computing the size of memory needed be calculating
the number of Slapi_Value pointers to put inthe array, but we
are multiplying that by the size of "Slapi_Value **" when it should
be the size of "Slapi_Value *".
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
index 14f3e76..fa90d7f 100644
--- a/ldap/servers/slapd/schema.c
+++ b/ldap/servers/slapd/schema.c
@@ -4805,7 +4805,7 @@ va_expand_one_oc( const char *dn, Slapi_Value ***vap, const char *ocs )
}
newva = (Slapi_Value **)slapi_ch_realloc( (char *)*vap,
- ( i + 2 )*sizeof(Slapi_Value **));
+ ( i + 2 )*sizeof(Slapi_Value *));
newva[i] = slapi_value_new_string(sup_oc->oc_name);
newva[i+1] = NULL;
commit 72506b80ec141909d468e587252b55f3d9b62cb5
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Wed Mar 16 13:16:23 2011 -0700
Bug 688341 - (cov#10709) Fix Coverity code maintainability issues
The third argument to qsort() is incorrect. We should be specifying
the size of "Slapi_Entry *", not "Slapi_Entry **".
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index 9e0b57f..ceea429 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -3697,7 +3697,7 @@ slapi_entries_diff(Slapi_Entry **old_entries, Slapi_Entry **curr_entries,
for (cep = curr_entries; cep != NULL && *cep != NULL; cep++)
;
- qsort(curr_entries, cep - curr_entries, sizeof(Slapi_Entry **),
+ qsort(curr_entries, cep - curr_entries, sizeof(Slapi_Entry *),
entry_cmp_with_dn);
#ifdef ENTRY_DIFF_DEBUG
13 years, 1 month
ldap/servers
by Nathan Kinder
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
New commits:
commit bd148df8221f798463e060c66a2b7311c0778353
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Tue Mar 15 14:35:58 2011 -0700
Bug 687974 - (cov#10715) Fix Coverity uninitialized variables issues
The ldif2ldbm code can return an uninitialized integer if it runs
into a problem starting the dblayer to get the next USN. This block
of code should use the ret variable to capture the result of starting
the dblayer to ensure it is set before it gets returned.
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index fd7934a..cf0f539 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -708,21 +708,21 @@ int ldbm_back_ldif2ldbm( Slapi_PBlock *pb )
* initialize the USN counter to get the next USN */
if (plugin_enabled("USN", li->li_identity)) {
/* close immediately; no need to run db threads */
- int rc = dblayer_start(li,
+ ret = dblayer_start(li,
DBLAYER_NORMAL_MODE|DBLAYER_NO_DBTHREADS_MODE);
- if (rc) {
+ if (ret) {
LDAPDebug2Args(LDAP_DEBUG_ANY,
"ldbm_back_ldif2ldbm: dblayer_start failed! %s (%d)\n",
- dblayer_strerror(rc), rc);
+ dblayer_strerror(ret), ret);
goto fail;
}
/* initialize the USN counter */
ldbm_usn_init(li);
- rc = dblayer_close(li, DBLAYER_NORMAL_MODE);
- if (rc) {
+ ret = dblayer_close(li, DBLAYER_NORMAL_MODE);
+ if (ret != 0) {
LDAPDebug2Args(LDAP_DEBUG_ANY,
"ldbm_back_ldif2ldbm: dblayer_close failed! %s (%d)\n",
- dblayer_strerror(rc), rc);
+ dblayer_strerror(ret), ret);
}
}
13 years, 1 month
ldap/servers
by Noriko Hosoi
ldap/servers/slapd/back-ldbm/import-threads.c | 52 ++++++++++++++++--
ldap/servers/slapd/back-ldbm/ldif2ldbm.c | 24 +++++++-
ldap/servers/slapd/entry.c | 75 ++++++++++++++++++++++++--
ldap/servers/slapd/rdn.c | 36 ++++++++++++
ldap/servers/slapd/slap.h | 3 +
ldap/servers/slapd/slapi-plugin.h | 7 ++
6 files changed, 189 insertions(+), 8 deletions(-)
New commits:
commit bc40d7bf88c015c18ff6123c400119bd6b9b2966
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Thu Mar 17 11:21:19 2011 -0700
Bug 684996 - Exported tombstone cannot be imported correctly
https://bugzilla.redhat.com/show_bug.cgi?id=684996
Description: When nsslapd-subtree-rename-switch is on,
a tombstone entry has a special RDN which looks like this:
nsuniqueid=042d8081-...-ca8fe9f7,<original_leaf_rdn>
This special format was not treated properly.
This patch adds the code to handle the special tombstone
RDN, where an internal entry has the above RDN and points
the correct parent entry.
diff --git a/ldap/servers/slapd/back-ldbm/import-threads.c b/ldap/servers/slapd/back-ldbm/import-threads.c
index d743baa..df070a3 100644
--- a/ldap/servers/slapd/back-ldbm/import-threads.c
+++ b/ldap/servers/slapd/back-ldbm/import-threads.c
@@ -2136,11 +2136,11 @@ import_foreman(void *param)
goto error;
}
- if (! slapi_entry_flag_is_set(fi->entry->ep_entry,
- SLAPI_ENTRY_FLAG_TOMBSTONE)) {
+ if (entryrdn_get_switch() ||
+ !slapi_entry_flag_is_set(fi->entry->ep_entry,
+ SLAPI_ENTRY_FLAG_TOMBSTONE)) {
/*
- * Only check for a parent and add to the entry2dn index if
- * the entry is not a tombstone.
+ * Only check for a parent and add to the entry2dn index
*/
if (job->flags & FLAG_ABORT) {
goto error;
@@ -2865,6 +2865,50 @@ static int bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
job->fifo.c_bsize = 0;
backentry_free(&old_ep);
}
+ /* Is subtree-rename on? And is this a tombstone?
+ * If so, need a special treatment */
+ if (entryrdn_get_switch() &&
+ (ep->ep_entry->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE)) {
+ char *tombstone_rdn =
+ slapi_ch_strdup(slapi_entry_get_dn_const(ep->ep_entry));
+ if ((0 == PL_strncasecmp(tombstone_rdn, SLAPI_ATTR_UNIQUEID,
+ sizeof(SLAPI_ATTR_UNIQUEID) - 1)) &&
+ /* dn starts with "nsuniqueid=" */
+ (NULL == PL_strstr(tombstone_rdn, RUV_STORAGE_ENTRY_UNIQUEID))) {
+ /* and this is not an RUV */
+ char *sepp = PL_strchr(tombstone_rdn, ',');
+ /* dn looks like this:
+ * nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser,o=abc.com
+ * create a new srdn for the original dn
+ * uid=tuser,o=abc.com
+ */
+ if (sepp) {
+ Slapi_RDN mysrdn = {0};
+ if (slapi_rdn_init_all_dn(&mysrdn, sepp + 1)) {
+ slapi_log_error(SLAPI_LOG_FATAL, "bulk_import_queue",
+ "Failed to convert DN %s to RDN\n", sepp + 1);
+ slapi_ch_free_string(&tombstone_rdn);
+ /* entry is released in the frontend on failure*/
+ backentry_clear_entry(ep);
+ backentry_free( &ep ); /* release the backend wrapper */
+ PR_Unlock(job->wire_lock);
+ return -1;
+ }
+ sepp = PL_strchr(sepp + 1, ',');
+ if (sepp) {
+ Slapi_RDN *srdn = slapi_entry_get_srdn(ep->ep_entry);
+ /* nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser, */
+ /* ^ */
+ *sepp = '\0';
+ slapi_rdn_replace_rdn(&mysrdn, tombstone_rdn);
+ slapi_rdn_done(srdn);
+ slapi_entry_set_srdn(ep->ep_entry, &mysrdn);
+ slapi_rdn_done(&mysrdn);
+ }
+ }
+ }
+ slapi_ch_free_string(&tombstone_rdn);
+ }
newesize = (slapi_entry_size(ep->ep_entry) + sizeof(struct backentry));
if (newesize > job->fifo.bsize) { /* entry too big */
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index ccad8e6..fd7934a 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -254,6 +254,28 @@ int add_op_attrs(Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *ep,
slapi_sdn_set_dn_byval(&sdn, pdn);
err = entryrdn_index_read(be, &sdn, &pid, NULL);
slapi_sdn_done(&sdn);
+ if (DB_NOTFOUND == err) {
+ /*
+ * Could be a tombstone. E.g.,
+ * nsuniqueid=042d8081-..-ca8fe9f7,uid=tuser,o=abc,com
+ * If so, need to get the grandparent of the leaf.
+ */
+ if (slapi_entry_flag_is_set(ep->ep_entry,
+ SLAPI_ENTRY_FLAG_TOMBSTONE)) {
+ char *ppdn = slapi_dn_parent(pdn);
+ slapi_ch_free_string(&pdn);
+ if (NULL == ppdn) {
+ if (NULL != status) {
+ *status = IMPORT_ADD_OP_ATTRS_NO_PARENT;
+ goto next;
+ }
+ }
+ pdn = ppdn;
+ slapi_sdn_set_dn_byval(&sdn, pdn);
+ err = entryrdn_index_read(be, &sdn, &pid, NULL);
+ slapi_sdn_done(&sdn);
+ }
+ }
if (err) {
if (DB_NOTFOUND != err && 1 != err) {
LDAPDebug1Arg( LDAP_DEBUG_ANY, "database error %d\n", err );
@@ -291,7 +313,7 @@ int add_op_attrs(Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *ep,
*status = IMPORT_ADD_OP_ATTRS_NO_PARENT;
}
}
-
+next:
/* Get rid of attributes you're not allowed to specify yourself */
slapi_entry_delete_values( ep->ep_entry, hassubordinates, NULL );
slapi_entry_delete_values( ep->ep_entry, numsubordinates, NULL );
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index 33ac468..9e0b57f 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -61,6 +61,9 @@
#define DELETED_VALUE_STRING ";deleted"
#define DELETED_VALUE_STRSIZE 8 /* sizeof(";deleted") */
+/* a helper function to set special rdn to a tombstone entry */
+static int _entry_set_tombstone_rdn(Slapi_Entry *e, char *normdn);
+
/*
* An attribute name is of the form 'basename[;option]'.
* The state informaion is encoded in options. For example:
@@ -519,6 +522,18 @@ str2entry_fast( const char *rawdn, char *s, int flags, int read_stateinfo )
/* release read lock of name2asi, per-entry lock */
attr_syntax_unlock_read();
+ /* If this is a tombstone, it requires a special treatment for rdn. */
+ if (e->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE) {
+ /* tombstone */
+ if (_entry_set_tombstone_rdn(e, slapi_entry_get_dn_const(e))) {
+ LDAPDebug1Arg( LDAP_DEBUG_TRACE, "str2entry_fast: "
+ "tombstone entry has badly formatted dn: %s\n",
+ slapi_entry_get_dn_const(e) );
+ slapi_entry_free( e ); e = NULL;
+ goto done;
+ }
+ }
+
/* check to make sure there was a dn: line */
if ( slapi_entry_get_dn_const(e)==NULL ) {
if (!(SLAPI_STR2ENTRY_INCLUDE_VERSION_STR & flags))
@@ -807,7 +822,7 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
normdn = slapi_create_dn_string("%s", rawdn);
if (NULL == normdn) {
LDAPDebug1Arg(LDAP_DEBUG_TRACE,
- "str2entry_fast: Invalid DN: %s\n", rawdn);
+ "str2entry_dupcheck: Invalid DN: %s\n", rawdn);
slapi_entry_free( e );
if (freeval) slapi_ch_free_string(&bvvalue.bv_val);
csn_free(&attributedeletioncsn);
@@ -1221,6 +1236,17 @@ str2entry_dupcheck( const char *rawdn, char *s, int flags, int read_stateinfo )
/* release read lock of name2asi, per-entry lock */
attr_syntax_unlock_read();
+ /* If this is a tombstone, it requires a special treatment for rdn. */
+ if (e->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE) {
+ /* tombstone */
+ if (_entry_set_tombstone_rdn(e, slapi_entry_get_dn_const(e))) {
+ LDAPDebug1Arg( LDAP_DEBUG_TRACE, "str2entry_dupcheck: "
+ "tombstone entry has badly formatted dn: %s\n",
+ slapi_entry_get_dn_const(e) );
+ slapi_entry_free( e ); e = NULL;
+ goto free_and_return;
+ }
+ }
/* Add the RDN values, if asked, and if not already present */
if ( flags & SLAPI_STR2ENTRY_ADDRDNVALS ) {
@@ -1974,8 +2000,8 @@ slapi_entry_size(Slapi_Entry *e)
if (e->e_uniqueid) size += strlen(e->e_uniqueid) + 1;
if (e->e_dncsnset) size += csnset_size(e->e_dncsnset);
if (e->e_maxcsn) size += sizeof( CSN );
- size += slapi_dn_size(&e->e_sdn); /* covers rdn format,
- since (rdn length < dn length) */
+ size += slapi_dn_size(&e->e_sdn);
+ size += slapi_rdn_get_size(&e->e_srdn);
size += slapi_attrlist_size(e->e_attrs);
if (e->e_deleted_attrs) size += slapi_attrlist_size(e->e_deleted_attrs);
if (e->e_virtual_attrs) size += slapi_attrlist_size(e->e_virtual_attrs);
@@ -3830,3 +3856,46 @@ out:
return rval;
}
+
+/* a helper function to set special rdn to a tombstone entry */
+/* Since this a tombstone, it requires a special treatment for rdn*/
+static int
+_entry_set_tombstone_rdn(Slapi_Entry *e, char *normdn)
+{
+ int rc = 0;
+ char *tombstone_rdn = slapi_ch_strdup(normdn);
+ if ((0 == PL_strncasecmp(tombstone_rdn, SLAPI_ATTR_UNIQUEID,
+ sizeof(SLAPI_ATTR_UNIQUEID) - 1)) &&
+ (NULL == PL_strstr(tombstone_rdn, RUV_STORAGE_ENTRY_UNIQUEID))) {
+ /* dn starts with "nsuniqueid=" and this is not an RUV */
+ char *sepp = PL_strchr(tombstone_rdn, ',');
+ /* dn looks like this:
+ * nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser,o=abc.com
+ * create a new srdn for the original dn
+ * uid=tuser,o=abc.com
+ */
+ if (sepp) {
+ Slapi_RDN mysrdn = {0};
+ rc = slapi_rdn_init_all_dn(&mysrdn, sepp + 1);
+ if (rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "str2entry",
+ "Failed to convert DN %s to RDN\n", sepp + 1);
+ goto bail;
+ }
+ sepp = PL_strchr(sepp + 1, ',');
+ if (sepp) {
+ Slapi_RDN *srdn = slapi_entry_get_srdn(e);
+ /* nsuniqueid=042d8081-...-ca8fe9f7,uid=tuser, */
+ /* ^ */
+ *sepp = '\0';
+ slapi_rdn_replace_rdn(&mysrdn, tombstone_rdn);
+ slapi_rdn_done(srdn);
+ slapi_entry_set_srdn(e, &mysrdn);
+ slapi_rdn_done(&mysrdn);
+ }
+ }
+ }
+bail:
+ slapi_ch_free_string(&tombstone_rdn);
+ return rc;
+}
diff --git a/ldap/servers/slapd/rdn.c b/ldap/servers/slapd/rdn.c
index 39b40bd..e8b7915 100644
--- a/ldap/servers/slapd/rdn.c
+++ b/ldap/servers/slapd/rdn.c
@@ -997,3 +997,39 @@ slapi_rdn_partial_dup(Slapi_RDN *from, Slapi_RDN **to, int rdnidx)
(*to)->all_nrdns = charray_dup(&(from->all_nrdns[rdnidx]));
return 0;
}
+
+size_t
+slapi_rdn_get_size(Slapi_RDN *srdn)
+{
+ size_t sz = 0;
+ char **ptr;
+
+ if (!srdn) {
+ goto bail;
+ }
+ sz = sizeof(Slapi_RDN);
+ if (srdn->rdn) {
+ sz += strlen(srdn->rdn) + 1;
+ }
+ if (srdn->nrdn) {
+ sz += strlen(srdn->nrdn) + 1;
+ }
+ if (srdn->rdns) {
+ for (ptr = srdn->rdns; ptr && *ptr; ptr++) {
+ sz += strlen(*ptr) + 1;
+ }
+ }
+ if (srdn->all_rdns) {
+ for (ptr = srdn->all_rdns; ptr && *ptr; ptr++) {
+ sz += strlen(*ptr) + 1;
+ }
+ }
+ if (srdn->all_nrdns) {
+ for (ptr = srdn->all_nrdns; ptr && *ptr; ptr++) {
+ sz += strlen(*ptr) + 1;
+ }
+ }
+bail:
+ return sz;
+}
+
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index a19e5c8..b3728d3 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -2259,4 +2259,7 @@ extern char *attr_dataversion;
#define LDAP_VIRTUAL_LIST_VIEW_ERROR 0x4C /* 76 */
#endif
+/* copied from replication/repl5.h */
+#define RUV_STORAGE_ENTRY_UNIQUEID "ffffffff-ffffffff-ffffffff-ffffffff"
+
#endif /* _slap_h_ */
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 8613c60..f0be0a6 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -3071,6 +3071,13 @@ int slapi_rdn_replace_rdn(Slapi_RDN *srdn, char *new_rdn);
*/
int slapi_rdn_partial_dup(Slapi_RDN *from, Slapi_RDN **to, int idx);
+/**
+ * Return the size of the RDN
+ *
+ * \param srdn A pointer to Slapi_RDN to calculate the size
+ * \return The size of the given RDN.
+ */
+size_t slapi_rdn_get_size(Slapi_RDN *srdn);
/*
* utility routines for dealing with DNs
13 years, 1 month
Branch '389-ds-base-1.2.8' - ldap/servers
by Richard Allen Megginson
ldap/servers/slapd/saslbind.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
New commits:
commit fb7547ffeb15a92027c64cba207d134f3e8a0eae
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Mar 9 18:27:05 2011 -0700
Bug 683250 - slapd crashing when traffic replayed
https://bugzilla.redhat.com/show_bug.cgi?id=683250
Resolves: bug 683250
Bug Description: slapd crashing when traffic replayed
Reviewed by: nkinder (Thanks!)
Branch: 389-ds-base-1.2.8
Fix Description: There was a race condition in the saslbind.c code if multiple
threads and multiple connections were doing gssapi at the same time, with
different points of failure. The solution is to increase the size of the
mutex section in saslbind.c so that all access of pb->pb_conn are protected.
Thanks to Jeremy Mates <jmates(a)uw.edu> for finding this issue and for his
assistance in testing.
Platforms tested: RHEL6 x86_64, Fedora 14 i386
Flag Day: no
Doc impact: no
(cherry picked from commit 2c8637c242ace8a7d61474913c861e336a7809cd)
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
index 5204b56..f9f51df 100644
--- a/ldap/servers/slapd/saslbind.c
+++ b/ldap/servers/slapd/saslbind.c
@@ -729,26 +729,26 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
/*
* Determine whether a given sasl mechanism is supported by
* this sasl connection. Returns true/false.
+ * NOTE: caller must lock pb->pb_conn->c_mutex
*/
static int
-ids_sasl_mech_supported(Slapi_PBlock *pb, sasl_conn_t *sasl_conn, const char *mech)
+ids_sasl_mech_supported(Slapi_PBlock *pb, const char *mech)
{
int i, ret = 0;
char **mechs;
char *dupstr;
const char *str;
int sasl_result = 0;
+ sasl_conn_t *sasl_conn = (sasl_conn_t *)pb->pb_conn->c_sasl_conn;
LDAPDebug( LDAP_DEBUG_TRACE, "=> ids_sasl_mech_supported\n", 0, 0, 0 );
- /* sasl_listmech is not thread-safe, so we lock here */
- PR_Lock(pb->pb_conn->c_mutex);
+ /* sasl_listmech is not thread-safe - caller must lock pb_conn */
sasl_result = sasl_listmech(sasl_conn,
NULL, /* username */
"", ",", "",
&str, NULL, NULL);
- PR_Unlock(pb->pb_conn->c_mutex);
if (sasl_result != SASL_OK) {
return 0;
}
@@ -800,13 +800,13 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
PR_ASSERT(pb);
PR_ASSERT(pb->pb_conn);
- PR_Lock(pb->pb_conn->c_mutex);
+ PR_Lock(pb->pb_conn->c_mutex); /* BIG LOCK */
continuing = pb->pb_conn->c_flags & CONN_FLAG_SASL_CONTINUE;
pb->pb_conn->c_flags &= ~CONN_FLAG_SASL_CONTINUE; /* reset flag */
sasl_conn = (sasl_conn_t*)pb->pb_conn->c_sasl_conn;
- PR_Unlock(pb->pb_conn->c_mutex);
if (sasl_conn == NULL) {
+ PR_Unlock(pb->pb_conn->c_mutex);
send_ldap_result( pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL,
"sasl library unavailable", 0, NULL );
return;
@@ -820,10 +820,10 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
/* Work around a bug in the sasl library. We've told the
* library that CRAM-MD5 is disabled, but it gives us a
- * different error code to SASL_NOMECH.
+ * different error code to SASL_NOMECH. Must be called
+ * while holding the pb_conn lock
*/
- /* richm - this locks and unlocks pb->pb_conn */
- if (!ids_sasl_mech_supported(pb, sasl_conn, mech)) {
+ if (!ids_sasl_mech_supported(pb, mech)) {
rc = SASL_NOMECH;
goto sasl_check_result;
}
@@ -860,7 +860,6 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
* using the new mechanism. We also need to do this if the
* mechanism changed in the middle of the SASL authentication
* process. */
- PR_Lock(pb->pb_conn->c_mutex);
if ((pb->pb_conn->c_flags & CONN_FLAG_SASL_COMPLETE) || continuing) {
Slapi_Operation *operation;
slapi_pblock_get( pb, SLAPI_OPERATION, &operation);
@@ -882,11 +881,10 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
if (sasl_conn == NULL) {
send_ldap_result( pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL,
"sasl library unavailable", 0, NULL );
- PR_Unlock(pb->pb_conn->c_mutex);
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
return;
}
}
- PR_Unlock(pb->pb_conn->c_mutex);
rc = sasl_server_start(sasl_conn, mech,
cred->bv_val, cred->bv_len,
@@ -899,6 +897,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
/* retrieve the authenticated username */
if (sasl_getprop(sasl_conn, SASL_USERNAME,
(const void**)&username) != SASL_OK) {
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
"could not obtain sasl username", 0, NULL);
break;
@@ -919,6 +918,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
}
}
if (dn == NULL) {
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
"could not get auth dn from sasl", 0, NULL);
break;
@@ -933,8 +933,6 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
*ssfp = 0;
}
- /* this is stuff we have to do inside the conn mutex */
- PR_Lock(pb->pb_conn->c_mutex);
/* Set a flag to signify that sasl bind is complete */
pb->pb_conn->c_flags |= CONN_FLAG_SASL_COMPLETE;
/* note - we set this here in case there are pre-bind
@@ -952,7 +950,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
bind_credentials_set_nolock(pb->pb_conn, authtype, dn,
NULL, NULL, NULL, bind_target_entry);
- PR_Unlock(pb->pb_conn->c_mutex);
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
if (plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) != 0){
break;
@@ -1042,6 +1040,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
case SASL_CONTINUE: /* another step needed */
pb->pb_conn->c_flags |= CONN_FLAG_SASL_CONTINUE;
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
if (plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) != 0){
break;
@@ -1063,6 +1062,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
case SASL_NOMECH:
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL,
"sasl mechanism not supported", 0, NULL);
break;
@@ -1070,6 +1070,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
default: /* other error */
errstr = sasl_errdetail(sasl_conn);
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
(char*)errstr, 0, NULL);
break;
13 years, 1 month
ldap/servers
by Richard Allen Megginson
ldap/servers/slapd/saslbind.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
New commits:
commit 2c8637c242ace8a7d61474913c861e336a7809cd
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Mar 9 18:27:05 2011 -0700
Bug 683250 - slapd crashing when traffic replayed
https://bugzilla.redhat.com/show_bug.cgi?id=683250
Resolves: bug 683250
Bug Description: slapd crashing when traffic replayed
Reviewed by: nkinder (Thanks!)
Branch: master
Fix Description: There was a race condition in the saslbind.c code if multiple
threads and multiple connections were doing gssapi at the same time, with
different points of failure. The solution is to increase the size of the
mutex section in saslbind.c so that all access of pb->pb_conn are protected.
Thanks to Jeremy Mates <jmates(a)uw.edu> for finding this issue and for his
assistance in testing.
Platforms tested: RHEL6 x86_64, Fedora 14 i386
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
index 5204b56..f9f51df 100644
--- a/ldap/servers/slapd/saslbind.c
+++ b/ldap/servers/slapd/saslbind.c
@@ -729,26 +729,26 @@ char **ids_sasl_listmech(Slapi_PBlock *pb)
/*
* Determine whether a given sasl mechanism is supported by
* this sasl connection. Returns true/false.
+ * NOTE: caller must lock pb->pb_conn->c_mutex
*/
static int
-ids_sasl_mech_supported(Slapi_PBlock *pb, sasl_conn_t *sasl_conn, const char *mech)
+ids_sasl_mech_supported(Slapi_PBlock *pb, const char *mech)
{
int i, ret = 0;
char **mechs;
char *dupstr;
const char *str;
int sasl_result = 0;
+ sasl_conn_t *sasl_conn = (sasl_conn_t *)pb->pb_conn->c_sasl_conn;
LDAPDebug( LDAP_DEBUG_TRACE, "=> ids_sasl_mech_supported\n", 0, 0, 0 );
- /* sasl_listmech is not thread-safe, so we lock here */
- PR_Lock(pb->pb_conn->c_mutex);
+ /* sasl_listmech is not thread-safe - caller must lock pb_conn */
sasl_result = sasl_listmech(sasl_conn,
NULL, /* username */
"", ",", "",
&str, NULL, NULL);
- PR_Unlock(pb->pb_conn->c_mutex);
if (sasl_result != SASL_OK) {
return 0;
}
@@ -800,13 +800,13 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
PR_ASSERT(pb);
PR_ASSERT(pb->pb_conn);
- PR_Lock(pb->pb_conn->c_mutex);
+ PR_Lock(pb->pb_conn->c_mutex); /* BIG LOCK */
continuing = pb->pb_conn->c_flags & CONN_FLAG_SASL_CONTINUE;
pb->pb_conn->c_flags &= ~CONN_FLAG_SASL_CONTINUE; /* reset flag */
sasl_conn = (sasl_conn_t*)pb->pb_conn->c_sasl_conn;
- PR_Unlock(pb->pb_conn->c_mutex);
if (sasl_conn == NULL) {
+ PR_Unlock(pb->pb_conn->c_mutex);
send_ldap_result( pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL,
"sasl library unavailable", 0, NULL );
return;
@@ -820,10 +820,10 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
/* Work around a bug in the sasl library. We've told the
* library that CRAM-MD5 is disabled, but it gives us a
- * different error code to SASL_NOMECH.
+ * different error code to SASL_NOMECH. Must be called
+ * while holding the pb_conn lock
*/
- /* richm - this locks and unlocks pb->pb_conn */
- if (!ids_sasl_mech_supported(pb, sasl_conn, mech)) {
+ if (!ids_sasl_mech_supported(pb, mech)) {
rc = SASL_NOMECH;
goto sasl_check_result;
}
@@ -860,7 +860,6 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
* using the new mechanism. We also need to do this if the
* mechanism changed in the middle of the SASL authentication
* process. */
- PR_Lock(pb->pb_conn->c_mutex);
if ((pb->pb_conn->c_flags & CONN_FLAG_SASL_COMPLETE) || continuing) {
Slapi_Operation *operation;
slapi_pblock_get( pb, SLAPI_OPERATION, &operation);
@@ -882,11 +881,10 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
if (sasl_conn == NULL) {
send_ldap_result( pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL,
"sasl library unavailable", 0, NULL );
- PR_Unlock(pb->pb_conn->c_mutex);
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
return;
}
}
- PR_Unlock(pb->pb_conn->c_mutex);
rc = sasl_server_start(sasl_conn, mech,
cred->bv_val, cred->bv_len,
@@ -899,6 +897,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
/* retrieve the authenticated username */
if (sasl_getprop(sasl_conn, SASL_USERNAME,
(const void**)&username) != SASL_OK) {
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
"could not obtain sasl username", 0, NULL);
break;
@@ -919,6 +918,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
}
}
if (dn == NULL) {
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
"could not get auth dn from sasl", 0, NULL);
break;
@@ -933,8 +933,6 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
*ssfp = 0;
}
- /* this is stuff we have to do inside the conn mutex */
- PR_Lock(pb->pb_conn->c_mutex);
/* Set a flag to signify that sasl bind is complete */
pb->pb_conn->c_flags |= CONN_FLAG_SASL_COMPLETE;
/* note - we set this here in case there are pre-bind
@@ -952,7 +950,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
bind_credentials_set_nolock(pb->pb_conn, authtype, dn,
NULL, NULL, NULL, bind_target_entry);
- PR_Unlock(pb->pb_conn->c_mutex);
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
if (plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) != 0){
break;
@@ -1042,6 +1040,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
case SASL_CONTINUE: /* another step needed */
pb->pb_conn->c_flags |= CONN_FLAG_SASL_CONTINUE;
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
if (plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) != 0){
break;
@@ -1063,6 +1062,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
case SASL_NOMECH:
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL,
"sasl mechanism not supported", 0, NULL);
break;
@@ -1070,6 +1070,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
default: /* other error */
errstr = sasl_errdetail(sasl_conn);
+ PR_Unlock(pb->pb_conn->c_mutex); /* BIG LOCK */
send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
(char*)errstr, 0, NULL);
break;
13 years, 1 month
Branch '389-ds-base-1.2.8' - ldap/servers
by Noriko Hosoi
ldap/servers/plugins/replication/repl5_agmt.c | 35 ++++++++++++++++++--
ldap/servers/plugins/replication/repl5_agmtlist.c | 14 ++++++++
ldap/servers/plugins/replication/repl5_connection.c | 1
3 files changed, 48 insertions(+), 2 deletions(-)
New commits:
commit cc578f100603dfe8640b7f2836d60ca8263699db
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Mar 11 12:04:31 2011 -0800
Bug 668909 - Can't modify replication agreement in some cases
https://bugzilla.redhat.com/show_bug.cgi?id=668909
Description: Code to modify nsds5ReplicaPort in replication agreement
was not implemented. This patch adds it.
When an agreement change is detected in conn_connect, it resets
the values needed to make a connection including the port number.
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index db86854..a8b7a05 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -953,7 +953,7 @@ int
agmt_set_credentials_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
{
Slapi_Attr *sattr = NULL;
- int return_value = 0;
+ int return_value = -1;
PR_ASSERT(NULL != ra);
slapi_entry_attr_find(e, type_nsds5ReplicaCredentials, &sattr);
@@ -970,6 +970,7 @@ agmt_set_credentials_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
ra->creds->bv_val = slapi_ch_calloc(1, bv->bv_len + 1);
memcpy(ra->creds->bv_val, bv->bv_val, bv->bv_len);
ra->creds->bv_len = bv->bv_len;
+ return_value = 0;
}
}
/* If no credentials set, set to zero-length string */
@@ -988,7 +989,7 @@ int
agmt_set_binddn_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
{
Slapi_Attr *sattr = NULL;
- int return_value = 0;
+ int return_value = -1;
PR_ASSERT(NULL != ra);
slapi_entry_attr_find(e, type_nsds5ReplicaBindDN, &sattr);
@@ -1003,6 +1004,7 @@ agmt_set_binddn_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
{
const char *val = slapi_value_get_string(sval);
ra->binddn = slapi_ch_strdup(val);
+ return_value = 0;
}
}
/* If no BindDN set, set to zero-length string */
@@ -1014,6 +1016,35 @@ agmt_set_binddn_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
return return_value;
}
+/*
+ * Reset the port number of the remote replica.
+ *
+ * Returns 0 if port set, or -1 if an error occurred.
+ */
+int
+agmt_set_port_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
+{
+ Slapi_Attr *sattr = NULL;
+ int return_value = -1;
+
+ PR_ASSERT(NULL != ra);
+ slapi_entry_attr_find(e, type_nsds5ReplicaPort, &sattr);
+ PR_Lock(ra->lock);
+ if (NULL != sattr)
+ {
+ Slapi_Value *sval = NULL;
+ slapi_attr_first_value(sattr, &sval);
+ if (NULL != sval)
+ {
+ ra->port = slapi_value_get_int(sval);
+ return_value = 0;
+ }
+ }
+ PR_Unlock(ra->lock);
+ prot_notify_agmt_changed(ra->protocol, ra->long_name);
+ return return_value;
+}
+
static int
agmt_parse_excluded_attrs_filter(const char *attr_string, size_t *offset)
{
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index 00b4459..cf497b6 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -373,6 +373,20 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
}
}
else if (slapi_attr_types_equivalent(mods[i]->mod_type,
+ type_nsds5ReplicaPort))
+ {
+ /* New replica port */
+ if (agmt_set_port_from_entry(agmt, e) != 0)
+ {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "agmtlist_modify_callback: "
+ "failed to update port for agreement %s\n",
+ agmt_get_long_name(agmt));
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ }
+ }
+ else if (slapi_attr_types_equivalent(mods[i]->mod_type,
type_nsds5TransportInfo))
{
/* do not allow GSSAPI if using TLS/SSL */
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index 67c8263..47850b3 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -1020,6 +1020,7 @@ conn_connect(Repl_Connection *conn)
conn->transport_flags = agmt_get_transport_flags(conn->agmt);
conn->timeout.tv_sec = agmt_get_timeout(conn->agmt);
conn->flag_agmt_changed = 0;
+ conn->port = agmt_get_port(conn->agmt); /* port could be updated */
slapi_ch_free((void **)&conn->plain);
}
PR_Unlock(conn->lock);
13 years, 1 month
ldap/servers
by Noriko Hosoi
ldap/servers/plugins/replication/repl5_agmt.c | 35 ++++++++++++++++++--
ldap/servers/plugins/replication/repl5_agmtlist.c | 14 ++++++++
ldap/servers/plugins/replication/repl5_connection.c | 1
3 files changed, 48 insertions(+), 2 deletions(-)
New commits:
commit 34f2f30578d69f4aaa7445f6f388b03f9fc5c3ca
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Mar 11 12:04:31 2011 -0800
Bug 668909 - Can't modify replication agreement in some cases
https://bugzilla.redhat.com/show_bug.cgi?id=668909
Description: Code to modify nsds5ReplicaPort in replication agreement
was not implemented. This patch adds it.
When an agreement change is detected in conn_connect, it resets
the values needed to make a connection including the port number.
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index db86854..a8b7a05 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -953,7 +953,7 @@ int
agmt_set_credentials_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
{
Slapi_Attr *sattr = NULL;
- int return_value = 0;
+ int return_value = -1;
PR_ASSERT(NULL != ra);
slapi_entry_attr_find(e, type_nsds5ReplicaCredentials, &sattr);
@@ -970,6 +970,7 @@ agmt_set_credentials_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
ra->creds->bv_val = slapi_ch_calloc(1, bv->bv_len + 1);
memcpy(ra->creds->bv_val, bv->bv_val, bv->bv_len);
ra->creds->bv_len = bv->bv_len;
+ return_value = 0;
}
}
/* If no credentials set, set to zero-length string */
@@ -988,7 +989,7 @@ int
agmt_set_binddn_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
{
Slapi_Attr *sattr = NULL;
- int return_value = 0;
+ int return_value = -1;
PR_ASSERT(NULL != ra);
slapi_entry_attr_find(e, type_nsds5ReplicaBindDN, &sattr);
@@ -1003,6 +1004,7 @@ agmt_set_binddn_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
{
const char *val = slapi_value_get_string(sval);
ra->binddn = slapi_ch_strdup(val);
+ return_value = 0;
}
}
/* If no BindDN set, set to zero-length string */
@@ -1014,6 +1016,35 @@ agmt_set_binddn_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
return return_value;
}
+/*
+ * Reset the port number of the remote replica.
+ *
+ * Returns 0 if port set, or -1 if an error occurred.
+ */
+int
+agmt_set_port_from_entry(Repl_Agmt *ra, const Slapi_Entry *e)
+{
+ Slapi_Attr *sattr = NULL;
+ int return_value = -1;
+
+ PR_ASSERT(NULL != ra);
+ slapi_entry_attr_find(e, type_nsds5ReplicaPort, &sattr);
+ PR_Lock(ra->lock);
+ if (NULL != sattr)
+ {
+ Slapi_Value *sval = NULL;
+ slapi_attr_first_value(sattr, &sval);
+ if (NULL != sval)
+ {
+ ra->port = slapi_value_get_int(sval);
+ return_value = 0;
+ }
+ }
+ PR_Unlock(ra->lock);
+ prot_notify_agmt_changed(ra->protocol, ra->long_name);
+ return return_value;
+}
+
static int
agmt_parse_excluded_attrs_filter(const char *attr_string, size_t *offset)
{
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index 00b4459..cf497b6 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -373,6 +373,20 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
}
}
else if (slapi_attr_types_equivalent(mods[i]->mod_type,
+ type_nsds5ReplicaPort))
+ {
+ /* New replica port */
+ if (agmt_set_port_from_entry(agmt, e) != 0)
+ {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "agmtlist_modify_callback: "
+ "failed to update port for agreement %s\n",
+ agmt_get_long_name(agmt));
+ *returncode = LDAP_OPERATIONS_ERROR;
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ }
+ }
+ else if (slapi_attr_types_equivalent(mods[i]->mod_type,
type_nsds5TransportInfo))
{
/* do not allow GSSAPI if using TLS/SSL */
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index 67c8263..47850b3 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -1020,6 +1020,7 @@ conn_connect(Repl_Connection *conn)
conn->transport_flags = agmt_get_transport_flags(conn->agmt);
conn->timeout.tv_sec = agmt_get_timeout(conn->agmt);
conn->flag_agmt_changed = 0;
+ conn->port = agmt_get_port(conn->agmt); /* port could be updated */
slapi_ch_free((void **)&conn->plain);
}
PR_Unlock(conn->lock);
13 years, 1 month
help/en src/com
by Nathan Kinder
help/en/help/configtab_schema3.html | 12
help/en/help/configtab_schema4.html | 12
src/com/netscape/admin/dirserv/dirserv.properties | 6
src/com/netscape/admin/dirserv/panel/AttributeDialog.java | 327 +++++++++-
src/com/netscape/admin/dirserv/panel/SchemaAttributesPanel.java | 48 +
5 files changed, 371 insertions(+), 34 deletions(-)
New commits:
commit c95594f53800cf51736d9d0a95c51213e473ddee
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Thu Mar 10 13:16:31 2011 -0800
Bug 616707 - Add attribute matching rule UI to Console
This patch adds support for viewing and modifying the matching rules
used by an attribute to the Console UI. When one creates or edits an
attribute in the schema, 3 new combo boxes can be used to set the
equality, ordering, and substring matching rules to be used by the
attribute. The Console will only allow the matching rules whose
syntax matches that of the attribute to be selected.
diff --git a/help/en/help/configtab_schema3.html b/help/en/help/configtab_schema3.html
index 598d38a..eb309e6 100644
--- a/help/en/help/configtab_schema3.html
+++ b/help/en/help/configtab_schema3.html
@@ -26,6 +26,18 @@ Syntax—Displays the syntax of the attribute. For example, the syntax type o
<li>
Multi—Defines whether the attribute is multi-valued. If the checkbox in this column is selected, the attribute can be multi-valued. The directory allows more than one instance of a multi-valued attribute per entry.
</li>
+
+<li>
+Equality MR—Displays the equality matching rule used by the attribute.
+</li>
+
+<li>
+Ordering MR—Displays the ordering matching rule used by the attribute.
+</li>
+
+<li>
+Substring MR—Displays the substring matching rule used by the attribute.
+</li>
</ul>
<p class="text">
diff --git a/help/en/help/configtab_schema4.html b/help/en/help/configtab_schema4.html
index 0545906..f8bb4c2 100644
--- a/help/en/help/configtab_schema4.html
+++ b/help/en/help/configtab_schema4.html
@@ -27,5 +27,17 @@ This dialog box allows you to create new attributes or edit existing ones.
</p>
<p class="text">
+<b>Equality matching rule (optional). </b>Select an equality matching rule to be used by the attribute. Select <code>none</code> if you do not want to specify a matching rule. The selected matching rule must be allowed to be used with the selected syntax in order to enable the OK button.
+</p>
+
+<p class="text">
+<b>Ordering matching rule (optional). </b>Select an ordering matching rule to be used by the attribute. Select <code>none</code> if you do not want to specify a matching rule. The selected matching rule must be allowed to be used with the selected syntax in order to enable the OK button.
+</p>
+
+<p class="text">
+<b>Substring matching rule (optional). </b>Select a substring matching rule to be used by the attribute. Select <code>none</code> if you do not want to specify a matching rule. The selected matching rule must be allowed to be used with the selected syntax in order to enable the OK button.
+</p>
+
+<p class="text">
<b>Multi-valued. </b>When selected, this option specifies that the attribute you are creating is multi-valued, meaning an entry may contain more than one instance of this attribute.
</p>
diff --git a/src/com/netscape/admin/dirserv/dirserv.properties b/src/com/netscape/admin/dirserv/dirserv.properties
index 90b56bd..d5915b2 100644
--- a/src/com/netscape/admin/dirserv/dirserv.properties
+++ b/src/com/netscape/admin/dirserv/dirserv.properties
@@ -752,6 +752,9 @@ schemaattributes-newsyntax-5=Distinguished Name
schemaattributes-newsyntax-6=Integer
schemaattributes-newsyntax-default=Case Ignore String
schemaattributes-newsyntax-unknown=Unknown
+schemaattributes-newmrequality-label=Equality matching rule (optional):
+schemaattributes-newmrordering-label=Ordering matching rule (optional):
+schemaattributes-newmrsubstring-label=Substring matching rule (optional):
schemaattributes-current-title=Current Attributes
schemaattributes-standard-label=Standard Attributes (Read-Only):
schemaattributes-userdefined-label=User Defined Attributes:
@@ -759,6 +762,9 @@ schemaattributes-namecolumn-label=Name
schemaattributes-oidcolumn-label=OID
schemaattributes-syntaxcolumn-label=Syntax
schemaattributes-multicolumn-label=Multi
+schemaattributes-mrequality-label=Equality MR
+schemaattributes-mrordering-label= Ordering MR
+schemaattributes-mrsubstring-label= Substring MR
schemaattributes-clear-label=Clear
schemaattributes-create-label=Create...
schemaattributes-create-mnemonic=A
diff --git a/src/com/netscape/admin/dirserv/panel/AttributeDialog.java b/src/com/netscape/admin/dirserv/panel/AttributeDialog.java
index e0d89eb..b59de38 100644
--- a/src/com/netscape/admin/dirserv/panel/AttributeDialog.java
+++ b/src/com/netscape/admin/dirserv/panel/AttributeDialog.java
@@ -187,12 +187,30 @@ class AttributePanel extends BlankPanel {
break;
}
}
+
String superior = null;
LDAPAttributeSchema las =
new LDAPAttributeSchema(name, oid, desc,
syntaxOID,
!multi, superior, aliases);
las.setQualifier("X-ORIGIN", "user defined");
+
+ // Set the matching rules if any were selected
+ String selectedEqMatchingRule = (String)_cmbAttributeMrEquality.getSelectedItem();
+ if ((selectedEqMatchingRule != null) && (!selectedEqMatchingRule.equalsIgnoreCase("none"))) {
+ las.setQualifier("EQUALITY", selectedEqMatchingRule);
+ }
+
+ String selectedOrdMatchingRule = (String)_cmbAttributeMrOrdering.getSelectedItem();
+ if ((selectedOrdMatchingRule != null) && (!selectedOrdMatchingRule.equalsIgnoreCase("none"))) {
+ las.setQualifier("ORDERING", selectedOrdMatchingRule);
+ }
+
+ String selectedSubMatchingRule = (String)_cmbAttributeMrSubstring.getSelectedItem();
+ if ((selectedSubMatchingRule != null) && (!selectedSubMatchingRule.equalsIgnoreCase("none"))) {
+ las.setQualifier("SUBSTR", selectedSubMatchingRule);
+ }
+
boolean done = false;
boolean deleted = false;
boolean status = false;
@@ -475,7 +493,96 @@ class AttributePanel extends BlankPanel {
}
}
}
-
+
+ /* check if the EQUALITY matching rule can be used with the syntax */
+ boolean isEqMatchingRuleValid = true;
+ boolean isEqMatchingRuleModified = false;
+ String selectedEqMatchingRule = (String)_cmbAttributeMrEquality.getSelectedItem();
+ String originalEqMatchingRule = null;
+ if (_las != null) {
+ String [] mr_eq_vals = _las.getQualifier("EQUALITY");
+ if ((mr_eq_vals != null) && (mr_eq_vals.length > 0)) {
+ originalEqMatchingRule = mr_eq_vals[0];
+ }
+
+ if (selectedEqMatchingRule != null) {
+ // was the matching rule modified?
+ if ((originalEqMatchingRule != null) && !originalEqMatchingRule.equals(selectedEqMatchingRule)) {
+ isEqMatchingRuleModified = true;
+ }
+
+ // get the name of the syntax used in the matching rule
+ String selectedEqSyntax = null;
+ if (_htMatchingRuleStrings.get(selectedEqMatchingRule) != null) {
+ selectedEqSyntax = (String)_htSyntaxStrings.get(_htMatchingRuleStrings.get(selectedEqMatchingRule));
+ }
+
+ // is the matching rule valid?
+ if ((selectedEqSyntax != null) && !selectedEqSyntax.equals(selectedSyntax)) {
+ isEqMatchingRuleValid = false;
+ }
+ }
+ }
+
+ /* check if the ORDERING matching rule can be used with the syntax */
+ boolean isOrdMatchingRuleValid = true;
+ boolean isOrdMatchingRuleModified = false;
+ String selectedOrdMatchingRule = (String)_cmbAttributeMrOrdering.getSelectedItem();
+ String originalOrdMatchingRule = null;
+ if (_las != null) {
+ String [] mr_ord_vals = _las.getQualifier("ORDERING");
+ if ((mr_ord_vals != null) && (mr_ord_vals.length > 0)) {
+ originalOrdMatchingRule = mr_ord_vals[0];
+ }
+
+ if (selectedOrdMatchingRule != null) {
+ // was the matching rule modified?
+ if ((originalOrdMatchingRule != null) && !originalOrdMatchingRule.equals(selectedOrdMatchingRule)) {
+ isOrdMatchingRuleModified = true;
+ }
+
+ // get the name of the syntax used in the matching rule
+ String selectedOrdSyntax = null;
+ if (_htMatchingRuleStrings.get(selectedOrdMatchingRule) != null) {
+ selectedOrdSyntax = (String)_htSyntaxStrings.get(_htMatchingRuleStrings.get(selectedOrdMatchingRule));
+ }
+
+ // is the matching rule valid?
+ if ((selectedOrdSyntax != null) && !selectedOrdSyntax.equals(selectedSyntax)) {
+ isOrdMatchingRuleValid = false;
+ }
+ }
+ }
+
+ /* check if the SUBSTR matching rule can be used with the syntax */
+ boolean isSubMatchingRuleValid = true;
+ boolean isSubMatchingRuleModified = false;
+ String selectedSubMatchingRule = (String)_cmbAttributeMrSubstring.getSelectedItem();
+ String originalSubMatchingRule = null;
+ if (_las != null) {
+ String [] mr_sub_vals = _las.getQualifier("SUBSTR");
+ if ((mr_sub_vals != null) && (mr_sub_vals.length > 0)) {
+ originalSubMatchingRule = mr_sub_vals[0];
+ }
+
+ if (selectedSubMatchingRule != null) {
+ // was the matching rule modified?
+ if ((originalSubMatchingRule != null) && !originalSubMatchingRule.equals(selectedSubMatchingRule)) {
+ isSubMatchingRuleModified = true;
+ }
+
+ // get the name of the syntax used in the matching rule
+ String selectedSubSyntax = null;
+ if (_htMatchingRuleStrings.get(selectedSubMatchingRule) != null) {
+ selectedSubSyntax = (String)_htSyntaxStrings.get(_htMatchingRuleStrings.get(selectedSubMatchingRule));
+ }
+
+ // is the matching rule valid?
+ if ((selectedSubSyntax != null) && !selectedSubSyntax.equals(selectedSyntax)) {
+ isSubMatchingRuleValid = false;
+ }
+ }
+ }
/* CHECK MULTIVALUED (always valid, only modification) */
boolean isMultiValuedModified = false;
@@ -522,6 +629,29 @@ class AttributePanel extends BlankPanel {
setChangeState(_lAttributeSyntax, CHANGE_STATE_UNMODIFIED);
}
+ if (!isEqMatchingRuleValid) {
+ setChangeState(_lAttributeMrEquality, CHANGE_STATE_ERROR);
+ } else if (isEqMatchingRuleModified) {
+ setChangeState(_lAttributeMrEquality, CHANGE_STATE_MODIFIED);
+ } else {
+ setChangeState(_lAttributeMrEquality, CHANGE_STATE_UNMODIFIED);
+ }
+
+ if (!isOrdMatchingRuleValid) {
+ setChangeState(_lAttributeMrOrdering, CHANGE_STATE_ERROR);
+ } else if (isOrdMatchingRuleModified) {
+ setChangeState(_lAttributeMrOrdering, CHANGE_STATE_MODIFIED);
+ } else {
+ setChangeState(_lAttributeMrOrdering, CHANGE_STATE_UNMODIFIED);
+ }
+
+ if (!isSubMatchingRuleValid) {
+ setChangeState(_lAttributeMrSubstring, CHANGE_STATE_ERROR);
+ } else if (isSubMatchingRuleModified) {
+ setChangeState(_lAttributeMrSubstring, CHANGE_STATE_MODIFIED);
+ } else {
+ setChangeState(_lAttributeMrSubstring, CHANGE_STATE_UNMODIFIED);
+ }
if (isMultiValuedModified) {
setChangeState(_ckbAttributeIsMulti, CHANGE_STATE_MODIFIED);
@@ -531,7 +661,8 @@ class AttributePanel extends BlankPanel {
boolean isValid = isNameValid &&
isAliasValid &&
- isOIDValid;
+ isOIDValid && isEqMatchingRuleValid &&
+ isOrdMatchingRuleValid && isSubMatchingRuleValid;
_dlg.setOKButtonEnabled( isValid );
}
@@ -550,35 +681,45 @@ class AttributePanel extends BlankPanel {
}
protected JPanel createNewAttributeArea() {
- // create the widgets
- _lAttributeName = makeJLabel(PANEL_NAME, "newname");
- _tfAttributeName = makeJTextField(PANEL_NAME, "newname",
+ /* In _htSyntaxStrings we have as key the OID of the syntax, and as value, the Description of the Syntax */
+ if ( _htSyntaxStrings == null ) {
+ _htSyntaxStrings = SchemaAttributesPanel.getSyntaxStrings(getModel().getSchema());
+ }
+
+ // In _htMatchingRuleStrings we have as key the name of the MR, and as value, the AVA syntax OID
+ if ( _htMatchingRuleStrings == null ) {
+ _htMatchingRuleStrings = SchemaAttributesPanel.getMatchingRuleStrings(getModel().getSchema());
+ }
+
+ // create the widgets
+ _lAttributeName = makeJLabel(PANEL_NAME, "newname");
+ _tfAttributeName = makeJTextField(PANEL_NAME, "newname",
null, 20);
_lAttributeName.setLabelFor(_tfAttributeName);
_lAttributeAliases = makeJLabel(PANEL_NAME, "newaliases");
- _tfAttributeAliases = makeJTextField(PANEL_NAME, "newaliases",
+ _tfAttributeAliases = makeJTextField(PANEL_NAME, "newaliases",
null, 20);
_lAttributeAliases.setLabelFor(_tfAttributeAliases);
- _lAttributeOID = makeJLabel(PANEL_NAME, "newoid");
- _tfAttributeOID = makeJTextField(PANEL_NAME, "newoid",
+ _lAttributeOID = makeJLabel(PANEL_NAME, "newoid");
+ _tfAttributeOID = makeJTextField(PANEL_NAME, "newoid",
null, 20);
_lAttributeOID.setLabelFor(_tfAttributeOID);
- _lAttributeDesc = makeJLabel(PANEL_NAME, "newdesc");
- _tfAttributeDesc = makeJTextField(PANEL_NAME, "newdesc",
+ _lAttributeDesc = makeJLabel(PANEL_NAME, "newdesc");
+ _tfAttributeDesc = makeJTextField(PANEL_NAME, "newdesc",
null, 20);
_lAttributeDesc.setLabelFor(_tfAttributeDesc);
- _ckbAttributeIsMulti = makeJCheckBox(PANEL_NAME, "newmulti",
+ _ckbAttributeIsMulti = makeJCheckBox(PANEL_NAME, "newmulti",
false);
// Value by default
_ckbAttributeIsMulti.setSelected(true);
_ckbAttributeIsMulti.addActionListener(this);
- _lAttributeSyntax = makeJLabel(PANEL_NAME, "newsyntax");
- _cmbAttributeSyntax = makeJComboBox(PANEL_NAME, "newsyntax",
+ _lAttributeSyntax = makeJLabel(PANEL_NAME, "newsyntax");
+ _cmbAttributeSyntax = makeJComboBox(PANEL_NAME, "newsyntax",
null);
_lAttributeSyntax.setLabelFor(_cmbAttributeSyntax);
_cmbAttributeSyntax.addItemListener(this);
@@ -593,12 +734,38 @@ class AttributePanel extends BlankPanel {
if ( c instanceof JTextField )
((JTextField)c).setMargin( getTextInsets() );
}
- /* In _htSyntaxStrings we have as key the OID of the syntax, and as value, the Description of the Syntax */
- if ( _htSyntaxStrings == null ) {
- _htSyntaxStrings = SchemaAttributesPanel.getSyntaxStrings(getModel().getSchema());
+
+ // Equality matching rules
+ _lAttributeMrEquality = makeJLabel(PANEL_NAME, "newmrequality");
+ _cmbAttributeMrEquality = makeJComboBox(PANEL_NAME, "newmrequality",
+ null);
+ _lAttributeMrEquality.setLabelFor(_cmbAttributeMrEquality);
+ _cmbAttributeMrEquality.addItemListener(this);
+ UIFactory.setToolTip(PANEL_NAME, "newmrequality", _cmbAttributeMrEquality);
+ ed = _cmbAttributeMrEquality.getEditor();
+ if ( ed != null ) {
+ Component c = ed.getEditorComponent();
+ if ( c instanceof JTextField )
+ ((JTextField)c).setMargin( getTextInsets() );
}
+
+ // Ordering matching rules
+ _lAttributeMrOrdering = makeJLabel(PANEL_NAME, "newmrordering");
+ _cmbAttributeMrOrdering = makeJComboBox(PANEL_NAME, "newmrordering",
+ null);
+ _lAttributeMrOrdering.setLabelFor(_cmbAttributeMrOrdering);
+ _cmbAttributeMrOrdering.addItemListener(this);
+
+
+ // Substring matching rules
+ _lAttributeMrSubstring = makeJLabel(PANEL_NAME, "newmrsubstring");
+ _cmbAttributeMrSubstring = makeJComboBox(PANEL_NAME, "newmrsubstring",
+ null);
+ _lAttributeMrSubstring.setLabelFor(_cmbAttributeMrSubstring);
+ _cmbAttributeMrSubstring.addItemListener(this);
+
/* We add the different syntaxes to the combobox */
- Enumeration syntaxes = _htSyntaxStrings.elements();
+ Enumeration syntaxes = _htSyntaxStrings.elements();
while (syntaxes.hasMoreElements()) {
String item = (String)syntaxes.nextElement();
if (item != null) {
@@ -606,9 +773,28 @@ class AttributePanel extends BlankPanel {
}
}
- // layout the widgets
- // create a panel to hold things
- JPanel panel = new JPanel(new GridBagLayout());
+ // Fill in the combo boxes with a sorted list of matching rules
+ _cmbAttributeMrEquality.insertItemAt("none", 0);
+ _cmbAttributeMrOrdering.insertItemAt("none", 0);
+ _cmbAttributeMrSubstring.insertItemAt("none", 0);
+ Vector vMatchingRules = new Vector (_htMatchingRuleStrings.keySet());
+ Collections.sort(vMatchingRules);
+ Enumeration matchingrules = vMatchingRules.elements();
+ while (matchingrules.hasMoreElements()) {
+ String item = (String)matchingrules.nextElement();
+ // Don't add the matching rule if it's syntax isn't in the hashtable of
+ // syntax strings. This is to avoid including matching rules that use the
+ // substring assertion syntax, which we don't support.
+ if ((item != null) && (_htSyntaxStrings.get(_htMatchingRuleStrings.get(item)) != null)) {
+ _cmbAttributeMrEquality.addItem(item);
+ _cmbAttributeMrOrdering.addItem(item);
+ _cmbAttributeMrSubstring.addItem(item);
+ }
+ }
+
+ // layout the widgets
+ // create a panel to hold things
+ JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder( new EmptyBorder( 0, 0, 0, 0 ) );
GridBagConstraints gbc = new GridBagConstraints();
int different = UIFactory.getDifferentSpace();
@@ -681,6 +867,45 @@ class AttributePanel extends BlankPanel {
panel.add(_cmbAttributeSyntax, gbc);
gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.gridwidth = gbc.RELATIVE;
+ gbc.weightx = 0;
+ gbc.insets = left;
+ panel.add(_lAttributeMrEquality, gbc);
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = right;
+ panel.add(_cmbAttributeMrEquality, gbc);
+
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.gridwidth = gbc.RELATIVE;
+ gbc.weightx = 0;
+ gbc.insets = left;
+ panel.add(_lAttributeMrOrdering, gbc);
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = right;
+ panel.add(_cmbAttributeMrOrdering, gbc);
+
+ gbc.fill = gbc.NONE;
+ gbc.anchor = gbc.NORTHEAST;
+ gbc.gridwidth = gbc.RELATIVE;
+ gbc.weightx = 0;
+ gbc.insets = left;
+ panel.add(_lAttributeMrSubstring, gbc);
+ gbc.fill = gbc.HORIZONTAL;
+ gbc.anchor = gbc.WEST;
+ gbc.weightx = 1;
+ gbc.gridwidth = gbc.REMAINDER;
+ gbc.insets = right;
+ panel.add(_cmbAttributeMrSubstring, gbc);
+
+ gbc.fill = gbc.NONE;
gbc.weightx = 0.0;
gbc.anchor = gbc.NORTHEAST;
gbc.gridwidth = gbc.RELATIVE;
@@ -704,12 +929,52 @@ class AttributePanel extends BlankPanel {
if (syntax != null) {
_cmbAttributeSyntax.setSelectedItem( syntax );
}
+
+ String [] mr_eq_vals = _las.getQualifier("EQUALITY");
+ if ((mr_eq_vals != null) && (mr_eq_vals.length > 0)) {
+ String mr_eq = mr_eq_vals[0];
+ if (mr_eq != null) {
+ _cmbAttributeMrEquality.setSelectedItem( mr_eq );
+ } else {
+ _cmbAttributeMrEquality.setSelectedIndex(0);
+ }
+ } else {
+ _cmbAttributeMrEquality.setSelectedIndex(0);
+ }
+
+ String [] mr_ord_vals = _las.getQualifier("ORDERING");
+ if ((mr_ord_vals != null) && (mr_ord_vals.length > 0)) {
+ String mr_ord = mr_ord_vals[0];
+ if (mr_ord != null) {
+ _cmbAttributeMrOrdering.setSelectedItem( mr_ord );
+ } else {
+ _cmbAttributeMrOrdering.setSelectedIndex(0);
+ }
+ } else {
+ _cmbAttributeMrOrdering.setSelectedIndex(0);
+ }
+
+ String [] mr_sub_vals = _las.getQualifier("SUBSTR");
+ if ((mr_sub_vals != null) && (mr_sub_vals.length > 0)) {
+ String mr_sub = mr_sub_vals[0];
+ if (mr_sub != null) {
+ _cmbAttributeMrSubstring.setSelectedItem( mr_sub );
+ } else {
+ _cmbAttributeMrSubstring.setSelectedIndex(0);
+ }
+ } else {
+ _cmbAttributeMrSubstring.setSelectedIndex(0);
+ }
+
_ckbAttributeIsMulti.setSelected( !_las.isSingleValued() );
} else {
/* Give a default value */
- _tfAttributeName.setText(DSUtil._resource.getString(
- PANEL_NAME,
- "newname-default"));
+ _tfAttributeName.setText(DSUtil._resource.getString(PANEL_NAME, "newname-default"));
+
+ /* Select none for all matching rules */
+ _cmbAttributeMrEquality.setSelectedIndex(0);
+ _cmbAttributeMrOrdering.setSelectedIndex(0);
+ _cmbAttributeMrSubstring.setSelectedIndex(0);
}
return panel;
}
@@ -767,11 +1032,14 @@ class AttributePanel extends BlankPanel {
*
* @param e Event indicating what changed
*/
- public void itemStateChanged(ItemEvent e) {
- if (e.getSource().equals(_cmbAttributeSyntax)) {
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getSource().equals(_cmbAttributeSyntax) ||
+ e.getSource().equals(_cmbAttributeMrEquality) ||
+ e.getSource().equals(_cmbAttributeMrOrdering) ||
+ e.getSource().equals(_cmbAttributeMrSubstring)) {
checkOkay();
}
- }
+ }
private JLabel _lAttributeAliases;
@@ -779,16 +1047,23 @@ class AttributePanel extends BlankPanel {
private JLabel _lAttributeName;
private JLabel _lAttributeDesc;
private JLabel _lAttributeSyntax;
+ private JLabel _lAttributeMrEquality;
+ private JLabel _lAttributeMrOrdering;
+ private JLabel _lAttributeMrSubstring;
private JTextField _tfAttributeName; // new attribute name
private JTextField _tfAttributeAliases; // aliases
private JTextField _tfAttributeOID; // oid for new attribute (optional)
private JTextField _tfAttributeDesc; // attribute description (optional)
private JCheckBox _ckbAttributeIsMulti; // true if attr is multivalued
private JComboBox _cmbAttributeSyntax; // syntax for new attribute
+ private JComboBox _cmbAttributeMrEquality; //equality matching rule
+ private JComboBox _cmbAttributeMrOrdering; //ordering matching rule
+ private JComboBox _cmbAttributeMrSubstring; //substring matching rule
private LDAPAttributeSchema _las = null;
private boolean _create = false;
private SimpleDialog _dlg;
private Hashtable _htSyntaxStrings = null;
+ private Hashtable _htMatchingRuleStrings = null;
static final public String PANEL_NAME = "schemaattributes"; // name of panel in resource file
}
diff --git a/src/com/netscape/admin/dirserv/panel/SchemaAttributesPanel.java b/src/com/netscape/admin/dirserv/panel/SchemaAttributesPanel.java
index b605fa1..5514b2f 100644
--- a/src/com/netscape/admin/dirserv/panel/SchemaAttributesPanel.java
+++ b/src/com/netscape/admin/dirserv/panel/SchemaAttributesPanel.java
@@ -81,10 +81,23 @@ public class SchemaAttributesPanel extends BlankPanel
return "";
}
- /**
- * Takes an ID in format 1.2.3.4{128} and creates an ID without the length definition.
- * In this case the resulting ID is 1.2.3.4
- */
+ // Create a hashtable of matching rule names to the AVA syntax OIDs
+ static Hashtable getMatchingRuleStrings(LDAPSchema sch) {
+ Hashtable htMatchingRuleStrings = new Hashtable();
+ Enumeration matchingrules = sch.getMatchingRules();
+ while (matchingrules.hasMoreElements()) {
+ LDAPMatchingRuleSchema mr = (LDAPMatchingRuleSchema)matchingrules.nextElement();
+ if (mr != null) {
+ htMatchingRuleStrings.put(mr.getName(), mr.getSyntaxString());
+ }
+ }
+ return htMatchingRuleStrings;
+ }
+
+ /**
+ * Takes an ID in format 1.2.3.4{128} and creates an ID without the length definition.
+ * In this case the resulting ID is 1.2.3.4
+ */
private static String getNormalizedID(String id) {
String normalizedId;
int index = id.indexOf('{');
@@ -236,9 +249,12 @@ public class SchemaAttributesPanel extends BlankPanel
String dummy = new String(); // for getClass()
Object[][] colHeader = {
{DSUtil._resource.getString(_section, "namecolumn-label"), dummy.getClass()},
- {DSUtil._resource.getString(_section, "oidcolumn-label"), dummy.getClass()},
- {DSUtil._resource.getString(_section, "syntaxcolumn-label"), dummy.getClass()},
- {DSUtil._resource.getString(_section, "multicolumn-label"), Boolean.TYPE}
+ {DSUtil._resource.getString(_section, "oidcolumn-label"), dummy.getClass()},
+ {DSUtil._resource.getString(_section, "syntaxcolumn-label"), dummy.getClass()},
+ {DSUtil._resource.getString(_section, "multicolumn-label"), Boolean.TYPE},
+ {DSUtil._resource.getString(_section, "mrequality-label"), dummy.getClass()},
+ {DSUtil._resource.getString(_section, "mrordering-label"), dummy.getClass()},
+ {DSUtil._resource.getString(_section, "mrsubstring-label"), dummy.getClass()}
};
/* create standard attributes panel */
@@ -768,8 +784,12 @@ class AttrTableModel extends AbstractTableModel {
}
}
void addRow(LDAPAttributeSchema las) {
- Object row[] = new Object[4];
+ Object row[] = new Object[7];
String name = las.getName();
+ String [] mr_eq_vals = las.getQualifier("EQUALITY");
+ String [] mr_ord_vals = las.getQualifier("ORDERING");
+ String [] mr_sub_vals = las.getQualifier("SUBSTR");
+
// can't have alias list as first column in table because the code uses
// that value to look up the attribute schema
// String[] aliases = las.getAliases();
@@ -781,6 +801,18 @@ class AttrTableModel extends AbstractTableModel {
row[1] = las.getID();
row[2] = SchemaAttributesPanel.getSyntaxString(las.getSyntaxString());
row[3] = new Boolean( !las.isSingleValued() );
+
+ // Fill in any matching rules that are set
+ if ((mr_eq_vals != null) && (mr_eq_vals.length > 0)) {
+ row[4] = mr_eq_vals[0];
+ }
+ if ((mr_ord_vals != null) && (mr_ord_vals.length > 0)) {
+ row[5] = mr_ord_vals[0];
+ }
+ if ((mr_sub_vals != null) && (mr_sub_vals.length > 0)) {
+ row[6] = mr_sub_vals[0];
+ }
+
addRow(row);
}
void addRow( Object[] values ) {
13 years, 1 month