X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fschema_init.c;h=774876d7ffb6c307fdbec11d55e4cf9645331ddb;hb=ae63be3894c799771d0ccabec1e376c7478cd263;hp=8a63407093da4adb4be447839544a6cc8eaf5ff1;hpb=5ab4c575f4ca5d933a175259bb28a57bddc6423f;p=openldap diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 8a63407093..774876d7ff 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -15,15 +15,290 @@ #include "slap.h" #include "ldap_pvt.h" +#include "lutil_md5.h" + +/* recycled validatation routines */ +#define berValidate blobValidate + +/* unimplemented validators */ +#define bitStringValidate NULL +#define booleanValidate NULL + +/* recycled normalization routines */ +#define faxNumberNormalize numericStringNormalize +#define phoneNumberNormalize numericStringNormalize +#define telexNumberNormalize numericStringNormalize +#define integerNormalize numericStringNormalize + +/* unimplemented normalizers */ +#define bitStringNormalize NULL +#define booleanNormalize NULL + +/* unimplemented pretters */ +#define booleanPretty NULL +#define dnPretty NULL +#define integerPretty NULL + +/* recycled matching routines */ +#define caseIgnoreMatch caseIgnoreIA5Match +#define caseIgnoreOrderingMatch caseIgnoreMatch +#define caseIgnoreSubstringsMatch caseIgnoreIA5SubstringsMatch + +#define caseExactMatch caseExactIA5Match +#define caseExactOrderingMatch caseExactMatch +#define caseExactSubstringsMatch caseExactIA5SubstringsMatch + +#define numericStringMatch caseIgnoreMatch +#define objectIdentifierMatch numericStringMatch +#define integerMatch numericStringMatch +#define telephoneNumberMatch numericStringMatch +#define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch +#define generalizedTimeMatch numericStringMatch +#define generalizedTimeOrderingMatch numericStringMatch + +/* unimplemented matching routines */ +#define caseIgnoreListMatch NULL +#define caseIgnoreListSubstringsMatch NULL +#define bitStringMatch NULL +#define presentationAddressMatch NULL +#define uniqueMemberMatch NULL +#define protocolInformationMatch NULL +#define integerFirstComponentMatch NULL + +#define OpenLDAPaciMatch NULL +#define authPasswordMatch NULL + +/* unimplied indexer/filter routines */ +#define caseIgnoreIA5SubstringsIndexer NULL +#define caseIgnoreIA5SubstringsFilter NULL + +/* recycled indexing/filtering routines */ +#define caseIgnoreIndexer caseIgnoreIA5Indexer +#define caseIgnoreFilter caseIgnoreIA5Filter +#define caseExactIndexer caseExactIA5Indexer +#define caseExactFilter caseExactIA5Filter +#define dnIndexer caseIgnoreIndexer +#define dnFilter caseIgnoreFilter + +#define caseIgnoreSubstringsIndexer caseIgnoreIA5SubstringsIndexer +#define caseIgnoreSubstringsFilter caseIgnoreIA5SubstringsFilter +#define caseExactSubstringsIndexer caseExactIA5SubstringsIndexer +#define caseExactSubstringsFilter caseExactIA5SubstringsFilter +#define caseExactIA5SubstringsFilter caseIgnoreIA5SubstringsFilter +#define caseExactIA5SubstringsIndexer caseIgnoreIA5SubstringsIndexer + + +static int +octetStringMatch( + int *matchp, + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + int match = value->bv_len - ((struct berval *) assertedValue)->bv_len; + + if( match == 0 ) { + match = memcmp( value->bv_val, + ((struct berval *) assertedValue)->bv_val, + value->bv_len ); + } + + *matchp = match; + return LDAP_SUCCESS; +} + +/* Index generation function */ +int octetStringIndexer( + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + struct berval **values, + struct berval ***keysp ) +{ + int i; + size_t slen, mlen; + struct berval **keys; + lutil_MD5_CTX MD5context; + unsigned char MD5digest[16]; + struct berval digest; + digest.bv_val = MD5digest; + digest.bv_len = sizeof(MD5digest); + + for( i=0; values[i] != NULL; i++ ) { + /* just count them */ + } + + assert( i > 0 ); + + keys = ch_malloc( sizeof( struct berval * ) * (i+1) ); + + slen = strlen( syntax->ssyn_oid ); + mlen = strlen( mr->smr_oid ); + + for( i=0; values[i] != NULL; i++ ) { + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + values[i]->bv_val, values[i]->bv_len ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[i] = ber_bvdup( &digest ); + } + + keys[i] = NULL; + + *keysp = keys; + + return LDAP_SUCCESS; +} + +/* Index generation function */ +int octetStringFilter( + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + void * assertValue, + struct berval ***keysp ) +{ + size_t slen, mlen; + struct berval **keys; + lutil_MD5_CTX MD5context; + unsigned char MD5digest[LUTIL_MD5_BYTES]; + struct berval *value = (struct berval *) assertValue; + struct berval digest; + digest.bv_val = MD5digest; + digest.bv_len = sizeof(MD5digest); + + slen = strlen( syntax->ssyn_oid ); + mlen = strlen( mr->smr_oid ); + + keys = ch_malloc( sizeof( struct berval * ) * 2 ); + + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + value->bv_val, value->bv_len ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[0] = ber_bvdup( &digest ); + keys[1] = NULL; + + *keysp = keys; + + return LDAP_SUCCESS; +} + +static int +dnValidate( + Syntax *syntax, + struct berval *in ) +{ + int rc; + char *dn; + + if( in->bv_len == 0 ) return LDAP_SUCCESS; + + dn = ch_strdup( in->bv_val ); + + rc = dn_validate( dn ) == NULL + ? LDAP_INVALID_SYNTAX : LDAP_SUCCESS; + + ch_free( dn ); + return rc; +} + +static int +dnNormalize( + Syntax *syntax, + struct berval *val, + struct berval **normalized ) +{ + struct berval *out = ber_bvdup( val ); + + if( out->bv_len != 0 ) { + char *dn; +#ifdef USE_DN_NORMALIZE + dn = dn_normalize( out->bv_val ); +#else + dn = dn_validate( out->bv_val ); +#endif + + if( dn == NULL ) { + ber_bvfree( out ); + return LDAP_INVALID_SYNTAX; + } + + out->bv_val = dn; + out->bv_len = strlen( dn ); + } + + *normalized = out; + return LDAP_SUCCESS; +} + +static int +dnMatch( + int *matchp, + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + int match; + struct berval *asserted = (struct berval *) assertedValue; + + match = value->bv_len - asserted->bv_len; + + if( match == 0 ) { +#ifdef USE_DN_NORMALIZE + match = strcmp( value->bv_val, asserted->bv_val ); +#else + match = strcasecmp( value->bv_val, asserted->bv_val ); +#endif + } + + Debug( LDAP_DEBUG_ARGS, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n", + match, value->bv_val, asserted->bv_val ); + + *matchp = match; + return LDAP_SUCCESS; +} + +static int +inValidate( + Syntax *syntax, + struct berval *in ) +{ + /* any value allowed */ + return LDAP_OTHER; +} -#define berValidate blobValidate static int blobValidate( Syntax *syntax, struct berval *in ) { /* any value allowed */ - return 0; + return LDAP_SUCCESS; } static int @@ -35,28 +310,28 @@ UTF8StringValidate( int len; unsigned char *u = in->bv_val; + if( !in->bv_len ) return LDAP_INVALID_SYNTAX; + for( count = in->bv_len; count > 0; count-=len, u+=len ) { /* get the length indicated by the first byte */ len = LDAP_UTF8_CHARLEN( u ); /* should not be zero */ - if( len == 0 ) return -1; + if( len == 0 ) return LDAP_INVALID_SYNTAX; /* make sure len corresponds with the offset to the next character */ - if( LDAP_UTF8_OFFSET( u ) != len ) return -1; + if( LDAP_UTF8_OFFSET( u ) != len ) return LDAP_INVALID_SYNTAX; } - if( count != 0 ) return -1; + if( count != 0 ) return LDAP_INVALID_SYNTAX; - return 0; + return LDAP_SUCCESS; } static int UTF8StringNormalize( - unsigned use, Syntax *syntax, - MatchingRule *mr, struct berval *val, struct berval **normalized ) { @@ -72,9 +347,9 @@ UTF8StringNormalize( LDAP_UTF8_INCR( p ); } - if( *p ) { + if( *p == '\0' ) { ch_free( newval ); - return 1; + return LDAP_INVALID_SYNTAX; } newval->bv_val = ch_strdup( p ); @@ -104,7 +379,7 @@ UTF8StringNormalize( assert( *newval->bv_val ); assert( newval->bv_val < p ); - assert( p <= q ); + assert( p >= q ); /* cannot start with a space */ assert( !ldap_utf8_isspace(newval->bv_val) ); @@ -126,9 +401,9 @@ UTF8StringNormalize( *q = '\0'; newval->bv_len = q - newval->bv_val; - normalized = &newval; + *normalized = newval; - return 0; + return LDAP_SUCCESS; } static int @@ -140,31 +415,31 @@ oidValidate( if( val->bv_len == 0 ) return 0; - if( isdigit(val->bv_val[0]) ) { + if( OID_LEADCHAR(val->bv_val[0]) ) { int dot = 0; for(i=1; i < val->bv_len; i++) { - if( val->bv_val[i] == '.' ) { + if( OID_SEPARATOR( val->bv_val[i] ) ) { if( dot++ ) return 1; - } else if ( isdigit(val->bv_val[i]) ) { + } else if ( OID_CHAR( val->bv_val[i] ) ) { dot = 0; } else { - return 1; + return LDAP_INVALID_SYNTAX; } } - return !dot ? 0 : 1; + return !dot ? LDAP_SUCCESS : LDAP_INVALID_SYNTAX; - } else if( isalpha(val->bv_val[0]) ) { + } else if( DESC_LEADCHAR(val->bv_val[0]) ) { for(i=1; i < val->bv_len; i++) { - if( !isalpha(val->bv_val[i] ) ) { - return 1; + if( !DESC_CHAR(val->bv_val[i] ) ) { + return LDAP_INVALID_SYNTAX; } } - return 0; + return LDAP_SUCCESS; } - return 1; + return LDAP_INVALID_SYNTAX; } static int @@ -174,11 +449,13 @@ integerValidate( { ber_len_t i; + if( !val->bv_len ) return LDAP_INVALID_SYNTAX; + for(i=0; i < val->bv_len; i++) { - if( !isdigit(val->bv_val[i]) ) return -1; + if( !ASCII_DIGIT(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX; } - return 0; + return LDAP_SUCCESS; } static int @@ -188,11 +465,13 @@ printableStringValidate( { ber_len_t i; + if( !val->bv_len ) return LDAP_INVALID_SYNTAX; + for(i=0; i < val->bv_len; i++) { - if( !isprint(val->bv_val[i]) ) return -1; + if( !isprint(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX; } - return 0; + return LDAP_SUCCESS; } static int @@ -202,11 +481,13 @@ IA5StringValidate( { ber_len_t i; + if( !val->bv_len ) return LDAP_INVALID_SYNTAX; + for(i=0; i < val->bv_len; i++) { - if( !isascii(val->bv_val[i]) ) return -1; + if( !isascii(val->bv_val[i]) ) return LDAP_INVALID_SYNTAX; } - return 0; + return LDAP_SUCCESS; } static int @@ -220,7 +501,7 @@ IA5StringConvert( struct berval *bv = ch_malloc( sizeof(struct berval) ); bv->bv_len = len * sizeof( ldap_unicode_t ); - bv->bv_val = (char *) u = ch_malloc( bv->bv_len + sizeof( ldap_unicode_t ) );; + bv->bv_val = (char *) u = ch_malloc( bv->bv_len + sizeof(ldap_unicode_t) ); for(i=0; i < len; i++ ) { /* @@ -232,14 +513,12 @@ IA5StringConvert( u[i] = 0; *out = bv; - return 0; + return LDAP_SUCCESS; } static int IA5StringNormalize( - unsigned use, Syntax *syntax, - MatchingRule *mr, struct berval *val, struct berval **normalized ) { @@ -251,25 +530,25 @@ IA5StringNormalize( p = val->bv_val; /* Ignore initial whitespace */ - while ( isspace( *p++ ) ) { - /* EMPTY */ ; + while ( ASCII_SPACE( *p ) ) { + p++; } - if( *p ) { + if( *p != '\0' ) { ch_free( newval ); - return 1; + return LDAP_INVALID_SYNTAX; } newval->bv_val = ch_strdup( p ); p = q = newval->bv_val; while ( *p ) { - if ( isspace( *p ) ) { + if ( ASCII_SPACE( *p ) ) { *q++ = *p++; /* Ignore the extra whitespace */ - while ( isspace( *p++ ) ) { - /* EMPTY */ ; + while ( ASCII_SPACE( *p ) ) { + p++; } } else { *q++ = *p++; @@ -281,7 +560,7 @@ IA5StringNormalize( assert( p <= q ); /* cannot start with a space */ - assert( !isspace(*newval->bv_val) ); + assert( !ASCII_SPACE(*newval->bv_val) ); /* * If the string ended in space, backup the pointer one @@ -289,54 +568,924 @@ IA5StringNormalize( * all whitespace to a single space. */ - if ( isspace( q[-1] ) ) { + if ( ASCII_SPACE( q[-1] ) ) { --q; } /* cannot end with a space */ - assert( !isspace( q[-1] ) ); + assert( !ASCII_SPACE( q[-1] ) ); /* null terminate */ *q = '\0'; newval->bv_len = q - newval->bv_val; - normalized = &newval; + *normalized = newval; - return 0; + return LDAP_SUCCESS; } static int caseExactIA5Match( + int *matchp, + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + int match = value->bv_len - ((struct berval *) assertedValue)->bv_len; + + if( match == 0 ) { + match = strncmp( value->bv_val, + ((struct berval *) assertedValue)->bv_val, + value->bv_len ); + } + + *matchp = match; + return LDAP_SUCCESS; +} + +static int +caseExactIA5SubstringsMatch( + int *matchp, unsigned use, Syntax *syntax, MatchingRule *mr, struct berval *value, void *assertedValue ) { - return strcmp( value->bv_val, - ((struct berval *) assertedValue)->bv_val ); + int match = 0; + SubstringsAssertion *sub = assertedValue; + struct berval left = *value; + int i; + ber_len_t inlen=0; + + /* Add up asserted input length */ + if( sub->sa_initial ) { + inlen += sub->sa_initial->bv_len; + } + if( sub->sa_any ) { + for(i=0; sub->sa_any[i] != NULL; i++) { + inlen += sub->sa_any[i]->bv_len; + } + } + if( sub->sa_final ) { + inlen += sub->sa_final->bv_len; + } + + if( sub->sa_initial ) { + if( inlen > left.bv_len ) { + match = 1; + goto done; + } + + match = strncmp( sub->sa_initial->bv_val, left.bv_val, + sub->sa_initial->bv_len ); + + if( match != 0 ) { + goto done; + } + + left.bv_val += sub->sa_initial->bv_len; + left.bv_len -= sub->sa_initial->bv_len; + inlen -= sub->sa_initial->bv_len; + } + + if( sub->sa_final ) { + if( inlen > left.bv_len ) { + match = 1; + goto done; + } + + match = strncmp( sub->sa_final->bv_val, + &left.bv_val[left.bv_len - sub->sa_final->bv_len], + sub->sa_final->bv_len ); + + if( match != 0 ) { + goto done; + } + + left.bv_len -= sub->sa_final->bv_len; + inlen -= sub->sa_final->bv_len; + } + + if( sub->sa_any ) { + for(i=0; sub->sa_any[i]; i++) { + ber_len_t idx; + char *p; + +retry: + if( inlen > left.bv_len ) { + /* not enough length */ + match = 1; + goto done; + } + + if( sub->sa_any[i]->bv_len == 0 ) { + continue; + } + + p = strchr( left.bv_val, *sub->sa_any[i]->bv_val ); + + if( p == NULL ) { + match = 1; + goto done; + } + + idx = p - left.bv_val; + assert( idx < left.bv_len ); + + if( idx >= left.bv_len ) { + /* this shouldn't happen */ + return LDAP_OTHER; + } + + left.bv_val = p; + left.bv_len -= idx; + + if( sub->sa_any[i]->bv_len > left.bv_len ) { + /* not enough left */ + match = 1; + goto done; + } + + match = strncmp( left.bv_val, + sub->sa_any[i]->bv_val, + sub->sa_any[i]->bv_len ); + + if( match != 0 ) { + left.bv_val++; + left.bv_len--; + goto retry; + } + + left.bv_val += sub->sa_any[i]->bv_len; + left.bv_len -= sub->sa_any[i]->bv_len; + inlen -= sub->sa_any[i]->bv_len; + } + } + +done: + *matchp = match; + return LDAP_SUCCESS; +} + +/* Index generation function */ +int caseExactIA5Indexer( + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + struct berval **values, + struct berval ***keysp ) +{ + int i; + size_t slen, mlen; + struct berval **keys; + lutil_MD5_CTX MD5context; + unsigned char MD5digest[16]; + struct berval digest; + digest.bv_val = MD5digest; + digest.bv_len = sizeof(MD5digest); + + for( i=0; values[i] != NULL; i++ ) { + /* just count them */ + } + + assert( i > 0 ); + + keys = ch_malloc( sizeof( struct berval * ) * (i+1) ); + + slen = strlen( syntax->ssyn_oid ); + mlen = strlen( mr->smr_oid ); + + for( i=0; values[i] != NULL; i++ ) { + struct berval *value = values[i]; + + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + value->bv_val, value->bv_len ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[i] = ber_bvdup( &digest ); + } + + keys[i] = NULL; + *keysp = keys; + return LDAP_SUCCESS; +} + +/* Index generation function */ +int caseExactIA5Filter( + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + void * assertValue, + struct berval ***keysp ) +{ + size_t slen, mlen; + struct berval **keys; + lutil_MD5_CTX MD5context; + unsigned char MD5digest[LUTIL_MD5_BYTES]; + struct berval *value; + struct berval digest; + digest.bv_val = MD5digest; + digest.bv_len = sizeof(MD5digest); + + slen = strlen( syntax->ssyn_oid ); + mlen = strlen( mr->smr_oid ); + + value = (struct berval *) assertValue; + + keys = ch_malloc( sizeof( struct berval * ) * 2 ); + + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + value->bv_val, value->bv_len ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[0] = ber_bvdup( &digest ); + keys[1] = NULL; + + *keysp = keys; + return LDAP_SUCCESS; } static int caseIgnoreIA5Match( + int *matchp, unsigned use, Syntax *syntax, MatchingRule *mr, struct berval *value, void *assertedValue ) { - return strcasecmp( value->bv_val, - ((struct berval *) assertedValue)->bv_val ); + int match = value->bv_len - ((struct berval *) assertedValue)->bv_len; + + if( match == 0 ) { + match = strncasecmp( value->bv_val, + ((struct berval *) assertedValue)->bv_val, + value->bv_len ); + } + + *matchp = match; + return LDAP_SUCCESS; +} + +static char *strcasechr( const char *str, int c ) +{ + char *lower = strchr( str, TOLOWER(c) ); + char *upper = strchr( str, TOUPPER(c) ); + + if( lower && upper ) { + return lower < upper ? lower : upper; + } else if ( lower ) { + return lower; + } else { + return upper; + } +} + +static int +caseIgnoreIA5SubstringsMatch( + int *matchp, + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + int match = 0; + SubstringsAssertion *sub = assertedValue; + struct berval left = *value; + int i; + ber_len_t inlen=0; + + /* Add up asserted input length */ + if( sub->sa_initial ) { + inlen += sub->sa_initial->bv_len; + } + if( sub->sa_any ) { + for(i=0; sub->sa_any[i] != NULL; i++) { + inlen += sub->sa_any[i]->bv_len; + } + } + if( sub->sa_final ) { + inlen += sub->sa_final->bv_len; + } + + if( sub->sa_initial ) { + if( inlen > left.bv_len ) { + match = 1; + goto done; + } + + match = strncasecmp( sub->sa_initial->bv_val, left.bv_val, + sub->sa_initial->bv_len ); + + if( match != 0 ) { + goto done; + } + + left.bv_val += sub->sa_initial->bv_len; + left.bv_len -= sub->sa_initial->bv_len; + inlen -= sub->sa_initial->bv_len; + } + + if( sub->sa_final ) { + if( inlen > left.bv_len ) { + match = 1; + goto done; + } + + match = strncasecmp( sub->sa_final->bv_val, + &left.bv_val[left.bv_len - sub->sa_final->bv_len], + sub->sa_final->bv_len ); + + if( match != 0 ) { + goto done; + } + + left.bv_len -= sub->sa_final->bv_len; + inlen -= sub->sa_final->bv_len; + } + + if( sub->sa_any ) { + for(i=0; sub->sa_any[i]; i++) { + ber_len_t idx; + char *p; + +retry: + if( inlen > left.bv_len ) { + /* not enough length */ + match = 1; + goto done; + } + + if( sub->sa_any[i]->bv_len == 0 ) { + continue; + } + + p = strcasechr( left.bv_val, *sub->sa_any[i]->bv_val ); + + if( p == NULL ) { + match = 1; + goto done; + } + + idx = p - left.bv_val; + assert( idx < left.bv_len ); + + if( idx >= left.bv_len ) { + /* this shouldn't happen */ + return LDAP_OTHER; + } + + left.bv_val = p; + left.bv_len -= idx; + + if( sub->sa_any[i]->bv_len > left.bv_len ) { + /* not enough left */ + match = 1; + goto done; + } + + match = strncasecmp( left.bv_val, + sub->sa_any[i]->bv_val, + sub->sa_any[i]->bv_len ); + + if( match != 0 ) { + left.bv_val++; + left.bv_len--; + + goto retry; + } + + left.bv_val += sub->sa_any[i]->bv_len; + left.bv_len -= sub->sa_any[i]->bv_len; + inlen -= sub->sa_any[i]->bv_len; + } + } + +done: + *matchp = match; + return LDAP_SUCCESS; +} + +/* Index generation function */ +int caseIgnoreIA5Indexer( + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + struct berval **values, + struct berval ***keysp ) +{ + int i; + size_t slen, mlen; + struct berval **keys; + lutil_MD5_CTX MD5context; + unsigned char MD5digest[16]; + struct berval digest; + digest.bv_val = MD5digest; + digest.bv_len = sizeof(MD5digest); + + for( i=0; values[i] != NULL; i++ ) { + /* just count them */ + } + + assert( i > 0 ); + + keys = ch_malloc( sizeof( struct berval * ) * (i+1) ); + + slen = strlen( syntax->ssyn_oid ); + mlen = strlen( mr->smr_oid ); + + for( i=0; values[i] != NULL; i++ ) { + struct berval *value = ber_bvdup( values[i] ); + ldap_pvt_str2upper( value->bv_val ); + + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + value->bv_val, value->bv_len ); + lutil_MD5Final( MD5digest, &MD5context ); + + ber_bvfree( value ); + + keys[i] = ber_bvdup( &digest ); + } + + keys[i] = NULL; + *keysp = keys; + return LDAP_SUCCESS; +} + +/* Index generation function */ +int caseIgnoreIA5Filter( + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + void * assertValue, + struct berval ***keysp ) +{ + size_t slen, mlen; + struct berval **keys; + lutil_MD5_CTX MD5context; + unsigned char MD5digest[LUTIL_MD5_BYTES]; + struct berval *value; + struct berval digest; + digest.bv_val = MD5digest; + digest.bv_len = sizeof(MD5digest); + + slen = strlen( syntax->ssyn_oid ); + mlen = strlen( mr->smr_oid ); + + value = ber_bvdup( (struct berval *) assertValue ); + ldap_pvt_str2upper( value->bv_val ); + + keys = ch_malloc( sizeof( struct berval * ) * 2 ); + + lutil_MD5Init( &MD5context ); + if( prefix != NULL && prefix->bv_len > 0 ) { + lutil_MD5Update( &MD5context, + prefix->bv_val, prefix->bv_len ); + } + lutil_MD5Update( &MD5context, + syntax->ssyn_oid, slen ); + lutil_MD5Update( &MD5context, + mr->smr_oid, mlen ); + lutil_MD5Update( &MD5context, + value->bv_val, value->bv_len ); + lutil_MD5Final( MD5digest, &MD5context ); + + keys[0] = ber_bvdup( &digest ); + keys[1] = NULL; + + ber_bvfree( value ); + + *keysp = keys; + return LDAP_SUCCESS; +} + +static int +numericStringNormalize( + Syntax *syntax, + struct berval *val, + struct berval **normalized ) +{ + /* similiar to IA5StringNormalize except removes all spaces */ + struct berval *newval; + char *p, *q; + + newval = ch_malloc( sizeof( struct berval ) ); + + p = val->bv_val; + + /* Ignore initial whitespace */ + while ( ASCII_SPACE( *p ) ) { + p++; + } + + if( *p != '\0' ) { + ch_free( newval ); + return LDAP_INVALID_SYNTAX; + } + + newval->bv_val = ch_strdup( p ); + p = q = newval->bv_val; + + while ( *p ) { + if ( ASCII_SPACE( *p ) ) { + /* Ignore whitespace */ + p++; + } else { + *q++ = *p++; + } + } + + assert( *newval->bv_val ); + assert( newval->bv_val < p ); + assert( p <= q ); + + /* cannot start with a space */ + assert( !ASCII_SPACE(*newval->bv_val) ); + + /* cannot end with a space */ + assert( !ASCII_SPACE( q[-1] ) ); + + /* null terminate */ + *q = '\0'; + + newval->bv_len = q - newval->bv_val; + *normalized = newval; + + return LDAP_SUCCESS; +} + +static int +objectIdentifierFirstComponentMatch( + int *matchp, + unsigned use, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + int rc = LDAP_SUCCESS; + int match; + struct berval *asserted = (struct berval *) assertedValue; + ber_len_t i; + struct berval oid; + + if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) { + return LDAP_INVALID_SYNTAX; + } + + /* trim leading white space */ + for( i=1; ASCII_SPACE(value->bv_val[i]) && i < value->bv_len; i++ ) { + /* empty */ + } + + /* grab next word */ + oid.bv_val = &value->bv_val[i]; + oid.bv_len = value->bv_len - i; + for( i=1; ASCII_SPACE(value->bv_val[i]) && i < oid.bv_len; i++ ) { + /* empty */ + } + oid.bv_len = i; + + /* insert attributeTypes, objectclass check here */ + if( OID_LEADCHAR(asserted->bv_val[0]) ) { + rc = objectIdentifierMatch( &match, use, syntax, mr, &oid, asserted ); + + } else { + char *stored = ch_malloc( oid.bv_len + 1 ); + memcpy( stored, oid.bv_val, oid.bv_len ); + stored[oid.bv_len] = '\0'; + + if ( !strcmp( syntax->ssyn_oid, SLAP_SYNTAX_MATCHINGRULES_OID ) ) { + MatchingRule *asserted_mr = mr_find( asserted->bv_val ); + MatchingRule *stored_mr = mr_find( stored ); + + if( asserted_mr == NULL ) { + rc = SLAPD_COMPARE_UNDEFINED; + } else { + match = asserted_mr != stored_mr; + } + + } else if ( !strcmp( syntax->ssyn_oid, + SLAP_SYNTAX_ATTRIBUTETYPES_OID ) ) + { + AttributeType *asserted_at = at_find( asserted->bv_val ); + AttributeType *stored_at = at_find( stored ); + + if( asserted_at == NULL ) { + rc = SLAPD_COMPARE_UNDEFINED; + } else { + match = asserted_at != stored_at; + } + + } else if ( !strcmp( syntax->ssyn_oid, + SLAP_SYNTAX_OBJECTCLASSES_OID ) ) + { + ObjectClass *asserted_oc = oc_find( asserted->bv_val ); + ObjectClass *stored_oc = oc_find( stored ); + + if( asserted_oc == NULL ) { + rc = SLAPD_COMPARE_UNDEFINED; + } else { + match = asserted_oc != stored_oc; + } + } + + ch_free( stored ); + } + + Debug( LDAP_DEBUG_ARGS, "objectIdentifierFirstComponentMatch " + "%d\n\t\"%s\"\n\t\"%s\"\n", + match, value->bv_val, asserted->bv_val ); + + if( rc == LDAP_SUCCESS ) *matchp = match; + return rc; +} + +static int +check_time_syntax (struct berval *val, + int start, + int *parts) +{ + static int ceiling[9] = { 99, 99, 11, 30, 23, 59, 59, 12, 59 }; + static int mdays[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + char *p, *e; + int part, c, neg = 0; + + if( val->bv_len == 0 ) + return LDAP_INVALID_SYNTAX; + + p = (char *)val->bv_val; + e = p + val->bv_len; + + /* Ignore initial whitespace */ + while ( ( p < e ) && ASCII_SPACE( *p ) ) { + p++; + } + + if (e - p < 13 - (2 * start)) + return LDAP_INVALID_SYNTAX; + + for (part = 0; part < 9; part++) + parts[part] = 0; + + for (part = start; part < 7; part++) { + c = *p; + if ((part == 6) + && (c == 'Z' + || c == '+' + || c == '-')) + { + part++; + break; + } + p++; + c -= '0'; + if (p == e) + return LDAP_INVALID_SYNTAX; + if (c < 0 || c > 9) + return LDAP_INVALID_SYNTAX; + parts[part] = c; + + c = *p++ - '0'; + if (p == e) + return LDAP_INVALID_SYNTAX; + if (c < 0 || c > 9) + return LDAP_INVALID_SYNTAX; + parts[part] *= 10; + parts[part] += c; + + if (part == 2 || part == 3) + parts[part]--; + if (parts[part] < 0) + return LDAP_INVALID_SYNTAX; + if (parts[part] > ceiling[part]) + return LDAP_INVALID_SYNTAX; + } + if (parts[2] == 1) { + if (parts[3] > mdays[parts[2]]) + return LDAP_INVALID_SYNTAX; + if (parts[1] & 0x03) { + /* FIXME: This is an incomplete leap-year + * check that fails in 2100, 2200, 2300, + * 2500, 2600, 2700, ... + */ + if (parts[3] > mdays[parts[2]] - 1) + return LDAP_INVALID_SYNTAX; + } + } + c = *p++; + if (c == 'Z') { + /* all done */ + } else if (c != '+' && c != '-') { + return LDAP_INVALID_SYNTAX; + } else { + if (c == '-') + neg = 1; + if (p > e - 4) + return LDAP_INVALID_SYNTAX; + for (part = 7; part < 9; part++) { + c = *p++ - '0'; + if (c < 0 || c > 9) + return LDAP_INVALID_SYNTAX; + parts[part] = c; + + c = *p++ - '0'; + if (c < 0 || c > 9) + return LDAP_INVALID_SYNTAX; + parts[part] *= 10; + parts[part] += c; + if (parts[part] < 0 || parts[part] > ceiling[part]) + return LDAP_INVALID_SYNTAX; + } + } + + /* Ignore trailing whitespace */ + while ( ( p < e ) && ASCII_SPACE( *p ) ) { + p++; + } + if (p != e) + return LDAP_INVALID_SYNTAX; + + if (neg == 0) { + parts[4] += parts[7]; + parts[5] += parts[8]; + for (part = 7; --part > 0; ) { + if (part != 3) + c = ceiling[part]; + else { + /* FIXME: This is an incomplete leap-year + * check that fails in 2100, 2200, 2300, + * 2500, 2600, 2700, ... + */ + c = mdays[parts[2]]; + if (parts[2] == 1) + c--; + } + if (parts[part] > c) { + parts[part] -= c + 1; + parts[part - 1]++; + } + } + } else { + parts[4] -= parts[7]; + parts[5] -= parts[8]; + for (part = 7; --part > 0; ) { + if (part != 3) + c = ceiling[part]; + else { + /* FIXME: This is an incomplete leap-year + * check that fails in 2100, 2200, 2300, + * 2500, 2600, 2700, ... + */ + c = mdays[(parts[2] - 1) % 12]; + if (parts[2] == 2) + c--; + } + if (parts[part] < 0) { + parts[part] += c + 1; + parts[part - 1]--; + } + } + } + + return LDAP_SUCCESS; +} + +static int +utcTimeNormalize( + Syntax *syntax, + struct berval *val, + struct berval **normalized ) +{ + struct berval *out; + int parts[9], rc; + + rc = check_time_syntax(val, 1, parts); + if (rc != LDAP_SUCCESS) { + return rc; + } + + *normalized = NULL; + out = ch_malloc( sizeof(struct berval) ); + if( out == NULL ) + return LBER_ERROR_MEMORY; + + out->bv_val = ch_malloc( 14 ); + if ( out->bv_val == NULL ) { + ch_free( out ); + return LBER_ERROR_MEMORY; + } + + sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ldZ", + parts[1], parts[2] + 1, parts[3] + 1, + parts[4], parts[5], parts[6] ); + out->bv_len = 13; + *normalized = out; + + return LDAP_SUCCESS; +} + +static int +utcTimeValidate( + Syntax *syntax, + struct berval *in ) +{ + int parts[9]; + + return check_time_syntax(in, 1, parts); +} + +static int +generalizedTimeNormalize( + Syntax *syntax, + struct berval *val, + struct berval **normalized ) +{ + struct berval *out; + int parts[9], rc; + + rc = check_time_syntax(val, 0, parts); + if (rc != LDAP_SUCCESS) { + return rc; + } + + *normalized = NULL; + out = ch_malloc( sizeof(struct berval) ); + if( out == NULL ) + return LBER_ERROR_MEMORY; + + out->bv_val = ch_malloc( 16 ); + if ( out->bv_val == NULL ) { + ch_free( out ); + return LBER_ERROR_MEMORY; + } + + sprintf( out->bv_val, "%02ld%02ld%02ld%02ld%02ld%02ld%02ldZ", + parts[0], parts[1], parts[2] + 1, parts[3] + 1, + parts[4], parts[5], parts[6] ); + out->bv_len = 15; + *normalized = out; + + return LDAP_SUCCESS; +} + +static int +generalizedTimeValidate( + Syntax *syntax, + struct berval *in ) +{ + int parts[9]; + + return check_time_syntax(in, 0, parts); } struct syntax_defs_rec { char *sd_desc; int sd_flags; slap_syntax_validate_func *sd_validate; + slap_syntax_transform_func *sd_normalize; + slap_syntax_transform_func *sd_pretty; +#ifdef SLAPD_BINARY_CONVERSION slap_syntax_transform_func *sd_ber2str; slap_syntax_transform_func *sd_str2ber; +#endif }; +#define X_HIDE "X-HIDE 'TRUE' " #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' " #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' " @@ -352,9 +1501,9 @@ struct syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.4.1.1466.115.121.1.5 DESC 'Binary' " X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BER, berValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.6 DESC 'Bit String' )", - 0, NULL, NULL, NULL}, + 0, bitStringValidate, bitStringNormalize, NULL }, {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )", - 0, NULL, NULL, NULL}, + 0, booleanValidate, booleanNormalize, booleanPretty}, {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' " X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL}, @@ -366,14 +1515,14 @@ struct syntax_defs_rec syntax_defs[] = { SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )", 0, NULL, NULL, NULL}, - {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'DN' )", - 0, blobValidate, NULL, NULL}, + {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )", + 0, dnValidate, dnNormalize, dnPretty}, {"( 1.3.6.1.4.1.1466.115.121.1.13 DESC 'Data Quality' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.14 DESC 'Delivery Method' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.15 DESC 'Directory String' )", - 0, UTF8StringValidate, NULL, NULL}, + 0, UTF8StringValidate, UTF8StringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.16 DESC 'DIT Content Rule Description' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.17 DESC 'DIT Structure Rule Description' )", @@ -385,17 +1534,17 @@ struct syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.4.1.1466.115.121.1.21 DESC 'Enhanced Guide' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.22 DESC 'Facsimile Telephone Number' )", - 0, blobValidate, NULL, NULL}, + 0, IA5StringValidate, faxNumberNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.23 DESC 'Fax' " X_NOT_H_R ")", SLAP_SYNTAX_BLOB, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.24 DESC 'Generalized Time' )", - 0, NULL, NULL, NULL}, + 0, generalizedTimeValidate, generalizedTimeNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.25 DESC 'Guide' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )", - 0, IA5StringValidate, NULL, NULL}, + 0, IA5StringValidate, IA5StringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.27 DESC 'Integer' )", - 0, integerValidate, NULL, NULL}, + 0, integerValidate, integerNormalize, integerPretty}, {"( 1.3.6.1.4.1.1466.115.121.1.28 DESC 'JPEG' " X_NOT_H_R ")", SLAP_SYNTAX_BLOB, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.29 DESC 'Master And Shadow Access Points' )", @@ -413,7 +1562,7 @@ struct syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.4.1.1466.115.121.1.35 DESC 'Name Form Description' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.36 DESC 'Numeric String' )", - 0, NULL, NULL, NULL}, + 0, IA5StringValidate, numericStringNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.37 DESC 'Object Class Description' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.38 DESC 'OID' )", @@ -434,13 +1583,13 @@ struct syntax_defs_rec syntax_defs[] = { X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.50 DESC 'Telephone Number' )", - 0, blobValidate, NULL, NULL}, + 0, IA5StringValidate, phoneNumberNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.51 DESC 'Teletex Terminal Identifier' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.52 DESC 'Telex Number' )", - 0, NULL, NULL, NULL}, + 0, IA5StringValidate, telexNumberNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.53 DESC 'UTC Time' )", - 0, NULL, NULL, NULL}, + 0, utcTimeValidate, utcTimeNormalize, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.54 DESC 'LDAP Syntax Description' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.55 DESC 'Modify Rights' )", @@ -453,8 +1602,16 @@ struct syntax_defs_rec syntax_defs[] = { 0, NULL, NULL, NULL}, /* OpenLDAP Experimental Syntaxes */ - {"( " SLAPD_OID_ACI_SYNTAX " DESC 'OpenLDAP Experimental ACI' )", + {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )", + 0, IA5StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */, NULL, NULL}, + {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )", 0, NULL, NULL, NULL}, + {"( 1.3.6.1.4.1.4203.666.2.3 DESC 'OpenLDAP void' " X_HIDE ")" , + SLAP_SYNTAX_HIDE, inValidate, NULL, NULL}, +#if 0 /* not needed */ + {"( 1.3.6.1.4.1.4203.666.2.4 DESC 'OpenLDAP DN' " X_HIDE ")" , + SLAP_SYNTAX_HIDE, inValidate, NULL, NULL}, +#endif {NULL, 0, NULL, NULL, NULL} }; @@ -495,86 +1652,61 @@ struct mrule_defs_rec { * 2.5.13.44 attributeIntegrityMatch */ -/* recycled matching functions */ -#define caseIgnoreMatch caseIgnoreIA5Match -#define caseExactMatch caseExactIA5Match - -/* unimplemented matching functions */ -#define objectIdentifierMatch NULL -#define distinguishedNameMatch NULL -#define caseIgnoreOrderingMatch NULL -#define caseIgnoreSubstringsMatch NULL -#define caseExactOrderingMatch NULL -#define caseExactSubstringsMatch NULL -#define numericStringMatch NULL -#define numericStringSubstringsMatch NULL -#define caseIgnoreListMatch NULL -#define caseIgnoreListSubstringsMatch NULL -#define integerMatch NULL -#define bitStringMatch NULL -#define octetStringMatch NULL -#define telephoneNumberMatch NULL -#define telephoneNumberSubstringsMatch NULL -#define presentationAddressMatch NULL -#define uniqueMemberMatch NULL -#define protocolInformationMatch NULL -#define generalizedTimeMatch NULL -#define generalizedTimeOrderingMatch NULL -#define integerFirstComponentMatch NULL -#define objectIdentifierFirstComponentMatch NULL -#define caseIgnoreIA5SubstringsMatch NULL - struct mrule_defs_rec mrule_defs[] = { {"( 2.5.13.0 NAME 'objectIdentifierMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, objectIdentifierMatch, NULL, NULL}, + NULL, NULL, objectIdentifierMatch, + caseIgnoreIA5Indexer, caseIgnoreIA5Filter}, {"( 2.5.13.1 NAME 'distinguishedNameMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, distinguishedNameMatch, NULL, NULL}, + NULL, NULL, dnMatch, dnIndexer, dnFilter}, {"( 2.5.13.2 NAME 'caseIgnoreMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, UTF8StringNormalize, caseIgnoreMatch, NULL, NULL}, + NULL, NULL, caseIgnoreMatch, caseIgnoreIndexer, caseIgnoreFilter}, {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", SLAP_MR_ORDERING, - NULL, UTF8StringNormalize, caseIgnoreOrderingMatch, NULL, NULL}, + NULL, NULL, caseIgnoreOrderingMatch, NULL, NULL}, {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", SLAP_MR_SUBSTR | SLAP_MR_EXT, - NULL, UTF8StringNormalize, caseIgnoreSubstringsMatch, NULL, NULL}, + NULL, NULL, caseIgnoreSubstringsMatch, + caseIgnoreSubstringsIndexer, caseIgnoreSubstringsFilter}, /* Next three are not in the RFC's, but are needed for compatibility */ {"( 2.5.13.5 NAME 'caseExactMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, UTF8StringNormalize, caseExactMatch, NULL, NULL}, + NULL, NULL, caseExactMatch, caseExactIndexer, caseExactFilter}, {"( 2.5.13.6 NAME 'caseExactOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", SLAP_MR_ORDERING, - NULL, UTF8StringNormalize, caseExactOrderingMatch, NULL, NULL}, + NULL, NULL, caseExactOrderingMatch, NULL, NULL}, {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", SLAP_MR_SUBSTR | SLAP_MR_EXT, - NULL, UTF8StringNormalize, caseExactSubstringsMatch, NULL, NULL}, + NULL, NULL, caseExactSubstringsMatch, + caseExactSubstringsIndexer, caseExactSubstringsFilter}, {"( 2.5.13.8 NAME 'numericStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, numericStringMatch, NULL, NULL}, + NULL, NULL, caseIgnoreIA5Match, NULL, NULL}, {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", SLAP_MR_SUBSTR | SLAP_MR_EXT, - NULL, NULL, numericStringSubstringsMatch, NULL, NULL}, + NULL, NULL, caseIgnoreIA5SubstringsMatch, + caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter}, {"( 2.5.13.11 NAME 'caseIgnoreListMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", @@ -599,7 +1731,7 @@ struct mrule_defs_rec mrule_defs[] = { {"( 2.5.13.17 NAME 'octetStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, NULL, octetStringMatch, NULL, NULL}, + NULL, NULL, octetStringMatch, octetStringIndexer, octetStringFilter}, {"( 2.5.13.20 NAME 'telephoneNumberMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", @@ -649,23 +1781,32 @@ struct mrule_defs_rec mrule_defs[] = { {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, IA5StringNormalize, caseExactIA5Match, NULL, NULL}, + NULL, NULL, caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter}, {"( 1.3.6.1.4.1.1466.109.114.2 NAME 'caseIgnoreIA5Match' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, - NULL, IA5StringNormalize, caseIgnoreIA5Match, NULL, NULL}, + NULL, NULL, caseIgnoreIA5Match, caseExactIA5Indexer, caseExactIA5Filter}, {"( 1.3.6.1.4.1.1466.109.114.3 NAME 'caseIgnoreIA5SubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", SLAP_MR_SUBSTR, - NULL, IA5StringNormalize, caseIgnoreIA5SubstringsMatch, NULL, NULL}, + NULL, NULL, caseIgnoreIA5SubstringsMatch, + caseIgnoreIA5SubstringsIndexer, caseIgnoreIA5SubstringsFilter}, + + {"( 1.3.6.1.4.1.4203.666.4.1 NAME 'authPasswordMatch' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", + SLAP_MR_EQUALITY, + NULL, NULL, authPasswordMatch, NULL, NULL}, + + {"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' " + "SYNTAX 1.3.6.1.4.1.4203.666.2.1 )", + SLAP_MR_EQUALITY, + NULL, NULL, OpenLDAPaciMatch, NULL, NULL}, {NULL, SLAP_MR_NONE, NULL, NULL, NULL} }; -static int schema_init_done = 0; - int schema_init( void ) { @@ -679,13 +1820,19 @@ schema_init( void ) res = register_syntax( syntax_defs[i].sd_desc, syntax_defs[i].sd_flags, syntax_defs[i].sd_validate, + syntax_defs[i].sd_normalize, + syntax_defs[i].sd_pretty +#ifdef SLAPD_BINARY_CONVERSION + , syntax_defs[i].sd_ber2str, - syntax_defs[i].sd_str2ber ); + syntax_defs[i].sd_str2ber +#endif + ); if ( res ) { fprintf( stderr, "schema_init: Error registering syntax %s\n", syntax_defs[i].sd_desc ); - return -1; + return LDAP_OTHER; } } @@ -710,135 +1857,9 @@ schema_init( void ) fprintf( stderr, "schema_init: Error registering matching rule %s\n", mrule_defs[i].mrd_desc ); - return -1; + return LDAP_OTHER; } } schema_init_done = 1; - return( 0 ); -} - -#ifdef SLAPD_SCHEMA_NOT_COMPAT -struct slap_internal_schema slap_schema; - -struct slap_schema_oc_map { - char *ssom_name; - size_t ssom_offset; -} oc_map[] = { - { "alias", offsetof(struct slap_internal_schema, si_oc_alias) }, - { "referral", offsetof(struct slap_internal_schema, si_oc_referral) }, - { NULL, 0 } -}; - -struct slap_schema_ad_map { - char *ssam_name; - size_t ssam_offset; -} ad_map[] = { - { "objectClass", - offsetof(struct slap_internal_schema, si_ad_objectClass) }, - - { "creatorsName", - offsetof(struct slap_internal_schema, si_ad_creatorsName) }, - { "createTimestamp", - offsetof(struct slap_internal_schema, si_ad_createTimestamp) }, - { "modifiersName", - offsetof(struct slap_internal_schema, si_ad_modifiersName) }, - { "modifyTimestamp", - offsetof(struct slap_internal_schema, si_ad_modifyTimestamp) }, - - { "subschemaSubentry", - offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) }, - - { "namingContexts", - offsetof(struct slap_internal_schema, si_ad_namingContexts) }, - { "supportedControl", - offsetof(struct slap_internal_schema, si_ad_supportedControl) }, - { "supportedExtension", - offsetof(struct slap_internal_schema, si_ad_supportedExtension) }, - { "supportedLDAPVersion", - offsetof(struct slap_internal_schema, si_ad_supportedLDAPVersion) }, -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND - { "supportedACIMechanisms", - offsetof(struct slap_internal_schema, si_ad_supportedACIMechanisms) }, - -#endif - { "supportedSASLMechanisms", - offsetof(struct slap_internal_schema, si_ad_supportedSASLMechanisms) }, - - { "attributeTypes", - offsetof(struct slap_internal_schema, si_ad_attributeTypes) }, - { "ldapSyntaxes", - offsetof(struct slap_internal_schema, si_ad_ldapSyntaxes) }, - { "matchingRules", - offsetof(struct slap_internal_schema, si_ad_matchingRules) }, - { "objectClasses", - offsetof(struct slap_internal_schema, si_ad_objectClasses) }, - - { "ref", - offsetof(struct slap_internal_schema, si_ad_ref) }, - - { "entry", - offsetof(struct slap_internal_schema, si_ad_entry) }, - { "children", - offsetof(struct slap_internal_schema, si_ad_children) }, - - { "userPassword", - offsetof(struct slap_internal_schema, si_ad_userPassword) }, - { "authPassword", - offsetof(struct slap_internal_schema, si_ad_authPassword) }, -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND - { "krbName", - offsetof(struct slap_internal_schema, si_ad_krbName) }, -#endif - - { NULL, 0 } -}; - -#endif - -int -schema_prep( void ) -{ -#ifdef SLAPD_SCHEMA_NOT_COMPAT - int i; -#endif - /* we should only be called once after schema_init() was called */ - assert( schema_init_done == 1 ); - -#ifdef SLAPD_SCHEMA_NOT_COMPAT - for( i=0; oc_map[i].ssom_name; i++ ) { - ObjectClass ** ocp = (ObjectClass **) - &(((char *) &slap_schema)[oc_map[i].ssom_offset]); - - *ocp = oc_find( oc_map[i].ssom_name ); - - if( *ocp == NULL ) { - fprintf( stderr, - "No objectClass \"%s\" defined in schema\n", - oc_map[i].ssom_name ); - return LDAP_OBJECT_CLASS_VIOLATION; - } - } - - for( i=0; ad_map[i].ssam_name; i++ ) { - int rc; - const char *text; - - AttributeDescription ** adp = (AttributeDescription **) - &(((char *) &slap_schema)[ad_map[i].ssam_offset]); - - *adp = NULL; - - rc = slap_str2ad( ad_map[i].ssam_name, adp, &text ); - - if( rc != LDAP_SUCCESS ) { - fprintf( stderr, - "No attribute \"%s\" defined in schema\n", - ad_map[i].ssam_name ); - return rc; - } - } -#endif - - ++schema_init_done; - return 0; + return LDAP_SUCCESS; }