summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
*/