From: Pierangelo Masarati Date: Sat, 30 Aug 2008 14:30:31 +0000 (+0000) Subject: implement caseIgnoreListMatch (ITS#5608) X-Git-Tag: ACLCHECK_0~1403 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=03793fd9f40b7cdaa261083f8abde5b5f475665b;p=openldap implement caseIgnoreListMatch (ITS#5608) --- diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index fd386a74f2..26c3ec4a5e 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1987,6 +1987,168 @@ telephoneNumberNormalize( return LDAP_SUCCESS; } +static int +postalAddressValidate( + Syntax *syntax, + struct berval *in ) +{ + struct berval bv = *in; + int c; + + for ( c = 0; c < in->bv_len; c++ ) { + if ( in->bv_val[c] == '\\' ) { + c++; + if ( strncasecmp( &in->bv_val[c], "24", STRLENOF( "24" ) ) != 0 + && strncasecmp( &in->bv_val[c], "5C", STRLENOF( "5C" ) ) != 0 ) + { + return LDAP_INVALID_SYNTAX; + } + continue; + } + + if ( in->bv_val[c] == '$' ) { + bv.bv_len = &in->bv_val[c] - bv.bv_val; + if ( UTF8StringValidate( NULL, &bv ) != LDAP_SUCCESS ) { + return LDAP_INVALID_SYNTAX; + } + bv.bv_val = &in->bv_val[c] + 1; + } + } + + bv.bv_len = &in->bv_val[c] - bv.bv_val; + return UTF8StringValidate( NULL, &bv ); +} + +static int +postalAddressNormalize( + slap_mask_t usage, + Syntax *syntax, + MatchingRule *mr, + struct berval *val, + struct berval *normalized, + void *ctx ) +{ + BerVarray lines = NULL, nlines = NULL; + int l, c; + int nescapes = 0; + int rc = LDAP_SUCCESS; + MatchingRule *xmr = NULL; + struct berval bv = BER_BVNULL; + char *p; + + if ( SLAP_MR_ASSOCIATED( mr, slap_schema.si_mr_caseIgnoreListMatch ) ) { + xmr = slap_schema.si_mr_caseIgnoreMatch; + + } else { + xmr = slap_schema.si_mr_caseExactMatch; + } + + for ( l = 0, c = 0; c < val->bv_len; c++ ) { + if ( val->bv_val[c] == '$' ) { + l++; + } + } + + lines = slap_sl_calloc( sizeof( struct berval ), 2 * ( l + 2 ), ctx ); + nlines = &lines[l + 2]; + + lines[0].bv_val = val->bv_val; + for ( l = 0, c = 0; c < val->bv_len; c++ ) { + if ( val->bv_val[c] == '$' ) { + lines[l].bv_len = &val->bv_val[c] - lines[l].bv_val; + l++; + lines[l].bv_val = &val->bv_val[c + 1]; + } + } + lines[l].bv_len = &val->bv_val[c] - lines[l].bv_val; + + normalized->bv_len = l; + + for ( l = 0; !BER_BVISNULL( &lines[l] ); l++ ) { + int s, d; + ber_len_t oldlen; + + ber_bvreplace_x( &bv, &lines[l], ctx ); + oldlen = bv.bv_len; + for ( d = 0, s = 0; s < oldlen; d++, s++ ) { + if ( bv.bv_val[s] == '\\' ) { + if ( &bv.bv_val[s] - &bv.bv_val[0] + STRLENOF( "\\XX" ) > oldlen ) { + rc = LDAP_INVALID_SYNTAX; + goto done; + + } else if ( strncasecmp( &bv.bv_val[s + 1], "24", STRLENOF( "24" ) ) == 0 ) { + bv.bv_val[d] = '$'; + + } else if ( strncasecmp( &bv.bv_val[s + 1], "5C", STRLENOF( "5C" ) ) == 0 ) { + bv.bv_val[d] = '\\'; + + } else { + rc = LDAP_INVALID_SYNTAX; + goto done; + } + + nescapes++; + s += 2; + bv.bv_len -= 2; + + } else { + bv.bv_val[d] = bv.bv_val[s]; + } + } + + rc = UTF8StringNormalize( usage, NULL, xmr, &bv, &nlines[l], ctx ); + if ( rc != LDAP_SUCCESS ) { + rc = LDAP_INVALID_SYNTAX; + goto done; + } + + normalized->bv_len += nlines[l].bv_len; + } + + normalized->bv_len += 2*nescapes; + + normalized->bv_val = slap_sl_malloc( normalized->bv_len + 1, ctx ); + + p = normalized->bv_val; + for ( l = 0; !BER_BVISNULL( &nlines[l] ); l++ ) { + for ( c = 0; c < nlines[l].bv_len; c++ ) { + switch ( nlines[l].bv_val[c] ) { + case '\\': + p = lutil_strcopy( p, "\\5C" ); + break; + + case '$': + p = lutil_strcopy( p, "\\24" ); + break; + + default: + *p++ = nlines[l].bv_val[c]; + break; + } + } + + *p++ = '$'; + } + *--p = '\0'; + + assert( p - normalized->bv_val == normalized->bv_len ); + +done:; + if ( !BER_BVISNULL( &bv ) ) { + ber_memfree_x( bv.bv_val, ctx ); + } + + if ( nlines != NULL ) { + for ( l = 0; !BER_BVISNULL( &nlines[ l ] ); l++ ) { + slap_sl_free( nlines[l].bv_val, ctx ); + } + + slap_sl_free( lines, ctx ); + } + + return rc; +} + int numericoidValidate( Syntax *syntax, @@ -4688,7 +4850,7 @@ static slap_syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.4.1.1466.115.121.1.40 DESC 'Octet String' )", 0, NULL, blobValidate, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.41 DESC 'Postal Address' )", - 0, NULL, UTF8StringValidate, NULL}, + 0, NULL, postalAddressValidate, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.42 DESC 'Protocol Information' )", 0, NULL, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.43 DESC 'Presentation Address' )", @@ -4993,7 +5155,9 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.11 NAME 'caseIgnoreListMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, - NULL, NULL, NULL, NULL, NULL, NULL }, + NULL, postalAddressNormalize, octetStringMatch, + octetStringIndexer, octetStringFilter, + NULL }, {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", diff --git a/servers/slapd/schema_prep.c b/servers/slapd/schema_prep.c index 42f9a5e943..28bcc96c1d 100644 --- a/servers/slapd/schema_prep.c +++ b/servers/slapd/schema_prep.c @@ -1072,6 +1072,10 @@ static struct slap_schema_mr_map { { "objectIdentifierFirstComponentMatch", offsetof(struct slap_internal_schema, si_mr_objectIdentifierFirstComponentMatch) }, + { "caseIgnoreMatch", + offsetof(struct slap_internal_schema, si_mr_caseIgnoreMatch) }, + { "caseIgnoreListMatch", + offsetof(struct slap_internal_schema, si_mr_caseIgnoreListMatch) }, { NULL, 0 } }; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 431a7743b7..95c4e898ac 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -969,6 +969,8 @@ struct slap_internal_schema { MatchingRule *si_mr_integerMatch; MatchingRule *si_mr_integerFirstComponentMatch; MatchingRule *si_mr_objectIdentifierFirstComponentMatch; + MatchingRule *si_mr_caseIgnoreMatch; + MatchingRule *si_mr_caseIgnoreListMatch; /* Syntaxes */ Syntax *si_syn_directoryString;