summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Megginson <rmeggins@redhat.com>2010-02-16 15:56:59 -0700
committerRich Megginson <rmeggins@redhat.com>2010-02-17 15:05:40 -0700
commitecf93e699b04d45fdfa07b12094adaab0233c47a (patch)
treec8725f13871e4d45cd97aec529417289234c8676
parent6adbad044ef95411882ec546281a0df6d0816673 (diff)
downloadds-ecf93e699b04d45fdfa07b12094adaab0233c47a.tar.gz
ds-ecf93e699b04d45fdfa07b12094adaab0233c47a.tar.xz
ds-ecf93e699b04d45fdfa07b12094adaab0233c47a.zip
change syntax plugins to register required matching rule plugins
https://bugzilla.redhat.com/show_bug.cgi?id=559315 Resolves: 559315 Description: Searching some attributes are now case sensitive when they were previously case-insensitive Reviewed by: nhosoi (Thanks!) - also added some suggested comments I added code to allow the syntax plugins to register corresponding matching rules. That is, the functions that the syntax plugins use for filter matching and key generation can also be used for matching rules with the new wrapper code. I added some convenience functions and structures in the syntax plugin code to make it easier to add matching rules in the future. I also added a new feature to the matching rule code - in the LDAP spec definition of matching rule, the syntax provided in the matching rule definition is the syntax for the _assertion value_ used with the matching rule, which is not necessarily the same as the syntax of the _attribute values_ to which the matching rule can be applied. For example, matching rules that apply to syntax DirectoryString can also be applied in some cases to PrintableString, CountryString, and IA5String. There are several other cases like this as well. I also introduced the concept of a compat syntax that can be used with a matching rule. The server will now check, when reading in the schema, if the syntax and matching rules for an attribute are consistent. Finally, for 05rfc4523.ldif, I changed the attributes to use octetStringMatch instead of one of the unimplemented certificate matching rules.
-rw-r--r--Makefile.am1
-rw-r--r--[-rwxr-xr-x]Makefile.in15
-rw-r--r--ldap/schema/05rfc4523.ldif14
-rw-r--r--ldap/servers/plugins/syntaxes/bin.c90
-rw-r--r--ldap/servers/plugins/syntaxes/bitstring.c36
-rw-r--r--ldap/servers/plugins/syntaxes/ces.c139
-rw-r--r--ldap/servers/plugins/syntaxes/cis.c256
-rw-r--r--ldap/servers/plugins/syntaxes/dn.c42
-rw-r--r--ldap/servers/plugins/syntaxes/int.c64
-rw-r--r--ldap/servers/plugins/syntaxes/nameoptuid.c41
-rw-r--r--ldap/servers/plugins/syntaxes/numericstring.c116
-rw-r--r--ldap/servers/plugins/syntaxes/syntax.h56
-rw-r--r--ldap/servers/plugins/syntaxes/syntax_common.c117
-rw-r--r--ldap/servers/plugins/syntaxes/tel.c62
-rw-r--r--ldap/servers/slapd/attrsyntax.c45
-rw-r--r--ldap/servers/slapd/match.c57
-rw-r--r--ldap/servers/slapd/plugin_mr.c82
-rw-r--r--ldap/servers/slapd/slapi-plugin.h35
18 files changed, 1157 insertions, 111 deletions
diff --git a/Makefile.am b/Makefile.am
index d2c52ffd..1774ccdc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1047,6 +1047,7 @@ libsyntax_plugin_la_SOURCES = ldap/servers/plugins/syntaxes/bin.c \
ldap/servers/plugins/syntaxes/phonetic.c \
ldap/servers/plugins/syntaxes/sicis.c \
ldap/servers/plugins/syntaxes/string.c \
+ ldap/servers/plugins/syntaxes/syntax_common.c \
ldap/servers/plugins/syntaxes/tel.c \
ldap/servers/plugins/syntaxes/telex.c \
ldap/servers/plugins/syntaxes/teletex.c \
diff --git a/Makefile.in b/Makefile.in
index fc381a0d..fe2d14bd 100755..100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -626,6 +626,7 @@ am_libsyntax_plugin_la_OBJECTS = \
ldap/servers/plugins/syntaxes/libsyntax_plugin_la-phonetic.lo \
ldap/servers/plugins/syntaxes/libsyntax_plugin_la-sicis.lo \
ldap/servers/plugins/syntaxes/libsyntax_plugin_la-string.lo \
+ ldap/servers/plugins/syntaxes/libsyntax_plugin_la-syntax_common.lo \
ldap/servers/plugins/syntaxes/libsyntax_plugin_la-tel.lo \
ldap/servers/plugins/syntaxes/libsyntax_plugin_la-telex.lo \
ldap/servers/plugins/syntaxes/libsyntax_plugin_la-teletex.lo \
@@ -2036,6 +2037,7 @@ libsyntax_plugin_la_SOURCES = ldap/servers/plugins/syntaxes/bin.c \
ldap/servers/plugins/syntaxes/phonetic.c \
ldap/servers/plugins/syntaxes/sicis.c \
ldap/servers/plugins/syntaxes/string.c \
+ ldap/servers/plugins/syntaxes/syntax_common.c \
ldap/servers/plugins/syntaxes/tel.c \
ldap/servers/plugins/syntaxes/telex.c \
ldap/servers/plugins/syntaxes/teletex.c \
@@ -3808,6 +3810,9 @@ ldap/servers/plugins/syntaxes/libsyntax_plugin_la-sicis.lo: \
ldap/servers/plugins/syntaxes/libsyntax_plugin_la-string.lo: \
ldap/servers/plugins/syntaxes/$(am__dirstamp) \
ldap/servers/plugins/syntaxes/$(DEPDIR)/$(am__dirstamp)
+ldap/servers/plugins/syntaxes/libsyntax_plugin_la-syntax_common.lo: \
+ ldap/servers/plugins/syntaxes/$(am__dirstamp) \
+ ldap/servers/plugins/syntaxes/$(DEPDIR)/$(am__dirstamp)
ldap/servers/plugins/syntaxes/libsyntax_plugin_la-tel.lo: \
ldap/servers/plugins/syntaxes/$(am__dirstamp) \
ldap/servers/plugins/syntaxes/$(DEPDIR)/$(am__dirstamp)
@@ -4585,6 +4590,8 @@ mostlyclean-compile:
-rm -f ldap/servers/plugins/syntaxes/libsyntax_plugin_la-sicis.lo
-rm -f ldap/servers/plugins/syntaxes/libsyntax_plugin_la-string.$(OBJEXT)
-rm -f ldap/servers/plugins/syntaxes/libsyntax_plugin_la-string.lo
+ -rm -f ldap/servers/plugins/syntaxes/libsyntax_plugin_la-syntax_common.$(OBJEXT)
+ -rm -f ldap/servers/plugins/syntaxes/libsyntax_plugin_la-syntax_common.lo
-rm -f ldap/servers/plugins/syntaxes/libsyntax_plugin_la-tel.$(OBJEXT)
-rm -f ldap/servers/plugins/syntaxes/libsyntax_plugin_la-tel.lo
-rm -f ldap/servers/plugins/syntaxes/libsyntax_plugin_la-teletex.$(OBJEXT)
@@ -5263,6 +5270,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-phonetic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-sicis.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-string.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-syntax_common.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-tel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-teletex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-telex.Plo@am__quote@
@@ -8012,6 +8020,13 @@ ldap/servers/plugins/syntaxes/libsyntax_plugin_la-string.lo: ldap/servers/plugin
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsyntax_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/syntaxes/libsyntax_plugin_la-string.lo `test -f 'ldap/servers/plugins/syntaxes/string.c' || echo '$(srcdir)/'`ldap/servers/plugins/syntaxes/string.c
+ldap/servers/plugins/syntaxes/libsyntax_plugin_la-syntax_common.lo: ldap/servers/plugins/syntaxes/syntax_common.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsyntax_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/syntaxes/libsyntax_plugin_la-syntax_common.lo -MD -MP -MF "ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-syntax_common.Tpo" -c -o ldap/servers/plugins/syntaxes/libsyntax_plugin_la-syntax_common.lo `test -f 'ldap/servers/plugins/syntaxes/syntax_common.c' || echo '$(srcdir)/'`ldap/servers/plugins/syntaxes/syntax_common.c; \
+@am__fastdepCC_TRUE@ then mv -f "ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-syntax_common.Tpo" "ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-syntax_common.Plo"; else rm -f "ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-syntax_common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ldap/servers/plugins/syntaxes/syntax_common.c' object='ldap/servers/plugins/syntaxes/libsyntax_plugin_la-syntax_common.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsyntax_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/syntaxes/libsyntax_plugin_la-syntax_common.lo `test -f 'ldap/servers/plugins/syntaxes/syntax_common.c' || echo '$(srcdir)/'`ldap/servers/plugins/syntaxes/syntax_common.c
+
ldap/servers/plugins/syntaxes/libsyntax_plugin_la-tel.lo: ldap/servers/plugins/syntaxes/tel.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsyntax_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/syntaxes/libsyntax_plugin_la-tel.lo -MD -MP -MF "ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-tel.Tpo" -c -o ldap/servers/plugins/syntaxes/libsyntax_plugin_la-tel.lo `test -f 'ldap/servers/plugins/syntaxes/tel.c' || echo '$(srcdir)/'`ldap/servers/plugins/syntaxes/tel.c; \
@am__fastdepCC_TRUE@ then mv -f "ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-tel.Tpo" "ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-tel.Plo"; else rm -f "ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-tel.Tpo"; exit 1; fi
diff --git a/ldap/schema/05rfc4523.ldif b/ldap/schema/05rfc4523.ldif
index ed2d5b22..74334f3f 100644
--- a/ldap/schema/05rfc4523.ldif
+++ b/ldap/schema/05rfc4523.ldif
@@ -11,7 +11,7 @@ dn: cn=schema
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )
attributeTypes: ( 2.5.4.36 NAME 'userCertificate'
DESC 'X.509 user certificate'
- EQUALITY certificateExactMatch
+ EQUALITY octetStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
X-ORIGIN 'RFC 4523' )
#
@@ -23,7 +23,7 @@ attributeTypes: ( 2.5.4.36 NAME 'userCertificate'
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )
attributeTypes: ( 2.5.4.37 NAME 'cACertificate'
DESC 'X.509 CA certificate'
- EQUALITY certificateExactMatch
+ EQUALITY octetStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
X-ORIGIN 'RFC 4523' )
#
@@ -36,7 +36,7 @@ attributeTypes: ( 2.5.4.37 NAME 'cACertificate'
# X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.40 NAME 'crossCertificatePair'
DESC 'X.509 cross certificate pair'
- EQUALITY certificatePairExactMatch
+ EQUALITY octetStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
X-ORIGIN 'RFC 4523' )
#
@@ -49,7 +49,7 @@ attributeTypes: ( 2.5.4.40 NAME 'crossCertificatePair'
# X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.39 NAME 'certificateRevocationList'
DESC 'X.509 certificate revocation list'
- EQUALITY certificateListExactMatch
+ EQUALITY octetStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
X-ORIGIN 'RFC 4523' )
#
@@ -62,7 +62,7 @@ attributeTypes: ( 2.5.4.39 NAME 'certificateRevocationList'
# X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.38 NAME 'authorityRevocationList'
DESC 'X.509 authority revocation list'
- EQUALITY certificateListExactMatch
+ EQUALITY octetStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
X-ORIGIN 'RFC 4523' )
#
@@ -75,7 +75,7 @@ attributeTypes: ( 2.5.4.38 NAME 'authorityRevocationList'
# X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.53 NAME 'deltaRevocationList'
DESC 'X.509 delta revocation list'
- EQUALITY certificateListExactMatch
+ EQUALITY octetStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
X-ORIGIN 'RFC 4523' )
#
@@ -88,7 +88,7 @@ attributeTypes: ( 2.5.4.53 NAME 'deltaRevocationList'
# X-ORIGIN 'RFC 4523' )
attributeTypes: ( 2.5.4.52 NAME 'supportedAlgorithms'
DESC 'X.509 supported algorithms'
- EQUALITY algorithmIdentifierMatch
+ EQUALITY octetStringMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
X-ORIGIN 'RFC 4523' )
#
diff --git a/ldap/servers/plugins/syntaxes/bin.c b/ldap/servers/plugins/syntaxes/bin.c
index 229e1424..b1b46593 100644
--- a/ldap/servers/plugins/syntaxes/bin.c
+++ b/ldap/servers/plugins/syntaxes/bin.c
@@ -52,12 +52,18 @@
#include <sys/types.h>
#include "syntax.h"
+#define CERTIFICATE_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.8"
+#define CERTIFICATELIST_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.9"
+#define CERTIFICATEPAIR_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.10"
+#define SUPPORTEDALGORITHM_SYNTAX_OID "1.3.6.1.4.1.1466.115.121.1.49"
+
static int bin_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
static int bin_values2keys( Slapi_PBlock *pb, Slapi_Value **bvals,
Slapi_Value ***ivals, int ftype );
static int bin_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *bval,
Slapi_Value ***ivals, int ftype );
+static int bin_compare(struct berval *v1, struct berval *v2);
/*
* Attribute syntaxes. We treat all of these the same since the
@@ -98,6 +104,66 @@ static Slapi_PluginDesc fax_pdesc = {
"Fax attribute syntax plugin"
};
+static const char *octetStringMatch_names[] = {"octetStringMatch", "2.5.13.17", NULL};
+static const char *octetStringOrderingMatch_names[] = {"octetStringOrderingMatch", "2.5.13.18", NULL};
+
+static char *octetStringCompat_syntaxes[] = {BINARY_SYNTAX_OID, JPEG_SYNTAX_OID, FAX_SYNTAX_OID, CERTIFICATE_SYNTAX_OID, CERTIFICATELIST_SYNTAX_OID, CERTIFICATEPAIR_SYNTAX_OID, SUPPORTEDALGORITHM_SYNTAX_OID, NULL};
+
+static struct mr_plugin_def mr_plugin_table[] = {
+{{"2.5.13.17", NULL, "octetStringMatch", "The octetStringMatch rule compares an assertion value of the Octet "
+"String syntax to an attribute value of a syntax (e.g., the Octet "
+"String or JPEG syntax) whose corresponding ASN.1 type is the OCTET "
+"STRING ASN.1 type. "
+"The rule evaluates to TRUE if and only if the attribute value and the "
+"assertion value are the same length and corresponding octets (by "
+"position) are the same.", OCTETSTRING_SYNTAX_OID, 0, octetStringCompat_syntaxes}, /* matching rule desc */
+ {"octetStringMatch-mr", VENDOR, DS_PACKAGE_VERSION, "octetStringMatch matching rule plugin"}, /* plugin desc */
+ octetStringMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, bin_filter_ava, NULL, bin_values2keys,
+ bin_assertion2keys_ava, NULL, bin_compare},
+{{"2.5.13.18", NULL, "octetStringOrderingMatch", "The octetStringOrderingMatch rule compares an assertion value of the "
+"Octet String syntax to an attribute value of a syntax (e.g., the "
+"Octet String or JPEG syntax) whose corresponding ASN.1 type is the "
+"OCTET STRING ASN.1 type. "
+"The rule evaluates to TRUE if and only if the attribute value appears "
+"earlier in the collation order than the assertion value. The rule "
+"compares octet strings from the first octet to the last octet, and "
+"from the most significant bit to the least significant bit within the "
+"octet. The first occurrence of a different bit determines the "
+"ordering of the strings. A zero bit precedes a one bit. If the "
+"strings contain different numbers of octets but the longer string is "
+"identical to the shorter string up to the length of the shorter "
+"string, then the shorter string precedes the longer string.",
+OCTETSTRING_SYNTAX_OID, 0, octetStringCompat_syntaxes}, /* matching rule desc */
+ {"octetStringOrderingMatch-mr", VENDOR, DS_PACKAGE_VERSION, "octetStringOrderingMatch matching rule plugin"}, /* plugin desc */
+ octetStringOrderingMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, bin_filter_ava, NULL, bin_values2keys,
+ bin_assertion2keys_ava, NULL, bin_compare}
+};
+/*
+certificateExactMatch
+certificateListExactMatch
+certificatePairExactMatch
+algorithmIdentifierMatch
+certificateMatch
+certificatePairMatch
+certificateListMatch
+*/
+
+static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
+
+static int
+matching_rule_plugin_init(Slapi_PBlock *pb)
+{
+ return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
+}
+
+static int
+register_matching_rule_plugins()
+{
+ return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
+}
+
/*
* register_bin_like_plugin(): register all items for a bin-like plugin.
*/
@@ -134,6 +200,7 @@ bin_init( Slapi_PBlock *pb )
LDAPDebug( LDAP_DEBUG_PLUGIN, "=> bin_init\n", 0, 0, 0 );
rc = register_bin_like_plugin( pb, &bin_pdesc, bin_names,
BINARY_SYNTAX_OID );
+ rc |= register_matching_rule_plugins();
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= bin_init %d\n", rc, 0, 0 );
return( rc );
}
@@ -268,3 +335,26 @@ bin_assertion2keys_ava( Slapi_PBlock *pb, Slapi_Value *bval,
}
return( 0 );
}
+
+#define BV_EMPTY(bv) ((!bv || !bv->bv_len || !bv->bv_val))
+
+static int
+bin_compare(
+ struct berval *v1,
+ struct berval *v2
+)
+{
+ int rc = 0;
+
+ if (BV_EMPTY(v1) && BV_EMPTY(v2)) {
+ rc = 0; /* empty == empty */
+ } else if (BV_EMPTY(v1) && !BV_EMPTY(v2)) {
+ rc = 1; /* something in v2 always greater than empty v1 */
+ } else if (!BV_EMPTY(v1) && BV_EMPTY(v2)) {
+ rc = -1; /* something in v1 always greater than empty v2 */
+ } else { /* both have actual data */
+ rc = slapi_berval_cmp(v1, v2);
+ }
+
+ return rc;
+}
diff --git a/ldap/servers/plugins/syntaxes/bitstring.c b/ldap/servers/plugins/syntaxes/bitstring.c
index 70738f10..eefe8fc4 100644
--- a/ldap/servers/plugins/syntaxes/bitstring.c
+++ b/ldap/servers/plugins/syntaxes/bitstring.c
@@ -66,6 +66,41 @@ static char *names[] = { "Bit String", "bitstring", BITSTRING_SYNTAX_OID, 0 };
static Slapi_PluginDesc pdesc = { "bitstring-syntax", VENDOR, DS_PACKAGE_VERSION,
"Bit String attribute syntax plugin" };
+static const char *bitStringMatch_names[] = {"bitStringMatch", "2.5.13.16", NULL};
+
+static struct mr_plugin_def mr_plugin_table[] = {
+ {{"2.5.13.16", NULL, "bitStringMatch", "The bitStringMatch rule compares an assertion value of the Bit String "
+ "syntax to an attribute value of a syntax (e.g., the Bit String "
+ "syntax) whose corresponding ASN.1 type is BIT STRING. "
+ "If the corresponding ASN.1 type of the attribute syntax does not have "
+ "a named bit list [ASN.1] (which is the case for the Bit String "
+ "syntax), then the rule evaluates to TRUE if and only if the attribute "
+ "value has the same number of bits as the assertion value and the bits "
+ "match on a bitwise basis. "
+ "If the corresponding ASN.1 type does have a named bit list, then "
+ "bitStringMatch operates as above, except that trailing zero bits in "
+ "the attribute and assertion values are treated as absent.",
+ BITSTRING_SYNTAX_OID, 0, NULL /* only the specified syntax is supported */}, /* matching rule desc */
+ {"bitStringMatch-mr", VENDOR, DS_PACKAGE_VERSION, "bitStringMatch matching rule plugin"}, /* plugin desc */
+ bitStringMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, bitstring_filter_ava, NULL, bitstring_values2keys,
+ bitstring_assertion2keys_ava, NULL, bitstring_compare}
+};
+
+static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
+
+static int
+matching_rule_plugin_init(Slapi_PBlock *pb)
+{
+ return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
+}
+
+static int
+register_matching_rule_plugins()
+{
+ return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
+}
+
int
bitstring_init( Slapi_PBlock *pb )
{
@@ -99,6 +134,7 @@ bitstring_init( Slapi_PBlock *pb )
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALIDATE,
(void *) bitstring_validate );
+ rc |= register_matching_rule_plugins();
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= bitstring_init %d\n", rc, 0, 0 );
return( rc );
}
diff --git a/ldap/servers/plugins/syntaxes/ces.c b/ldap/servers/plugins/syntaxes/ces.c
index 077afc1b..07abcd5d 100644
--- a/ldap/servers/plugins/syntaxes/ces.c
+++ b/ldap/servers/plugins/syntaxes/ces.c
@@ -49,6 +49,10 @@
#include <sys/types.h>
#include "syntax.h"
+/* this is used in proposed schema, but there is no official
+ OID yet - so for now, use our private MR OID namespace */
+#define CASEEXACTIA5SUBSTRINGSMATCH_OID "2.16.840.1.113730.3.3.1"
+
static int ces_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
static int ces_filter_sub( Slapi_PBlock *pb, char *initial, char **any,
@@ -75,6 +79,140 @@ static Slapi_PluginDesc ia5_pdesc = { "ces-syntax", VENDOR,
static Slapi_PluginDesc uri_pdesc = { "uri-syntax", VENDOR,
DS_PACKAGE_VERSION, "uri attribute syntax plugin" };
+static const char *caseExactIA5Match_names[] = {"caseExactIA5Match", "1.3.6.1.4.1.1466.109.114.1", NULL};
+static const char *caseExactMatch_names[] = {"caseExactMatch", "2.5.13.5", NULL};
+static const char *caseExactOrderingMatch_names[] = {"caseExactOrderingMatch", "2.5.13.6", NULL};
+static const char *caseExactSubstringsMatch_names[] = {"caseExactSubstringsMatch", "2.5.13.7", NULL};
+static const char *caseExactIA5SubstringsMatch_names[] = {"caseExactIA5SubstringsMatch", CASEEXACTIA5SUBSTRINGSMATCH_OID, NULL};
+
+static char *dirString_syntaxes[] = {COUNTRYSTRING_SYNTAX_OID,
+ DIRSTRING_SYNTAX_OID,
+ PRINTABLESTRING_SYNTAX_OID,NULL};
+static char *dirStringCompat_syntaxes[] = {COUNTRYSTRING_SYNTAX_OID,
+ PRINTABLESTRING_SYNTAX_OID,NULL};
+static char *ia5String_syntaxes[] = {IA5STRING_SYNTAX_OID,NULL};
+
+/* for some reason vendorName and vendorVersion are dirstring but want
+ to use EQUALITY caseExactIA5Match ???? RFC 3045
+ also the old definition of automountInformation from 60autofs.ldif
+ does the same thing */
+static char *caseExactIA5Match_syntaxes[] = {DIRSTRING_SYNTAX_OID, NULL};
+
+static struct mr_plugin_def mr_plugin_table[] = {
+{{"1.3.6.1.4.1.1466.109.114.1", NULL, "caseExactIA5Match", "The caseExactIA5Match rule compares an assertion value of the IA5 "
+"String syntax to an attribute value of a syntax (e.g., the IA5 String "
+"syntax) whose corresponding ASN.1 type is IA5String. "
+"The rule evaluates to TRUE if and only if the prepared attribute "
+"value character string and the prepared assertion value character "
+"string have the same number of characters and corresponding "
+"characters have the same code point. "
+"In preparing the attribute value and assertion value for comparison, "
+"characters are not case folded in the Map preparation step, and only "
+"Insignificant Space Handling is applied in the Insignificant "
+"Character Handling step.",
+IA5STRING_SYNTAX_OID, 0, caseExactIA5Match_syntaxes}, /* matching rule desc */
+ {"caseExactIA5Match-mr", VENDOR, DS_PACKAGE_VERSION, "caseExactIA5Match matching rule plugin"}, /* plugin desc */
+ caseExactIA5Match_names, /* matching rule name/oid/aliases */
+ NULL, NULL, ces_filter_ava, NULL, ces_values2keys,
+ ces_assertion2keys_ava, NULL, ces_compare},
+{{"2.5.13.5", NULL, "caseExactMatch", "The caseExactMatch rule compares an assertion value of the Directory "
+"String syntax to an attribute value of a syntax (e.g., the Directory "
+"String, Printable String, Country String, or Telephone Number syntax) "
+"whose corresponding ASN.1 type is DirectoryString or one of the "
+"alternative string types of DirectoryString, such as PrintableString "
+"(the other alternatives do not correspond to any syntax defined in "
+"this document). "
+"The rule evaluates to TRUE if and only if the prepared attribute "
+"value character string and the prepared assertion value character "
+"string have the same number of characters and corresponding "
+"characters have the same code point. "
+"In preparing the attribute value and assertion value for comparison, "
+"characters are not case folded in the Map preparation step, and only "
+"Insignificant Space Handling is applied in the Insignificant "
+"Character Handling step.",
+DIRSTRING_SYNTAX_OID, 0, dirStringCompat_syntaxes}, /* matching rule desc */
+ {"caseExactMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseExactMatch matching rule plugin"}, /* plugin desc */
+ caseExactMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, ces_filter_ava, NULL, ces_values2keys,
+ ces_assertion2keys_ava, NULL, ces_compare},
+{{"2.5.13.6", NULL, "caseExactOrderingMatch", "The caseExactOrderingMatch rule compares an assertion value of the "
+"Directory String syntax to an attribute value of a syntax (e.g., the "
+"Directory String, Printable String, Country String, or Telephone "
+"Number syntax) whose corresponding ASN.1 type is DirectoryString or "
+"one of its alternative string types. "
+"The rule evaluates to TRUE if and only if, in the code point "
+"collation order, the prepared attribute value character string "
+"appears earlier than the prepared assertion value character string; "
+"i.e., the attribute value is \"less than\" the assertion value. "
+"In preparing the attribute value and assertion value for comparison, "
+"characters are not case folded in the Map preparation step, and only "
+"Insignificant Space Handling is applied in the Insignificant "
+"Character Handling step.",
+DIRSTRING_SYNTAX_OID, 0, dirStringCompat_syntaxes}, /* matching rule desc */
+ {"caseExactOrderingMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseExactOrderingMatch matching rule plugin"}, /* plugin desc */
+ caseExactOrderingMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, ces_filter_ava, NULL, ces_values2keys,
+ ces_assertion2keys_ava, NULL, ces_compare},
+{{"2.5.13.7", NULL, "caseExactSubstringsMatch", "The caseExactSubstringsMatch rule compares an assertion value of the "
+"Substring Assertion syntax to an attribute value of a syntax (e.g., "
+"the Directory String, Printable String, Country String, or Telephone "
+"Number syntax) whose corresponding ASN.1 type is DirectoryString or "
+"one of its alternative string types. "
+"The rule evaluates to TRUE if and only if (1) the prepared substrings "
+"of the assertion value match disjoint portions of the prepared "
+"attribute value character string in the order of the substrings in "
+"the assertion value, (2) an <initial> substring, if present, matches "
+"the beginning of the prepared attribute value character string, and "
+"(3) a <final> substring, if present, matches the end of the prepared "
+"attribute value character string. A prepared substring matches a "
+"portion of the prepared attribute value character string if "
+"corresponding characters have the same code point. "
+"In preparing the attribute value and assertion value substrings for "
+"comparison, characters are not case folded in the Map preparation "
+"step, and only Insignificant Space Handling is applied in the "
+"Insignificant Character Handling step.",
+"1.3.6.1.4.1.1466.115.121.1.58", 0, dirString_syntaxes}, /* matching rule desc */
+ {"caseExactSubstringsMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseExactSubstringsMatch matching rule plugin"}, /* plugin desc */
+ caseExactSubstringsMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, NULL, ces_filter_sub, ces_values2keys,
+ NULL, ces_assertion2keys_sub, ces_compare},
+{{CASEEXACTIA5SUBSTRINGSMATCH_OID, NULL, "caseExactIA5SubstringsMatch", "The caseExactIA5SubstringsMatch rule compares an assertion value of the "
+"Substring Assertion syntax to an attribute value of a syntax (e.g., "
+"the IA5 syntax) whose corresponding ASN.1 type is IA5 String or "
+"one of its alternative string types. "
+"The rule evaluates to TRUE if and only if (1) the prepared substrings "
+"of the assertion value match disjoint portions of the prepared "
+"attribute value character string in the order of the substrings in "
+"the assertion value, (2) an <initial> substring, if present, matches "
+"the beginning of the prepared attribute value character string, and "
+"(3) a <final> substring, if present, matches the end of the prepared "
+"attribute value character string. A prepared substring matches a "
+"portion of the prepared attribute value character string if "
+"corresponding characters have the same code point. "
+"In preparing the attribute value and assertion value substrings for "
+"comparison, characters are not case folded in the Map preparation "
+"step, and only Insignificant Space Handling is applied in the "
+"Insignificant Character Handling step.",
+"1.3.6.1.4.1.1466.115.121.1.58", 0, ia5String_syntaxes}, /* matching rule desc */
+ {"caseExactIA5SubstringsMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseExactIA5SubstringsMatch matching rule plugin"}, /* plugin desc */
+ caseExactIA5SubstringsMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, NULL, ces_filter_sub, ces_values2keys,
+ NULL, ces_assertion2keys_sub, ces_compare}
+};
+
+static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
+
+static int
+matching_rule_plugin_init(Slapi_PBlock *pb)
+{
+ return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
+}
+
+static int
+register_matching_rule_plugins()
+{
+ return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
+}
/*
* register_ces_like_plugin(): register all items for a cis-like plugin.
@@ -124,6 +262,7 @@ ces_init( Slapi_PBlock *pb )
LDAPDebug( LDAP_DEBUG_PLUGIN, "=> ces_init\n", 0, 0, 0 );
rc = register_ces_like_plugin(pb,&ia5_pdesc,ia5_names,IA5STRING_SYNTAX_OID, ia5_validate);
+ rc |= register_matching_rule_plugins();
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= ces_init %d\n", rc, 0, 0 );
return( rc );
diff --git a/ldap/servers/plugins/syntaxes/cis.c b/ldap/servers/plugins/syntaxes/cis.c
index 4a15e5e2..77f6d55e 100644
--- a/ldap/servers/plugins/syntaxes/cis.c
+++ b/ldap/servers/plugins/syntaxes/cis.c
@@ -95,16 +95,6 @@ static char *time_names[] = { "GeneralizedTime", "time",
#define GENERALIZEDTIMEMATCH_OID "2.5.13.27"
#define GENERALIZEDTIMEORDERINGMATCH_OID "2.5.13.28"
-static Slapi_MatchingRuleEntry
-generalizedTimeMatch = { GENERALIZEDTIMEMATCH_OID, NULL /* no alias? */,
- "generalizedTimeMatch", "The rule evaluates to TRUE if and only if the attribute value represents the same universal coordinated time as the assertion value.",
- GENERALIZEDTIME_SYNTAX_OID, 0 /* not obsolete */ };
-
-static Slapi_MatchingRuleEntry
-generalizedTimeOrderingMatch = { GENERALIZEDTIMEORDERINGMATCH_OID, NULL /* no alias? */,
- "generalizedTimeOrderingMatch", "The rule evaluates to TRUE if and only if the attribute value represents a universal coordinated time that is earlier than the universal coordinated time represented by the assertion value.",
- GENERALIZEDTIME_SYNTAX_OID, 0 /* not obsolete */ };
-
static char *country_names[] = { "Country String",
COUNTRYSTRING_SYNTAX_OID, 0};
@@ -180,6 +170,248 @@ static Slapi_PluginDesc printable_pdesc = { "printablestring-syntax",
VENDOR, DS_PACKAGE_VERSION,
"Printable String attribtue syntax plugin" };
+static const char *generalizedTimeMatch_names[] = {"generalizedTimeMatch", GENERALIZEDTIMEMATCH_OID, NULL};
+static const char *generalizedTimeOrderingMatch_names[] = {"generalizedTimeOrderingMatch", GENERALIZEDTIMEORDERINGMATCH_OID, NULL};
+static const char *booleanMatch_names[] = {"booleanMatch", "2.5.13.13", NULL};
+static const char *caseIgnoreIA5Match_names[] = {"caseIgnoreIA5Match", "1.3.6.1.4.1.1466.109.114.2", NULL};
+static const char *caseIgnoreIA5SubstringsMatch_names[] = {"caseIgnoreIA5SubstringsMatch", "1.3.6.1.4.1.1466.109.114.3", NULL};
+static const char *caseIgnoreListMatch_names[] = {"caseIgnoreListMatch", "2.5.13.11", NULL};
+static const char *caseIgnoreListSubstringsMatch_names[] = {"caseIgnoreListSubstringsMatch", "2.5.13.12", NULL};
+static const char *caseIgnoreMatch_names[] = {"caseIgnoreMatch", "2.5.13.2", NULL};
+static const char *caseIgnoreOrderingMatch_names[] = {"caseIgnoreOrderingMatch", "2.5.13.3", NULL};
+static const char *caseIgnoreSubstringsMatch_names[] = {"caseIgnoreSubstringsMatch", "2.5.13.4", NULL};
+static const char *directoryStringFirstComponentMatch_names[] = {"directoryStringFirstComponentMatch", "2.5.13.31", NULL};
+static const char *objectIdentifierMatch_names[] = {"objectIdentifierMatch", "2.5.13.0", NULL};
+static const char *objectIdentifierFirstComponentMatch_names[] = {"objectIdentifierFirstComponentMatch", "2.5.13.30", NULL};
+
+static char *dirString_syntaxes[] = {COUNTRYSTRING_SYNTAX_OID,
+ DIRSTRING_SYNTAX_OID,
+ PRINTABLESTRING_SYNTAX_OID,NULL};
+static char *dirStringCompat_syntaxes[] = {COUNTRYSTRING_SYNTAX_OID,
+ PRINTABLESTRING_SYNTAX_OID,NULL};
+static char *caseIgnoreIA5SubstringsMatch_syntaxes[] = {IA5STRING_SYNTAX_OID,NULL};
+static char *caseIgnoreListSubstringsMatch_syntaxes[] = {POSTALADDRESS_SYNTAX_OID,NULL};
+static char *objectIdentifierFirstComponentMatch_syntaxes[] = {DIRSTRING_SYNTAX_OID, NULL};
+
+static struct mr_plugin_def mr_plugin_table[] = {
+{{GENERALIZEDTIMEMATCH_OID, NULL /* no alias? */,
+ "generalizedTimeMatch", "The rule evaluates to TRUE if and only if the attribute value represents the same universal coordinated time as the assertion value.",
+ GENERALIZEDTIME_SYNTAX_OID, 0 /* not obsolete */, NULL /* no other syntaxes supported */ },
+ {"generalizedTimeMatch-mr", VENDOR, DS_PACKAGE_VERSION, "generalizedTimeMatch matching rule plugin"}, /* plugin desc */
+ generalizedTimeMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, cis_compare},
+{{GENERALIZEDTIMEORDERINGMATCH_OID, NULL /* no alias? */,
+ "generalizedTimeOrderingMatch", "The rule evaluates to TRUE if and only if the attribute value represents a universal coordinated time that is earlier than the universal coordinated time represented by the assertion value.",
+ GENERALIZEDTIME_SYNTAX_OID, 0 /* not obsolete */, NULL /* no other syntaxes supported */ },
+ {"generalizedTimeOrderingMatch-mr", VENDOR, DS_PACKAGE_VERSION, "generalizedTimeOrderingMatch matching rule plugin"}, /* plugin desc */
+ generalizedTimeOrderingMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, cis_compare},
+/* strictly speaking, boolean is case sensitive */
+{{"2.5.13.13", NULL, "booleanMatch", "The booleanMatch rule compares an assertion value of the Boolean "
+"syntax to an attribute value of a syntax (e.g., the Boolean syntax) "
+"whose corresponding ASN.1 type is BOOLEAN. "
+"The rule evaluates to TRUE if and only if the attribute value and the "
+"assertion value are both TRUE or both FALSE.", BOOLEAN_SYNTAX_OID, 0, NULL /* no other syntaxes supported */}, /* matching rule desc */
+ {"booleanMatch-mr", VENDOR, DS_PACKAGE_VERSION, "booleanMatch matching rule plugin"}, /* plugin desc */
+ booleanMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, cis_compare},
+{{"1.3.6.1.4.1.1466.109.114.2", NULL, "caseIgnoreIA5Match", "The caseIgnoreIA5Match rule compares an assertion value of the IA5 "
+"String syntax to an attribute value of a syntax (e.g., the IA5 String "
+"syntax) whose corresponding ASN.1 type is IA5String. "
+"The rule evaluates to TRUE if and only if the prepared attribute "
+"value character string and the prepared assertion value character "
+"string have the same number of characters and corresponding "
+"characters have the same code point. "
+"In preparing the attribute value and assertion value for comparison, "
+"characters are case folded in the Map preparation step, and only "
+"Insignificant Space Handling is applied in the Insignificant "
+"Character Handling step.", IA5STRING_SYNTAX_OID, 0, NULL /* no other syntaxes supported */}, /* matching rule desc */
+ {"caseIgnoreIA5Match-mr", VENDOR, DS_PACKAGE_VERSION, "caseIgnoreIA5Match matching rule plugin"}, /* plugin desc */
+ caseIgnoreIA5Match_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, cis_compare},
+{{"1.3.6.1.4.1.1466.109.114.3", NULL, "caseIgnoreIA5SubstringsMatch", "The caseIgnoreIA5SubstringsMatch rule compares an assertion value of "
+"the Substring Assertion syntax to an attribute value of a syntax "
+"(e.g., the IA5 String syntax) whose corresponding ASN.1 type is "
+"IA5String. "
+"The rule evaluates to TRUE if and only if (1) the prepared substrings "
+"of the assertion value match disjoint portions of the prepared "
+"attribute value character string in the order of the substrings in "
+"the assertion value, (2) an <initial> substring, if present, matches "
+"the beginning of the prepared attribute value character string, and "
+"(3) a <final> substring, if present, matches the end of the prepared "
+"attribute value character string. A prepared substring matches a "
+"portion of the prepared attribute value character string if "
+"corresponding characters have the same code point. "
+"In preparing the attribute value and assertion value substrings for "
+"comparison, characters are case folded in the Map preparation step, "
+"and only Insignificant Space Handling is applied in the Insignificant "
+"Character Handling step.", "1.3.6.1.4.1.1466.115.121.1.58", 0, caseIgnoreIA5SubstringsMatch_syntaxes}, /* matching rule desc */
+ {"caseIgnoreIA5SubstringsMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseIgnoreIA5SubstringsMatch matching rule plugin"}, /* plugin desc */
+ caseIgnoreIA5SubstringsMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, NULL, cis_filter_sub, cis_values2keys,
+ NULL, cis_assertion2keys_sub, NULL},
+{{"2.5.13.2", NULL, "caseIgnoreMatch", "The caseIgnoreMatch rule compares an assertion value of the Directory "
+"String syntax to an attribute value of a syntax (e.g., the Directory "
+"String, Printable String, Country String, or Telephone Number syntax) "
+"whose corresponding ASN.1 type is DirectoryString or one of its "
+"alternative string types. "
+"The rule evaluates to TRUE if and only if the prepared attribute "
+"value character string and the prepared assertion value character "
+"string have the same number of characters and corresponding "
+"characters have the same code point. "
+"In preparing the attribute value and assertion value for comparison, "
+"characters are case folded in the Map preparation step, and only "
+"Insignificant Space Handling is applied in the Insignificant "
+"Character Handling step.", DIRSTRING_SYNTAX_OID, 0, dirStringCompat_syntaxes}, /* matching rule desc */
+ {"caseIgnoreMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseIgnoreMatch matching rule plugin"}, /* plugin desc */
+ caseIgnoreMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, cis_compare},
+{{"2.5.13.3", NULL, "caseIgnoreOrderingMatch", "The caseIgnoreOrderingMatch rule compares an assertion value of the "
+"Directory String syntax to an attribute value of a syntax (e.g., the "
+"Directory String, Printable String, Country String, or Telephone "
+"Number syntax) whose corresponding ASN.1 type is DirectoryString or "
+"one of its alternative string types. "
+"The rule evaluates to TRUE if and only if, in the code point "
+"collation order, the prepared attribute value character string "
+"appears earlier than the prepared assertion value character string; "
+"i.e., the attribute value is \"less than\" the assertion value. "
+"In preparing the attribute value and assertion value for comparison, "
+"characters are case folded in the Map preparation step, and only "
+"Insignificant Space Handling is applied in the Insignificant "
+"Character Handling step.", DIRSTRING_SYNTAX_OID, 0, dirStringCompat_syntaxes}, /* matching rule desc */
+ {"caseIgnoreOrderingMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseIgnoreOrderingMatch matching rule plugin"}, /* plugin desc */
+ caseIgnoreOrderingMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, cis_compare},
+{{"2.5.13.4", NULL, "caseIgnoreSubstringsMatch", "The caseIgnoreSubstringsMatch rule compares an assertion value of the "
+"Substring Assertion syntax to an attribute value of a syntax (e.g., "
+"the Directory String, Printable String, Country String, or Telephone "
+"Number syntax) whose corresponding ASN.1 type is DirectoryString or "
+"one of its alternative string types. "
+"The rule evaluates to TRUE if and only if (1) the prepared substrings "
+"of the assertion value match disjoint portions of the prepared "
+"attribute value character string in the order of the substrings in "
+"the assertion value, (2) an <initial> substring, if present, matches "
+"the beginning of the prepared attribute value character string, and "
+"(3) a <final> substring, if present, matches the end of the prepared "
+"attribute value character string. A prepared substring matches a "
+"portion of the prepared attribute value character string if "
+"corresponding characters have the same code point. "
+"In preparing the attribute value and assertion value substrings for "
+"comparison, characters are case folded in the Map preparation step, "
+"and only Insignificant Space Handling is applied in the Insignificant "
+"Character Handling step.", "1.3.6.1.4.1.1466.115.121.1.58", 0, dirString_syntaxes}, /* matching rule desc */
+ {"caseIgnoreSubstringsMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseIgnoreSubstringsMatch matching rule plugin"}, /* plugin desc */
+ caseIgnoreSubstringsMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, NULL, cis_filter_sub, cis_values2keys,
+ NULL, cis_assertion2keys_sub, cis_compare},
+{{"2.5.13.11", NULL, "caseIgnoreListMatch", "The caseIgnoreListMatch rule compares an assertion value that is a "
+"sequence of strings to an attribute value of a syntax (e.g., the "
+"Postal Address syntax) whose corresponding ASN.1 type is a SEQUENCE "
+"OF the DirectoryString ASN.1 type. "
+"The rule evaluates to TRUE if and only if the attribute value and the "
+"assertion value have the same number of strings and corresponding "
+"strings (by position) match according to the caseIgnoreMatch matching "
+"rule. "
+"In [X.520], the assertion syntax for this matching rule is defined to "
+"be: "
+" SEQUENCE OF DirectoryString {ub-match} "
+"That is, it is different from the corresponding type for the Postal "
+"Address syntax. The choice of the Postal Address syntax for the "
+"assertion syntax of the caseIgnoreListMatch in LDAP should not be "
+"seen as limiting the matching rule to apply only to attributes with "
+"the Postal Address syntax.", POSTALADDRESS_SYNTAX_OID, 0, NULL /* postal syntax only */}, /* matching rule desc */
+ {"caseIgnoreListMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseIgnoreListMatch matching rule plugin"}, /* plugin desc */
+ caseIgnoreListMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, cis_compare},
+{{"2.5.13.12", NULL, "caseIgnoreListSubstringsMatch", "The caseIgnoreListSubstringsMatch rule compares an assertion value of "
+"the Substring Assertion syntax to an attribute value of a syntax "
+"(e.g., the Postal Address syntax) whose corresponding ASN.1 type is a "
+"SEQUENCE OF the DirectoryString ASN.1 type. "
+"The rule evaluates to TRUE if and only if the assertion value "
+"matches, per the caseIgnoreSubstringsMatch rule, the character string "
+"formed by concatenating the strings of the attribute value, except "
+"that none of the <initial>, <any>, or <final> substrings of the "
+"assertion value are considered to match a substring of the "
+"concatenated string which spans more than one of the original strings "
+"of the attribute value. "
+"Note that, in terms of the LDAP-specific encoding of the Postal "
+"Address syntax, the concatenated string omits the <DOLLAR> line "
+"separator and the escaping of \"\\\" and \"$\" characters.",
+"1.3.6.1.4.1.1466.115.121.1.58", 0, caseIgnoreListSubstringsMatch_syntaxes}, /* matching rule desc */
+ {"caseIgnoreListSubstringsMatch-mr", VENDOR, DS_PACKAGE_VERSION, "caseIgnoreListSubstringsMatch matching rule plugin"}, /* plugin desc */
+ caseIgnoreListSubstringsMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, NULL, cis_filter_sub, cis_values2keys,
+ NULL, cis_assertion2keys_sub, cis_compare},
+{{"2.5.13.0", NULL, "objectIdentifierMatch", "The objectIdentifierMatch rule compares an assertion value of the OID "
+"syntax to an attribute value of a syntax (e.g., the OID syntax) whose "
+"corresponding ASN.1 type is OBJECT IDENTIFIER. "
+"The rule evaluates to TRUE if and only if the assertion value and the "
+"attribute value represent the same object identifier; that is, the "
+"same sequence of integers, whether represented explicitly in the "
+"<numericoid> form of <oid> or implicitly in the <descr> form (see "
+"[RFC4512]). "
+"If an LDAP client supplies an assertion value in the <descr> form and "
+"the chosen descriptor is not recognized by the server, then the "
+"objectIdentifierMatch rule evaluates to Undefined.",
+OID_SYNTAX_OID, 0, NULL /* OID syntax only for now */}, /* matching rule desc */
+ {"objectIdentifierMatch-mr", VENDOR, DS_PACKAGE_VERSION, "objectIdentifierMatch matching rule plugin"}, /* plugin desc */
+ objectIdentifierMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, cis_compare},
+{{"2.5.13.31", NULL, "directoryStringFirstComponentMatch", "The directoryStringFirstComponentMatch rule compares an assertion "
+"value of the Directory String syntax to an attribute value of a "
+"syntax whose corresponding ASN.1 type is a SEQUENCE with a mandatory "
+"first component of the DirectoryString ASN.1 type. "
+"Note that the assertion syntax of this matching rule differs from the "
+"attribute syntax of attributes for which this is the equality "
+"matching rule. "
+"The rule evaluates to TRUE if and only if the assertion value matches "
+"the first component of the attribute value using the rules of "
+"caseIgnoreMatch.", DIRSTRING_SYNTAX_OID, 0, dirStringCompat_syntaxes}, /* matching rule desc */
+ {"directoryStringFirstComponentMatch-mr", VENDOR, DS_PACKAGE_VERSION, "directoryStringFirstComponentMatch matching rule plugin"}, /* plugin desc */
+ directoryStringFirstComponentMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, NULL},
+{{"2.5.13.30", NULL, "objectIdentifierFirstComponentMatch",
+"The objectIdentifierFirstComponentMatch rule compares an assertion "
+"value of the OID syntax to an attribute value of a syntax (e.g., the "
+"Attribute Type Description, DIT Content Rule Description, LDAP Syntax "
+"Description, Matching Rule Description, Matching Rule Use "
+"Description, Name Form Description, or Object Class Description "
+"syntax) whose corresponding ASN.1 type is a SEQUENCE with a mandatory "
+"first component of the OBJECT IDENTIFIER ASN.1 type. "
+"Note that the assertion syntax of this matching rule differs from the "
+"attribute syntax of attributes for which this is the equality "
+"matching rule. "
+"The rule evaluates to TRUE if and only if the assertion value matches "
+"the first component of the attribute value using the rules of "
+"objectIdentifierMatch.", OID_SYNTAX_OID, 0, objectIdentifierFirstComponentMatch_syntaxes}, /* matching rule desc */
+ {"objectIdentifierFirstComponentMatch-mr", VENDOR, DS_PACKAGE_VERSION, "objectIdentifierFirstComponentMatch matching rule plugin"}, /* plugin desc */
+ objectIdentifierFirstComponentMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, cis_filter_ava, NULL, cis_values2keys,
+ cis_assertion2keys_ava, NULL, NULL}
+};
+
+static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
+
+static int
+matching_rule_plugin_init(Slapi_PBlock *pb)
+{
+ return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
+}
+
+static int
+register_matching_rule_plugins()
+{
+ return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
+}
/*
* register_cis_like_plugin(): register all items for a cis-like plugin.
@@ -229,6 +461,7 @@ cis_init( Slapi_PBlock *pb )
LDAPDebug( LDAP_DEBUG_PLUGIN, "=> cis_init\n", 0, 0, 0 );
rc = register_cis_like_plugin( pb, &dirstring_pdesc, dirstring_names,
DIRSTRING_SYNTAX_OID, dirstring_validate );
+ rc |= register_matching_rule_plugins();
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= cis_init %d\n", rc, 0, 0 );
return( rc );
}
@@ -254,9 +487,6 @@ time_init( Slapi_PBlock *pb )
LDAPDebug( LDAP_DEBUG_PLUGIN, "=> time_init\n", 0, 0, 0 );
rc = register_cis_like_plugin( pb, &time_pdesc, time_names,
GENERALIZEDTIME_SYNTAX_OID, time_validate );
- /* also register this plugin for matching rules */
- rc |= slapi_matchingrule_register(&generalizedTimeMatch);
- rc |= slapi_matchingrule_register(&generalizedTimeOrderingMatch);
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= time_init %d\n", rc, 0, 0 );
return( rc );
}
diff --git a/ldap/servers/plugins/syntaxes/dn.c b/ldap/servers/plugins/syntaxes/dn.c
index 9a41a05c..092175a0 100644
--- a/ldap/servers/plugins/syntaxes/dn.c
+++ b/ldap/servers/plugins/syntaxes/dn.c
@@ -65,6 +65,47 @@ static char *names[] = { "DN", DN_SYNTAX_OID, 0 };
static Slapi_PluginDesc pdesc = { "dn-syntax", VENDOR,
DS_PACKAGE_VERSION, "distinguished name attribute syntax plugin" };
+static const char *distinguishedNameMatch_names[] = {"distinguishedNameMatch", "2.5.13.1", NULL};
+
+static struct mr_plugin_def mr_plugin_table[] = {
+{{"2.5.13.1", NULL, "distinguishedNameMatch", "The distinguishedNameMatch rule compares an assertion value of the DN "
+"syntax to an attribute value of a syntax (e.g., the DN syntax) whose "
+"corresponding ASN.1 type is DistinguishedName. "
+"The rule evaluates to TRUE if and only if the attribute value and the "
+"assertion value have the same number of relative distinguished names "
+"and corresponding relative distinguished names (by position) are the "
+"same. A relative distinguished name (RDN) of the assertion value is "
+"the same as an RDN of the attribute value if and only if they have "
+"the same number of attribute value assertions and each attribute "
+"value assertion (AVA) of the first RDN is the same as the AVA of the "
+"second RDN with the same attribute type. The order of the AVAs is "
+"not significant. Also note that a particular attribute type may "
+"appear in at most one AVA in an RDN. Two AVAs with the same "
+"attribute type are the same if their values are equal according to "
+"the equality matching rule of the attribute type. If one or more of "
+"the AVA comparisons evaluate to Undefined and the remaining AVA "
+"comparisons return TRUE then the distinguishedNameMatch rule "
+"evaluates to Undefined.", DN_SYNTAX_OID, 0, NULL /* dn only for now */}, /* matching rule desc */
+ {"distinguishedNameMatch-mr", VENDOR, DS_PACKAGE_VERSION, "distinguishedNameMatch matching rule plugin"}, /* plugin desc */
+ distinguishedNameMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, dn_filter_ava, NULL, dn_values2keys,
+ dn_assertion2keys_ava, NULL, NULL},
+};
+
+static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
+
+static int
+matching_rule_plugin_init(Slapi_PBlock *pb)
+{
+ return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
+}
+
+static int
+register_matching_rule_plugins()
+{
+ return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
+}
+
int
dn_init( Slapi_PBlock *pb )
{
@@ -93,6 +134,7 @@ dn_init( Slapi_PBlock *pb )
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALIDATE,
(void *) dn_validate );
+ rc |= register_matching_rule_plugins();
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= dn_init %d\n", rc, 0, 0 );
return( rc );
}
diff --git a/ldap/servers/plugins/syntaxes/int.c b/ldap/servers/plugins/syntaxes/int.c
index ace93657..b3a7de08 100644
--- a/ldap/servers/plugins/syntaxes/int.c
+++ b/ldap/servers/plugins/syntaxes/int.c
@@ -65,16 +65,59 @@ static char *names[] = { "INTEGER", "int", INTEGER_SYNTAX_OID, 0 };
static Slapi_PluginDesc pdesc = { "int-syntax", VENDOR,
DS_PACKAGE_VERSION, "integer attribute syntax plugin" };
-static Slapi_MatchingRuleEntry
-integerMatch = { INTEGERMATCH_OID, NULL /* no alias? */,
- "integerMatch", "The rule evaluates to TRUE if and only if the attribute value and the assertion value are the same integer value.",
- INTEGER_SYNTAX_OID, 0 /* not obsolete */ };
+static const char *integerMatch_names[] = {"integerMatch", INTEGERMATCH_OID, NULL};
+static const char *integerOrderingMatch_names[] = {"integerOrderingMatch", INTEGERORDERINGMATCH_OID, NULL};
+static const char *integerFirstComponentMatch_names[] = {"integerFirstComponentMatch", "2.5.13.29", NULL};
+
+/* hack for now until we can support all of the rfc4517 syntaxes */
+static char *integerFirstComponentMatch_syntaxes[] = {DIRSTRING_SYNTAX_OID, NULL};
+
+static struct mr_plugin_def mr_plugin_table[] = {
+{{INTEGERMATCH_OID, NULL /* no alias? */,
+ "integerMatch", "The rule evaluates to TRUE if and only if the attribute value and the assertion value are the same integer value.",
+ INTEGER_SYNTAX_OID, 0 /* not obsolete */, NULL /* no other compatible syntaxes */ },
+ {"integerMatch-mr", VENDOR, DS_PACKAGE_VERSION, "integerMatch matching rule plugin" },
+ integerMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, int_filter_ava, NULL, int_values2keys,
+ int_assertion2keys, NULL, int_compare},
+{{INTEGERORDERINGMATCH_OID, NULL /* no alias? */,
+ "integerOrderingMatch", "The rule evaluates to TRUE if and only if the integer value of the attribute value is less than the integer value of the assertion value.",
+ INTEGER_SYNTAX_OID, 0 /* not obsolete */, NULL /* no other compatible syntaxes */ },
+ {"integerOrderingMatch-mr", VENDOR, DS_PACKAGE_VERSION, "integerOrderingMatch matching rule plugin" },
+ integerOrderingMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, int_filter_ava, NULL, int_values2keys,
+ int_assertion2keys, NULL, int_compare},
+/* NOTE: THIS IS BROKEN - WE DON'T SUPPORT THE FIRSTCOMPONENT match */
+{{"2.5.13.29", NULL, "integerFirstComponentMatch", "The integerFirstComponentMatch rule compares an assertion value of "
+"the Integer syntax to an attribute value of a syntax (e.g., the DIT "
+"Structure Rule Description syntax) whose corresponding ASN.1 type is "
+"a SEQUENCE with a mandatory first component of the INTEGER ASN.1 "
+"type. "
+"Note that the assertion syntax of this matching rule differs from the "
+"attribute syntax of attributes for which this is the equality "
+"matching rule. "
+"The rule evaluates to TRUE if and only if the assertion value and the "
+"first component of the attribute value are the same integer value.",
+INTEGER_SYNTAX_OID, 0, integerFirstComponentMatch_syntaxes}, /* matching rule desc */
+ {"integerFirstComponentMatch-mr", VENDOR, DS_PACKAGE_VERSION, "integerFirstComponentMatch matching rule plugin"}, /* plugin desc */
+ integerFirstComponentMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, int_filter_ava, NULL, int_values2keys,
+ int_assertion2keys, NULL, int_compare},
+};
+
+static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
-static Slapi_MatchingRuleEntry
-integerOrderingMatch = { INTEGERORDERINGMATCH_OID, NULL /* no alias? */,
- "integerOrderingMatch", "The rule evaluates to TRUE if and only if the integer value of the attribute value is less than the integer value of the assertion value.",
- INTEGER_SYNTAX_OID, 0 /* not obsolete */ };
+static int
+matching_rule_plugin_init(Slapi_PBlock *pb)
+{
+ return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
+}
+static int
+register_matching_rule_plugins()
+{
+ return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
+}
int
int_init( Slapi_PBlock *pb )
@@ -105,10 +148,7 @@ int_init( Slapi_PBlock *pb )
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALIDATE,
(void *) int_validate );
- /* also register this plugin for matching rules */
- rc |= slapi_matchingrule_register(&integerMatch);
- rc |= slapi_matchingrule_register(&integerOrderingMatch);
-
+ rc |= register_matching_rule_plugins();
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= int_init %d\n", rc, 0, 0 );
return( rc );
}
diff --git a/ldap/servers/plugins/syntaxes/nameoptuid.c b/ldap/servers/plugins/syntaxes/nameoptuid.c
index b46ac533..8a76e05d 100644
--- a/ldap/servers/plugins/syntaxes/nameoptuid.c
+++ b/ldap/servers/plugins/syntaxes/nameoptuid.c
@@ -66,6 +66,46 @@ static char *names[] = { "Name And Optional UID", "nameoptuid", NAMEANDOPTIONALU
static Slapi_PluginDesc pdesc = { "nameoptuid-syntax", VENDOR, DS_PACKAGE_VERSION,
"Name And Optional UID attribute syntax plugin" };
+static const char *uniqueMemberMatch_names[] = {"uniqueMemberMatch", "2.5.13.23", NULL};
+static struct mr_plugin_def mr_plugin_table[] = {
+{{"2.5.13.23", NULL, "uniqueMemberMatch", "The uniqueMemberMatch rule compares an assertion value of the Name "
+"And Optional UID syntax to an attribute value of a syntax (e.g., the "
+"Name And Optional UID syntax) whose corresponding ASN.1 type is "
+"NameAndOptionalUID. "
+"The rule evaluates to TRUE if and only if the <distinguishedName> "
+"components of the assertion value and attribute value match according "
+"to the distinguishedNameMatch rule and either, (1) the <BitString> "
+"component is absent from both the attribute value and assertion "
+"value, or (2) the <BitString> component is present in both the "
+"attribute value and the assertion value and the <BitString> component "
+"of the assertion value matches the <BitString> component of the "
+"attribute value according to the bitStringMatch rule. "
+"Note that this matching rule has been altered from its description in "
+"X.520 [X.520] in order to make the matching rule commutative. Server "
+"implementors should consider using the original X.520 semantics "
+"(where the matching was less exact) for approximate matching of "
+"attributes with uniqueMemberMatch as the equality matching rule.",
+NAMEANDOPTIONALUID_SYNTAX_OID, 0, NULL /* no other syntaxes supported */}, /* matching rule desc */
+ {"uniqueMemberMatch-mr", VENDOR, DS_PACKAGE_VERSION, "uniqueMemberMatch matching rule plugin"}, /* plugin desc */
+ uniqueMemberMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, nameoptuid_filter_ava, NULL, nameoptuid_values2keys,
+ nameoptuid_assertion2keys_ava, NULL, nameoptuid_compare},
+};
+
+static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
+
+static int
+matching_rule_plugin_init(Slapi_PBlock *pb)
+{
+ return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
+}
+
+static int
+register_matching_rule_plugins()
+{
+ return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
+}
+
int
nameoptuid_init( Slapi_PBlock *pb )
{
@@ -99,6 +139,7 @@ nameoptuid_init( Slapi_PBlock *pb )
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALIDATE,
(void *) nameoptuid_validate );
+ rc |= register_matching_rule_plugins();
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= nameoptuid_init %d\n", rc, 0, 0 );
return( rc );
}
diff --git a/ldap/servers/plugins/syntaxes/numericstring.c b/ldap/servers/plugins/syntaxes/numericstring.c
index acda9acd..d1bf475d 100644
--- a/ldap/servers/plugins/syntaxes/numericstring.c
+++ b/ldap/servers/plugins/syntaxes/numericstring.c
@@ -49,10 +49,14 @@
static int numstr_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
Slapi_Value **bvals, int ftype, Slapi_Value **retVal );
+static int numstr_filter_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value **bvals );
static int numstr_values2keys( Slapi_PBlock *pb, Slapi_Value **val,
Slapi_Value ***ivals, int ftype );
static int numstr_assertion2keys( Slapi_PBlock *pb, Slapi_Value *val,
Slapi_Value ***ivals, int ftype );
+static int numstr_assertion2keys_sub( Slapi_PBlock *pb, char *initial, char **any,
+ char *final, Slapi_Value ***ivals );
static int numstr_compare(struct berval *v1, struct berval *v2);
static int numstr_validate(struct berval *val);
@@ -61,36 +65,65 @@ static char *names[] = { "Numeric String", "numstr", NUMERICSTRING_SYNTAX_OID, 0
#define NUMERICSTRINGMATCH_OID "2.5.13.8"
#define NUMERICSTRINGORDERINGMATCH_OID "2.5.13.9"
-#define NUMERICSTRINGSUBSTRINGMATCH_OID "2.5.13.10"
+#define NUMERICSTRINGSUBSTRINGSMATCH_OID "2.5.13.10"
static Slapi_PluginDesc pdesc = { "numstr-syntax", VENDOR,
DS_PACKAGE_VERSION, "numeric string attribute syntax plugin" };
-static Slapi_MatchingRuleEntry
-numericStringMatch = { NUMERICSTRINGMATCH_OID, NULL /* no alias? */,
- "numericStringMatch", "The rule evaluates to TRUE if and only if the prepared "
- "attribute value character string and the prepared assertion value character "
- "string have the same number of characters and corresponding characters have "
- "the same code point.",
- NUMERICSTRING_SYNTAX_OID, 0 /* not obsolete */ };
-
-static Slapi_MatchingRuleEntry
-numericStringOrderingMatch = { NUMERICSTRINGORDERINGMATCH_OID, NULL /* no alias? */,
- "numericStringOrderingMatch", "The rule evaluates to TRUE if and only if, "
- "in the code point collation order, the prepared attribute value character "
- "string appears earlier than the prepared assertion value character string; "
- "i.e., the attribute value is less than the assertion value.",
- NUMERICSTRING_SYNTAX_OID, 0 /* not obsolete */ };
-
-static Slapi_MatchingRuleEntry
-numericStringSubstringMatch = { NUMERICSTRINGSUBSTRINGMATCH_OID, NULL /* no alias? */,
- "numericStringSubstringMatch", "The rule evaluates to TRUE if and only if (1) "
- "the prepared substrings of the assertion value match disjoint portions of "
- "the prepared attribute value, (2) an initial substring, if present, matches "
- "the beginning of the prepared attribute value character string, and (3) a "
- "final substring, if present, matches the end of the prepared attribute value "
- "character string.",
- NUMERICSTRING_SYNTAX_OID, 0 /* not obsolete */ };
+static const char *numericStringMatch_names[] = {"numericStringMatch", NUMERICSTRINGMATCH_OID, NULL};
+static const char *numericStringOrderingMatch_names[] = {"numericStringOrderingMatch", NUMERICSTRINGORDERINGMATCH_OID, NULL};
+static const char *numericStringSubstringsMatch_names[] = {"numericStringSubstringsMatch", NUMERICSTRINGSUBSTRINGSMATCH_OID, NULL};
+
+static char *numericStringSubstringsMatch_syntaxes[] = {NUMERICSTRING_SYNTAX_OID,NULL};
+
+static struct mr_plugin_def mr_plugin_table[] = {
+{{NUMERICSTRINGMATCH_OID, NULL /* no alias? */,
+ "numericStringMatch", "The rule evaluates to TRUE if and only if the prepared "
+ "attribute value character string and the prepared assertion value character "
+ "string have the same number of characters and corresponding characters have "
+ "the same code point.",
+ NUMERICSTRING_SYNTAX_OID, 0 /* not obsolete */, NULL /* numstr syntax only for now */ },
+ {"numericStringMatch-mr", VENDOR, DS_PACKAGE_VERSION, "numericStringMatch matching rule plugin"}, /* plugin desc */
+ numericStringMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, numstr_filter_ava, NULL, numstr_values2keys,
+ numstr_assertion2keys, NULL, numstr_compare},
+{{NUMERICSTRINGORDERINGMATCH_OID, NULL /* no alias? */,
+ "numericStringOrderingMatch", "The rule evaluates to TRUE if and only if, "
+ "in the code point collation order, the prepared attribute value character "
+ "string appears earlier than the prepared assertion value character string; "
+ "i.e., the attribute value is less than the assertion value.",
+ NUMERICSTRING_SYNTAX_OID, 0 /* not obsolete */, NULL /* numstr syntax only for now */ },
+ {"numericStringOrderingMatch-mr", VENDOR, DS_PACKAGE_VERSION, "numericStringOrderingMatch matching rule plugin"}, /* plugin desc */
+ numericStringOrderingMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, numstr_filter_ava, NULL, numstr_values2keys,
+ numstr_assertion2keys, NULL, numstr_compare},
+{{NUMERICSTRINGSUBSTRINGSMATCH_OID, NULL /* no alias? */,
+ "numericStringSubstringsMatch", "The rule evaluates to TRUE if and only if (1) "
+ "the prepared substrings of the assertion value match disjoint portions of "
+ "the prepared attribute value, (2) an initial substring, if present, matches "
+ "the beginning of the prepared attribute value character string, and (3) a "
+ "final substring, if present, matches the end of the prepared attribute value "
+ "character string.",
+ "1.3.6.1.4.1.1466.115.121.1.58", 0 /* not obsolete */, numericStringSubstringsMatch_syntaxes}, /* matching rule desc */
+ {"numericStringSubstringsMatch-mr", VENDOR, DS_PACKAGE_VERSION, "numericStringSubstringsMatch matching rule plugin"}, /* plugin desc */
+ numericStringSubstringsMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, NULL, numstr_filter_sub, numstr_values2keys,
+ NULL, numstr_assertion2keys_sub, numstr_compare},
+};
+
+static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
+
+static int
+matching_rule_plugin_init(Slapi_PBlock *pb)
+{
+ return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
+}
+
+static int
+register_matching_rule_plugins()
+{
+ return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
+}
int
numstr_init( Slapi_PBlock *pb )
@@ -121,11 +154,7 @@ numstr_init( Slapi_PBlock *pb )
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALIDATE,
(void *) numstr_validate );
- /* also register this plugin for matching rules */
- rc |= slapi_matchingrule_register(&numericStringMatch);
- rc |= slapi_matchingrule_register(&numericStringOrderingMatch);
- rc |= slapi_matchingrule_register(&numericStringSubstringMatch);
-
+ rc |= register_matching_rule_plugins();
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= numstr_init %d\n", rc, 0, 0 );
return( rc );
}
@@ -139,6 +168,18 @@ numstr_filter_ava( Slapi_PBlock *pb, struct berval *bvfilter,
}
static int
+numstr_filter_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value **bvals
+)
+{
+ return( string_filter_sub( pb, initial, any, final, bvals, SYNTAX_SI | SYNTAX_CES ) );
+}
+
+static int
numstr_values2keys( Slapi_PBlock *pb, Slapi_Value **vals, Slapi_Value ***ivals, int ftype )
{
return( string_values2keys( pb, vals, ivals, SYNTAX_SI | SYNTAX_CES,
@@ -152,6 +193,19 @@ numstr_assertion2keys( Slapi_PBlock *pb, Slapi_Value *val, Slapi_Value ***ivals,
SYNTAX_SI | SYNTAX_CES, ftype ));
}
+static int
+numstr_assertion2keys_sub(
+ Slapi_PBlock *pb,
+ char *initial,
+ char **any,
+ char *final,
+ Slapi_Value ***ivals
+)
+{
+ return( string_assertion2keys_sub( pb, initial, any, final, ivals,
+ SYNTAX_SI | SYNTAX_CES ) );
+}
+
static int numstr_compare(
struct berval *v1,
struct berval *v2
diff --git a/ldap/servers/plugins/syntaxes/syntax.h b/ldap/servers/plugins/syntaxes/syntax.h
index 4007028f..ec3d5f03 100644
--- a/ldap/servers/plugins/syntaxes/syntax.h
+++ b/ldap/servers/plugins/syntaxes/syntax.h
@@ -61,10 +61,6 @@
#define SUBMIDDLE 3
#define SUBEND 3
-#ifndef MIN
-#define MIN( a, b ) (a < b ? a : b )
-#endif
-
#define SYNTAX_PLUGIN_SUBSYSTEM "syntax-plugin"
/* The following are derived from RFC 4512, section 1.4. */
@@ -131,4 +127,56 @@ int distinguishedname_validate( const char *begin, const char *end );
int rdn_validate( const char *begin, const char *end, const char **last );
int bitstring_validate_internal(const char *begin, const char *end);
+struct mr_plugin_def {
+ Slapi_MatchingRuleEntry mr_def_entry; /* for slapi_matchingrule_register */
+ Slapi_PluginDesc mr_plg_desc; /* for SLAPI_PLUGIN_DESCRIPTION */
+ const char **mr_names; /* list of oid and names, NULL terminated SLAPI_PLUGIN_MR_NAMES */
+ /* these are optional for new style mr plugins */
+ IFP mr_filter_create; /* old style factory function SLAPI_PLUGIN_MR_FILTER_CREATE_FN */
+ IFP mr_indexer_create; /* old style factory function SLAPI_PLUGIN_MR_INDEXER_CREATE_FN */
+ /* new style syntax plugin functions */
+ /* not all functions will apply to all matching rule types */
+ /* e.g. a SUBSTR rule will not have a filter_ava func */
+ IFP mr_filter_ava; /* SLAPI_PLUGIN_MR_FILTER_AVA */
+ IFP mr_filter_sub; /* SLAPI_PLUGIN_MR_FILTER_SUB */
+ IFP mr_values2keys; /* SLAPI_PLUGIN_MR_VALUES2KEYS */
+ IFP mr_assertion2keys_ava; /* SLAPI_PLUGIN_MR_ASSERTION2KEYS_AVA */
+ IFP mr_assertion2keys_sub; /* SLAPI_PLUGIN_MR_ASSERTION2KEYS_SUB */
+ IFP mr_compare; /* SLAPI_PLUGIN_MR_COMPARE - only for ORDERING */
+};
+
+int syntax_register_matching_rule_plugins(struct mr_plugin_def mr_plugin_table[], size_t mr_plugin_table_size, IFP matching_rule_plugin_init);
+int syntax_matching_rule_plugin_init(Slapi_PBlock *pb, struct mr_plugin_def mr_plugin_table[], size_t mr_plugin_table_size);
+
#endif
+
+#ifdef UNSUPPORTED_MATCHING_RULES
+/* list of names/oids/aliases for each matching rule */
+static const char *keywordMatch_names[] = {"keywordMatch", "2.5.13.33", NULL};
+static const char *wordMatch_names[] = {"wordMatch", "2.5.13.32", NULL};
+/* table of matching rule plugin defs for mr register and plugin register */
+static struct mr_plugin_def mr_plugin_table[] = {
+{{"2.5.13.33", NULL, "keywordMatch", "The keywordMatch rule compares an assertion value of the Directory"
+"String syntax to an attribute value of a syntax (e.g., the Directory"
+"String syntax) whose corresponding ASN.1 type is DirectoryString."
+"The rule evaluates to TRUE if and only if the assertion value"
+"character string matches any keyword in the attribute value. The"
+"identification of keywords in the attribute value and the exactness"
+"of the match are both implementation specific.", "1.3.6.1.4.1.1466.115.121.1.15", 0}, /* matching rule desc */
+ {"keywordMatch-mr", VENDOR, DS_PACKAGE_VERSION, "keywordMatch matching rule plugin"}, /* plugin desc */
+ keywordMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, mr_filter_ava, mr_filter_sub, mr_values2keys,
+ mr_assertion2keys_ava, mr_assertion2keys_sub, mr_compare, keywordMatch_syntaxes},,
+{{"2.5.13.32", NULL, "wordMatch", "The wordMatch rule compares an assertion value of the Directory"
+"String syntax to an attribute value of a syntax (e.g., the Directory"
+"String syntax) whose corresponding ASN.1 type is DirectoryString."
+"The rule evaluates to TRUE if and only if the assertion value word"
+"matches, according to the semantics of caseIgnoreMatch, any word in"
+"the attribute value. The precise definition of a word is"
+"implementation specific.", "1.3.6.1.4.1.1466.115.121.1.15", 0}, /* matching rule desc */
+ {"wordMatch-mr", VENDOR, DS_PACKAGE_VERSION, "wordMatch matching rule plugin"}, /* plugin desc */
+ wordMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, mr_filter_ava, mr_filter_sub, mr_values2keys,
+ mr_assertion2keys_ava, mr_assertion2keys_sub, mr_compare, wordMatch_syntaxes},
+};
+#endif /* UNSUPPORTED_MATCHING_RULES */
diff --git a/ldap/servers/plugins/syntaxes/syntax_common.c b/ldap/servers/plugins/syntaxes/syntax_common.c
new file mode 100644
index 00000000..713d9a03
--- /dev/null
+++ b/ldap/servers/plugins/syntaxes/syntax_common.c
@@ -0,0 +1,117 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This Program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the License.
+ *
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link to the code of this Program
+ * through those well defined interfaces identified in the file named EXCEPTION
+ * found in the source code files (the "Approved Interfaces"). The files of
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
+ * the Approved Interfaces without causing the resulting work to be covered by
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "syntax.h"
+
+int
+syntax_register_matching_rule_plugins(
+ struct mr_plugin_def mr_plugin_table[],
+ size_t mr_plugin_table_size,
+ IFP matching_rule_plugin_init
+)
+{
+ int rc = -1;
+ int ii;
+
+ for (ii = 0; ii < mr_plugin_table_size; ++ii) {
+ char *argv[2];
+
+ argv[0] = mr_plugin_table[ii].mr_def_entry.mr_name;
+ argv[1] = NULL;
+ rc = slapi_register_plugin_ext("matchingrule", 1 /* enabled */,
+ "matching_rule_plugin_init",
+ matching_rule_plugin_init,
+ mr_plugin_table[ii].mr_def_entry.mr_name,
+ argv, NULL, PLUGIN_DEFAULT_PRECEDENCE);
+ }
+
+ return rc;
+}
+
+int
+syntax_matching_rule_plugin_init(
+ Slapi_PBlock *pb,
+ struct mr_plugin_def mr_plugin_table[],
+ size_t mr_plugin_table_size
+)
+{
+ int ii;
+ char **argv = NULL;
+ int rc = -1;
+ struct mr_plugin_def *mrpd = NULL;
+
+ slapi_pblock_get(pb, SLAPI_PLUGIN_ARGV, &argv);
+ if (!argv || !argv[0]) {
+ slapi_log_error(SLAPI_LOG_FATAL, "syntax_matching_rule_plugin_init",
+ "Error: matching rule plugin name not specified\n");
+ return rc;
+ }
+ for (ii = 0; ii < mr_plugin_table_size; ++ii) {
+ /* get the arguments - argv[0] is our plugin name */
+ /* find the plugin name in the table */
+ if (!strcmp(mr_plugin_table[ii].mr_def_entry.mr_name, argv[0])) {
+ mrpd = &mr_plugin_table[ii];
+ rc = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, &mrpd->mr_plg_desc);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, mrpd->mr_filter_create);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, mrpd->mr_indexer_create);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_MR_FILTER_AVA, mrpd->mr_filter_ava);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_MR_FILTER_SUB, mrpd->mr_filter_sub);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_MR_VALUES2KEYS, mrpd->mr_values2keys);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_MR_ASSERTION2KEYS_AVA, mrpd->mr_assertion2keys_ava);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_MR_ASSERTION2KEYS_SUB, mrpd->mr_assertion2keys_sub);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_MR_NAMES, mrpd->mr_names);
+ rc |= slapi_pblock_set(pb, SLAPI_PLUGIN_MR_COMPARE, mrpd->mr_compare);
+ break;
+ }
+ }
+
+ if (!mrpd) {
+ slapi_log_error(SLAPI_LOG_FATAL, "syntax_matching_rule_plugin_init",
+ "Error: matching rule plugin name [%s] not found\n",
+ argv[0]);
+ } else {
+ rc = slapi_matchingrule_register(&mrpd->mr_def_entry);
+ }
+
+ return rc;
+}
+
diff --git a/ldap/servers/plugins/syntaxes/tel.c b/ldap/servers/plugins/syntaxes/tel.c
index 8c74908b..10c7ced1 100644
--- a/ldap/servers/plugins/syntaxes/tel.c
+++ b/ldap/servers/plugins/syntaxes/tel.c
@@ -66,6 +66,67 @@ static char *names[] = { "TelephoneNumber", "tel", TELEPHONE_SYNTAX_OID, 0 };
static Slapi_PluginDesc pdesc = { "tele-syntax", VENDOR, DS_PACKAGE_VERSION,
"telephoneNumber attribute syntax plugin" };
+static const char *telephoneNumberMatch_names[] = {"telephoneNumberMatch", "2.5.13.20", NULL};
+static const char *telephoneNumberSubstringsMatch_names[] = {"telephoneNumberSubstringsMatch", "2.5.13.21", NULL};
+
+static char *telephoneNumberSubstringsMatch_syntaxes[] = {TELEPHONE_SYNTAX_OID, NULL};
+
+static struct mr_plugin_def mr_plugin_table[] = {
+{{"2.5.13.20", NULL, "telephoneNumberMatch", "The telephoneNumberMatch rule compares an assertion value of the "
+"Telephone Number syntax to an attribute value of a syntax (e.g., the "
+"Telephone Number syntax) whose corresponding ASN.1 type is a "
+"PrintableString representing a telephone number. "
+"The rule evaluates to TRUE if and only if the prepared attribute "
+"value character string and the prepared assertion value character "
+"string have the same number of characters and corresponding "
+"characters have the same code point. "
+"In preparing the attribute value and assertion value for comparison, "
+"characters are case folded in the Map preparation step, and only "
+"telephoneNumber Insignificant Character Handling is applied in the "
+"Insignificant Character Handling step.",
+TELEPHONE_SYNTAX_OID, 0, NULL /* tel syntax only */}, /* matching rule desc */
+ {"telephoneNumberMatch-mr", VENDOR, DS_PACKAGE_VERSION, "telephoneNumberMatch matching rule plugin"}, /* plugin desc */
+ telephoneNumberMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, tel_filter_ava, NULL, tel_values2keys,
+ tel_assertion2keys_ava, NULL, tel_compare},
+{{"2.5.13.21", NULL, "telephoneNumberSubstringsMatch", "The telephoneNumberSubstringsMatch rule compares an assertion value "
+"of the Substring Assertion syntax to an attribute value of a syntax "
+"(e.g., the Telephone Number syntax) whose corresponding ASN.1 type is "
+"a PrintableString representing a telephone number. "
+"The rule evaluates to TRUE if and only if (1) the prepared substrings "
+"of the assertion value match disjoint portions of the prepared "
+"attribute value character string in the order of the substrings in "
+"the assertion value, (2) an <initial> substring, if present, matches "
+"the beginning of the prepared attribute value character string, and "
+"(3) a <final> substring, if present, matches the end of the prepared "
+"attribute value character string. A prepared substring matches a "
+"portion of the prepared attribute value character string if "
+"corresponding characters have the same code point. "
+"In preparing the attribute value and assertion value substrings for "
+"comparison, characters are case folded in the Map preparation step, "
+"and only telephoneNumber Insignificant Character Handling is applied "
+"in the Insignificant Character Handling step.",
+"1.3.6.1.4.1.1466.115.121.1.58", 0, telephoneNumberSubstringsMatch_syntaxes}, /* matching rule desc */
+ {"telephoneNumberSubstringsMatch-mr", VENDOR, DS_PACKAGE_VERSION, "telephoneNumberSubstringsMatch matching rule plugin"}, /* plugin desc */
+ telephoneNumberSubstringsMatch_names, /* matching rule name/oid/aliases */
+ NULL, NULL, NULL, tel_filter_sub, tel_values2keys,
+ NULL, tel_assertion2keys_sub, tel_compare},
+};
+
+static size_t mr_plugin_table_size = sizeof(mr_plugin_table)/sizeof(mr_plugin_table[0]);
+
+static int
+matching_rule_plugin_init(Slapi_PBlock *pb)
+{
+ return syntax_matching_rule_plugin_init(pb, mr_plugin_table, mr_plugin_table_size);
+}
+
+static int
+register_matching_rule_plugins()
+{
+ return syntax_register_matching_rule_plugins(mr_plugin_table, mr_plugin_table_size, matching_rule_plugin_init);
+}
+
int
tel_init( Slapi_PBlock *pb )
{
@@ -99,6 +160,7 @@ tel_init( Slapi_PBlock *pb )
rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_SYNTAX_VALIDATE,
(void *) tel_validate );
+ rc |= register_matching_rule_plugins();
LDAPDebug( LDAP_DEBUG_PLUGIN, "<= tel_init %d\n", rc, 0, 0 );
return( rc );
}
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
index 11b272a0..f39c0e96 100644
--- a/ldap/servers/slapd/attrsyntax.c
+++ b/ldap/servers/slapd/attrsyntax.c
@@ -546,6 +546,9 @@ attr_syntax_dup( struct asyntaxinfo *a )
newas->asi_flags = a->asi_flags;
newas->asi_oid = slapi_ch_strdup( a->asi_oid);
newas->asi_syntaxlength = a->asi_syntaxlength;
+ newas->asi_mr_eq_plugin = a->asi_mr_eq_plugin;
+ newas->asi_mr_ord_plugin = a->asi_mr_ord_plugin;
+ newas->asi_mr_sub_plugin = a->asi_mr_sub_plugin;
return( newas );
}
@@ -658,9 +661,11 @@ attr_syntax_create(
{
char *s;
struct asyntaxinfo a;
+ int rc = LDAP_SUCCESS;
/* XXXmcs: had to cast away const in many places below */
memset(&a, 0, sizeof(a));
+ *asip = NULL;
a.asi_name = slapi_ch_strdup(attr_names[0]);
if ( NULL != attr_names[1] ) {
a.asi_aliases = (char **)&attr_names[1]; /* all but the zero'th element */
@@ -674,8 +679,45 @@ attr_syntax_create(
a.asi_origin = (char **)attr_origins;
a.asi_plugin = plugin_syntax_find( attr_syntax );
a.asi_syntaxlength = syntaxlength;
+ /* ideally, we would report an error and fail to start if there was some problem
+ with the matching rule - but since this functionality is new, and we might
+ cause havoc if lots of servers failed to start because of bogus schema, we
+ just report an error here - at some point in the future, we should actually
+ report an error and exit, or allow the user to control the behavior - for
+ now, just log an error, and address each case
+ */
+ if (mr_equality && !slapi_matchingrule_is_compat(mr_equality, attr_syntax)) {
+ slapi_log_error(SLAPI_LOG_FATAL, "attr_syntax_create",
+ "Error: the EQUALITY matching rule [%s] is not compatible "
+ "with the syntax [%s] for the attribute [%s]\n",
+ mr_equality, attr_syntax, attr_names[0]);
+/*
+ rc = LDAP_INAPPROPRIATE_MATCHING;
+ goto done;
+*/
+ }
a.asi_mr_eq_plugin = plugin_mr_find( mr_equality );
+ if (mr_ordering && !slapi_matchingrule_is_compat(mr_ordering, attr_syntax)) {
+ slapi_log_error(SLAPI_LOG_FATAL, "attr_syntax_create",
+ "Error: the ORDERING matching rule [%s] is not compatible "
+ "with the syntax [%s] for the attribute [%s]\n",
+ mr_ordering, attr_syntax, attr_names[0]);
+/*
+ rc = LDAP_INAPPROPRIATE_MATCHING;
+ goto done;
+*/
+ }
a.asi_mr_ord_plugin = plugin_mr_find( mr_ordering );
+ if (mr_substring && !slapi_matchingrule_is_compat(mr_substring, attr_syntax)) {
+ slapi_log_error(SLAPI_LOG_FATAL, "attr_syntax_create",
+ "Error: the SUBSTR matching rule [%s] is not compatible "
+ "with the syntax [%s] for the attribute [%s]\n",
+ mr_substring, attr_syntax, attr_names[0]);
+/*
+ rc = LDAP_INAPPROPRIATE_MATCHING;
+ goto done;
+*/
+ }
a.asi_mr_sub_plugin = plugin_mr_find( mr_substring );
a.asi_flags = flags;
@@ -694,9 +736,10 @@ attr_syntax_create(
}
*asip = attr_syntax_dup(&a);
+done:
slapi_ch_free((void **)&a.asi_name);
- return LDAP_SUCCESS;
+ return rc;
}
diff --git a/ldap/servers/slapd/match.c b/ldap/servers/slapd/match.c
index 24d9137b..241b182c 100644
--- a/ldap/servers/slapd/match.c
+++ b/ldap/servers/slapd/match.c
@@ -182,6 +182,7 @@ slapi_matchingrule_free(Slapi_MatchingRuleEntry **mrEntry,
slapi_ch_free((void **)&((*mrEntry)->mr_desc));
slapi_ch_free((void **)&((*mrEntry)->mr_syntax));
slapi_ch_free((void **)&((*mrEntry)->mr_oidalias));
+ slapi_ch_array_free((*mrEntry)->mr_compat_syntax);
}
slapi_ch_free((void **)mrEntry);
return;
@@ -244,6 +245,7 @@ int slapi_matchingrule_register(Slapi_MatchingRuleEntry *mrule)
slapi_ch_strdup((char *) mrule->mr_syntax);
}
newmrl->mr_entry->mr_obsolete = mrule->mr_obsolete;
+ newmrl->mr_entry->mr_compat_syntax = charray_dup(mrule->mr_compat_syntax);
for(mrl = g_get_global_mrl();
((NULL != mrl) && (NULL != mrl->mrl_next));
@@ -277,18 +279,57 @@ int slapi_matchingrule_unregister(char *oid)
int slapi_matchingrule_is_ordering(const char *oid_or_name, const char *syntax_oid)
{
struct matchingRuleList *mrl=NULL;
+
+ if (slapi_matchingrule_is_compat(oid_or_name, syntax_oid)) {
+ for (mrl = g_get_global_mrl(); mrl != NULL; mrl = mrl->mrl_next) {
+ if (mrl->mr_entry->mr_name && !strcasecmp(oid_or_name, mrl->mr_entry->mr_name)) {
+ return (mrl->mr_entry->mr_name &&
+ PL_strcasestr(mrl->mr_entry->mr_name, "ordering"));
+ }
+ if (mrl->mr_entry->mr_oid && !strcmp(oid_or_name, mrl->mr_entry->mr_oid)) {
+ return (mrl->mr_entry->mr_name &&
+ PL_strcasestr(mrl->mr_entry->mr_name, "ordering"));
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ See if a matching rule for this name or OID
+ is compatible with the given syntax.
+*/
+int slapi_matchingrule_is_compat(const char *mr_oid_or_name, const char *syntax_oid)
+{
+ struct matchingRuleList *mrl=NULL;
+ int found = 0;
+
for (mrl = g_get_global_mrl(); mrl != NULL; mrl = mrl->mrl_next) {
- if (mrl->mr_entry->mr_name && !strcasecmp(oid_or_name, mrl->mr_entry->mr_name)) {
- return (mrl->mr_entry->mr_name &&
- PL_strcasestr(mrl->mr_entry->mr_name, "ordering") &&
- !strcmp(mrl->mr_entry->mr_syntax, syntax_oid));
+ if (mrl->mr_entry->mr_name && !strcasecmp(mr_oid_or_name, mrl->mr_entry->mr_name)) {
+ found = 1;
+ break;
+ }
+ if (mrl->mr_entry->mr_oid && !strcmp(mr_oid_or_name, mrl->mr_entry->mr_oid)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found && mrl) {
+ char **mr_syntax;
+ if (!strcmp(mrl->mr_entry->mr_syntax, syntax_oid)) {
+ return 1;
}
- if (mrl->mr_entry->mr_oid && !strcmp(oid_or_name, mrl->mr_entry->mr_oid)) {
- return (mrl->mr_entry->mr_name &&
- PL_strcasestr(mrl->mr_entry->mr_name, "ordering") &&
- !strcmp(mrl->mr_entry->mr_syntax, syntax_oid));
+ for (mr_syntax = mrl->mr_entry->mr_compat_syntax;
+ mr_syntax;
+ mr_syntax++) {
+ if (!strcmp(*mr_syntax, syntax_oid)) {
+ return 1;
+ }
}
}
+
return 0;
}
diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c
index b8b0499c..194f8aef 100644
--- a/ldap/servers/slapd/plugin_mr.c
+++ b/ldap/servers/slapd/plugin_mr.c
@@ -94,21 +94,30 @@ slapi_get_global_mr_plugins()
struct slapdplugin *
plugin_mr_find( const char *nameoroid )
{
- struct slapdplugin *pi;
+ struct slapdplugin *pi = NULL;
- for ( pi = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); pi != NULL; pi = pi->plg_next ) {
+ for ( pi = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); (nameoroid != NULL) && (pi != NULL); pi = pi->plg_next ) {
if ( charray_inlist( pi->plg_mr_names, (char *)nameoroid ) ) {
break;
}
}
+
+ if (!nameoroid) {
+ pi = NULL;
+ }
+
+ if (nameoroid && !pi) {
+ slapi_log_error(SLAPI_LOG_CONFIG, "plugin_mr_find",
+ "Error: matching rule plugin for [%s] not found\n", nameoroid);
+ }
+
return ( pi );
}
static int
-plugin_mr_get_type(struct slapdplugin *pi, int *ordering)
+plugin_mr_get_type(struct slapdplugin *pi)
{
int rc = LDAP_FILTER_EQUALITY;
- *ordering = 0;
if (pi) {
char **str = pi->plg_mr_names;
for (; str && *str; ++str) {
@@ -121,7 +130,7 @@ plugin_mr_get_type(struct slapdplugin *pi, int *ordering)
break;
}
if (PL_strcasestr(*str, "ordering")) {
- *ordering = 1;
+ rc = LDAP_FILTER_GE;
break;
}
}
@@ -249,7 +258,8 @@ mr_private_indexer_done(struct mr_private *mrpriv)
{
if (mrpriv && mrpriv->sva) {
valuearray_free(&mrpriv->sva);
- } else if (mrpriv && mrpriv->bva) {
+ }
+ if (mrpriv && mrpriv->bva) {
ber_bvecfree(mrpriv->bva);
mrpriv->bva = NULL;
}
@@ -301,9 +311,8 @@ mr_wrap_mr_index_sv_fn(Slapi_PBlock* pb)
} else if (!pi->plg_mr_values2keys) {
LDAPDebug0Args(LDAP_DEBUG_ANY, "mr_wrap_mr_index_sv_fn: error - plugin has no plg_mr_values2keys function\n");
} else {
- int ordering = 0;
struct mr_private *mrpriv = NULL;
- int ftype = plugin_mr_get_type(pi, &ordering);
+ int ftype = plugin_mr_get_type(pi);
slapi_pblock_get(pb, SLAPI_PLUGIN_MR_VALUES, &in_vals);
(*pi->plg_mr_values2keys)(pb, in_vals, &out_vals, ftype);
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_KEYS, out_vals);
@@ -334,15 +343,22 @@ mr_wrap_mr_index_fn(Slapi_PBlock* pb)
valuearray_init_bervalarray(in_vals, &in_vals_sv);
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_VALUES, in_vals_sv); /* use sv */
rc = mr_wrap_mr_index_sv_fn(pb);
+ /* clean up in_vals_sv */
+ valuearray_free(&in_vals_sv);
+ /* restore old in_vals */
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_VALUES, in_vals);
/* get result sv keys */
slapi_pblock_get(pb, SLAPI_PLUGIN_MR_KEYS, &out_vals_sv);
/* convert to bvec */
valuearray_get_bervalarray(out_vals_sv, &out_vals);
- valuearray_free(&out_vals_sv); /* don't need svals */
+ /* NOTE: mrpriv owns out_vals_sv (mpriv->sva) - will
+ get freed by mr_private_indexer_done() */
/* we have to save out_vals to free next time or during destroy */
slapi_pblock_get(pb, SLAPI_PLUGIN_OBJECT, &mrpriv);
mr_private_indexer_done(mrpriv); /* free old vals, if any */
mrpriv->bva = out_vals; /* save pointer for later */
+ /* set return value berval array for caller */
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_KEYS, out_vals);
return rc;
}
@@ -396,8 +412,8 @@ default_mr_filter_index(Slapi_PBlock *pb)
slapi_pblock_get(pb, SLAPI_PLUGIN_OBJECT, &mrpriv);
- slapi_pblock_set(pb, SLAPI_PLUGIN, mrpriv->pi);
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_TYPE, mrpriv->type);
+ slapi_pblock_set(pb, SLAPI_PLUGIN, (void *)mrpriv->pi);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_TYPE, (void *)mrpriv->type);
/* extensible_candidates uses struct berval ** indexer */
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, mr_wrap_mr_index_fn);
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_VALUES, mrpriv->values);
@@ -405,7 +421,7 @@ default_mr_filter_index(Slapi_PBlock *pb)
is the indextype value passed to index_index2prefix - it must be the
same OID as used in the index configuration for the index matching
rule */
- slapi_pblock_set(pb, SLAPI_PLUGIN_MR_OID, mrpriv->oid);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_MR_OID, (void *)mrpriv->oid);
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_QUERY_OPERATOR, &mrpriv->op);
return rc;
@@ -427,23 +443,27 @@ default_mr_filter_create(Slapi_PBlock *pb)
!slapi_pblock_get(pb, SLAPI_PLUGIN_MR_VALUE, &mrVALUE) && mrVALUE != NULL &&
!slapi_pblock_get(pb, SLAPI_PLUGIN, &pi) && pi != NULL) {
int op = SLAPI_OP_EQUAL;
- int ordering = 0;
struct mr_private *mrpriv = NULL;
+ int ftype = 0;
LDAPDebug2Args(LDAP_DEBUG_FILTER, "=> default_mr_filter_create(oid %s; type %s)\n",
mrOID, mrTYPE);
- int ftype = plugin_mr_get_type(pi, &ordering);
+ ftype = plugin_mr_get_type(pi);
/* map the ftype to the op type */
- if (ftype == LDAP_FILTER_EQUALITY) {
- if (ordering) { /* not sure what to do here - default to GE */
- op = SLAPI_OP_GREATER_OR_EQUAL;
- }
+ if (ftype == LDAP_FILTER_GE) {
+ /*
+ * The rule evaluates to TRUE if and only if, in the code point
+ * collation order, the prepared attribute value character string
+ * appears earlier than the prepared assertion value character string;
+ * i.e., the attribute value is "less than" the assertion value.
+ */
+ op = SLAPI_OP_LESS;
/*
} else if (ftype == LDAP_FILTER_SUBSTRINGS) {
op = SLAPI_OP_SUBSTRING;
*/
- } else { /* unsupported */
+ } else if (ftype != LDAP_FILTER_EQUALITY) { /* unsupported */
/* NOTE: we cannot currently support substring matching rules - the
reason is that the API provides no way to pass in the search time limit
required by the syntax filter substring match functions
@@ -498,7 +518,7 @@ default_mr_filter_create(Slapi_PBlock *pb)
mrOID ? "" : " oid",
mrTYPE ? "" : " attribute type",
mrVALUE ? "" : " filter value");
- }
+ }
done:
LDAPDebug1Arg(LDAP_DEBUG_FILTER, "=> default_mr_filter_create: %d\n", rc);
@@ -526,6 +546,10 @@ attempt_mr_filter_create (mr_filter_t* f, struct slapdplugin* mrp, Slapi_PBlock*
rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
}
}
+ if (NULL == mrf_create) {
+ /* no create func - unavailable */
+ rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+ }
return rc;
}
@@ -552,22 +576,22 @@ plugin_mr_filter_create (mr_filter_t* f)
}
}
}
- if (rc)
- {
+ if (rc)
+ {
/* look for a new syntax-style mr plugin */
mrp = plugin_mr_find(f->mrf_oid);
if (mrp)
{
- /* set the default index create fn */
- pblock_init(&pb);
- slapi_pblock_set(&pb, SLAPI_PLUGIN, mrp);
- slapi_pblock_set(&pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, default_mr_filter_create);
+ /* set the default index create fn */
+ pblock_init(&pb);
+ slapi_pblock_set(&pb, SLAPI_PLUGIN, mrp);
+ slapi_pblock_set(&pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, default_mr_filter_create);
if (!(rc = attempt_mr_filter_create (f, mrp, &pb)))
{
plugin_mr_bind (f->mrf_oid, mrp); /* for future reference */
- }
+ }
}
- }
+ }
if (!rc)
{
/* This plugin has created the desired filter. */
@@ -586,7 +610,7 @@ slapi_mr_filter_index (Slapi_Filter* f, Slapi_PBlock* pb)
int rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
if (f->f_choice == LDAP_FILTER_EXTENDED && f->f_mr.mrf_index != NULL &&
!(rc = slapi_pblock_set (pb, SLAPI_PLUGIN_OBJECT, f->f_mr.mrf_object)))
- {
+ {
rc = f->f_mr.mrf_index (pb);
}
return rc;
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 5f0fc47f..5f97c055 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -4466,12 +4466,13 @@ int slapi_berval_cmp(const struct berval* L, const struct berval* R);
! memcmp ((L)->bv_val, (R)->bv_val, (L)->bv_len))
typedef struct slapi_matchingRuleEntry {
- char *mr_oid;
- char *mr_oidalias;
- char *mr_name;
- char *mr_desc;
- char *mr_syntax;
- int mr_obsolete;
+ char *mr_oid; /* the official oid */
+ char *mr_oidalias; /* not currently used */
+ char *mr_name; /* the official name */
+ char *mr_desc; /* a description */
+ char *mr_syntax; /* the assertion syntax OID */
+ int mr_obsolete; /* is mr obsolete? */
+ char **mr_compat_syntax; /* list of OIDs of other syntaxes that can use this matching rule */
} slapi_matchingRuleEntry;
typedef struct slapi_matchingRuleEntry Slapi_MatchingRuleEntry;
@@ -4482,8 +4483,30 @@ int slapi_matchingrule_get(Slapi_MatchingRuleEntry *mr, int arg, void *value);
int slapi_matchingrule_set(Slapi_MatchingRuleEntry *mr, int arg, void *value);
int slapi_matchingrule_register(Slapi_MatchingRuleEntry *mrEntry);
int slapi_matchingrule_unregister(char *oid);
+
+/**
+ * Is the given matching rule an ordering matching rule and is it
+ * compatible with the given syntax?
+ *
+ * \param name_or_oid Name or OID of a matching rule
+ * \param syntax_oid OID of a syntax
+ * \return \c TRUE if the matching rule is an ordering rule and can be used by the given syntax
+ * \return \c FALSE otherwise
+ */
int slapi_matchingrule_is_ordering(const char *oid_or_name, const char *syntax_oid);
+/**
+ * Can the given syntax OID use the given matching rule name/OID? A
+ * matching rule can apply to more than one syntax. Use this function
+ * to determine if the given syntax can use the given matching rule.
+ *
+ * \param mr_name_or_oid Name or OID of a matching rule
+ * \param syntax_oid OID of a syntax
+ * \return \c TRUE if the syntax can be used with the matching rule
+ * \return \c FALSE otherwise
+ */
+int slapi_matchingrule_is_compat(const char *mr_oid_or_name, const char *syntax_oid);
+
/*
* access control
*/