X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fschema_init.c;h=2455a2a1f33bba4d788f8e469e405a268ba254df;hb=8d0711b08f24e9084c816800d6e74be89c7a0a49;hp=08fc1da9ed9d2caaf535f52f2b40a3f6813447ad;hpb=a35d5b90fca2b5f68e335758fd97a1efaebda83b;p=openldap diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 08fc1da9ed..2455a2a1f3 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -1,78 +1,10 @@ /* schema_init.c - init builtin schema */ /* $OpenLDAP$ */ /* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ -/**** -LDAP/X.500 string syntax / matching rules have a few oddities. This -comment attempts to detail how slapd(8) treats them. - -Summary: - StringSyntax X.500 LDAP Matching - DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces - PrintableString subset subset i/e + ignore insignificant spaces - NumericString subset subset ignore all spaces - IA5String ASCII ASCII i/e + ignore insignificant spaces - TeletexString T.61 T.61 i/e + ignore insignificant spaces - - TelephoneNumber subset subset i + ignore all spaces and "-" - - See draft-ietf-ldapbis-strpro for details (once published). - - -Directory String - - In X.500(93), a directory string can be either a PrintableString, - a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)). - In later versions, more CHOICEs were added. In all cases the string - must be non-empty. - - In LDPAv3, a directory string is a UTF-8 encoded UCS string. - - For matching, there are both case ignore and exact rules. Both - also require that "insignificant" spaces be ignored. - spaces before the first non-space are ignored; - spaces after the last non-space are ignored; - spaces after a space are ignored. - Note: by these rules (and as clarified in X.520), a string of only - spaces is to be treated as if held one space, not empty (which would - be a syntax error). - -NumericString - In ASN.1, numeric string is just a string of digits and spaces and - could be empty. However, in X.500, all attribute values of numeric - string carry a non-empty constraint. For example: - - internationalISDNNumber ATTRIBUTE ::= { - WITH SYNTAX InternationalISDNNumber - EQUALITY MATCHING RULE numericStringMatch - SUBSTRINGS MATCHING RULE numericStringSubstringsMatch - ID id-at-internationalISDNNumber } - InternationalISDNNumber ::= NumericString (SIZE(1..ub-international-isdn-number)) - - Unfornately, some assertion values are don't carry the same constraint - (but its unclear how such an assertion could ever be true). In LDAP, - there is one syntax (numericString) not two (numericString with constraint, - numericString without constraint). This should be treated as numericString - with non-empty constraint. Note that while someone may have no - ISDN number, there are no ISDN numbers which are zero length. - - In matching, spaces are ignored. - -PrintableString - In ASN.1, Printable string is just a string of printable characters and - can be empty. In X.500, semantics much like NumericString (see serialNumber - for a like example) excepting uses insignificant space handling instead of - ignore all spaces. - -IA5String - Basically same as PrintableString. There are no examples in X.500, but - same logic applies. So we require them to be non-empty as well. - -****/ - - #include "portable.h" #include @@ -105,7 +37,7 @@ IA5String /* recycled matching routines */ #define bitStringMatch octetStringMatch #define numericStringMatch caseIgnoreIA5Match -#define objectIdentifierMatch caseIgnoreIA5Match +#define objectIdentifierMatch octetStringMatch #define telephoneNumberMatch caseIgnoreIA5Match #define telephoneNumberSubstringsMatch caseIgnoreIA5SubstringsMatch #define generalizedTimeMatch caseIgnoreIA5Match @@ -205,8 +137,28 @@ octetStringMatch( return LDAP_SUCCESS; } +static int +octetStringOrderingMatch( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + ber_len_t v_len = value->bv_len; + ber_len_t av_len = ((struct berval *) assertedValue)->bv_len; + int match = memcmp( value->bv_val, + ((struct berval *) assertedValue)->bv_val, + (v_len < av_len ? v_len : av_len) ); + if( match == 0 ) + match = v_len - av_len; + *matchp = match; + return LDAP_SUCCESS; +} + /* Index generation function */ -static int octetStringIndexer( +int octetStringIndexer( slap_mask_t use, slap_mask_t flags, Syntax *syntax, @@ -254,6 +206,7 @@ static int octetStringIndexer( } keys[i].bv_val = NULL; + keys[i].bv_len = 0; *keysp = keys; @@ -261,20 +214,20 @@ static int octetStringIndexer( } /* Index generation function */ -static int octetStringFilter( +int octetStringFilter( slap_mask_t use, slap_mask_t flags, Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { size_t slen, mlen; BerVarray keys; HASH_CONTEXT HASHcontext; unsigned char HASHdigest[HASH_BYTES]; - struct berval *value = (struct berval *) assertValue; + struct berval *value = (struct berval *) assertedValue; struct berval digest; digest.bv_val = HASHdigest; digest.bv_len = sizeof(HASHdigest); @@ -299,6 +252,7 @@ static int octetStringFilter( ber_dupbv( keys, &digest ); keys[1].bv_val = NULL; + keys[1].bv_len = 0; *keysp = keys; @@ -310,8 +264,8 @@ inValidate( Syntax *syntax, struct berval *in ) { - /* any value allowed */ - return LDAP_OTHER; + /* no value allowed */ + return LDAP_INVALID_SYNTAX; } static int @@ -360,46 +314,6 @@ bitStringValidate( return LDAP_SUCCESS; } -static int -bitStringNormalize( - Syntax *syntax, - struct berval *val, - struct berval *normalized ) -{ - /* - * A normalized bitString is has no extaneous (leading) zero bits. - * That is, '00010'B is normalized to '10'B - * However, as a special case, '0'B requires no normalization. - */ - char *p; - - /* start at the first bit */ - p = &val->bv_val[1]; - - /* Find the first non-zero bit */ - while ( *p == '0' ) p++; - - if( *p == '\'' ) { - /* no non-zero bits */ - ber_str2bv( "\'0\'B", sizeof("\'0\'B") - 1, 1, normalized ); - goto done; - } - - normalized->bv_val = ch_malloc( val->bv_len + 1 ); - - normalized->bv_val[0] = '\''; - normalized->bv_len = 1; - - for( ; *p != '\0'; p++ ) { - normalized->bv_val[normalized->bv_len++] = *p; - } - - normalized->bv_val[normalized->bv_len] = '\0'; - -done: - return LDAP_SUCCESS; -} - static int nameUIDValidate( Syntax *syntax, @@ -451,57 +365,44 @@ nameUIDNormalize( ber_dupbv( &out, val ); if( out.bv_len != 0 ) { - struct berval uidin = { 0, NULL }; - struct berval uidout = { 0, NULL }; + struct berval uid = { 0, NULL }; if( out.bv_val[out.bv_len-1] == 'B' && out.bv_val[out.bv_len-2] == '\'' ) { /* assume presence of optional UID */ - uidin.bv_val = strrchr( out.bv_val, '#' ); + uid.bv_val = strrchr( out.bv_val, '#' ); - if( uidin.bv_val == NULL ) { + if( uid.bv_val == NULL ) { free( out.bv_val ); return LDAP_INVALID_SYNTAX; } - uidin.bv_len = out.bv_len - (uidin.bv_val - out.bv_val); - out.bv_len -= uidin.bv_len--; + uid.bv_len = out.bv_len - (uid.bv_val - out.bv_val); + out.bv_len -= uid.bv_len--; /* temporarily trim the UID */ - *(uidin.bv_val++) = '\0'; - - rc = bitStringNormalize( syntax, &uidin, &uidout ); - - if( rc != LDAP_SUCCESS ) { - free( out.bv_val ); - return LDAP_INVALID_SYNTAX; - } + *(uid.bv_val++) = '\0'; } -#ifdef USE_DN_NORMALIZE rc = dnNormalize2( NULL, &out, normalized ); -#else - rc = dnPretty2( NULL, &out, normalized ); -#endif if( rc != LDAP_SUCCESS ) { free( out.bv_val ); - free( uidout.bv_val ); return LDAP_INVALID_SYNTAX; } - if( uidout.bv_len ) { + if( uid.bv_len ) { normalized->bv_val = ch_realloc( normalized->bv_val, - normalized->bv_len + uidout.bv_len + sizeof("#") ); + normalized->bv_len + uid.bv_len + sizeof("#") ); /* insert the separator */ normalized->bv_val[normalized->bv_len++] = '#'; /* append the UID */ AC_MEMCPY( &normalized->bv_val[normalized->bv_len], - uidout.bv_val, uidout.bv_len ); - normalized->bv_len += uidout.bv_len; + uid.bv_val, uid.bv_len ); + normalized->bv_len += uid.bv_len; /* terminate */ normalized->bv_val[normalized->bv_len] = '\0'; @@ -556,6 +457,76 @@ booleanMatch( return LDAP_SUCCESS; } +/*------------------------------------------------------------------- +LDAP/X.500 string syntax / matching rules have a few oddities. This +comment attempts to detail how slapd(8) treats them. + +Summary: + StringSyntax X.500 LDAP Matching + DirectoryString CHOICE UTF8 i/e + ignore insignificant spaces + PrintableString subset subset i/e + ignore insignificant spaces + NumericString subset subset ignore all spaces + IA5String ASCII ASCII i/e + ignore insignificant spaces + TeletexString T.61 T.61 i/e + ignore insignificant spaces + + TelephoneNumber subset subset i + ignore all spaces and "-" + + See draft-ietf-ldapbis-strpro for details (once published). + + +Directory String - + In X.500(93), a directory string can be either a PrintableString, + a bmpString, or a UniversalString (e.g., UCS (a subset of Unicode)). + In later versions, more CHOICEs were added. In all cases the string + must be non-empty. + + In LDAPv3, a directory string is a UTF-8 encoded UCS string. + + For matching, there are both case ignore and exact rules. Both + also require that "insignificant" spaces be ignored. + spaces before the first non-space are ignored; + spaces after the last non-space are ignored; + spaces after a space are ignored. + Note: by these rules (and as clarified in X.520), a string of only + spaces is to be treated as if held one space, not empty (which + would be a syntax error). + +NumericString + In ASN.1, numeric string is just a string of digits and spaces + and could be empty. However, in X.500, all attribute values of + numeric string carry a non-empty constraint. For example: + + internationalISDNNumber ATTRIBUTE ::= { + WITH SYNTAX InternationalISDNNumber + EQUALITY MATCHING RULE numericStringMatch + SUBSTRINGS MATCHING RULE numericStringSubstringsMatch + ID id-at-internationalISDNNumber } + InternationalISDNNumber ::= + NumericString (SIZE(1..ub-international-isdn-number)) + + Unforunately, some assertion values are don't carry the same + constraint (but its unclear how such an assertion could ever + be true). In LDAP, there is one syntax (numericString) not two + (numericString with constraint, numericString without constraint). + This should be treated as numericString with non-empty constraint. + Note that while someone may have no ISDN number, there are no ISDN + numbers which are zero length. + + In matching, spaces are ignored. + +PrintableString + In ASN.1, Printable string is just a string of printable characters + and can be empty. In X.500, semantics much like NumericString (see + serialNumber for a like example) excepting uses insignificant space + handling instead of ignore all spaces. + +IA5String + Basically same as PrintableString. There are no examples in X.500, + but same logic applies. So we require them to be non-empty as + well. + +-------------------------------------------------------------------*/ + static int UTF8StringValidate( Syntax *syntax, @@ -665,7 +636,7 @@ UTF8StringNormalize( assert( q+len <= p ); /* cannot start with a space */ - assert( !ASCII_SPACE(normalized->bv_val[0]) ); + assert( !ASCII_SPACE( normalized->bv_val[0] ) ); /* * If the string ended in space, backup the pointer one @@ -701,7 +672,7 @@ UTF8SubstringsassertionNormalize( SubstringsAssertion *nsa; int i; - nsa = (SubstringsAssertion *)ch_calloc( 1, sizeof(SubstringsAssertion) ); + nsa = (SubstringsAssertion *)SLAP_CALLOC( 1, sizeof(SubstringsAssertion) ); if( nsa == NULL ) { return NULL; } @@ -717,10 +688,15 @@ UTF8SubstringsassertionNormalize( for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) { /* empty */ } - nsa->sa_any = (struct berval *)ch_malloc( (i + 1) * sizeof(struct berval) ); + nsa->sa_any = (struct berval *) + SLAP_MALLOC( (i + 1) * sizeof(struct berval) ); + if( nsa->sa_any == NULL ) { + goto err; + } + for( i=0; sa->sa_any[i].bv_val != NULL; i++ ) { UTF8bvnormalize( &sa->sa_any[i], &nsa->sa_any[i], - casefold ); + casefold ); if( nsa->sa_any[i].bv_val == NULL ) { goto err; } @@ -739,7 +715,7 @@ UTF8SubstringsassertionNormalize( err: if ( nsa->sa_final.bv_val ) free( nsa->sa_final.bv_val ); - if ( nsa->sa_any )ber_bvarray_free( nsa->sa_any ); + if ( nsa->sa_any ) ber_bvarray_free( nsa->sa_any ); if ( nsa->sa_initial.bv_val ) free( nsa->sa_initial.bv_val ); ch_free( nsa ); return NULL; @@ -776,7 +752,8 @@ approxMatch( } /* Yes, this is necessary */ - assertv = UTF8bvnormalize( ((struct berval *)assertedValue), NULL, LDAP_UTF8_APPROX ); + assertv = UTF8bvnormalize( ((struct berval *)assertedValue), + NULL, LDAP_UTF8_APPROX ); if( assertv == NULL ) { ber_bvfree( nval ); *matchp = 1; @@ -924,7 +901,7 @@ approxFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { char *c; @@ -933,7 +910,8 @@ approxFilter( BerVarray keys; /* Yes, this is necessary */ - val = UTF8bvnormalize( ((struct berval *)assertValue), NULL, LDAP_UTF8_APPROX ); + val = UTF8bvnormalize( ((struct berval *)assertedValue), + NULL, LDAP_UTF8_APPROX ); if( val == NULL || val->bv_val == NULL ) { keys = (struct berval *)ch_malloc( sizeof(struct berval) ); keys[0].bv_val = NULL; @@ -1062,7 +1040,7 @@ approxFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { BerVarray keys; @@ -1071,7 +1049,7 @@ approxFilter( keys = (struct berval *)ch_malloc( sizeof( struct berval * ) * 2 ); /* Yes, this is necessary */ - s = UTF8normalize( ((struct berval *)assertValue), + s = UTF8normalize( ((struct berval *)assertedValue), UTF8_NOCASEFOLD ); if( s == NULL ) { keys[0] = NULL; @@ -1327,7 +1305,7 @@ static int caseExactIgnoreFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { unsigned casefold; @@ -1347,7 +1325,7 @@ static int caseExactIgnoreFilter( casefold = ( mr != caseExactMatchingRule ) ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; - UTF8bvnormalize( (struct berval *) assertValue, &value, casefold ); + UTF8bvnormalize( (struct berval *) assertedValue, &value, casefold ); /* This usually happens if filter contains bad UTF8 */ if( value.bv_val == NULL ) { keys = ch_malloc( sizeof( struct berval ) ); @@ -1566,7 +1544,7 @@ static int caseExactIgnoreSubstringsFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { SubstringsAssertion *sa; @@ -1583,7 +1561,7 @@ static int caseExactIgnoreSubstringsFilter( casefold = ( mr != caseExactSubstringsMatchingRule ) ? LDAP_UTF8_CASEFOLD : LDAP_UTF8_NOCASEFOLD; - sa = UTF8SubstringsassertionNormalize( assertValue, casefold ); + sa = UTF8SubstringsassertionNormalize( assertedValue, casefold ); if( sa == NULL ) { *keysp = NULL; return LDAP_SUCCESS; @@ -2015,7 +1993,7 @@ static int integerFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { size_t slen, mlen; @@ -2030,7 +2008,7 @@ static int integerFilter( slen = syntax->ssyn_oidlen; mlen = mr->smr_oidlen; - integerNormalize( syntax, assertValue, &norm ); + integerNormalize( syntax, assertedValue, &norm ); keys = ch_malloc( sizeof( struct berval ) * 2 ); @@ -2116,7 +2094,9 @@ printablesStringValidate( } } - if( len == 0 ) LDAP_INVALID_SYNTAX; + if( len == 0 ) { + return LDAP_INVALID_SYNTAX; + } return LDAP_SUCCESS; } @@ -2407,7 +2387,7 @@ static int caseExactIA5Filter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { size_t slen, mlen; @@ -2422,7 +2402,7 @@ static int caseExactIA5Filter( slen = syntax->ssyn_oidlen; mlen = mr->smr_oidlen; - value = (struct berval *) assertValue; + value = (struct berval *) assertedValue; keys = ch_malloc( sizeof( struct berval ) * 2 ); @@ -2613,10 +2593,10 @@ static int caseExactIA5SubstringsFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { - SubstringsAssertion *sa = assertValue; + SubstringsAssertion *sa = assertedValue; char pre; ber_len_t nkeys = 0; size_t slen, mlen, klen; @@ -2994,7 +2974,7 @@ static int caseIgnoreIA5Filter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { size_t slen, mlen; @@ -3009,7 +2989,7 @@ static int caseIgnoreIA5Filter( slen = syntax->ssyn_oidlen; mlen = mr->smr_oidlen; - ber_dupbv( &value, (struct berval *) assertValue ); + ber_dupbv( &value, (struct berval *) assertedValue ); ldap_pvt_str2lower( value.bv_val ); keys = ch_malloc( sizeof( struct berval ) * 2 ); @@ -3208,10 +3188,10 @@ static int caseIgnoreIA5SubstringsFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { - SubstringsAssertion *sa = assertValue; + SubstringsAssertion *sa = assertedValue; char pre; ber_len_t nkeys = 0; size_t slen, mlen, klen; @@ -3439,7 +3419,7 @@ objectIdentifierFirstComponentMatch( int rc = LDAP_SUCCESS; int match; struct berval *asserted = (struct berval *) assertedValue; - ber_len_t i; + ber_len_t i, j; struct berval oid; if( value->bv_len == 0 || value->bv_val[0] != '(' /*')'*/ ) { @@ -3453,8 +3433,8 @@ objectIdentifierFirstComponentMatch( /* 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++ ) { + j = value->bv_len - i; + for( i=0; !ASCII_SPACE(oid.bv_val[i]) && i < j; i++ ) { /* empty */ } oid.bv_len = i; @@ -3510,7 +3490,6 @@ objectIdentifierFirstComponentMatch( match, value->bv_val, asserted->bv_val ); #endif - if( rc == LDAP_SUCCESS ) *matchp = match; return rc; } @@ -3528,14 +3507,18 @@ integerBitAndMatch( /* safe to assume integers are NUL terminated? */ lValue = strtoul(value->bv_val, NULL, 10); - if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) + if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) { return LDAP_CONSTRAINT_VIOLATION; + } lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10); - if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE ) + if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) + && errno == ERANGE ) + { return LDAP_CONSTRAINT_VIOLATION; + } - *matchp = (lValue & lAssertedValue); + *matchp = (lValue & lAssertedValue) ? 0 : 1; return LDAP_SUCCESS; } @@ -3552,21 +3535,24 @@ integerBitOrMatch( /* safe to assume integers are NUL terminated? */ lValue = strtoul(value->bv_val, NULL, 10); - if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) + if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) { return LDAP_CONSTRAINT_VIOLATION; + } lAssertedValue = strtol(((struct berval *)assertedValue)->bv_val, NULL, 10); - if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) && errno == ERANGE ) + if(( lAssertedValue == LONG_MIN || lAssertedValue == LONG_MAX) + && errno == ERANGE ) + { return LDAP_CONSTRAINT_VIOLATION; + } - *matchp = (lValue | lAssertedValue); + *matchp = (lValue | lAssertedValue) ? 0 : -1; return LDAP_SUCCESS; } #ifdef HAVE_TLS #include #include -char digit[] = "0123456789"; /* * Next function returns a string representation of a ASN1_INTEGER. @@ -3578,6 +3564,7 @@ asn1_integer2str(ASN1_INTEGER *a, struct berval *bv) { char buf[256]; char *p; + static char digit[] = "0123456789"; /* We work backwards, make it fill from the end of buf */ p = buf + sizeof(buf) - 1; @@ -3620,8 +3607,8 @@ asn1_integer2str(ASN1_INTEGER *a, struct berval *bv) return NULL; } *--p = digit[carry]; - if (copy[base] == 0) - base++; + + if (copy[base] == 0) base++; } free(copy); } @@ -3665,7 +3652,9 @@ certificateExactConvert( X509_free(xcert); return LDAP_INVALID_SYNTAX; } - if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) != LDAP_SUCCESS ) { + if ( dnX509normalize(X509_get_issuer_name(xcert), &issuer_dn ) + != LDAP_SUCCESS ) + { X509_free(xcert); ber_memfree(serial.bv_val); return LDAP_INVALID_SYNTAX; @@ -3713,33 +3702,34 @@ serial_and_issuer_parse( begin = assertion->bv_val; end = assertion->bv_val+assertion->bv_len-1; - for (p=begin; p<=end && *p != '$'; p++) - ; - if ( p > end ) - return LDAP_INVALID_SYNTAX; + for (p=begin; p<=end && *p != '$'; p++) /* empty */ ; + if ( p > end ) return LDAP_INVALID_SYNTAX; - /* p now points at the $ sign, now use begin and end to delimit the - serial number */ - while (ASCII_SPACE(*begin)) - begin++; + /* p now points at the $ sign, now use + * begin and end to delimit the serial number + */ + while (ASCII_SPACE(*begin)) begin++; end = p-1; - while (ASCII_SPACE(*end)) - end--; + while (ASCII_SPACE(*end)) end--; + + if( end <= begin ) return LDAP_INVALID_SYNTAX; bv.bv_len = end-begin+1; bv.bv_val = begin; ber_dupbv(serial, &bv); /* now extract the issuer, remember p was at the dollar sign */ - if ( issuer_dn ) { - begin = p+1; - end = assertion->bv_val+assertion->bv_len-1; - while (ASCII_SPACE(*begin)) - begin++; - /* should we trim spaces at the end too? is it safe always? */ + begin = p+1; + end = assertion->bv_val+assertion->bv_len-1; + while (ASCII_SPACE(*begin)) begin++; + /* should we trim spaces at the end too? is it safe always? no, no */ + if( end <= begin ) return LDAP_INVALID_SYNTAX; + + if ( issuer_dn ) { bv.bv_len = end-begin+1; bv.bv_val = begin; + dnNormalize2( NULL, &bv, issuer_dn ); } @@ -3783,8 +3773,7 @@ certificateExactMatch( X509_free(xcert); serial_and_issuer_parse(assertedValue, - &asserted_serial, - &asserted_issuer_dn); + &asserted_serial, &asserted_issuer_dn); ret = integerMatch( matchp, @@ -3880,8 +3869,7 @@ static int certificateExactIndexer( asn1_integer2str(xcert->cert_info->serialNumber, &serial); X509_free(xcert); integerNormalize( slap_schema.si_syn_integer, - &serial, - &keys[i] ); + &serial, &keys[i] ); ber_memfree(serial.bv_val); #ifdef NEW_LOGGING LDAP_LOG( CONFIG, ENTRY, @@ -3907,15 +3895,15 @@ static int certificateExactFilter( Syntax *syntax, MatchingRule *mr, struct berval *prefix, - void * assertValue, + void * assertedValue, BerVarray *keysp ) { BerVarray keys; struct berval asserted_serial; + int ret; - serial_and_issuer_parse(assertValue, - &asserted_serial, - NULL); + ret = serial_and_issuer_parse( assertedValue, &asserted_serial, NULL ); + if( ret != LDAP_SUCCESS ) return ret; keys = ch_malloc( sizeof( struct berval ) * 2 ); integerNormalize( syntax, &asserted_serial, &keys[0] ); @@ -4258,19 +4246,10 @@ bootParameterValidate( return LDAP_SUCCESS; } -static struct syntax_defs_rec { - char *sd_desc; #define X_BINARY "X-BINARY-TRANSFER-REQUIRED 'TRUE' " #define X_NOT_H_R "X-NOT-HUMAN-READABLE 'TRUE' " - 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 -} syntax_defs[] = { + +static slap_syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.4.1.1466.115.121.1.1 DESC 'ACI Item' " X_BINARY X_NOT_H_R ")", SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, NULL, NULL, NULL}, @@ -4285,7 +4264,7 @@ static struct syntax_defs_rec { 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, bitStringValidate, bitStringNormalize, NULL }, + 0, bitStringValidate, NULL, NULL }, {"( 1.3.6.1.4.1.1466.115.121.1.7 DESC 'Boolean' )", 0, booleanValidate, NULL, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' " @@ -4403,7 +4382,7 @@ static struct syntax_defs_rec { * Chadwick in private mail. */ {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )", - 0, NULL, NULL, NULL}, + 0, UTF8StringValidate, NULL, NULL}, #endif /* OpenLDAP Experimental Syntaxes */ @@ -4426,11 +4405,37 @@ static struct syntax_defs_rec { {NULL, 0, NULL, NULL, NULL} }; +#ifdef HAVE_TLS +char *certificateExactMatchSyntaxes[] = { + "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */, + NULL +}; +#endif +char *directoryStringSyntaxes[] = { + "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */, + NULL +}; +char *integerFirstComponentMatchSyntaxes[] = { + "1.3.6.1.4.1.1466.115.121.1.27" /* INTEGER */, + "1.3.6.1.4.1.1466.115.121.1.17" /* ditStructureRuleDescription */, + NULL +}; +char *objectIdentifierFirstComponentMatchSyntaxes[] = { + "1.3.6.1.4.1.1466.115.121.1.38" /* OID */, + "1.3.6.1.4.1.1466.115.121.1.3" /* attributeTypeDescription */, + "1.3.6.1.4.1.1466.115.121.1.16" /* ditContentRuleDescription */, + "1.3.6.1.4.1.1466.115.121.1.54" /* ldapSyntaxDescription */, + "1.3.6.1.4.1.1466.115.121.1.30" /* matchingRuleDescription */, + "1.3.6.1.4.1.1466.115.121.1.31" /* matchingRuleUseDescription */, + "1.3.6.1.4.1.1466.115.121.1.35" /* nameFormDescription */, + "1.3.6.1.4.1.1466.115.121.1.37" /* objectClassDescription */, + NULL +}; + /* * Other matching rules in X.520 that we do not use (yet): * * 2.5.13.9 numericStringOrderingMatch - * 2.5.13.18 octetStringOrderingMatch * 2.5.13.19 octetStringSubstringsMatch * 2.5.13.25 uTCTimeMatch * 2.5.13.26 uTCTimeOrderingMatch @@ -4448,24 +4453,14 @@ static struct syntax_defs_rec { * 2.5.13.43 readerAndKeyIDMatch * 2.5.13.44 attributeIntegrityMatch */ -static struct mrule_defs_rec { - char * mrd_desc; - slap_mask_t mrd_usage; - slap_mr_convert_func * mrd_convert; - slap_mr_normalize_func * mrd_normalize; - slap_mr_match_func * mrd_match; - slap_mr_indexer_func * mrd_indexer; - slap_mr_filter_func * mrd_filter; - - char * mrd_associated; -} mrule_defs[] = { +static slap_mrule_defs_rec mrule_defs[] = { /* * EQUALITY matching rules must be listed after associated APPROX * matching rules. So, we list all APPROX matching rules first. */ {"( " directoryStringApproxMatchOID " NAME 'directoryStringApproxMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, + SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL, NULL, NULL, directoryStringApproxMatch, directoryStringApproxIndexer, @@ -4474,7 +4469,7 @@ static struct mrule_defs_rec { {"( " IA5StringApproxMatchOID " NAME 'IA5StringApproxMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, + SLAP_MR_HIDE | SLAP_MR_EQUALITY_APPROX | SLAP_MR_EXT, NULL, NULL, NULL, IA5StringApproxMatch, IA5StringApproxIndexer, @@ -4487,14 +4482,14 @@ static struct mrule_defs_rec { {"( 2.5.13.0 NAME 'objectIdentifierMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, objectIdentifierMatch, caseIgnoreIA5Indexer, caseIgnoreIA5Filter, NULL}, {"( 2.5.13.1 NAME 'distinguishedNameMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, dnMatch, dnIndexer, dnFilter, NULL}, @@ -4502,20 +4497,21 @@ static struct mrule_defs_rec { {"( 2.5.13.2 NAME 'caseIgnoreMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, + directoryStringSyntaxes, NULL, NULL, caseIgnoreMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter, directoryStringApproxMatchOID }, {"( 2.5.13.3 NAME 'caseIgnoreOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_ORDERING, + SLAP_MR_ORDERING, directoryStringSyntaxes, NULL, NULL, caseIgnoreOrderingMatch, NULL, 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, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseExactIgnoreSubstringsMatch, caseExactIgnoreSubstringsIndexer, @@ -4524,21 +4520,21 @@ static struct mrule_defs_rec { {"( 2.5.13.5 NAME 'caseExactMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, directoryStringSyntaxes, NULL, NULL, caseExactMatch, caseExactIgnoreIndexer, caseExactIgnoreFilter, directoryStringApproxMatchOID }, {"( 2.5.13.6 NAME 'caseExactOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )", - SLAP_MR_ORDERING, + SLAP_MR_ORDERING, directoryStringSyntaxes, NULL, NULL, caseExactOrderingMatch, NULL, 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, + SLAP_MR_SUBSTR, directoryStringSyntaxes, NULL, NULL, caseExactIgnoreSubstringsMatch, caseExactIgnoreSubstringsIndexer, @@ -4547,7 +4543,7 @@ static struct mrule_defs_rec { {"( 2.5.13.8 NAME 'numericStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, NULL, NULL, caseIgnoreIA5Match, caseIgnoreIA5Indexer, @@ -4556,7 +4552,7 @@ static struct mrule_defs_rec { {"( 2.5.13.10 NAME 'numericStringSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseIgnoreIA5SubstringsMatch, caseIgnoreIA5SubstringsIndexer, @@ -4565,56 +4561,63 @@ static struct mrule_defs_rec { {"( 2.5.13.11 NAME 'caseIgnoreListMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, NULL, NULL, caseIgnoreListMatch, NULL, NULL, NULL}, {"( 2.5.13.12 NAME 'caseIgnoreListSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseIgnoreListSubstringsMatch, NULL, NULL, NULL}, {"( 2.5.13.13 NAME 'booleanMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, booleanMatch, NULL, NULL, NULL}, {"( 2.5.13.14 NAME 'integerMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, integerMatch, integerIndexer, integerFilter, NULL}, {"( 2.5.13.15 NAME 'integerOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_ORDERING, + SLAP_MR_ORDERING, NULL, NULL, NULL, integerOrderingMatch, NULL, NULL, NULL}, {"( 2.5.13.16 NAME 'bitStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.6 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, bitStringMatch, bitStringIndexer, bitStringFilter, NULL}, {"( 2.5.13.17 NAME 'octetStringMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, octetStringMatch, octetStringIndexer, octetStringFilter, NULL}, + {"( 2.5.13.18 NAME 'octetStringOrderingMatch' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )", + SLAP_MR_ORDERING, NULL, + NULL, NULL, + octetStringOrderingMatch, NULL, NULL, + NULL}, + {"( 2.5.13.20 NAME 'telephoneNumberMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.50 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, NULL, NULL, telephoneNumberMatch, telephoneNumberIndexer, @@ -4623,7 +4626,7 @@ static struct mrule_defs_rec { {"( 2.5.13.21 NAME 'telephoneNumberSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", - SLAP_MR_SUBSTR | SLAP_MR_EXT, + SLAP_MR_SUBSTR, NULL, NULL, NULL, telephoneNumberSubstringsMatch, telephoneNumberSubstringsIndexer, @@ -4632,42 +4635,42 @@ static struct mrule_defs_rec { {"( 2.5.13.22 NAME 'presentationAddressMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.43 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, {"( 2.5.13.23 NAME 'uniqueMemberMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, uniqueMemberMatch, NULL, NULL, NULL}, {"( 2.5.13.24 NAME 'protocolInformationMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.42 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, protocolInformationMatch, NULL, NULL, NULL}, {"( 2.5.13.27 NAME 'generalizedTimeMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, generalizedTimeMatch, NULL, NULL, NULL}, {"( 2.5.13.28 NAME 'generalizedTimeOrderingMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 )", - SLAP_MR_ORDERING, + SLAP_MR_ORDERING, NULL, NULL, NULL, generalizedTimeOrderingMatch, NULL, NULL, NULL}, {"( 2.5.13.29 NAME 'integerFirstComponentMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, integerFirstComponentMatchSyntaxes, NULL, NULL, integerFirstComponentMatch, NULL, NULL, NULL}, @@ -4675,6 +4678,7 @@ static struct mrule_defs_rec { {"( 2.5.13.30 NAME 'objectIdentifierFirstComponentMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, + objectIdentifierFirstComponentMatchSyntaxes, NULL, NULL, objectIdentifierFirstComponentMatch, NULL, NULL, NULL}, @@ -4682,7 +4686,7 @@ static struct mrule_defs_rec { #ifdef HAVE_TLS {"( 2.5.13.34 NAME 'certificateExactMatch' " "SYNTAX 1.2.826.0.1.3344810.7.1 )", - SLAP_MR_EQUALITY | SLAP_MR_EXT, + SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes, certificateExactConvert, NULL, certificateExactMatch, certificateExactIndexer, certificateExactFilter, @@ -4691,21 +4695,21 @@ static struct mrule_defs_rec { {"( 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, + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, NULL, caseExactIA5Match, caseExactIA5Indexer, caseExactIA5Filter, IA5StringApproxMatchOID }, {"( 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 | SLAP_MR_DN_FOLD, + SLAP_MR_EQUALITY | SLAP_MR_EXT | SLAP_MR_DN_FOLD, NULL, NULL, NULL, caseIgnoreIA5Match, caseIgnoreIA5Indexer, caseIgnoreIA5Filter, IA5StringApproxMatchOID }, {"( 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, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseIgnoreIA5SubstringsMatch, caseIgnoreIA5SubstringsIndexer, @@ -4714,7 +4718,7 @@ static struct mrule_defs_rec { {"( 1.3.6.1.4.1.4203.1.2.1 NAME 'caseExactIA5SubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", - SLAP_MR_SUBSTR, + SLAP_MR_SUBSTR, NULL, NULL, NULL, caseExactIA5SubstringsMatch, caseExactIA5SubstringsIndexer, @@ -4725,7 +4729,7 @@ static struct mrule_defs_rec { /* needs updating */ {"( 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, + SLAP_MR_EQUALITY, NULL, NULL, NULL, authPasswordMatch, NULL, NULL, NULL}, @@ -4734,7 +4738,7 @@ static struct mrule_defs_rec { #ifdef SLAPD_ACI_ENABLED {"( 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, + SLAP_MR_EQUALITY, NULL, NULL, NULL, OpenLDAPaciMatch, NULL, NULL, NULL}, @@ -4742,19 +4746,21 @@ static struct mrule_defs_rec { {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EXT, + SLAP_MR_EXT, NULL, NULL, NULL, integerBitAndMatch, NULL, NULL, NULL}, {"( 1.2.840.113556.1.4.804 NAME 'integerBitOrMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", - SLAP_MR_EXT, + SLAP_MR_EXT, NULL, NULL, NULL, integerBitOrMatch, NULL, NULL, NULL}, - {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL} + {NULL, SLAP_MR_NONE, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL } }; int @@ -4767,17 +4773,7 @@ slap_schema_init( void ) assert( schema_init_done == 0 ); for ( i=0; syntax_defs[i].sd_desc != NULL; i++ ) { - 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 -#endif - ); + res = register_syntax( &syntax_defs[i] ); if ( res ) { fprintf( stderr, "slap_schema_init: Error registering syntax %s\n", @@ -4787,22 +4783,16 @@ slap_schema_init( void ) } for ( i=0; mrule_defs[i].mrd_desc != NULL; i++ ) { - if( mrule_defs[i].mrd_usage == SLAP_MR_NONE ) { + if( mrule_defs[i].mrd_usage == SLAP_MR_NONE && + mrule_defs[i].mrd_compat_syntaxes == NULL ) + { fprintf( stderr, "slap_schema_init: Ingoring unusable matching rule %s\n", mrule_defs[i].mrd_desc ); continue; } - res = register_matching_rule( - mrule_defs[i].mrd_desc, - mrule_defs[i].mrd_usage, - mrule_defs[i].mrd_convert, - mrule_defs[i].mrd_normalize, - mrule_defs[i].mrd_match, - mrule_defs[i].mrd_indexer, - mrule_defs[i].mrd_filter, - mrule_defs[i].mrd_associated ); + res = register_matching_rule( &mrule_defs[i] ); if ( res ) { fprintf( stderr, @@ -4830,5 +4820,6 @@ schema_destroy( void ) for ( i=0; i < (int)(sizeof(mr_ptr)/sizeof(mr_ptr[0])); i++ ) *mr_ptr[i].mr = NULL; mr_destroy(); + mru_destroy(); syn_destroy(); }