1 /* schema_init.c - init builtin schema */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2004 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
24 #include <ac/string.h>
25 #include <ac/socket.h>
31 #include "ldap_utf8.h"
34 #include <openssl/x509.h>
35 #include <openssl/err.h>
36 #include <openssl/rsa.h>
37 #include <openssl/crypto.h>
38 #include <openssl/pem.h>
39 #include <openssl/bio.h>
40 #include <openssl/asn1.h>
41 #include <openssl/x509v3.h>
42 #include <openssl/ssl.h>
45 #include "lutil_hash.h"
46 #define HASH_BYTES LUTIL_HASH_BYTES
47 #define HASH_CONTEXT lutil_HASH_CTX
48 #define HASH_Init(c) lutil_HASHInit(c)
49 #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
50 #define HASH_Final(d,c) lutil_HASHFinal(d,c)
52 #define OpenLDAPaciMatch NULL
54 /* approx matching rules */
55 #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
56 #define directoryStringApproxMatch approxMatch
57 #define directoryStringApproxIndexer approxIndexer
58 #define directoryStringApproxFilter approxFilter
59 #define IA5StringApproxMatchOID "1.3.6.1.4.1.4203.666.4.5"
60 #define IA5StringApproxMatch approxMatch
61 #define IA5StringApproxIndexer approxIndexer
62 #define IA5StringApproxFilter approxFilter
69 /* no value allowed */
70 return LDAP_INVALID_SYNTAX;
78 /* any value allowed */
82 #define berValidate blobValidate
89 if ( in->bv_len < 2 ) return LDAP_INVALID_SYNTAX;
90 if ( in->bv_val[0] != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
97 static int certificateValidate( Syntax *syntax, struct berval *in )
100 unsigned char *p = (unsigned char *)in->bv_val;
102 xcert = d2i_X509(NULL, &p, in->bv_len);
103 if ( !xcert ) return LDAP_INVALID_SYNTAX;
108 #define certificateValidate sequenceValidate
117 struct berval *value,
118 void *assertedValue )
120 struct berval *asserted = (struct berval *) assertedValue;
121 int match = value->bv_len - asserted->bv_len;
124 match = memcmp( value->bv_val, asserted->bv_val, value->bv_len );
132 octetStringOrderingMatch(
137 struct berval *value,
138 void *assertedValue )
140 struct berval *asserted = (struct berval *) assertedValue;
141 ber_len_t v_len = value->bv_len;
142 ber_len_t av_len = asserted->bv_len;
144 int match = memcmp( value->bv_val, asserted->bv_val,
145 (v_len < av_len ? v_len : av_len) );
147 if( match == 0 ) match = v_len - av_len;
153 /* Index generation function */
154 int octetStringIndexer(
159 struct berval *prefix,
167 HASH_CONTEXT HASHcontext;
168 unsigned char HASHdigest[HASH_BYTES];
169 struct berval digest;
170 digest.bv_val = (char *)HASHdigest;
171 digest.bv_len = sizeof(HASHdigest);
173 for( i=0; values[i].bv_val != NULL; i++ ) {
174 /* just count them */
177 /* we should have at least one value at this point */
180 keys = slap_sl_malloc( sizeof( struct berval ) * (i+1), ctx );
182 slen = syntax->ssyn_oidlen;
183 mlen = mr->smr_oidlen;
185 for( i=0; values[i].bv_val != NULL; i++ ) {
186 HASH_Init( &HASHcontext );
187 if( prefix != NULL && prefix->bv_len > 0 ) {
188 HASH_Update( &HASHcontext,
189 (unsigned char *)prefix->bv_val,
192 HASH_Update( &HASHcontext,
193 (unsigned char *)syntax->ssyn_oid, slen );
194 HASH_Update( &HASHcontext,
195 (unsigned char *)mr->smr_oid, mlen );
196 HASH_Update( &HASHcontext,
197 (unsigned char *)values[i].bv_val, values[i].bv_len );
198 HASH_Final( HASHdigest, &HASHcontext );
200 ber_dupbv_x( &keys[i], &digest, ctx );
203 keys[i].bv_val = NULL;
211 /* Index generation function */
212 int octetStringFilter(
217 struct berval *prefix,
218 void * assertedValue,
224 HASH_CONTEXT HASHcontext;
225 unsigned char HASHdigest[HASH_BYTES];
226 struct berval *value = (struct berval *) assertedValue;
227 struct berval digest;
228 digest.bv_val = (char *)HASHdigest;
229 digest.bv_len = sizeof(HASHdigest);
231 slen = syntax->ssyn_oidlen;
232 mlen = mr->smr_oidlen;
234 keys = slap_sl_malloc( sizeof( struct berval ) * 2, ctx );
236 HASH_Init( &HASHcontext );
237 if( prefix != NULL && prefix->bv_len > 0 ) {
238 HASH_Update( &HASHcontext,
239 (unsigned char *)prefix->bv_val, prefix->bv_len );
241 HASH_Update( &HASHcontext,
242 (unsigned char *)syntax->ssyn_oid, slen );
243 HASH_Update( &HASHcontext,
244 (unsigned char *)mr->smr_oid, mlen );
245 HASH_Update( &HASHcontext,
246 (unsigned char *)value->bv_val, value->bv_len );
247 HASH_Final( HASHdigest, &HASHcontext );
249 ber_dupbv_x( keys, &digest, ctx );
250 keys[1].bv_val = NULL;
259 octetStringSubstringsMatch(
264 struct berval *value,
265 void *assertedValue )
268 SubstringsAssertion *sub = assertedValue;
269 struct berval left = *value;
273 /* Add up asserted input length */
274 if( sub->sa_initial.bv_val ) {
275 inlen += sub->sa_initial.bv_len;
278 for(i=0; sub->sa_any[i].bv_val != NULL; i++) {
279 inlen += sub->sa_any[i].bv_len;
282 if( sub->sa_final.bv_val ) {
283 inlen += sub->sa_final.bv_len;
286 if( sub->sa_initial.bv_val ) {
287 if( inlen > left.bv_len ) {
292 match = memcmp( sub->sa_initial.bv_val, left.bv_val,
293 sub->sa_initial.bv_len );
299 left.bv_val += sub->sa_initial.bv_len;
300 left.bv_len -= sub->sa_initial.bv_len;
301 inlen -= sub->sa_initial.bv_len;
304 if( sub->sa_final.bv_val ) {
305 if( inlen > left.bv_len ) {
310 match = memcmp( sub->sa_final.bv_val,
311 &left.bv_val[left.bv_len - sub->sa_final.bv_len],
312 sub->sa_final.bv_len );
318 left.bv_len -= sub->sa_final.bv_len;
319 inlen -= sub->sa_final.bv_len;
323 for(i=0; sub->sa_any[i].bv_val; i++) {
328 if( inlen > left.bv_len ) {
329 /* not enough length */
334 if( sub->sa_any[i].bv_len == 0 ) {
338 p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len );
345 idx = p - left.bv_val;
347 if( idx >= left.bv_len ) {
348 /* this shouldn't happen */
355 if( sub->sa_any[i].bv_len > left.bv_len ) {
356 /* not enough left */
361 match = memcmp( left.bv_val,
362 sub->sa_any[i].bv_val,
363 sub->sa_any[i].bv_len );
371 left.bv_val += sub->sa_any[i].bv_len;
372 left.bv_len -= sub->sa_any[i].bv_len;
373 inlen -= sub->sa_any[i].bv_len;
382 /* Substrings Index generation function */
384 octetStringSubstringsIndexer(
389 struct berval *prefix,
394 ber_len_t i, j, nkeys;
398 HASH_CONTEXT HASHcontext;
399 unsigned char HASHdigest[HASH_BYTES];
400 struct berval digest;
401 digest.bv_val = (char *)HASHdigest;
402 digest.bv_len = sizeof(HASHdigest);
406 for( i=0; values[i].bv_val != NULL; i++ ) {
407 /* count number of indices to generate */
408 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
409 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_IF_MAXLEN ) {
410 nkeys += SLAP_INDEX_SUBSTR_IF_MAXLEN -
411 (SLAP_INDEX_SUBSTR_IF_MINLEN - 1);
412 } else if( values[i].bv_len >= SLAP_INDEX_SUBSTR_IF_MINLEN ) {
413 nkeys += values[i].bv_len - (SLAP_INDEX_SUBSTR_IF_MINLEN - 1);
417 if( flags & SLAP_INDEX_SUBSTR_ANY ) {
418 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_ANY_LEN ) {
419 nkeys += values[i].bv_len - (SLAP_INDEX_SUBSTR_ANY_LEN - 1);
423 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
424 if( values[i].bv_len >= SLAP_INDEX_SUBSTR_IF_MAXLEN ) {
425 nkeys += SLAP_INDEX_SUBSTR_IF_MAXLEN -
426 ( SLAP_INDEX_SUBSTR_IF_MINLEN - 1);
427 } else if( values[i].bv_len >= SLAP_INDEX_SUBSTR_IF_MINLEN ) {
428 nkeys += values[i].bv_len - (SLAP_INDEX_SUBSTR_IF_MINLEN - 1);
434 /* no keys to generate */
439 keys = slap_sl_malloc( sizeof( struct berval ) * (nkeys+1), ctx );
441 slen = syntax->ssyn_oidlen;
442 mlen = mr->smr_oidlen;
445 for( i=0; values[i].bv_val != NULL; i++ ) {
448 if( ( flags & SLAP_INDEX_SUBSTR_ANY ) &&
449 ( values[i].bv_len >= SLAP_INDEX_SUBSTR_ANY_LEN ) )
451 char pre = SLAP_INDEX_SUBSTR_PREFIX;
452 max = values[i].bv_len - (SLAP_INDEX_SUBSTR_ANY_LEN - 1);
454 for( j=0; j<max; j++ ) {
455 HASH_Init( &HASHcontext );
456 if( prefix != NULL && prefix->bv_len > 0 ) {
457 HASH_Update( &HASHcontext,
458 (unsigned char *)prefix->bv_val, prefix->bv_len );
461 HASH_Update( &HASHcontext,
462 (unsigned char *)&pre, sizeof( pre ) );
463 HASH_Update( &HASHcontext,
464 (unsigned char *)syntax->ssyn_oid, slen );
465 HASH_Update( &HASHcontext,
466 (unsigned char *)mr->smr_oid, mlen );
467 HASH_Update( &HASHcontext,
468 (unsigned char *)&values[i].bv_val[j],
469 SLAP_INDEX_SUBSTR_ANY_LEN );
470 HASH_Final( HASHdigest, &HASHcontext );
472 ber_dupbv_x( &keys[nkeys++], &digest, ctx );
476 /* skip if too short */
477 if( values[i].bv_len < SLAP_INDEX_SUBSTR_IF_MINLEN ) continue;
479 max = SLAP_INDEX_SUBSTR_IF_MAXLEN < values[i].bv_len
480 ? SLAP_INDEX_SUBSTR_IF_MAXLEN : values[i].bv_len;
482 for( j=SLAP_INDEX_SUBSTR_IF_MINLEN; j<=max; j++ ) {
485 if( flags & SLAP_INDEX_SUBSTR_INITIAL ) {
486 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
487 HASH_Init( &HASHcontext );
488 if( prefix != NULL && prefix->bv_len > 0 ) {
489 HASH_Update( &HASHcontext,
490 (unsigned char *)prefix->bv_val, prefix->bv_len );
492 HASH_Update( &HASHcontext,
493 (unsigned char *)&pre, sizeof( pre ) );
494 HASH_Update( &HASHcontext,
495 (unsigned char *)syntax->ssyn_oid, slen );
496 HASH_Update( &HASHcontext,
497 (unsigned char *)mr->smr_oid, mlen );
498 HASH_Update( &HASHcontext,
499 (unsigned char *)values[i].bv_val, j );
500 HASH_Final( HASHdigest, &HASHcontext );
502 ber_dupbv_x( &keys[nkeys++], &digest, ctx );
505 if( flags & SLAP_INDEX_SUBSTR_FINAL ) {
506 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
507 HASH_Init( &HASHcontext );
508 if( prefix != NULL && prefix->bv_len > 0 ) {
509 HASH_Update( &HASHcontext,
510 (unsigned char *)prefix->bv_val, prefix->bv_len );
512 HASH_Update( &HASHcontext,
513 (unsigned char *)&pre, sizeof( pre ) );
514 HASH_Update( &HASHcontext,
515 (unsigned char *)syntax->ssyn_oid, slen );
516 HASH_Update( &HASHcontext,
517 (unsigned char *)mr->smr_oid, mlen );
518 HASH_Update( &HASHcontext,
519 (unsigned char *)&values[i].bv_val[values[i].bv_len-j], j );
520 HASH_Final( HASHdigest, &HASHcontext );
522 ber_dupbv_x( &keys[nkeys++], &digest, ctx );
529 keys[nkeys].bv_val = NULL;
540 octetStringSubstringsFilter (
545 struct berval *prefix,
546 void * assertedValue,
550 SubstringsAssertion *sa;
553 size_t slen, mlen, klen;
555 HASH_CONTEXT HASHcontext;
556 unsigned char HASHdigest[HASH_BYTES];
557 struct berval *value;
558 struct berval digest;
560 sa = (SubstringsAssertion *) assertedValue;
562 if( flags & SLAP_INDEX_SUBSTR_INITIAL &&
563 sa->sa_initial.bv_val != NULL &&
564 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_IF_MINLEN )
569 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
571 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
572 if( sa->sa_any[i].bv_len >= SLAP_INDEX_SUBSTR_ANY_LEN ) {
573 /* don't bother accounting with stepping */
574 nkeys += sa->sa_any[i].bv_len -
575 ( SLAP_INDEX_SUBSTR_ANY_LEN - 1 );
580 if( flags & SLAP_INDEX_SUBSTR_FINAL &&
581 sa->sa_final.bv_val != NULL &&
582 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_IF_MINLEN )
592 digest.bv_val = (char *)HASHdigest;
593 digest.bv_len = sizeof(HASHdigest);
595 slen = syntax->ssyn_oidlen;
596 mlen = mr->smr_oidlen;
598 keys = slap_sl_malloc( sizeof( struct berval ) * (nkeys+1), ctx );
601 if( flags & SLAP_INDEX_SUBSTR_INITIAL &&
602 sa->sa_initial.bv_val != NULL &&
603 sa->sa_initial.bv_len >= SLAP_INDEX_SUBSTR_IF_MINLEN )
605 pre = SLAP_INDEX_SUBSTR_INITIAL_PREFIX;
606 value = &sa->sa_initial;
608 klen = SLAP_INDEX_SUBSTR_IF_MAXLEN < value->bv_len
609 ? SLAP_INDEX_SUBSTR_IF_MAXLEN : value->bv_len;
611 HASH_Init( &HASHcontext );
612 if( prefix != NULL && prefix->bv_len > 0 ) {
613 HASH_Update( &HASHcontext,
614 (unsigned char *)prefix->bv_val, prefix->bv_len );
616 HASH_Update( &HASHcontext,
617 (unsigned char *)&pre, sizeof( pre ) );
618 HASH_Update( &HASHcontext,
619 (unsigned char *)syntax->ssyn_oid, slen );
620 HASH_Update( &HASHcontext,
621 (unsigned char *)mr->smr_oid, mlen );
622 HASH_Update( &HASHcontext,
623 (unsigned char *)value->bv_val, klen );
624 HASH_Final( HASHdigest, &HASHcontext );
626 ber_dupbv_x( &keys[nkeys++], &digest, ctx );
629 if( flags & SLAP_INDEX_SUBSTR_ANY && sa->sa_any != NULL ) {
631 pre = SLAP_INDEX_SUBSTR_PREFIX;
632 klen = SLAP_INDEX_SUBSTR_ANY_LEN;
634 for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) {
635 if( sa->sa_any[i].bv_len < SLAP_INDEX_SUBSTR_ANY_LEN ) {
639 value = &sa->sa_any[i];
642 j <= value->bv_len - SLAP_INDEX_SUBSTR_ANY_LEN;
643 j += SLAP_INDEX_SUBSTR_ANY_STEP )
645 HASH_Init( &HASHcontext );
646 if( prefix != NULL && prefix->bv_len > 0 ) {
647 HASH_Update( &HASHcontext,
648 (unsigned char *)prefix->bv_val, prefix->bv_len );
650 HASH_Update( &HASHcontext,
651 (unsigned char *)&pre, sizeof( pre ) );
652 HASH_Update( &HASHcontext,
653 (unsigned char *)syntax->ssyn_oid, slen );
654 HASH_Update( &HASHcontext,
655 (unsigned char *)mr->smr_oid, mlen );
656 HASH_Update( &HASHcontext,
657 (unsigned char *)&value->bv_val[j], klen );
658 HASH_Final( HASHdigest, &HASHcontext );
660 ber_dupbv_x( &keys[nkeys++], &digest, ctx );
665 if( flags & SLAP_INDEX_SUBSTR_FINAL &&
666 sa->sa_final.bv_val != NULL &&
667 sa->sa_final.bv_len >= SLAP_INDEX_SUBSTR_IF_MINLEN )
669 pre = SLAP_INDEX_SUBSTR_FINAL_PREFIX;
670 value = &sa->sa_final;
672 klen = SLAP_INDEX_SUBSTR_IF_MAXLEN < value->bv_len
673 ? SLAP_INDEX_SUBSTR_IF_MAXLEN : value->bv_len;
675 HASH_Init( &HASHcontext );
676 if( prefix != NULL && prefix->bv_len > 0 ) {
677 HASH_Update( &HASHcontext,
678 (unsigned char *)prefix->bv_val, prefix->bv_len );
680 HASH_Update( &HASHcontext,
681 (unsigned char *)&pre, sizeof( pre ) );
682 HASH_Update( &HASHcontext,
683 (unsigned char *)syntax->ssyn_oid, slen );
684 HASH_Update( &HASHcontext,
685 (unsigned char *)mr->smr_oid, mlen );
686 HASH_Update( &HASHcontext,
687 (unsigned char *)&value->bv_val[value->bv_len-klen], klen );
688 HASH_Final( HASHdigest, &HASHcontext );
690 ber_dupbv_x( &keys[nkeys++], &digest, ctx );
694 keys[nkeys].bv_val = NULL;
711 /* very unforgiving validation, requires no normalization
712 * before simplistic matching
714 if( in->bv_len < 3 ) {
715 return LDAP_INVALID_SYNTAX;
719 * RFC 2252 section 6.3 Bit String
720 * bitstring = "'" *binary-digit "'B"
721 * binary-digit = "0" / "1"
722 * example: '0101111101'B
725 if( in->bv_val[0] != '\'' ||
726 in->bv_val[in->bv_len-2] != '\'' ||
727 in->bv_val[in->bv_len-1] != 'B' )
729 return LDAP_INVALID_SYNTAX;
732 for( i=in->bv_len-3; i>0; i-- ) {
733 if( in->bv_val[i] != '0' && in->bv_val[i] != '1' ) {
734 return LDAP_INVALID_SYNTAX;
749 if( in->bv_len == 0 ) return LDAP_SUCCESS;
751 ber_dupbv( &dn, in );
752 if( !dn.bv_val ) return LDAP_OTHER;
754 if( dn.bv_val[dn.bv_len-1] == 'B'
755 && dn.bv_val[dn.bv_len-2] == '\'' )
757 /* assume presence of optional UID */
760 for(i=dn.bv_len-3; i>1; i--) {
761 if( dn.bv_val[i] != '0' && dn.bv_val[i] != '1' ) {
765 if( dn.bv_val[i] != '\'' || dn.bv_val[i-1] != '#' ) {
766 ber_memfree( dn.bv_val );
767 return LDAP_INVALID_SYNTAX;
770 /* trim the UID to allow use of dnValidate */
771 dn.bv_val[i-1] = '\0';
775 rc = dnValidate( NULL, &dn );
777 ber_memfree( dn.bv_val );
793 LDAP_LOG( OPERATION, ARGS, ">>> nameUIDPretty: <%s>\n", val->bv_val, 0, 0 );
795 Debug( LDAP_DEBUG_TRACE, ">>> nameUIDPretty: <%s>\n", val->bv_val, 0, 0 );
798 if( val->bv_len == 0 ) {
799 ber_dupbv_x( out, val, ctx );
801 } else if ( val->bv_len > SLAP_LDAPDN_MAXLEN ) {
802 return LDAP_INVALID_SYNTAX;
806 struct berval dnval = *val;
807 struct berval uidval = BER_BVNULL;
809 if( val->bv_val[val->bv_len-1] == 'B'
810 && val->bv_val[val->bv_len-2] == '\'' )
812 uidval.bv_val=strrchr( val->bv_val, '#' );
813 if( uidval.bv_val ) {
814 dnval.bv_len = uidval.bv_val - dnval.bv_val;
815 uidval.bv_len = val->bv_len - dnval.bv_len;
822 rc = dnPretty( syntax, &dnval, out, ctx );
823 if( rc != LDAP_SUCCESS ) return rc;
825 if( uidval.bv_val ) {
826 char *tmp = slap_sl_realloc( out->bv_val, out->bv_len + uidval.bv_len + 2, ctx );
829 ber_memfree_x( out->bv_val, ctx );
833 out->bv_val[out->bv_len++] = '#';
835 got1 = uidval.bv_len < sizeof("'0'B");
836 for(i=0; i<uidval.bv_len; i++) {
837 c = uidval.bv_val[i];
840 if( got1 ) out->bv_val[out->bv_len++] = c;
845 out->bv_val[out->bv_len++] = c;
849 out->bv_val[out->bv_len] = '\0';
854 LDAP_LOG( OPERATION, ARGS, "<<< nameUIDPretty: <%s>\n", out->bv_val, 0, 0 );
856 Debug( LDAP_DEBUG_TRACE, "<<< nameUIDPretty: <%s>\n", out->bv_val, 0, 0 );
863 uniqueMemberNormalize(
868 struct berval *normalized,
874 assert( SLAP_MR_IS_VALUE_OF_SYNTAX( usage ));
876 ber_dupbv( &out, val );
877 if( BER_BVISEMPTY( &out ) ) {
881 struct berval uid = BER_BVNULL;
883 if( out.bv_val[out.bv_len-1] == 'B'
884 && out.bv_val[out.bv_len-2] == '\'' )
886 /* assume presence of optional UID */
887 uid.bv_val = strrchr( out.bv_val, '#' );
889 if( uid.bv_val == NULL ) {
891 return LDAP_INVALID_SYNTAX;
894 uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val);
895 out.bv_len -= uid.bv_len--;
897 /* temporarily trim the UID */
898 *(uid.bv_val++) = '\0';
901 rc = dnNormalize( 0, NULL, NULL, &out, normalized, ctx );
903 if( rc != LDAP_SUCCESS ) {
905 return LDAP_INVALID_SYNTAX;
909 normalized->bv_val = ch_realloc( normalized->bv_val,
910 normalized->bv_len + uid.bv_len + sizeof("#") );
912 /* insert the separator */
913 normalized->bv_val[normalized->bv_len++] = '#';
916 AC_MEMCPY( &normalized->bv_val[normalized->bv_len],
917 uid.bv_val, uid.bv_len );
918 normalized->bv_len += uid.bv_len;
921 normalized->bv_val[normalized->bv_len] = '\0';
936 struct berval *value,
937 void *assertedValue )
940 struct berval *asserted = (struct berval *) assertedValue;
941 struct berval assertedDN = BER_BVNULL;
942 struct berval assertedUID = BER_BVNULL;
943 struct berval valueDN = BER_BVNULL;
944 struct berval valueUID = BER_BVNULL;
946 if( asserted->bv_len != 0 ) {
947 assertedDN = *asserted;
949 if( assertedDN.bv_val[assertedDN.bv_len-1] == 'B'
950 && assertedDN.bv_val[assertedDN.bv_len-2] == '\'' )
952 /* assume presence of optional UID */
953 assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' );
955 if( assertedUID.bv_val == NULL ) {
956 return LDAP_INVALID_SYNTAX;
959 assertedUID.bv_len = assertedDN.bv_len -
960 (assertedUID.bv_val - assertedDN.bv_val);
961 assertedDN.bv_len -= assertedUID.bv_len--;
963 /* trim the separator */
964 assertedUID.bv_val++;
968 if( value->bv_len != 0 ) {
971 if( valueDN.bv_val[valueDN.bv_len-1] == 'B'
972 && valueDN.bv_val[valueDN.bv_len-2] == '\'' )
974 /* assume presence of optional UID */
975 valueUID.bv_val = strrchr( valueDN.bv_val, '#' );
977 if( valueUID.bv_val == NULL ) {
978 return LDAP_INVALID_SYNTAX;
981 valueUID.bv_len = valueDN.bv_len -
982 (assertedUID.bv_val - assertedDN.bv_val);
983 valueDN.bv_len -= valueUID.bv_len--;
985 /* trim the separator */
990 if( valueUID.bv_len && assertedUID.bv_len ) {
991 match = memcmp( valueUID.bv_val, assertedUID.bv_val, valueUID.bv_len );
998 return dnMatch( matchp, flags, syntax, mr, &valueDN, &assertedDN );
1002 * Handling boolean syntax and matching is quite rigid.
1003 * A more flexible approach would be to allow a variety
1004 * of strings to be normalized and prettied into TRUE
1012 /* very unforgiving validation, requires no normalization
1013 * before simplistic matching
1016 if( in->bv_len == 4 ) {
1017 if( bvmatch( in, &slap_true_bv ) ) {
1018 return LDAP_SUCCESS;
1020 } else if( in->bv_len == 5 ) {
1021 if( bvmatch( in, &slap_false_bv ) ) {
1022 return LDAP_SUCCESS;
1026 return LDAP_INVALID_SYNTAX;
1035 struct berval *value,
1036 void *assertedValue )
1038 /* simplistic matching allowed by rigid validation */
1039 struct berval *asserted = (struct berval *) assertedValue;
1040 *matchp = value->bv_len != asserted->bv_len;
1041 return LDAP_SUCCESS;
1044 /*-------------------------------------------------------------------
1045 LDAP/X.500 string syntax / matching rules have a few oddities. This
1046 comment attempts to detail how slapd(8) treats them.
1049 StringSyntax X.500 LDAP Matching/Comments
1050 DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces
1051 PrintableString subset subset i/e + ignore insignificant spaces
1052 PrintableString subset subset i/e + ignore insignificant spaces
1053 NumericString subset subset ignore all spaces
1054 IA5String ASCII ASCII i/e + ignore insignificant spaces
1055 TeletexString T.61 T.61 i/e + ignore insignificant spaces
1057 TelephoneNumber subset subset i + ignore all spaces and "-"
1059 See draft-ietf-ldapbis-strpro for details (once published).
1063 In X.500(93), a directory string can be either a PrintableString,
1064 a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)).
1065 In later versions, more CHOICEs were added. In all cases the string
1068 In LDAPv3, a directory string is a UTF-8 encoded UCS string.
1069 A directory string cannot be zero length.
1071 For matching, there are both case ignore and exact rules. Both
1072 also require that "insignificant" spaces be ignored.
1073 spaces before the first non-space are ignored;
1074 spaces after the last non-space are ignored;
1075 spaces after a space are ignored.
1076 Note: by these rules (and as clarified in X.520), a string of only
1077 spaces is to be treated as if held one space, not empty (which
1078 would be a syntax error).
1081 In ASN.1, numeric string is just a string of digits and spaces
1082 and could be empty. However, in X.500, all attribute values of
1083 numeric string carry a non-empty constraint. For example:
1085 internationalISDNNumber ATTRIBUTE ::= {
1086 WITH SYNTAX InternationalISDNNumber
1087 EQUALITY MATCHING RULE numericStringMatch
1088 SUBSTRINGS MATCHING RULE numericStringSubstringsMatch
1089 ID id-at-internationalISDNNumber }
1090 InternationalISDNNumber ::=
1091 NumericString (SIZE(1..ub-international-isdn-number))
1093 Unforunately, some assertion values are don't carry the same
1094 constraint (but its unclear how such an assertion could ever
1095 be true). In LDAP, there is one syntax (numericString) not two
1096 (numericString with constraint, numericString without constraint).
1097 This should be treated as numericString with non-empty constraint.
1098 Note that while someone may have no ISDN number, there are no ISDN
1099 numbers which are zero length.
1101 In matching, spaces are ignored.
1104 In ASN.1, Printable string is just a string of printable characters
1105 and can be empty. In X.500, semantics much like NumericString (see
1106 serialNumber for a like example) excepting uses insignificant space
1107 handling instead of ignore all spaces.
1110 Basically same as PrintableString. There are no examples in X.500,
1111 but same logic applies. So we require them to be non-empty as
1114 -------------------------------------------------------------------*/
1123 unsigned char *u = (unsigned char *)in->bv_val;
1125 if( in->bv_len == 0 && syntax == slap_schema.si_syn_directoryString ) {
1126 /* directory strings cannot be empty */
1127 return LDAP_INVALID_SYNTAX;
1130 for( count = in->bv_len; count > 0; count-=len, u+=len ) {
1131 /* get the length indicated by the first byte */
1132 len = LDAP_UTF8_CHARLEN2( u, len );
1134 /* very basic checks */
1137 if( (u[5] & 0xC0) != 0x80 ) {
1138 return LDAP_INVALID_SYNTAX;
1141 if( (u[4] & 0xC0) != 0x80 ) {
1142 return LDAP_INVALID_SYNTAX;
1145 if( (u[3] & 0xC0) != 0x80 ) {
1146 return LDAP_INVALID_SYNTAX;
1149 if( (u[2] & 0xC0 )!= 0x80 ) {
1150 return LDAP_INVALID_SYNTAX;
1153 if( (u[1] & 0xC0) != 0x80 ) {
1154 return LDAP_INVALID_SYNTAX;
1157 /* CHARLEN already validated it */
1160 return LDAP_INVALID_SYNTAX;
1163 /* make sure len corresponds with the offset
1164 to the next character */
1165 if( LDAP_UTF8_OFFSET( (char *)u ) != len ) return LDAP_INVALID_SYNTAX;
1169 return LDAP_INVALID_SYNTAX;
1172 return LDAP_SUCCESS;
1176 UTF8StringNormalize(
1181 struct berval *normalized,
1184 struct berval tmp, nvalue;
1188 assert( SLAP_MR_IS_VALUE_OF_SYNTAX( use ));
1190 if( val->bv_val == NULL ) {
1191 /* assume we're dealing with a syntax (e.g., UTF8String)
1192 * which allows empty strings
1194 normalized->bv_len = 0;
1195 normalized->bv_val = NULL;
1196 return LDAP_SUCCESS;
1199 flags = SLAP_MR_ASSOCIATED( mr, slap_schema.si_mr_caseExactMatch )
1200 ? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
1201 flags |= ( ( use & SLAP_MR_EQUALITY_APPROX ) == SLAP_MR_EQUALITY_APPROX )
1202 ? LDAP_UTF8_APPROX : 0;
1204 val = UTF8bvnormalize( val, &tmp, flags, ctx );
1209 /* collapse spaces (in place) */
1211 nvalue.bv_val = tmp.bv_val;
1213 wasspace=1; /* trim leading spaces */
1214 for( i=0; i<tmp.bv_len; i++) {
1215 if ( ASCII_SPACE( tmp.bv_val[i] )) {
1216 if( wasspace++ == 0 ) {
1217 /* trim repeated spaces */
1218 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
1222 nvalue.bv_val[nvalue.bv_len++] = tmp.bv_val[i];
1226 if( nvalue.bv_len ) {
1228 /* last character was a space, trim it */
1231 nvalue.bv_val[nvalue.bv_len] = '\0';
1234 /* string of all spaces is treated as one space */
1235 nvalue.bv_val[0] = ' ';
1236 nvalue.bv_val[1] = '\0';
1240 *normalized = nvalue;
1241 return LDAP_SUCCESS;
1244 #if defined(SLAPD_APPROX_INITIALS)
1245 # define SLAPD_APPROX_DELIMITER "._ "
1246 # define SLAPD_APPROX_WORDLEN 2
1248 # define SLAPD_APPROX_DELIMITER " "
1249 # define SLAPD_APPROX_WORDLEN 1
1258 struct berval *value,
1259 void *assertedValue )
1261 struct berval *nval, *assertv;
1262 char *val, **values, **words, *c;
1263 int i, count, len, nextchunk=0, nextavail=0;
1265 /* Yes, this is necessary */
1266 nval = UTF8bvnormalize( value, NULL, LDAP_UTF8_APPROX, NULL );
1267 if( nval == NULL ) {
1269 return LDAP_SUCCESS;
1272 /* Yes, this is necessary */
1273 assertv = UTF8bvnormalize( ((struct berval *)assertedValue),
1274 NULL, LDAP_UTF8_APPROX, NULL );
1275 if( assertv == NULL ) {
1278 return LDAP_SUCCESS;
1281 /* Isolate how many words there are */
1282 for ( c = nval->bv_val, count = 1; *c; c++ ) {
1283 c = strpbrk( c, SLAPD_APPROX_DELIMITER );
1284 if ( c == NULL ) break;
1289 /* Get a phonetic copy of each word */
1290 words = (char **)ch_malloc( count * sizeof(char *) );
1291 values = (char **)ch_malloc( count * sizeof(char *) );
1292 for ( c = nval->bv_val, i = 0; i < count; i++, c += strlen(c) + 1 ) {
1294 values[i] = phonetic(c);
1297 /* Work through the asserted value's words, to see if at least some
1298 of the words are there, in the same order. */
1300 while ( (ber_len_t) nextchunk < assertv->bv_len ) {
1301 len = strcspn( assertv->bv_val + nextchunk, SLAPD_APPROX_DELIMITER);
1306 #if defined(SLAPD_APPROX_INITIALS)
1307 else if( len == 1 ) {
1308 /* Single letter words need to at least match one word's initial */
1309 for( i=nextavail; i<count; i++ )
1310 if( !strncasecmp( assertv->bv_val + nextchunk, words[i], 1 )) {
1317 /* Isolate the next word in the asserted value and phonetic it */
1318 assertv->bv_val[nextchunk+len] = '\0';
1319 val = phonetic( assertv->bv_val + nextchunk );
1321 /* See if this phonetic chunk is in the remaining words of *value */
1322 for( i=nextavail; i<count; i++ ){
1323 if( !strcmp( val, values[i] ) ){
1331 /* This chunk in the asserted value was NOT within the *value. */
1337 /* Go on to the next word in the asserted value */
1341 /* If some of the words were seen, call it a match */
1342 if( nextavail > 0 ) {
1349 /* Cleanup allocs */
1350 ber_bvfree( assertv );
1351 for( i=0; i<count; i++ ) {
1352 ch_free( values[i] );
1358 return LDAP_SUCCESS;
1367 struct berval *prefix,
1373 int i,j, len, wordcount, keycount=0;
1374 struct berval *newkeys;
1375 BerVarray keys=NULL;
1377 for( j=0; values[j].bv_val != NULL; j++ ) {
1378 struct berval val = BER_BVNULL;
1379 /* Yes, this is necessary */
1380 UTF8bvnormalize( &values[j], &val, LDAP_UTF8_APPROX, NULL );
1381 assert( val.bv_val != NULL );
1383 /* Isolate how many words there are. There will be a key for each */
1384 for( wordcount = 0, c = val.bv_val; *c; c++) {
1385 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1386 if( len >= SLAPD_APPROX_WORDLEN ) wordcount++;
1388 if (*c == '\0') break;
1392 /* Allocate/increase storage to account for new keys */
1393 newkeys = (struct berval *)ch_malloc( (keycount + wordcount + 1)
1394 * sizeof(struct berval) );
1395 AC_MEMCPY( newkeys, keys, keycount * sizeof(struct berval) );
1396 if( keys ) ch_free( keys );
1399 /* Get a phonetic copy of each word */
1400 for( c = val.bv_val, i = 0; i < wordcount; c += len + 1 ) {
1402 if( len < SLAPD_APPROX_WORDLEN ) continue;
1403 ber_str2bv( phonetic( c ), 0, 0, &keys[keycount] );
1408 ber_memfree( val.bv_val );
1410 keys[keycount].bv_val = NULL;
1413 return LDAP_SUCCESS;
1422 struct berval *prefix,
1423 void * assertedValue,
1432 /* Yes, this is necessary */
1433 val = UTF8bvnormalize( ((struct berval *)assertedValue),
1434 NULL, LDAP_UTF8_APPROX, NULL );
1435 if( val == NULL || val->bv_val == NULL ) {
1436 keys = (struct berval *)ch_malloc( sizeof(struct berval) );
1437 keys[0].bv_val = NULL;
1440 return LDAP_SUCCESS;
1443 /* Isolate how many words there are. There will be a key for each */
1444 for( count = 0,c = val->bv_val; *c; c++) {
1445 len = strcspn(c, SLAPD_APPROX_DELIMITER);
1446 if( len >= SLAPD_APPROX_WORDLEN ) count++;
1448 if (*c == '\0') break;
1452 /* Allocate storage for new keys */
1453 keys = (struct berval *)ch_malloc( (count + 1) * sizeof(struct berval) );
1455 /* Get a phonetic copy of each word */
1456 for( c = val->bv_val, i = 0; i < count; c += len + 1 ) {
1458 if( len < SLAPD_APPROX_WORDLEN ) continue;
1459 ber_str2bv( phonetic( c ), 0, 0, &keys[i] );
1465 keys[count].bv_val = NULL;
1468 return LDAP_SUCCESS;
1471 /* Remove all spaces and '-' characters */
1473 telephoneNumberNormalize(
1478 struct berval *normalized,
1483 assert( SLAP_MR_IS_VALUE_OF_SYNTAX( usage ));
1485 /* validator should have refused an empty string */
1486 assert( val->bv_len );
1488 q = normalized->bv_val = slap_sl_malloc( val->bv_len + 1, ctx );
1490 for( p = val->bv_val; *p; p++ ) {
1491 if ( ! ( ASCII_SPACE( *p ) || *p == '-' )) {
1497 normalized->bv_len = q - normalized->bv_val;
1499 if( normalized->bv_len == 0 ) {
1500 slap_sl_free( normalized->bv_val, ctx );
1501 normalized->bv_val = NULL;
1502 return LDAP_INVALID_SYNTAX;
1505 return LDAP_SUCCESS;
1513 struct berval val = *in;
1515 if( val.bv_len == 0 ) {
1516 /* disallow empty strings */
1517 return LDAP_INVALID_SYNTAX;
1520 while( OID_LEADCHAR( val.bv_val[0] ) ) {
1521 if ( val.bv_len == 1 ) {
1522 return LDAP_SUCCESS;
1525 if ( val.bv_val[0] == '0' ) {
1532 while ( OID_LEADCHAR( val.bv_val[0] )) {
1536 if ( val.bv_len == 0 ) {
1537 return LDAP_SUCCESS;
1541 if( !OID_SEPARATOR( val.bv_val[0] )) {
1549 return LDAP_INVALID_SYNTAX;
1558 struct berval val = *in;
1560 if( val.bv_len == 0 ) return LDAP_INVALID_SYNTAX;
1562 if ( val.bv_val[0] == '-' ) {
1566 if( val.bv_len == 0 ) { /* bare "-" */
1567 return LDAP_INVALID_SYNTAX;
1570 if( val.bv_val[0] == '0' ) { /* "-0" */
1571 return LDAP_INVALID_SYNTAX;
1574 } else if ( val.bv_val[0] == '0' ) {
1575 if( val.bv_len > 1 ) { /* "0<more>" */
1576 return LDAP_INVALID_SYNTAX;
1579 return LDAP_SUCCESS;
1582 for( i=0; i < val.bv_len; i++ ) {
1583 if( !ASCII_DIGIT(val.bv_val[i]) ) {
1584 return LDAP_INVALID_SYNTAX;
1588 return LDAP_SUCCESS;
1597 struct berval *value,
1598 void *assertedValue )
1600 struct berval *asserted = (struct berval *) assertedValue;
1601 int vsign = 1, asign = 1; /* default sign = '+' */
1606 if( v.bv_val[0] == '-' ) {
1612 if( v.bv_len == 0 ) vsign = 0;
1615 if( a.bv_val[0] == '-' ) {
1621 if( a.bv_len == 0 ) vsign = 0;
1623 match = vsign - asign;
1625 match = ( v.bv_len != a.bv_len
1626 ? ( v.bv_len < a.bv_len ? -1 : 1 )
1627 : memcmp( v.bv_val, a.bv_val, v.bv_len ));
1628 if( vsign < 0 ) match = -match;
1632 return LDAP_SUCCESS;
1636 countryStringValidate(
1638 struct berval *val )
1640 if( val->bv_len != 2 ) return LDAP_INVALID_SYNTAX;
1642 if( !SLAP_PRINTABLE(val->bv_val[0]) ) {
1643 return LDAP_INVALID_SYNTAX;
1645 if( !SLAP_PRINTABLE(val->bv_val[1]) ) {
1646 return LDAP_INVALID_SYNTAX;
1649 return LDAP_SUCCESS;
1653 printableStringValidate(
1655 struct berval *val )
1659 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
1661 for(i=0; i < val->bv_len; i++) {
1662 if( !SLAP_PRINTABLE(val->bv_val[i]) ) {
1663 return LDAP_INVALID_SYNTAX;
1667 return LDAP_SUCCESS;
1671 printablesStringValidate(
1673 struct berval *val )
1677 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
1679 for(i=0,len=0; i < val->bv_len; i++) {
1680 int c = val->bv_val[i];
1684 return LDAP_INVALID_SYNTAX;
1688 } else if ( SLAP_PRINTABLE(c) ) {
1691 return LDAP_INVALID_SYNTAX;
1696 return LDAP_INVALID_SYNTAX;
1699 return LDAP_SUCCESS;
1705 struct berval *val )
1709 if( val->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
1711 for(i=0; i < val->bv_len; i++) {
1712 if( !LDAP_ASCII(val->bv_val[i]) ) {
1713 return LDAP_INVALID_SYNTAX;
1717 return LDAP_SUCCESS;
1726 struct berval *normalized,
1730 int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match);
1732 assert( val->bv_len );
1734 assert( SLAP_MR_IS_VALUE_OF_SYNTAX( use ));
1738 /* Ignore initial whitespace */
1739 while ( ASCII_SPACE( *p ) ) p++;
1741 normalized->bv_val = ber_strdup_x( p, ctx );
1742 p = q = normalized->bv_val;
1745 if ( ASCII_SPACE( *p ) ) {
1748 /* Ignore the extra whitespace */
1749 while ( ASCII_SPACE( *p ) ) {
1753 } else if ( casefold ) {
1754 /* Most IA5 rules require casefolding */
1755 *q++ = TOLOWER(*p); p++;
1762 assert( normalized->bv_val <= p );
1766 * If the string ended in space, backup the pointer one
1767 * position. One is enough because the above loop collapsed
1768 * all whitespace to a single space.
1770 if ( ASCII_SPACE( q[-1] ) ) --q;
1772 /* null terminate */
1775 normalized->bv_len = q - normalized->bv_val;
1776 if( normalized->bv_len == 0 ) {
1777 normalized->bv_val = slap_sl_realloc( normalized->bv_val, 2, ctx );
1778 normalized->bv_val[0] = ' ';
1779 normalized->bv_val[1] = '\0';
1780 normalized->bv_len = 1;
1783 return LDAP_SUCCESS;
1792 if( in->bv_len != 36 ) {
1794 return LDAP_INVALID_SYNTAX;
1797 for( i=0; i<36; i++ ) {
1803 if( in->bv_val[i] != '-' ) {
1804 return LDAP_INVALID_SYNTAX;
1808 if( !ASCII_HEX( in->bv_val[i]) ) {
1809 return LDAP_INVALID_SYNTAX;
1814 return LDAP_SUCCESS;
1823 struct berval *normalized,
1826 unsigned char octet = '\0';
1829 normalized->bv_len = 16;
1830 normalized->bv_val = slap_sl_malloc( normalized->bv_len+1, ctx );
1832 for( i=0, j=0; i<36; i++ ) {
1833 unsigned char nibble;
1834 if( val->bv_val[i] == '-' ) {
1837 } else if( ASCII_DIGIT( val->bv_val[i] ) ) {
1838 nibble = val->bv_val[i] - '0';
1840 } else if( ASCII_HEXLOWER( val->bv_val[i] ) ) {
1841 nibble = val->bv_val[i] - ('a'-10);
1843 } else if( ASCII_HEXUPPER( val->bv_val[i] ) ) {
1844 nibble = val->bv_val[i] - ('A'-10);
1847 slap_sl_free( normalized->bv_val, ctx );
1848 return LDAP_INVALID_SYNTAX;
1853 normalized->bv_val[j>>1] = octet;
1855 octet = nibble << 4;
1860 normalized->bv_val[normalized->bv_len] = 0;
1861 return LDAP_SUCCESS;
1867 numericStringValidate(
1873 if( in->bv_len == 0 ) return LDAP_INVALID_SYNTAX;
1875 for(i=0; i < in->bv_len; i++) {
1876 if( !SLAP_NUMERIC(in->bv_val[i]) ) {
1877 return LDAP_INVALID_SYNTAX;
1881 return LDAP_SUCCESS;
1885 numericStringNormalize(
1890 struct berval *normalized,
1893 /* removal all spaces */
1896 assert( val->bv_len );
1898 normalized->bv_val = slap_sl_malloc( val->bv_len + 1, ctx );
1901 q = normalized->bv_val;
1904 if ( ASCII_SPACE( *p ) ) {
1905 /* Ignore whitespace */
1912 /* we should have copied no more then is in val */
1913 assert( (q - normalized->bv_val) <= (p - val->bv_val) );
1915 /* null terminate */
1918 normalized->bv_len = q - normalized->bv_val;
1920 if( normalized->bv_len == 0 ) {
1921 normalized->bv_val = slap_sl_realloc( normalized->bv_val, 2, ctx );
1922 normalized->bv_val[0] = ' ';
1923 normalized->bv_val[1] = '\0';
1924 normalized->bv_len = 1;
1927 return LDAP_SUCCESS;
1931 * Integer conversion macros that will use the largest available
1934 #if defined(HAVE_STRTOLL) && defined(LLONG_MAX) && defined(LLONG_MIN) && defined(HAVE_LONG_LONG)
1935 # define SLAP_STRTOL(n,e,b) strtoll(n,e,b)
1936 # define SLAP_LONG_MAX LLONG_MAX
1937 # define SLAP_LONG_MIN LLONG_MIN
1938 # define SLAP_LONG long long
1940 # define SLAP_STRTOL(n,e,b) strtol(n,e,b)
1941 # define SLAP_LONG_MAX LONG_MAX
1942 # define SLAP_LONG_MIN LONG_MIN
1943 # define SLAP_LONG long
1944 #endif /* HAVE_STRTOLL ... */
1952 struct berval *value,
1953 void *assertedValue )
1955 SLAP_LONG lValue, lAssertedValue;
1957 /* safe to assume integers are NUL terminated? */
1958 lValue = SLAP_STRTOL(value->bv_val, NULL, 10);
1959 if(( lValue == SLAP_LONG_MIN || lValue == SLAP_LONG_MAX) && errno == ERANGE ) {
1960 return LDAP_CONSTRAINT_VIOLATION;
1963 lAssertedValue = SLAP_STRTOL(((struct berval *)assertedValue)->bv_val, NULL, 10);
1964 if(( lAssertedValue == SLAP_LONG_MIN || lAssertedValue == SLAP_LONG_MAX )
1965 && errno == ERANGE )
1967 return LDAP_CONSTRAINT_VIOLATION;
1970 *matchp = (lValue & lAssertedValue) ? 0 : 1;
1971 return LDAP_SUCCESS;
1980 struct berval *value,
1981 void *assertedValue )
1983 SLAP_LONG lValue, lAssertedValue;
1985 /* safe to assume integers are NUL terminated? */
1986 lValue = SLAP_STRTOL(value->bv_val, NULL, 10);
1987 if(( lValue == SLAP_LONG_MIN || lValue == SLAP_LONG_MAX ) && errno == ERANGE ) {
1988 return LDAP_CONSTRAINT_VIOLATION;
1991 lAssertedValue = SLAP_STRTOL(((struct berval *)assertedValue)->bv_val, NULL, 10);
1992 if(( lAssertedValue == SLAP_LONG_MIN || lAssertedValue == SLAP_LONG_MAX )
1993 && errno == ERANGE )
1995 return LDAP_CONSTRAINT_VIOLATION;
1998 *matchp = (lValue | lAssertedValue) ? 0 : -1;
1999 return LDAP_SUCCESS;
2003 serialNumberAndIssuerValidate(
2010 struct berval sn, i;
2011 if( in->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
2013 i.bv_val = strchr( in->bv_val, '$' );
2014 if( i.bv_val == NULL ) return LDAP_INVALID_SYNTAX;
2016 sn.bv_val = in->bv_val;
2017 sn.bv_len = i.bv_val - in->bv_val;
2020 i.bv_len = in->bv_len - (sn.bv_len + 1);
2022 /* validate serial number (strict for now) */
2023 for( n=0; n < sn.bv_len; n++ ) {
2024 if( !ASCII_DIGIT(sn.bv_val[n]) ) {
2025 return LDAP_INVALID_SYNTAX;
2030 rc = dnValidate( NULL, &i );
2031 if( rc ) return LDAP_INVALID_SYNTAX;
2033 return LDAP_SUCCESS;
2037 serialNumberAndIssuerPretty(
2046 struct berval sn, i, newi;
2052 LDAP_LOG( OPERATION, ARGS, ">>> serialNumberAndIssuerPretty: <%s>\n",
2053 val->bv_val, 0, 0 );
2055 Debug( LDAP_DEBUG_TRACE, ">>> serialNumberAndIssuerPretty: <%s>\n",
2056 val->bv_val, 0, 0 );
2059 if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
2061 i.bv_val = strchr( val->bv_val, '$' );
2062 if( i.bv_val == NULL ) return LDAP_INVALID_SYNTAX;
2064 sn.bv_val = val->bv_val;
2065 sn.bv_len = i.bv_val - val->bv_val;
2068 i.bv_len = val->bv_len - (sn.bv_len + 1);
2070 /* eat leading zeros */
2071 for( n=0; n < (sn.bv_len-1); n++ ) {
2072 if( sn.bv_val[n] != '0' ) break;
2077 for( n=0; n < sn.bv_len; n++ ) {
2078 if( !ASCII_DIGIT(sn.bv_val[n]) ) {
2079 return LDAP_INVALID_SYNTAX;
2084 rc = dnPretty( syntax, &i, &newi, ctx );
2085 if( rc ) return LDAP_INVALID_SYNTAX;
2087 /* make room from sn + "$" */
2088 out->bv_len = sn.bv_len + newi.bv_len + 1;
2089 out->bv_val = slap_sl_realloc( newi.bv_val, out->bv_len + 1, ctx );
2091 if( out->bv_val == NULL ) {
2092 slap_sl_free( newi.bv_val, ctx );
2096 /* push issuer over */
2097 AC_MEMCPY( &out->bv_val[sn.bv_len+1], newi.bv_val, newi.bv_len );
2098 /* insert sn and "$" */
2099 AC_MEMCPY( out->bv_val, sn.bv_val, sn.bv_len );
2100 out->bv_val[sn.bv_len] = '$';
2102 out->bv_val[out->bv_len] = '\0';
2105 LDAP_LOG( OPERATION, ARGS, "<<< serialNumberAndIssuerPretty: <%s>\n",
2106 out->bv_val, 0, 0 );
2108 Debug( LDAP_DEBUG_TRACE, "<<< serialNumberAndIssuerPretty: <%s>\n",
2109 out->bv_val, 0, 0 );
2112 return LDAP_SUCCESS;
2116 * This routine is called by certificateExactNormalize when
2117 * certificateExactNormalize receives a search string instead of
2118 * a certificate. This routine checks if the search value is valid
2119 * and then returns the normalized value
2122 serialNumberAndIssuerNormalize(
2133 struct berval sn, i, newi;
2139 LDAP_LOG( OPERATION, ARGS, ">>> serialNumberAndIssuerNormalize: <%s>\n",
2140 val->bv_val, 0, 0 );
2142 Debug( LDAP_DEBUG_TRACE, ">>> serialNumberAndIssuerNormalize: <%s>\n",
2143 val->bv_val, 0, 0 );
2146 if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
2148 i.bv_val = strchr( val->bv_val, '$' );
2149 if( i.bv_val == NULL ) return LDAP_INVALID_SYNTAX;
2151 sn.bv_val = val->bv_val;
2152 sn.bv_len = i.bv_val - val->bv_val;
2155 i.bv_len = val->bv_len - (sn.bv_len + 1);
2157 /* eat leading zeros */
2158 for( n=0; n < (sn.bv_len-1); n++ ) {
2159 if( sn.bv_val[n] != '0' ) break;
2164 for( n=0; n < sn.bv_len; n++ ) {
2165 if( !ASCII_DIGIT(sn.bv_val[n]) ) {
2166 return LDAP_INVALID_SYNTAX;
2171 rc = dnNormalize( usage, syntax, mr, &i, &newi, ctx );
2172 if( rc ) return LDAP_INVALID_SYNTAX;
2174 /* make room from sn + "$" */
2175 out->bv_len = sn.bv_len + newi.bv_len + 1;
2176 out->bv_val = slap_sl_realloc( newi.bv_val, out->bv_len + 1, ctx );
2178 if( out->bv_val == NULL ) {
2179 slap_sl_free( newi.bv_val, ctx );
2183 /* push issuer over */
2184 AC_MEMCPY( &out->bv_val[sn.bv_len+1], newi.bv_val, newi.bv_len );
2185 /* insert sn and "$" */
2186 AC_MEMCPY( out->bv_val, sn.bv_val, sn.bv_len );
2187 out->bv_val[sn.bv_len] = '$';
2189 out->bv_val[out->bv_len] = '\0';
2192 LDAP_LOG( OPERATION, ARGS, "<<< serialNumberAndIssuerNormalize: <%s>\n",
2193 out->bv_val, 0, 0 );
2195 Debug( LDAP_DEBUG_TRACE, "<<< serialNumberAndIssuerNormalize: <%s>\n",
2196 out->bv_val, 0, 0 );
2204 certificateExactNormalize(
2209 struct berval *normalized,
2212 int rc = LDAP_INVALID_SYNTAX;
2214 char *serial = NULL;
2215 ber_len_t seriallen;
2216 struct berval issuer_dn = BER_BVNULL;
2217 X509_NAME *name = NULL;
2218 ASN1_INTEGER *sn = NULL;
2221 if( val->bv_len == 0 ) goto done;
2223 if( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX(usage) ) {
2224 return serialNumberAndIssuerNormalize(0,NULL,NULL,val,normalized,ctx);
2227 assert( SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX(usage) );
2229 p = (unsigned char *)val->bv_val;
2230 xcert = d2i_X509( NULL, &p, val->bv_len);
2231 if( xcert == NULL ) goto done;
2233 sn=X509_get_serialNumber(xcert);
2234 if ( sn == NULL ) goto done;
2235 serial=i2s_ASN1_INTEGER(0, sn );
2236 if( serial == NULL ) goto done;
2237 seriallen=strlen(serial);
2239 name=X509_get_issuer_name(xcert);
2240 if( name == NULL ) goto done;
2241 rc = dnX509normalize( name, &issuer_dn );
2242 if( rc != LDAP_SUCCESS ) goto done;
2244 normalized->bv_len = seriallen + issuer_dn.bv_len + 1;
2245 normalized->bv_val = ch_malloc(normalized->bv_len+1);
2246 p = (unsigned char *)normalized->bv_val;
2247 AC_MEMCPY(p, serial, seriallen);
2250 AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
2251 p += issuer_dn.bv_len;
2255 LDAP_LOG( CONFIG, ARGS, "certificateExactNormalize: %s\n",
2256 normalized->bv_val, 0, 0 );
2258 Debug( LDAP_DEBUG_TRACE, "certificateExactNormalize: %s\n",
2259 normalized->bv_val, NULL, NULL );
2263 if (xcert) X509_free(xcert);
2264 if (serial) ch_free(serial);
2265 if (issuer_dn.bv_val) ber_memfree(issuer_dn.bv_val);
2269 #endif /* HAVE_TLS */
2272 #ifndef SUPPORT_OBSOLETE_UTC_SYNTAX
2273 /* slight optimization - does not need the start parameter */
2274 #define check_time_syntax(v, start, p, f) (check_time_syntax)(v, p, f)
2279 check_time_syntax (struct berval *val,
2282 struct berval *fraction)
2285 * start=0 GeneralizedTime YYYYmmddHH[MM[SS]][(./,)d...](Z|(+/-)HH[MM])
2286 * start=1 UTCTime YYmmddHHMM[SS][Z|(+/-)HHMM]
2287 * GeneralizedTime supports leap seconds, UTCTime does not.
2289 static const int ceiling[9] = { 100, 100, 12, 31, 24, 60, 60, 24, 60 };
2290 static const int mdays[2][12] = {
2291 /* non-leap years */
2292 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
2294 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
2297 int part, c, c1, c2, tzoffset, leapyear = 0;
2300 e = p + val->bv_len;
2302 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
2303 parts[0] = 20; /* century - any multiple of 4 from 04 to 96 */
2305 for (part = start; part < 7 && p < e; part++) {
2307 if (!ASCII_DIGIT(c1)) {
2312 return LDAP_INVALID_SYNTAX;
2315 if (!ASCII_DIGIT(c)) {
2316 return LDAP_INVALID_SYNTAX;
2318 c += c1 * 10 - '0' * 11;
2319 if ((part | 1) == 3) {
2322 return LDAP_INVALID_SYNTAX;
2325 if (c >= ceiling[part]) {
2326 if (! (c == 60 && part == 6 && start == 0))
2327 return LDAP_INVALID_SYNTAX;
2331 if (part < 5 + start) {
2332 return LDAP_INVALID_SYNTAX;
2334 for (; part < 9; part++) {
2338 /* leapyear check for the Gregorian calendar (year>1581) */
2339 if (parts[parts[1] == 0 ? 0 : 1] % 4 == 0)
2344 if (parts[3] >= mdays[leapyear][parts[2]]) {
2345 return LDAP_INVALID_SYNTAX;
2349 fraction->bv_val = p;
2350 fraction->bv_len = 0;
2351 if (p < e && (*p == '.' || *p == ',')) {
2353 while (++p < e && ASCII_DIGIT(*p))
2355 if (p - fraction->bv_val == 1) {
2356 return LDAP_INVALID_SYNTAX;
2358 for (end_num = p; end_num[-1] == '0'; --end_num)
2360 c = end_num - fraction->bv_val;
2362 fraction->bv_len = c;
2368 return start == 0 ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
2374 return LDAP_INVALID_SYNTAX;
2380 for (part = 7; part < 9 && p < e; part++) {
2382 if (!ASCII_DIGIT(c1)) {
2387 return LDAP_INVALID_SYNTAX;
2390 if (!ASCII_DIGIT(c2)) {
2391 return LDAP_INVALID_SYNTAX;
2393 parts[part] = c1 * 10 + c2 - '0' * 11;
2394 if (parts[part] >= ceiling[part]) {
2395 return LDAP_INVALID_SYNTAX;
2398 if (part < 8 + start) {
2399 return LDAP_INVALID_SYNTAX;
2402 if (tzoffset == '-') {
2403 /* negative offset to UTC, ie west of Greenwich */
2404 parts[4] += parts[7];
2405 parts[5] += parts[8];
2406 /* offset is just hhmm, no seconds */
2407 for (part = 6; --part >= 0; ) {
2411 c = mdays[leapyear][parts[2]];
2413 if (parts[part] >= c) {
2415 return LDAP_INVALID_SYNTAX;
2420 } else if (part != 5) {
2425 /* positive offset to UTC, ie east of Greenwich */
2426 parts[4] -= parts[7];
2427 parts[5] -= parts[8];
2428 for (part = 6; --part >= 0; ) {
2429 if (parts[part] < 0) {
2431 return LDAP_INVALID_SYNTAX;
2436 /* make first arg to % non-negative */
2437 c = mdays[leapyear][(parts[2] - 1 + 12) % 12];
2442 } else if (part != 5) {
2449 return p != e ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS;
2452 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
2459 struct berval *normalized )
2463 rc = check_time_syntax(val, 1, parts, NULL);
2464 if (rc != LDAP_SUCCESS) {
2468 normalized->bv_val = ch_malloc( 14 );
2469 if ( normalized->bv_val == NULL ) {
2470 return LBER_ERROR_MEMORY;
2473 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02dZ",
2474 parts[1], parts[2] + 1, parts[3] + 1,
2475 parts[4], parts[5], parts[6] );
2476 normalized->bv_len = 13;
2478 return LDAP_SUCCESS;
2488 return check_time_syntax(in, 1, parts, NULL);
2491 #endif /* SUPPORT_OBSOLETE_UTC_SYNTAX */
2494 generalizedTimeValidate(
2499 struct berval fraction;
2500 return check_time_syntax(in, 0, parts, &fraction);
2504 generalizedTimeNormalize(
2509 struct berval *normalized,
2514 struct berval fraction;
2516 rc = check_time_syntax(val, 0, parts, &fraction);
2517 if (rc != LDAP_SUCCESS) {
2521 len = sizeof("YYYYmmddHHMMSSZ")-1 + fraction.bv_len;
2522 normalized->bv_val = slap_sl_malloc( len + 1, ctx );
2523 if ( normalized->bv_val == NULL ) {
2524 return LBER_ERROR_MEMORY;
2527 sprintf( normalized->bv_val, "%02d%02d%02d%02d%02d%02d%02d",
2528 parts[0], parts[1], parts[2] + 1, parts[3] + 1,
2529 parts[4], parts[5], parts[6] );
2530 if ( fraction.bv_len ) {
2531 memcpy( normalized->bv_val + sizeof("YYYYmmddHHMMSSZ")-2,
2532 fraction.bv_val, fraction.bv_len );
2533 normalized->bv_val[sizeof("YYYYmmddHHMMSSZ")-2] = '.';
2535 strcpy( normalized->bv_val + len-1, "Z" );
2536 normalized->bv_len = len;
2538 return LDAP_SUCCESS;
2542 generalizedTimeOrderingMatch(
2547 struct berval *value,
2548 void *assertedValue )
2550 struct berval *asserted = (struct berval *) assertedValue;
2551 ber_len_t v_len = value->bv_len;
2552 ber_len_t av_len = asserted->bv_len;
2554 /* ignore trailing 'Z' when comparing */
2555 int match = memcmp( value->bv_val, asserted->bv_val,
2556 (v_len < av_len ? v_len : av_len) - 1 );
2557 if ( match == 0 ) match = v_len - av_len;
2560 return LDAP_SUCCESS;
2564 deliveryMethodValidate(
2566 struct berval *val )
2569 #define LENOF(s) (sizeof(s)-1)
2570 struct berval tmp = *val;
2572 * DeliveryMethod = pdm *( WSP DOLLAR WSP DeliveryMethod )
2573 * pdm = "any" / "mhs" / "physical" / "telex" / "teletex" /
2574 * "g3fax" / "g4fax" / "ia5" / "videotex" / "telephone"
2577 if( tmp.bv_len < 3 ) return LDAP_INVALID_SYNTAX;
2579 switch( tmp.bv_val[0] ) {
2582 if(( tmp.bv_len >= LENOF("any") ) &&
2583 ( strncasecmp(tmp.bv_val, "any", LENOF("any")) == 0 ))
2585 tmp.bv_len -= LENOF("any");
2586 tmp.bv_val += LENOF("any");
2589 return LDAP_INVALID_SYNTAX;
2593 if(( tmp.bv_len >= LENOF("mhs") ) &&
2594 ( strncasecmp(tmp.bv_val, "mhs", LENOF("mhs")) == 0 ))
2596 tmp.bv_len -= LENOF("mhs");
2597 tmp.bv_val += LENOF("mhs");
2600 return LDAP_INVALID_SYNTAX;
2604 if(( tmp.bv_len >= LENOF("physical") ) &&
2605 ( strncasecmp(tmp.bv_val, "physical", LENOF("physical")) == 0 ))
2607 tmp.bv_len -= LENOF("physical");
2608 tmp.bv_val += LENOF("physical");
2611 return LDAP_INVALID_SYNTAX;
2614 case 'T': /* telex or teletex or telephone */
2615 if(( tmp.bv_len >= LENOF("telex") ) &&
2616 ( strncasecmp(tmp.bv_val, "telex", LENOF("telex")) == 0 ))
2618 tmp.bv_len -= LENOF("telex");
2619 tmp.bv_val += LENOF("telex");
2622 if(( tmp.bv_len >= LENOF("teletex") ) &&
2623 ( strncasecmp(tmp.bv_val, "teletex", LENOF("teletex")) == 0 ))
2625 tmp.bv_len -= LENOF("teletex");
2626 tmp.bv_val += LENOF("teletex");
2629 if(( tmp.bv_len >= LENOF("telephone") ) &&
2630 ( strncasecmp(tmp.bv_val, "telephone", LENOF("telephone")) == 0 ))
2632 tmp.bv_len -= LENOF("telephone");
2633 tmp.bv_val += LENOF("telephone");
2636 return LDAP_INVALID_SYNTAX;
2639 case 'G': /* g3fax or g4fax */
2640 if(( tmp.bv_len >= LENOF("g3fax") ) && (
2641 ( strncasecmp(tmp.bv_val, "g3fax", LENOF("g3fax")) == 0 ) ||
2642 ( strncasecmp(tmp.bv_val, "g4fax", LENOF("g4fax")) == 0 )))
2644 tmp.bv_len -= LENOF("g3fax");
2645 tmp.bv_val += LENOF("g3fax");
2648 return LDAP_INVALID_SYNTAX;
2652 if(( tmp.bv_len >= LENOF("ia5") ) &&
2653 ( strncasecmp(tmp.bv_val, "ia5", LENOF("ia5")) == 0 ))
2655 tmp.bv_len -= LENOF("ia5");
2656 tmp.bv_val += LENOF("ia5");
2659 return LDAP_INVALID_SYNTAX;
2663 if(( tmp.bv_len >= LENOF("videotex") ) &&
2664 ( strncasecmp(tmp.bv_val, "videotex", LENOF("videotex")) == 0 ))
2666 tmp.bv_len -= LENOF("videotex");
2667 tmp.bv_val += LENOF("videotex");
2670 return LDAP_INVALID_SYNTAX;
2673 return LDAP_INVALID_SYNTAX;
2676 if( tmp.bv_len == 0 ) return LDAP_SUCCESS;
2678 while( tmp.bv_len && ( tmp.bv_val[0] == ' ' )) {
2682 if( tmp.bv_len && ( tmp.bv_val[0] == '$' )) {
2686 return LDAP_INVALID_SYNTAX;
2688 while( tmp.bv_len && ( tmp.bv_val[0] == ' ' )) {
2697 nisNetgroupTripleValidate(
2699 struct berval *val )
2704 if ( val->bv_len == 0 ) {
2705 return LDAP_INVALID_SYNTAX;
2708 p = (char *)val->bv_val;
2709 e = p + val->bv_len;
2711 if ( *p != '(' /*')'*/ ) {
2712 return LDAP_INVALID_SYNTAX;
2715 for ( p++; ( p < e ) && ( *p != /*'('*/ ')' ); p++ ) {
2719 return LDAP_INVALID_SYNTAX;
2722 } else if ( !AD_CHAR( *p ) ) {
2723 return LDAP_INVALID_SYNTAX;
2727 if ( ( commas != 2 ) || ( *p != /*'('*/ ')' ) ) {
2728 return LDAP_INVALID_SYNTAX;
2734 return LDAP_INVALID_SYNTAX;
2737 return LDAP_SUCCESS;
2741 bootParameterValidate(
2743 struct berval *val )
2747 if ( val->bv_len == 0 ) {
2748 return LDAP_INVALID_SYNTAX;
2751 p = (char *)val->bv_val;
2752 e = p + val->bv_len;
2755 for (; ( p < e ) && ( *p != '=' ); p++ ) {
2756 if ( !AD_CHAR( *p ) ) {
2757 return LDAP_INVALID_SYNTAX;
2762 return LDAP_INVALID_SYNTAX;
2766 for ( p++; ( p < e ) && ( *p != ':' ); p++ ) {
2767 if ( !AD_CHAR( *p ) ) {
2768 return LDAP_INVALID_SYNTAX;
2773 return LDAP_INVALID_SYNTAX;
2777 for ( p++; p < e; p++ ) {
2778 if ( !SLAP_PRINTABLE( *p ) ) {
2779 return LDAP_INVALID_SYNTAX;
2783 return LDAP_SUCCESS;
2787 firstComponentNormalize(
2792 struct berval *normalized,
2799 if( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX( usage )) {
2800 ber_dupbv_x( normalized, val, ctx );
2801 return LDAP_SUCCESS;
2804 if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX;
2806 if( val->bv_val[0] != '(' /*')'*/ &&
2807 val->bv_val[0] != '{' /*'}'*/ )
2809 return LDAP_INVALID_SYNTAX;
2812 /* trim leading white space */
2814 len < val->bv_len && ASCII_SPACE(val->bv_val[len]);
2820 /* grab next word */
2821 comp.bv_val = &val->bv_val[len];
2822 len = val->bv_len - len;
2824 !ASCII_SPACE(comp.bv_val[comp.bv_len]) && comp.bv_len < len;
2830 if( mr == slap_schema.si_mr_objectIdentifierFirstComponentMatch ) {
2831 rc = numericoidValidate( NULL, &comp );
2832 } else if( mr == slap_schema.si_mr_integerFirstComponentMatch ) {
2833 rc = integerValidate( NULL, &comp );
2835 rc = LDAP_INVALID_SYNTAX;
2839 if( rc == LDAP_SUCCESS ) {
2840 ber_dupbv_x( normalized, &comp, ctx );
2847 #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' "
2848 #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' "
2850 static slap_syntax_defs_rec syntax_defs[] = {
2851 {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' "
2852 X_BINARY X_NOT_H_R ")",
2853 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL},
2854 {"( 1.3.6.1.4.1.1466.115.121.1.2 DESC 'Access Point' " X_NOT_H_R ")",
2856 {"( 1.3.6.1.4.1.1466.115.121.1.3 DESC 'Attribute Type Description' )",
2858 {"( 1.3.6.1.4.1.1466.115.121.1.4 DESC 'Audio' "
2860 SLAP_SYNTAX_BLOB, blobValidate, NULL},
2861 {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' "
2863 SLAP_SYNTAX_BER, berValidate, NULL},
2864 {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )",
2865 0, bitStringValidate, NULL },
2866 {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )",
2867 0, booleanValidate, NULL},
2868 {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' "
2869 X_BINARY X_NOT_H_R ")",
2870 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, certificateValidate, NULL},
2871 {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' "
2872 X_BINARY X_NOT_H_R ")",
2873 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, sequenceValidate, NULL},
2874 {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' "
2875 X_BINARY X_NOT_H_R ")",
2876 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, sequenceValidate, NULL},
2877 {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )",
2878 0, countryStringValidate, NULL},
2879 {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )",
2880 0, dnValidate, dnPretty},
2881 {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )",
2883 {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )",
2884 0, deliveryMethodValidate, NULL},
2885 {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )",
2886 0, UTF8StringValidate, NULL},
2887 {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )",
2889 {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )",
2891 {"( 1.3.6.1.4.1.1466.115.121.1.19 DESC 'DSA Quality' )",
2893 {"( 1.3.6.1.4.1.1466.115.121.1.20 DESC 'DSE Type' )",
2895 {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )",
2897 {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )",
2898 0, printablesStringValidate, NULL},
2899 {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")",
2900 SLAP_SYNTAX_BLOB, NULL, NULL},
2901 {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )",
2902 0, generalizedTimeValidate, NULL},
2903 {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )",
2905 {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )",
2906 0, IA5StringValidate, NULL},
2907 {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )",
2908 0, integerValidate, NULL},
2909 {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")",
2910 SLAP_SYNTAX_BLOB, blobValidate, NULL},
2911 {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )",
2913 {"( 1.3.6.1.4.1.1466.115.121.1.30 DESC 'Matching Rule Description' )",
2915 {"( 1.3.6.1.4.1.1466.115.121.1.31 DESC 'Matching Rule Use Description' )",
2917 {"( 1.3.6.1.4.1.1466.115.121.1.32 DESC 'Mail Preference' )",
2919 {"( 1.3.6.1.4.1.1466.115.121.1.33 DESC 'MHS OR Address' )",
2921 {"( 1.3.6.1.4.1.1466.115.121.1.34 DESC 'Name And Optional UID' )",
2922 0, nameUIDValidate, nameUIDPretty },
2923 {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )",
2925 {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )",
2926 0, numericStringValidate, NULL},
2927 {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )",
2929 {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )",
2930 0, numericoidValidate, NULL},
2931 {"( 1.3.6.1.4.1.1466.115.121.1.39 DESC 'Other Mailbox' )",
2932 0, IA5StringValidate, NULL},
2933 {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )",
2934 0, blobValidate, NULL},
2935 {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )",
2936 0, UTF8StringValidate, NULL},
2937 {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )",
2939 {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )",
2941 {"( 1.3.6.1.4.1.1466.115.121.1.44 DESC 'Printable String' )",
2942 0, printableStringValidate, NULL},
2943 {"( 1.3.6.1.4.1.1466.115.121.1.45 DESC 'SubtreeSpecification' )",
2944 #define subtreeSpecificationValidate UTF8StringValidate /* FIXME */
2945 0, subtreeSpecificationValidate, NULL},
2946 {"( 1.3.6.1.4.1.1466.115.121.1.49 DESC 'Supported Algorithm' "
2947 X_BINARY X_NOT_H_R ")",
2948 SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL},
2949 {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )",
2950 0, printableStringValidate, NULL},
2951 {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )",
2953 {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )",
2954 0, printablesStringValidate, NULL},
2955 #ifdef SUPPORT_OBSOLETE_UTC_SYNTAX
2956 {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )",
2957 0, utcTimeValidate, NULL},
2959 {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )",
2961 {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )",
2963 {"( 1.3.6.1.4.1.1466.115.121.1.56 DESC 'LDAP Schema Definition' )",
2965 {"( 1.3.6.1.4.1.1466.115.121.1.57 DESC 'LDAP Schema Description' )",
2967 {"( 1.3.6.1.4.1.1466.115.121.1.58 DESC 'Substring Assertion' )",
2970 /* RFC 2307 NIS Syntaxes */
2971 {"( 1.3.6.1.1.1.0.0 DESC 'RFC2307 NIS Netgroup Triple' )",
2972 0, nisNetgroupTripleValidate, NULL},
2973 {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )",
2974 0, bootParameterValidate, NULL},
2976 /* From PKIX *//* This OID is not published yet. */
2977 {"( 1.2.826.0.1.3344810.7.1 DESC 'Certificate Serial Number and Issuer' )",
2979 serialNumberAndIssuerValidate,
2980 serialNumberAndIssuerPretty},
2982 #ifdef SLAPD_ACI_ENABLED
2983 /* OpenLDAP Experimental Syntaxes */
2984 {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
2986 UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
2990 #ifdef SLAPD_AUTHPASSWD
2991 /* needs updating */
2992 {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )",
2993 SLAP_SYNTAX_HIDE, NULL, NULL},
2996 {"( 1.3.6.1.4.1.4203.666.2.6 DESC 'UUID' )",
2997 SLAP_SYNTAX_HIDE, UUIDValidate, NULL},
2999 /* OpenLDAP Void Syntax */
3000 {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" ,
3001 SLAP_SYNTAX_HIDE, inValidate, NULL},
3002 {NULL, 0, NULL, NULL}
3005 char *certificateExactMatchSyntaxes[] = {
3006 "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */,
3009 char *directoryStringSyntaxes[] = {
3010 "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */,
3013 char *integerFirstComponentMatchSyntaxes[] = {
3014 "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */,
3015 "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */,
3018 char *objectIdentifierFirstComponentMatchSyntaxes[] = {
3019 "1.3.6.1.4.1.1466.115.121.1.38" /* OID */,
3020 "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */,
3021 "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */,
3022 "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */,
3023 "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */,
3024 "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */,
3025 "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */,
3026 "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */,
3031 * Other matching rules in X.520 that we do not use (yet):
3033 * 2.5.13.25 uTCTimeMatch
3034 * 2.5.13.26 uTCTimeOrderingMatch
3035 * 2.5.13.31* directoryStringFirstComponentMatch
3036 * 2.5.13.32* wordMatch
3037 * 2.5.13.33* keywordMatch
3038 * 2.5.13.36 certificatePairExactMatch
3039 * 2.5.13.37 certificatePairMatch
3040 * 2.5.13.38 certificateListExactMatch
3041 * 2.5.13.39 certificateListMatch
3042 * 2.5.13.40 algorithmIdentifierMatch
3043 * 2.5.13.41* storedPrefixMatch
3044 * 2.5.13.42 attributeCertificateMatch
3045 * 2.5.13.43 readerAndKeyIDMatch
3046 * 2.5.13.44 attributeIntegrityMatch
3048 * (*) described in RFC 3698 (LDAP: Additional Matching Rules)
3050 static slap_mrule_defs_rec mrule_defs[] = {
3052 * EQUALITY matching rules must be listed after associated APPROX
3053 * matching rules. So, we list all APPROX matching rules first.
3055 {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' "
3056 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3057 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
3058 NULL, NULL, directoryStringApproxMatch,
3059 directoryStringApproxIndexer, directoryStringApproxFilter,
3062 {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' "
3063 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3064 SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL,
3065 NULL, NULL, IA5StringApproxMatch,
3066 IA5StringApproxIndexer, IA5StringApproxFilter,
3070 * Other matching rules
3073 {"( 2.5.13.0 NAME 'objectIdentifierMatch' "
3074 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
3075 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3076 NULL, NULL, octetStringMatch,
3077 octetStringIndexer, octetStringFilter,
3080 {"( 2.5.13.1 NAME 'distinguishedNameMatch' "
3081 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )",
3082 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3083 NULL, dnNormalize, dnMatch,
3084 octetStringIndexer, octetStringFilter,
3087 {"( 2.5.13.2 NAME 'caseIgnoreMatch' "
3088 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3089 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
3090 NULL, UTF8StringNormalize, octetStringMatch,
3091 octetStringIndexer, octetStringFilter,
3092 directoryStringApproxMatchOID },
3094 {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' "
3095 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3096 SLAP_MR_ORDERING, directoryStringSyntaxes,
3097 NULL, UTF8StringNormalize, octetStringOrderingMatch,
3099 "caseIgnoreMatch" },
3101 {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' "
3102 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3103 SLAP_MR_SUBSTR, directoryStringSyntaxes,
3104 NULL, UTF8StringNormalize, octetStringSubstringsMatch,
3105 octetStringSubstringsIndexer, octetStringSubstringsFilter,
3106 "caseIgnoreMatch" },
3108 {"( 2.5.13.5 NAME 'caseExactMatch' "
3109 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3110 SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes,
3111 NULL, UTF8StringNormalize, octetStringMatch,
3112 octetStringIndexer, octetStringFilter,
3113 directoryStringApproxMatchOID },
3115 {"( 2.5.13.6 NAME 'caseExactOrderingMatch' "
3116 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )",
3117 SLAP_MR_ORDERING, directoryStringSyntaxes,
3118 NULL, UTF8StringNormalize, octetStringOrderingMatch,
3122 {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' "
3123 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3124 SLAP_MR_SUBSTR, directoryStringSyntaxes,
3125 NULL, UTF8StringNormalize, octetStringSubstringsMatch,
3126 octetStringSubstringsIndexer, octetStringSubstringsFilter,
3129 {"( 2.5.13.8 NAME 'numericStringMatch' "
3130 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
3131 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3132 NULL, numericStringNormalize, octetStringMatch,
3133 octetStringIndexer, octetStringFilter,
3136 {"( 2.5.13.9 NAME 'numericStringOrderingMatch' "
3137 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )",
3138 SLAP_MR_ORDERING, NULL,
3139 NULL, numericStringNormalize, octetStringOrderingMatch,
3141 "numericStringMatch" },
3143 {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' "
3144 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3145 SLAP_MR_SUBSTR, NULL,
3146 NULL, numericStringNormalize, octetStringSubstringsMatch,
3147 octetStringSubstringsIndexer, octetStringSubstringsFilter,
3148 "numericStringMatch" },
3150 {"( 2.5.13.11 NAME 'caseIgnoreListMatch' "
3151 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )",
3152 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3153 NULL, NULL, NULL, NULL, NULL, NULL },
3155 {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' "
3156 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3157 SLAP_MR_SUBSTR, NULL,
3158 NULL, NULL, NULL, NULL, NULL,
3159 "caseIgnoreListMatch" },
3161 {"( 2.5.13.13 NAME 'booleanMatch' "
3162 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )",
3163 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3164 NULL, NULL, booleanMatch,
3165 octetStringIndexer, octetStringFilter,
3168 {"( 2.5.13.14 NAME 'integerMatch' "
3169 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
3170 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3171 NULL, NULL, integerMatch,
3172 octetStringIndexer, octetStringFilter,
3175 {"( 2.5.13.15 NAME 'integerOrderingMatch' "
3176 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
3177 SLAP_MR_ORDERING, NULL,
3178 NULL, NULL, integerMatch,
3182 {"( 2.5.13.16 NAME 'bitStringMatch' "
3183 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )",
3184 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3185 NULL, NULL, octetStringMatch,
3186 octetStringIndexer, octetStringFilter,
3189 {"( 2.5.13.17 NAME 'octetStringMatch' "
3190 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
3191 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3192 NULL, NULL, octetStringMatch,
3193 octetStringIndexer, octetStringFilter,
3196 {"( 2.5.13.18 NAME 'octetStringOrderingMatch' "
3197 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
3198 SLAP_MR_ORDERING, NULL,
3199 NULL, NULL, octetStringOrderingMatch,
3201 "octetStringMatch" },
3203 {"( 2.5.13.19 NAME 'octetStringSubstringsMatch' "
3204 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
3205 SLAP_MR_SUBSTR, NULL,
3206 NULL, NULL, octetStringSubstringsMatch,
3207 octetStringSubstringsIndexer, octetStringSubstringsFilter,
3208 "octetStringMatch" },
3210 {"( 2.5.13.20 NAME 'telephoneNumberMatch' "
3211 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )",
3212 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3214 telephoneNumberNormalize, octetStringMatch,
3215 octetStringIndexer, octetStringFilter,
3218 {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' "
3219 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )",
3220 SLAP_MR_SUBSTR, NULL,
3221 NULL, telephoneNumberNormalize, octetStringSubstringsMatch,
3222 octetStringSubstringsIndexer, octetStringSubstringsFilter,
3223 "telephoneNumberMatch" },
3225 {"( 2.5.13.22 NAME 'presentationAddressMatch' "
3226 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )",
3227 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3228 NULL, NULL, NULL, NULL, NULL, NULL },
3230 {"( 2.5.13.23 NAME 'uniqueMemberMatch' "
3231 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )",
3232 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3233 NULL, uniqueMemberNormalize, uniqueMemberMatch,
3237 {"( 2.5.13.24 NAME 'protocolInformationMatch' "
3238 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )",
3239 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3240 NULL, NULL, NULL, NULL, NULL, NULL },
3242 {"( 2.5.13.27 NAME 'generalizedTimeMatch' "
3243 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
3244 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3245 NULL, generalizedTimeNormalize, octetStringMatch,
3249 {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' "
3250 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )",
3251 SLAP_MR_ORDERING, NULL,
3252 NULL, generalizedTimeNormalize, generalizedTimeOrderingMatch,
3254 "generalizedTimeMatch" },
3256 {"( 2.5.13.29 NAME 'integerFirstComponentMatch' "
3257 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
3258 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3259 integerFirstComponentMatchSyntaxes,
3260 NULL, firstComponentNormalize, integerMatch,
3261 octetStringIndexer, octetStringFilter,
3264 {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' "
3265 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )",
3266 SLAP_MR_EQUALITY | SLAP_MR_EXT,
3267 objectIdentifierFirstComponentMatchSyntaxes,
3268 NULL, firstComponentNormalize, octetStringMatch,
3269 octetStringIndexer, octetStringFilter,
3272 {"( 2.5.13.34 NAME 'certificateExactMatch' "
3273 "SYNTAX 1.2.826.0.1.3344810.7.1 )",
3274 SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes,
3276 NULL, certificateExactNormalize, octetStringMatch,
3277 octetStringIndexer, octetStringFilter,
3279 NULL, NULL, NULL, NULL, NULL,
3283 {"( 2.5.13.35 NAME 'certificateMatch' "
3284 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )",
3285 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3287 NULL, NULL, octetStringMatch,
3288 octetStringIndexer, octetStringFilter,
3290 NULL, NULL, NULL, NULL, NULL,
3294 {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' "
3295 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3296 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3297 NULL, IA5StringNormalize, octetStringMatch,
3298 octetStringIndexer, octetStringFilter,
3299 IA5StringApproxMatchOID },
3301 {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' "
3302 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3303 SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL,
3304 NULL, IA5StringNormalize, octetStringMatch,
3305 octetStringIndexer, octetStringFilter,
3306 IA5StringApproxMatchOID },
3308 {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' "
3309 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3310 SLAP_MR_SUBSTR, NULL,
3311 NULL, IA5StringNormalize, octetStringSubstringsMatch,
3312 octetStringSubstringsIndexer, octetStringSubstringsFilter,
3313 "caseIgnoreIA5Match" },
3315 {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' "
3316 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )",
3317 SLAP_MR_SUBSTR, NULL,
3318 NULL, IA5StringNormalize, octetStringSubstringsMatch,
3319 octetStringSubstringsIndexer, octetStringSubstringsFilter,
3320 "caseExactIA5Match" },
3322 #ifdef SLAPD_AUTHPASSWD
3323 /* needs updating */
3324 {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' "
3325 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )",
3326 SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
3327 NULL, NULL, authPasswordMatch,
3332 #ifdef SLAPD_ACI_ENABLED
3333 {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
3334 "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
3335 SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
3336 NULL, NULL, OpenLDAPaciMatch,
3341 {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' "
3342 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
3344 NULL, NULL, integerBitAndMatch,
3348 {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' "
3349 "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )",
3351 NULL, NULL, integerBitOrMatch,
3355 {"( 1.3.6.1.4.1.4203.666.4.6 NAME 'UUIDMatch' "
3356 "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )",
3357 SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
3358 NULL, UUIDNormalize, octetStringMatch,
3359 octetStringIndexer, octetStringFilter,
3362 {"( 1.3.6.1.4.1.4203.666.4.7 NAME 'UUIDOrderingMatch' "
3363 "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )",
3364 SLAP_MR_HIDE | SLAP_MR_ORDERING, NULL,
3365 NULL, UUIDNormalize, octetStringOrderingMatch,
3366 octetStringIndexer, octetStringFilter,
3369 {NULL, SLAP_MR_NONE, NULL,
3370 NULL, NULL, NULL, NULL, NULL,
3375 slap_schema_init( void )
3380 /* we should only be called once (from main) */
3381 assert( schema_init_done == 0 );
3383 for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) {
3384 res = register_syntax( &syntax_defs[i] );
3387 fprintf( stderr, "slap_schema_init: Error registering syntax %s\n",
3388 syntax_defs[i].sd_desc );
3393 for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) {
3394 if( mrule_defs[i].mrd_usage == SLAP_MR_NONE &&
3395 mrule_defs[i].mrd_compat_syntaxes == NULL )
3398 "slap_schema_init: Ignoring unusable matching rule %s\n",
3399 mrule_defs[i].mrd_desc );
3403 res = register_matching_rule( &mrule_defs[i] );
3407 "slap_schema_init: Error registering matching rule %s\n",
3408 mrule_defs[i].mrd_desc );
3413 res = slap_schema_load();
3414 schema_init_done = 1;
3419 schema_destroy( void )