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,
{"( 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' )",
{"( 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 )",