X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fschema_init.c;h=42f03d8f260a5d828e2939a3c4d0b52208d8aba6;hb=1bd26d5951cc929b0513d569186662650ce598d9;hp=5d373374397479658ec9cd727cac7c939bc66ae4;hpb=7d101bcd9801fcfcc67fb0b20a3dd4127a3a4cdc;p=openldap diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 5d37337439..42f03d8f26 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -17,7 +17,9 @@ #include "portable.h" #include +#ifdef HAVE_LIMITS_H #include +#endif #include #include @@ -48,8 +50,6 @@ #define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len) #define HASH_Final(d,c) lutil_HASHFinal(d,c) -#define OpenLDAPaciMatch NULL - /* approx matching rules */ #define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4" #define directoryStringApproxMatch approxMatch @@ -67,11 +67,19 @@ #define csnIndexer generalizedTimeIndexer #define csnFilter generalizedTimeFilter +#ifdef SLAP_AUTHZ_SYNTAX +/* FIXME: temporary */ +#define authzMatch octetStringMatch +#endif /* SLAP_AUTHZ_SYNTAX */ + unsigned int index_substr_if_minlen = SLAP_INDEX_SUBSTR_IF_MINLEN_DEFAULT; unsigned int index_substr_if_maxlen = SLAP_INDEX_SUBSTR_IF_MAXLEN_DEFAULT; unsigned int index_substr_any_len = SLAP_INDEX_SUBSTR_ANY_LEN_DEFAULT; unsigned int index_substr_any_step = SLAP_INDEX_SUBSTR_ANY_STEP_DEFAULT; +ldap_pvt_thread_mutex_t ad_undef_mutex; +ldap_pvt_thread_mutex_t oc_undef_mutex; + static int inValidate( Syntax *syntax, @@ -119,7 +127,7 @@ static int certificateValidate( Syntax *syntax, struct berval *in ) #define certificateValidate sequenceValidate #endif -static int +int octetStringMatch( int *matchp, slap_mask_t flags, @@ -402,7 +410,7 @@ octetStringSubstringsIndexer( BerVarray *keysp, void *ctx ) { - ber_len_t i, j, len, nkeys; + ber_len_t i, nkeys; size_t slen, mlen; BerVarray keys; @@ -519,7 +527,7 @@ octetStringSubstringsFilter ( { SubstringsAssertion *sa; char pre; - ber_len_t len, max, nkeys = 0; + ber_len_t nkeys = 0; size_t slen, mlen, klen; BerVarray keys; HASH_CONTEXT HASHcontext; @@ -890,8 +898,8 @@ nameUIDPretty( struct berval *out, void *ctx ) { - assert( val ); - assert( out ); + assert( val != NULL ); + assert( out != NULL ); Debug( LDAP_DEBUG_TRACE, ">>> nameUIDPretty: <%s>\n", val->bv_val, 0, 0 ); @@ -1058,8 +1066,9 @@ uniqueMemberMatch( struct berval *asserted = (struct berval *) assertedValue; struct berval assertedDN = *asserted; struct berval assertedUID = BER_BVNULL; - struct berval valueDN = BER_BVNULL; + struct berval valueDN = *value; struct berval valueUID = BER_BVNULL; + int approx = ((flags & SLAP_MR_EQUALITY_APPROX) == SLAP_MR_EQUALITY_APPROX); if ( !BER_BVISEMPTY( asserted ) ) { assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' ); @@ -1078,7 +1087,6 @@ uniqueMemberMatch( } if ( !BER_BVISEMPTY( value ) ) { - valueDN = *value; valueUID.bv_val = strrchr( valueDN.bv_val, '#' ); if ( !BER_BVISNULL( &valueUID ) ) { @@ -1107,11 +1115,109 @@ uniqueMemberMatch( *matchp = match; return LDAP_SUCCESS; } + + } else if ( !approx && valueUID.bv_len ) { + match = -1; + *matchp = match; + return LDAP_SUCCESS; + + } else if ( !approx && assertedUID.bv_len ) { + match = 1; + *matchp = match; + return LDAP_SUCCESS; } return dnMatch( matchp, flags, syntax, mr, &valueDN, &assertedDN ); } +static int +uniqueMemberIndexer( + slap_mask_t use, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + BerVarray values, + BerVarray *keysp, + void *ctx ) +{ + BerVarray dnvalues; + int rc; + int i; + for( i=0; !BER_BVISNULL( &values[i] ); i++ ) { + /* just count them */ + } + assert( i > 0 ); + + dnvalues = slap_sl_malloc( sizeof( struct berval ) * (i+1), ctx ); + + for( i=0; !BER_BVISNULL( &values[i] ); i++ ) { + struct berval assertedDN = values[i]; + struct berval assertedUID = BER_BVNULL; + + if ( !BER_BVISEMPTY( &assertedDN ) ) { + assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' ); + if ( !BER_BVISNULL( &assertedUID ) ) { + assertedUID.bv_val++; + assertedUID.bv_len = assertedDN.bv_len + - ( assertedUID.bv_val - assertedDN.bv_val ); + + if ( bitStringValidate( NULL, &assertedUID ) == LDAP_SUCCESS ) { + assertedDN.bv_len -= assertedUID.bv_len + 1; + + } else { + BER_BVZERO( &assertedUID ); + } + } + } + + dnvalues[i] = assertedDN; + } + BER_BVZERO( &dnvalues[i] ); + + rc = octetStringIndexer( use, flags, syntax, mr, prefix, + dnvalues, keysp, ctx ); + + slap_sl_free( dnvalues, ctx ); + return rc; +} + +static int +uniqueMemberFilter( + slap_mask_t use, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *prefix, + void * assertedValue, + BerVarray *keysp, + void *ctx ) +{ + struct berval *asserted = (struct berval *) assertedValue; + struct berval assertedDN = *asserted; + struct berval assertedUID = BER_BVNULL; + + if ( !BER_BVISEMPTY( asserted ) ) { + assertedUID.bv_val = strrchr( assertedDN.bv_val, '#' ); + if ( !BER_BVISNULL( &assertedUID ) ) { + assertedUID.bv_val++; + assertedUID.bv_len = assertedDN.bv_len + - ( assertedUID.bv_val - assertedDN.bv_val ); + + if ( bitStringValidate( NULL, &assertedUID ) == LDAP_SUCCESS ) { + assertedDN.bv_len -= assertedUID.bv_len + 1; + + } else { + BER_BVZERO( &assertedUID ); + } + } + } + + return octetStringFilter( use, flags, syntax, mr, prefix, + &assertedDN, keysp, ctx ); +} + + /* * Handling boolean syntax and matching is quite rigid. * A more flexible approach would be to allow a variety @@ -1323,7 +1429,10 @@ UTF8StringNormalize( nvalue.bv_len = 0; nvalue.bv_val = tmp.bv_val; - wasspace = 1; /* trim leading spaces */ + /* trim leading spaces? */ + wasspace = !((( use & SLAP_MR_SUBSTR_ANY ) == SLAP_MR_SUBSTR_ANY ) || + (( use & SLAP_MR_SUBSTR_FINAL ) == SLAP_MR_SUBSTR_FINAL )); + for( i = 0; i < tmp.bv_len; i++) { if ( ASCII_SPACE( tmp.bv_val[i] )) { if( wasspace++ == 0 ) { @@ -1337,8 +1446,11 @@ UTF8StringNormalize( } if( !BER_BVISEMPTY( &nvalue ) ) { - if( wasspace ) { - /* last character was a space, trim it */ + /* trim trailing space? */ + if( wasspace && ( + (( use & SLAP_MR_SUBSTR_INITIAL ) != SLAP_MR_SUBSTR_INITIAL ) && + ( use & SLAP_MR_SUBSTR_ANY ) != SLAP_MR_SUBSTR_ANY )) + { --nvalue.bv_len; } nvalue.bv_val[nvalue.bv_len] = '\0'; @@ -1354,6 +1466,137 @@ UTF8StringNormalize( return LDAP_SUCCESS; } +static int +directoryStringSubstringsMatch( + int *matchp, + slap_mask_t flags, + Syntax *syntax, + MatchingRule *mr, + struct berval *value, + void *assertedValue ) +{ + int match = 0; + SubstringsAssertion *sub = assertedValue; + struct berval left = *value; + int i; + int priorspace=0; + + if ( !BER_BVISNULL( &sub->sa_initial ) ) { + if ( sub->sa_initial.bv_len > left.bv_len ) { + /* not enough left */ + match = 1; + goto done; + } + + match = memcmp( 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; + + priorspace = ASCII_SPACE( + sub->sa_initial.bv_val[sub->sa_initial.bv_len] ); + } + + if ( sub->sa_any ) { + for ( i = 0; !BER_BVISNULL( &sub->sa_any[i] ); i++ ) { + ber_len_t idx; + char *p; + + if( priorspace && !BER_BVISEMPTY( &sub->sa_any[i] ) + && ASCII_SPACE( sub->sa_any[i].bv_val[0] )) + { + /* allow next space to match */ + left.bv_val--; + left.bv_len++; + } + priorspace=0; + +retry: + if ( BER_BVISEMPTY( &sub->sa_any[i] ) ) { + continue; + } + + if ( sub->sa_any[i].bv_len > left.bv_len ) { + /* not enough left */ + match = 1; + goto done; + } + + p = memchr( left.bv_val, *sub->sa_any[i].bv_val, left.bv_len ); + + if( p == NULL ) { + match = 1; + goto done; + } + + idx = p - left.bv_val; + + 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 = memcmp( 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; + + priorspace = ASCII_SPACE( + sub->sa_any[i].bv_val[sub->sa_any[i].bv_len] ); + } + } + + if ( !BER_BVISNULL( &sub->sa_final ) ) { + if( priorspace && !BER_BVISEMPTY( &sub->sa_final ) + && ASCII_SPACE( sub->sa_final.bv_val[0] )) + { + /* allow next space to match */ + left.bv_val--; + left.bv_len++; + } + + if ( sub->sa_final.bv_len > left.bv_len ) { + /* not enough left */ + match = 1; + goto done; + } + + match = memcmp( 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; + } + } + +done: + *matchp = match; + return LDAP_SUCCESS; +} + #if defined(SLAPD_APPROX_INITIALS) # define SLAPD_APPROX_DELIMITER "._ " # define SLAPD_APPROX_WORDLEN 2 @@ -1618,7 +1861,7 @@ telephoneNumberNormalize( return LDAP_SUCCESS; } -static int +int numericoidValidate( Syntax *syntax, struct berval *in ) @@ -1635,7 +1878,7 @@ numericoidValidate( return LDAP_SUCCESS; } - if ( val.bv_val[0] == '0' ) { + if ( val.bv_val[0] == '0' && !OID_SEPARATOR( val.bv_val[1] )) { break; } @@ -2083,7 +2326,7 @@ integerBitAndMatch( return LDAP_CONSTRAINT_VIOLATION; } - *matchp = (lValue & lAssertedValue) ? 0 : 1; + *matchp = ((lValue & lAssertedValue) == lAssertedValue) ? 0 : 1; return LDAP_SUCCESS; } @@ -2114,7 +2357,7 @@ integerBitOrMatch( return LDAP_CONSTRAINT_VIOLATION; } - *matchp = (lValue | lAssertedValue) ? 0 : -1; + *matchp = ((lValue & lAssertedValue) != 0) ? 0 : -1; return LDAP_SUCCESS; } @@ -2124,7 +2367,6 @@ serialNumberAndIssuerValidate( struct berval *in ) { int rc; - int state; ber_len_t n; struct berval sn, i; if( in->bv_len < 3 ) return LDAP_INVALID_SYNTAX; @@ -2158,12 +2400,11 @@ serialNumberAndIssuerPretty( void *ctx ) { int rc; - int state; ber_len_t n; struct berval sn, i, newi; - assert( val ); - assert( out ); + assert( val != NULL ); + assert( out != NULL ); Debug( LDAP_DEBUG_TRACE, ">>> serialNumberAndIssuerPretty: <%s>\n", val->bv_val, 0, 0 ); @@ -2198,13 +2439,14 @@ serialNumberAndIssuerPretty( out->bv_len = sn.bv_len + newi.bv_len + 1; out->bv_val = slap_sl_realloc( newi.bv_val, out->bv_len + 1, ctx ); - if( BER_BVISNULL( out ) ) { + if( out->bv_val == NULL ) { + out->bv_len = 0; slap_sl_free( newi.bv_val, ctx ); return LDAP_OTHER; } /* push issuer over */ - AC_MEMCPY( &out->bv_val[sn.bv_len+1], newi.bv_val, newi.bv_len ); + AC_MEMCPY( &out->bv_val[sn.bv_len+1], out->bv_val, newi.bv_len ); /* insert sn and "$" */ AC_MEMCPY( out->bv_val, sn.bv_val, sn.bv_len ); out->bv_val[sn.bv_len] = '$'; @@ -2233,12 +2475,11 @@ serialNumberAndIssuerNormalize( void *ctx ) { int rc; - int state; ber_len_t n; struct berval sn, i, newi; - assert( val ); - assert( out ); + assert( val != NULL ); + assert( out != NULL ); Debug( LDAP_DEBUG_TRACE, ">>> serialNumberAndIssuerNormalize: <%s>\n", val->bv_val, 0, 0 ); @@ -2275,13 +2516,14 @@ serialNumberAndIssuerNormalize( out->bv_len = sn.bv_len + newi.bv_len + 1; out->bv_val = slap_sl_realloc( newi.bv_val, out->bv_len + 1, ctx ); - if( BER_BVISNULL( out ) ) { + if( out->bv_val == NULL ) { + out->bv_len = 0; slap_sl_free( newi.bv_val, ctx ); return LDAP_OTHER; } /* push issuer over */ - AC_MEMCPY( &out->bv_val[sn.bv_len+1], newi.bv_val, newi.bv_len ); + AC_MEMCPY( &out->bv_val[sn.bv_len+1], out->bv_val, newi.bv_len ); /* insert sn and "$" */ AC_MEMCPY( out->bv_val, sn.bv_val, sn.bv_len ); out->bv_val[sn.bv_len] = '$'; @@ -2662,7 +2904,6 @@ int generalizedTimeIndexer( void *ctx ) { int i, j; - size_t slen, mlen; BerVarray keys; char tmp[5]; BerValue bvtmp; /* 40 bit index */ @@ -3182,22 +3423,14 @@ static slap_syntax_defs_rec syntax_defs[] = { serialNumberAndIssuerValidate, serialNumberAndIssuerPretty}, -#ifdef SLAPD_ACI_ENABLED - /* OpenLDAP Experimental Syntaxes */ - {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )", - SLAP_SYNTAX_HIDE, - UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */, - NULL}, -#endif - #ifdef SLAPD_AUTHPASSWD /* needs updating */ {"( 1.3.6.1.4.1.4203.666.2.2 DESC 'OpenLDAP authPassword' )", SLAP_SYNTAX_HIDE, NULL, NULL}, #endif - {"( 1.3.6.1.4.1.4203.666.2.6 DESC 'UUID' )", - SLAP_SYNTAX_HIDE, UUIDValidate, NULL}, + {"( 1.3.6.1.1.16.1 DESC 'UUID' )", + 0, UUIDValidate, NULL}, {"( 1.3.6.1.4.1.4203.666.11.2.1 DESC 'CSN' )", SLAP_SYNTAX_HIDE, csnValidate, NULL}, @@ -3205,6 +3438,13 @@ static slap_syntax_defs_rec syntax_defs[] = { /* OpenLDAP Void Syntax */ {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" , SLAP_SYNTAX_HIDE, inValidate, NULL}, + +#ifdef SLAP_AUTHZ_SYNTAX + /* FIXME: OID is unused, but not registered yet */ + {"( 1.3.6.1.4.1.4203.666.2.7 DESC 'OpenLDAP authz' )", + SLAP_SYNTAX_HIDE, authzValidate, authzPretty}, +#endif /* SLAP_AUTHZ_SYNTAX */ + {NULL, 0, NULL, NULL} }; @@ -3371,7 +3611,7 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.4 NAME 'caseIgnoreSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", SLAP_MR_SUBSTR, directoryStringSyntaxes, - NULL, UTF8StringNormalize, octetStringSubstringsMatch, + NULL, UTF8StringNormalize, directoryStringSubstringsMatch, octetStringSubstringsIndexer, octetStringSubstringsFilter, "caseIgnoreMatch" }, @@ -3392,7 +3632,7 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 2.5.13.7 NAME 'caseExactSubstringsMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.58 )", SLAP_MR_SUBSTR, directoryStringSyntaxes, - NULL, UTF8StringNormalize, octetStringSubstringsMatch, + NULL, UTF8StringNormalize, directoryStringSubstringsMatch, octetStringSubstringsIndexer, octetStringSubstringsFilter, "caseExactMatch" }, @@ -3501,7 +3741,7 @@ static slap_mrule_defs_rec mrule_defs[] = { "SYNTAX 1.3.6.1.4.1.1466.115.121.1.34 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, NULL, uniqueMemberNormalize, uniqueMemberMatch, - NULL, NULL, + uniqueMemberIndexer, uniqueMemberFilter, NULL }, {"( 2.5.13.24 NAME 'protocolInformationMatch' " @@ -3578,14 +3818,14 @@ static slap_mrule_defs_rec mrule_defs[] = { {"( 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, - NULL, IA5StringNormalize, octetStringSubstringsMatch, + NULL, IA5StringNormalize, directoryStringSubstringsMatch, octetStringSubstringsIndexer, octetStringSubstringsFilter, "caseIgnoreIA5Match" }, {"( 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, NULL, - NULL, IA5StringNormalize, octetStringSubstringsMatch, + NULL, IA5StringNormalize, directoryStringSubstringsMatch, octetStringSubstringsIndexer, octetStringSubstringsFilter, "caseExactIA5Match" }, @@ -3599,15 +3839,6 @@ static slap_mrule_defs_rec mrule_defs[] = { NULL}, #endif -#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_HIDE | SLAP_MR_EQUALITY, NULL, - NULL, NULL, OpenLDAPaciMatch, - NULL, NULL, - NULL}, -#endif - {"( 1.2.840.113556.1.4.803 NAME 'integerBitAndMatch' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )", SLAP_MR_EXT, NULL, @@ -3622,16 +3853,16 @@ static slap_mrule_defs_rec mrule_defs[] = { NULL, NULL, "integerMatch" }, - {"( 1.3.6.1.4.1.4203.666.4.6 NAME 'UUIDMatch' " - "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )", - SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL, + {"( 1.3.6.1.1.16.2 NAME 'UUIDMatch' " + "SYNTAX 1.3.6.1.1.16.1 )", + SLAP_MR_EQUALITY, NULL, NULL, UUIDNormalize, octetStringMatch, octetStringIndexer, octetStringFilter, NULL}, - {"( 1.3.6.1.4.1.4203.666.4.7 NAME 'UUIDOrderingMatch' " - "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )", - SLAP_MR_HIDE | SLAP_MR_ORDERING, NULL, + {"( 1.3.6.1.1.16.3 NAME 'UUIDOrderingMatch' " + "SYNTAX 1.3.6.1.1.16.1 )", + SLAP_MR_ORDERING, NULL, NULL, UUIDNormalize, octetStringOrderingMatch, octetStringIndexer, octetStringFilter, "UUIDMatch"}, @@ -3650,6 +3881,16 @@ static slap_mrule_defs_rec mrule_defs[] = { NULL, NULL, "CSNMatch" }, +#ifdef SLAP_AUTHZ_SYNTAX + /* FIXME: OID is unused, but not registered yet */ + {"( 1.3.6.1.4.1.4203.666.4.12 NAME 'authzMatch' " + "SYNTAX 1.3.6.1.4.1.4203.666.2.7 )", + SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL, + NULL, authzNormalize, authzMatch, + NULL, NULL, + NULL}, +#endif /* SLAP_AUTHZ_SYNTAX */ + {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL, NULL, NULL, NULL } @@ -3708,4 +3949,7 @@ schema_destroy( void ) mr_destroy(); mru_destroy(); syn_destroy(); + + ldap_pvt_thread_mutex_destroy( &ad_undef_mutex ); + ldap_pvt_thread_mutex_destroy( &oc_undef_mutex ); }