diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | Makefile.in | 15 | ||||
-rw-r--r-- | ldap/schema/05rfc4523.ldif | 14 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/bin.c | 90 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/bitstring.c | 36 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/ces.c | 139 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/cis.c | 256 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/dn.c | 42 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/int.c | 64 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/nameoptuid.c | 41 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/numericstring.c | 116 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/syntax.h | 56 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/syntax_common.c | 117 | ||||
-rw-r--r-- | ldap/servers/plugins/syntaxes/tel.c | 62 | ||||
-rw-r--r-- | ldap/servers/slapd/attrsyntax.c | 45 | ||||
-rw-r--r-- | ldap/servers/slapd/match.c | 57 | ||||
-rw-r--r-- | ldap/servers/slapd/plugin_mr.c | 82 | ||||
-rw-r--r-- | ldap/servers/slapd/slapi-plugin.h | 35 |
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 */ |