From 4d1a81fe51bd5a74b79b6de65087feb5f5c1bfa6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Julio=20S=C3=A1nchez=20Fern=C3=A1ndez?= Date: Thu, 8 Jul 1999 18:55:40 +0000 Subject: [PATCH] First step in third stage of new schema support. The backend compiles, but it is incomplete. The rest of slapd is broken, so don't even think about trying it. --- servers/slapd/back-ldbm/attr.c | 246 ++++++++++++++++----- servers/slapd/back-ldbm/back-ldbm.h | 16 +- servers/slapd/back-ldbm/bind.c | 124 ++--------- servers/slapd/back-ldbm/compare.c | 9 +- servers/slapd/back-ldbm/filterindex.c | 252 +++++++++------------- servers/slapd/back-ldbm/group.c | 12 +- servers/slapd/back-ldbm/index.c | 202 +++++------------ servers/slapd/back-ldbm/modify.c | 16 +- servers/slapd/back-ldbm/proto-back-ldbm.h | 7 +- servers/slapd/back-ldbm/search.c | 8 +- 10 files changed, 411 insertions(+), 481 deletions(-) diff --git a/servers/slapd/back-ldbm/attr.c b/servers/slapd/back-ldbm/attr.c index a5ece146fb..68997eec79 100644 --- a/servers/slapd/back-ldbm/attr.c +++ b/servers/slapd/back-ldbm/attr.c @@ -10,6 +10,16 @@ #include "slap.h" #include "back-ldbm.h" +static char **default_indexes = NULL; + +static char *all_basic_indexes[] = { + "pres", + "eq", + "approx", + "sub", + NULL +}; + static int ainfo_type_cmp( char *type, @@ -45,8 +55,24 @@ ainfo_dup( * if the duplicate definition is because we initialized the attr, * just add what came from the config file. otherwise, complain. */ - if ( a->ai_indexmask & INDEX_FROMINIT ) { - a->ai_indexmask |= b->ai_indexmask; + if ( a->ai_predef ) { + int i_old, i_add; + + for ( i_add = 0; b->ai_indexes[i_add]; i_add++ ) { + for ( i_old = 0; a->ai_indexes[i_old]; i_old++ ) { + if ( a->ai_indexes[i_old] == + b->ai_indexes[i_add] ) { + break; + } + } + if ( a->ai_indexes[i_old] == NULL ) { + /* Was not there, add it */ + a->ai_indexes = ch_realloc( a->ai_indexes, + (i_old+1) * sizeof( MatchingRule * ) ); + a->ai_indexes[i_old] = b->ai_indexes[i_add]; + a->ai_indexes[i_old+1] = NULL; + } + } return( 1 ); } @@ -55,30 +81,118 @@ ainfo_dup( } void -attr_masks( +attr_indexes( struct ldbminfo *li, - char *type, - int *indexmask, - int *syntaxmask + AttributeType *at, + MatchingRule ***indexes ) { struct attrinfo *a; + char *at_cn; - *indexmask = 0; - *syntaxmask = 0; - if ( (a = (struct attrinfo *) avl_find( li->li_attrs, type, + at_cn = at_canonical_name( at ); + *indexes = NULL; + if ( (a = (struct attrinfo *) avl_find( li->li_attrs, at_cn, (AVL_CMP) ainfo_type_cmp )) == NULL ) { - if ( (a = (struct attrinfo *) avl_find( li->li_attrs, "default", - (AVL_CMP) ainfo_type_cmp )) == NULL ) { - return; + /* + * ARGGHH!! FIXME + * we cannot do this!!! + * We would need a mutex to update the backend li_attrs!! + * If we build the list on the fly, then we have the + * problem on who is going to free it. It seems we always + * have to return a new array and the caller has to free + * it. Always. C'est dommage... + */ + int i, j, nind; + MatchingRule *mr; + + for ( nind = 0; default_indexes[nind]; nind++ ) + ; + a = (struct attrinfo *) ch_malloc( sizeof(struct attrinfo) ); + a->ai_type = ch_strdup( at_cn ); + a->ai_indexes = + ch_calloc( nind + 1, sizeof( MatchingRule * ) ); + j = 0; + for ( i = 0; default_indexes[i]; i++ ) { + if ( strncasecmp( default_indexes[i], + "pres", 4 ) == 0 ) { + a->ai_indexes[j++] = global_mr_presence; + } else if ( strncasecmp( default_indexes[i], + "eq", 2 ) == 0 ) { + if ( at->sat_equality ) { + a->ai_indexes[j++] = + at->sat_equality; + } + } else if ( strncasecmp( default_indexes[i], + "approx", 6 ) == 0 ) { + a->ai_indexes[j++] = global_mr_approx; + } else if ( strncasecmp( default_indexes[i], + "sub", 3 ) == 0 ) { + if ( at->sat_substr ) { + a->ai_indexes[j++] = + at->sat_substr; + } + } else if ( strncasecmp( default_indexes[i], + "none", 4 ) == 0 ) { + /* FIXME: Sheesh */ + j = 0; + a->ai_indexes[j] = NULL; + } else if ( ( mr = mr_find( default_indexes[i] ) ) != + NULL ) { + a->ai_indexes[j++] = mr; + } + } + a->ai_predef = 0; + switch (avl_insert( &li->li_attrs, (caddr_t) a, + (AVL_CMP) ainfo_cmp, (AVL_DUP) ainfo_dup )) + { + case 1: /* duplicate - updating init version */ + case 2: /* user duplicate - ignore and warn */ + /* FIXME: syslog something here, something wrong + is going on */ + free( a->ai_type ); + free( a->ai_indexes ); + free( (char *) a ); + break; + + default:; /* inserted ok */ + /* FALL */ } } - *indexmask = a->ai_indexmask; - if ( strcasecmp( a->ai_type, "default" ) == 0 ) { - *syntaxmask = attr_syntax( type ); - } else { - *syntaxmask = a->ai_syntaxmask; + *indexes = a->ai_indexes; +} + +static void +default_index_config( + char *fname, + int lineno, + char **indexes +) +{ + int i, j; + + for ( i = 0; indexes[i]; i++ ) + ; + default_indexes = ch_calloc( i, sizeof( char * ) ); + + j = 0; + for ( i = 0; indexes[i]; i++ ) { + if ( strncasecmp( indexes[j], "pres", 4 ) == 0 || + strncasecmp( indexes[j], "eq", 2 ) == 0 || + strncasecmp( indexes[j], "approx", 6 ) == 0 || + strncasecmp( indexes[j], "sub", 3 ) == 0 || + strncasecmp( indexes[j], "none", 4 ) == 0 || + mr_find( indexes[j] ) != NULL ) { + default_indexes[j++] = ch_strdup( indexes[i] ); + } else { + fprintf( stderr, + "%s: line %d: unknown index type \"%s\" (ignored)\n", + fname, lineno, indexes[j] ); + fprintf( stderr, + "valid index types are \"pres\", \"eq\", \"approx\", \"sub\" or \n" ); + } } + default_indexes[j] = NULL; } void @@ -91,62 +205,93 @@ attr_index_config( int init ) { - int i, j; + int i, j, k, nind; char **attrs, **indexes; + AttributeType *at; + MatchingRule *mr; struct attrinfo *a; + indexes = NULL; attrs = str2charray( argv[0], "," ); if ( argc > 1 ) { indexes = str2charray( argv[1], "," ); + } else { + indexes = all_basic_indexes; } + for ( nind = 0; indexes[nind]; nind++ ) + ; for ( i = 0; attrs[i] != NULL; i++ ) { + if ( !strcasecmp( attrs[i], "default" ) ) { + default_index_config( fname, lineno, indexes ); + continue; + } + at = at_find( attrs[i] ); + if ( !at ) { + fprintf( stderr, + "%s: line %d: unknown attribute type \"%s\" (ignored)\n", + fname, lineno, attrs[i] ); + continue; + } + k = 0; a = (struct attrinfo *) ch_malloc( sizeof(struct attrinfo) ); a->ai_type = ch_strdup( attrs[i] ); - a->ai_syntaxmask = attr_syntax( a->ai_type ); - if ( argc == 1 ) { - a->ai_indexmask = (INDEX_PRESENCE | INDEX_EQUALITY | - INDEX_APPROX | INDEX_SUB); - } else { - a->ai_indexmask = 0; - for ( j = 0; indexes[j] != NULL; j++ ) { - if ( strncasecmp( indexes[j], "pres", 4 ) - == 0 ) { - a->ai_indexmask |= INDEX_PRESENCE; - } else if ( strncasecmp( indexes[j], "eq", 2 ) - == 0 ) { - a->ai_indexmask |= INDEX_EQUALITY; - } else if ( strncasecmp( indexes[j], "approx", - 6 ) == 0 ) { - a->ai_indexmask |= INDEX_APPROX; - } else if ( strncasecmp( indexes[j], "sub", 3 ) - == 0 ) { - a->ai_indexmask |= INDEX_SUB; - } else if ( strncasecmp( indexes[j], "none", 4 ) + a->ai_indexes = + ch_calloc( nind + 1, sizeof( MatchingRule * ) ); + for ( j = 0; indexes[j] != NULL; j++ ) { + if ( strncasecmp( indexes[j], "pres", 4 ) == 0 ) { + a->ai_indexes[k++] = global_mr_presence; + } else if ( strncasecmp( indexes[j], "eq", 2 ) == 0 ) { + if ( at->sat_equality ) { + a->ai_indexes[k++] = + at->sat_equality; + } else { + fprintf( stderr, +"%s: line %d: attribute type \"%s\" does not have an equality matching rule\n", + fname, lineno, attrs[i] ); + + } + } else if ( strncasecmp( indexes[j], "approx", + 6 ) == 0 ) { + a->ai_indexes[k++] = global_mr_approx; + } else if ( strncasecmp( indexes[j], "sub", 3 ) == 0 ) { - if ( a->ai_indexmask != 0 ) { - fprintf( stderr, -"%s: line %d: index type \"none\" cannot be combined with other types\n", - fname, lineno ); - } - a->ai_indexmask = 0; + if ( at->sat_substr ) { + a->ai_indexes[k++] = + at->sat_substr; } else { fprintf( stderr, - "%s: line %d: unknown index type \"%s\" (ignored)\n", - fname, lineno, indexes[j] ); +"%s: line %d: attribute type \"%s\" does not have a substrings matching rule\n", + fname, lineno, attrs[i] ); + + } + } else if ( strncasecmp( indexes[j], "none", 4 ) + == 0 ) { + if ( a->ai_indexes[0] ) { fprintf( stderr, - "valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n" ); +"%s: line %d: index type \"none\" cannot be combined with other types\n", + fname, lineno ); } + /* FIXME: Possible leak */ + k = 0; + a->ai_indexes[k] = NULL; + } else if ( ( mr = mr_find( indexes[j] ) ) != NULL ) { + a->ai_indexes[k++] = mr; + } else { + fprintf( stderr, + "%s: line %d: unknown index type \"%s\" (ignored)\n", + fname, lineno, indexes[j] ); + fprintf( stderr, + "valid index types are \"pres\", \"eq\", \"approx\", \"sub\", or \n" ); } } - if ( init ) { - a->ai_indexmask |= INDEX_FROMINIT; - } + a->ai_predef = init; switch (avl_insert( &li->li_attrs, (caddr_t) a, (AVL_CMP) ainfo_cmp, (AVL_DUP) ainfo_dup )) { case 1: /* duplicate - updating init version */ free( a->ai_type ); + free( a->ai_indexes ); free( (char *) a ); break; @@ -155,6 +300,7 @@ attr_index_config( "%s: line %d: duplicate index definition for attr \"%s\" (ignored)\n", fname, lineno, a->ai_type ); free( a->ai_type ); + free( a->ai_indexes ); free( (char *) a ); break; diff --git a/servers/slapd/back-ldbm/back-ldbm.h b/servers/slapd/back-ldbm/back-ldbm.h index 267bbcffa6..3545ab3783 100644 --- a/servers/slapd/back-ldbm/back-ldbm.h +++ b/servers/slapd/back-ldbm/back-ldbm.h @@ -96,20 +96,8 @@ struct dbcache { /* for the cache of attribute information (which are indexed, etc.) */ struct attrinfo { char *ai_type; /* type name (cn, sn, ...) */ - int ai_indexmask; /* how the attr is indexed */ -#define INDEX_PRESENCE 0x01 -#define INDEX_EQUALITY 0x02 -#define INDEX_APPROX 0x04 -#define INDEX_SUB 0x08 -#define INDEX_UNKNOWN 0x10 -#define INDEX_FROMINIT 0x20 - int ai_syntaxmask; /* what kind of syntax */ -/* ...from slap.h... -#define SYNTAX_CIS 0x01 -#define SYNTAX_CES 0x02 -#define SYNTAX_BIN 0x04 - ... etc. ... -*/ + int ai_predef; /* internal predefined pseudo-attr */ + MatchingRule **ai_indexes; /* Indexes to keep */ }; #define MAXDBCACHE 10 diff --git a/servers/slapd/back-ldbm/bind.c b/servers/slapd/back-ldbm/bind.c index 1821c9b4cc..503d3c5826 100644 --- a/servers/slapd/back-ldbm/bind.c +++ b/servers/slapd/back-ldbm/bind.c @@ -19,45 +19,6 @@ extern int krbv4_ldap_auth(); #endif -static int -crypted_value_find( - struct berval **vals, - struct berval *v, - int syntax, - int normalize, - struct berval *cred -) -{ - int i; - for ( i = 0; vals[i] != NULL; i++ ) { - if ( syntax != SYNTAX_BIN ) { - int result; - -#ifdef SLAPD_CRYPT - ldap_pvt_thread_mutex_lock( &crypt_mutex ); -#endif - - result = lutil_passwd( - (char*) cred->bv_val, - (char*) vals[i]->bv_val, - NULL ); - -#ifdef SLAPD_CRYPT - ldap_pvt_thread_mutex_unlock( &crypt_mutex ); -#endif - - return result; - - } else { - if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) { - return( 0 ); - } - } - } - - return( 1 ); -} - int ldbm_back_bind( Backend *be, @@ -65,7 +26,6 @@ ldbm_back_bind( Operation *op, char *dn, int method, - char *mech, struct berval *cred, char** edn ) @@ -87,36 +47,21 @@ ldbm_back_bind( /* get entry with reader lock */ if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) { /* allow noauth binds */ - rc = 1; - if ( method == LDAP_AUTH_SIMPLE ) { - if( cred->bv_len == 0 ) { - /* SUCCESS */ - send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL ); - - } else if ( be_isroot_pw( be, dn, cred ) ) { - *edn = ch_strdup( be_root_dn( be ) ); - rc = 0; /* front end will send result */ - - } else { - send_ldap_result( conn, op, - LDAP_NO_SUCH_OBJECT, matched, NULL ); - } - - } else if ( method == LDAP_AUTH_SASL ) { - if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) { - /* insert DIGEST calls here */ - send_ldap_result( conn, op, - LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL, NULL ); - - } else { - send_ldap_result( conn, op, - LDAP_AUTH_METHOD_NOT_SUPPORTED, NULL, NULL ); - } - + if ( method == LDAP_AUTH_SIMPLE && cred->bv_len == 0 ) { + /* + * bind successful, but return 1 so we don't + * authorize based on noauth credentials + */ + send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL ); + rc = 1; + } else if ( be_isroot_pw( be, dn, cred ) ) { + /* front end will send result */ + *edn = ch_strdup( be_root_dn( be ) ); + rc = 0; } else { send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, matched, NULL ); + rc = 1; } - if ( matched != NULL ) { free( matched ); } @@ -127,14 +72,6 @@ ldbm_back_bind( /* check for deleted */ - if ( ! access_allowed( be, conn, op, e, - "entry", NULL, ACL_AUTH ) ) - { - send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, "", "" ); - rc = 1; - goto return_results; - } - switch ( method ) { case LDAP_AUTH_SIMPLE: if ( cred->bv_len == 0 ) { @@ -154,14 +91,6 @@ ldbm_back_bind( goto return_results; } - if ( ! access_allowed( be, conn, op, e, - "userpassword", NULL, ACL_AUTH ) ) - { - send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, "", "" ); - rc = 1; - goto return_results; - } - if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) { send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH, NULL, NULL ); @@ -171,7 +100,8 @@ ldbm_back_bind( goto return_results; } - if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 ) + if ( global_mr_password_eq->smr_compare( cred, a->a_vals ) != + 0 ) { send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS, NULL, NULL ); @@ -185,39 +115,20 @@ ldbm_back_bind( #ifdef HAVE_KERBEROS case LDAP_AUTH_KRBV41: - if ( ! access_allowed( be, conn, op, e, - "krbname", NULL, ACL_AUTH ) ) - { - send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, "", "" ); - rc = 1; - goto return_results; - } - if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) { send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS, NULL, NULL ); - rc = 1; - goto return_results; - } - - if ( ! access_allowed( be, conn, op, e, - "krbname", NULL, ACL_AUTH ) ) - { - send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, "", "" ); - rc = 1; + rc = 0; goto return_results; } - sprintf( krbname, "%s%s%s@%s", ad.pname, *ad.pinst ? "." : "", ad.pinst, ad.prealm ); - - if ( (a = attr_find( e->e_attrs, "krbname" )) == NULL ) { /* * no krbName values present: check against DN */ if ( strcasecmp( dn, krbname ) == 0 ) { - rc = 0; + rc = 0; /* XXX wild ass guess */ break; } send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH, @@ -248,9 +159,6 @@ ldbm_back_bind( goto return_results; #endif - case LDAP_AUTH_SASL: - /* insert SASL code here */ - default: send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED, NULL, "auth method not supported" ); diff --git a/servers/slapd/back-ldbm/compare.c b/servers/slapd/back-ldbm/compare.c index fc6e171444..6b7d59c6aa 100644 --- a/servers/slapd/back-ldbm/compare.c +++ b/servers/slapd/back-ldbm/compare.c @@ -24,6 +24,7 @@ ldbm_back_compare( char *matched; Entry *e; Attribute *a; + AttributeType *at; int rc; /* get entry with reader lock */ @@ -49,7 +50,13 @@ ldbm_back_compare( goto return_results; } - if ( value_find( a->a_vals, &ava->ava_value, a->a_syntax, 1 ) == 0 ) + if ( (at = at_find( ava->ava_type )) == NULL ) { + send_ldap_result( conn, op, LDAP_NO_SUCH_ATTRIBUTE, "", "" ); + rc = 1; + goto return_results; + } + + if ( value_find( a->a_vals, &ava->ava_value, at->sat_equality, 1 ) == 0 ) send_ldap_result( conn, op, LDAP_COMPARE_TRUE, "", "" ); else send_ldap_result( conn, op, LDAP_COMPARE_FALSE, "", "" ); diff --git a/servers/slapd/back-ldbm/filterindex.c b/servers/slapd/back-ldbm/filterindex.c index 2c32d50d9f..bcc1b0d0e0 100644 --- a/servers/slapd/back-ldbm/filterindex.c +++ b/servers/slapd/back-ldbm/filterindex.c @@ -15,7 +15,7 @@ static ID_BLOCK *presence_candidates( Backend *be, char *type ); static ID_BLOCK *approx_candidates( Backend *be, Ava *ava ); static ID_BLOCK *list_candidates( Backend *be, Filter *flist, int ftype ); static ID_BLOCK *substring_candidates( Backend *be, Filter *f ); -static ID_BLOCK *substring_comp_candidates( Backend *be, char *type, char *val, int prepost ); +static ID_BLOCK *extensible_candidates( Backend *be, Mra *mra ); /* * test_filter - test a filter against a single entry. @@ -24,6 +24,66 @@ static ID_BLOCK *substring_comp_candidates( Backend *be, char *type, char *val, * >0 an ldap error code */ +ID_BLOCK * +index_candidates( + Backend *be, + AttributeType *at, + MatchingRule *mr, + struct berval *val +) +{ + struct berval *vals[2]; + struct berval **svals; + int i, j; + ID_BLOCK *idl, *idl1, *idl2, *tmp; + + /* + * First, decompose the value into its constituents. If the + * matching rule does not know how to do it, then it is + * understood to be just one constituent and identical to our + * input. + */ + if ( mr->smr_skeys ) { + mr->smr_skeys( val, &svals ); + } else { + vals[0] = val; + vals[1] = NULL; + svals = vals; + } + + idl = NULL; + assert( mr->smr_index != NULL ); + /* Now take each piece and compute the indexing stems for it */ + for ( i = 0; svals[i]; i++ ) { + struct berval *isvals[2]; + struct berval **ivals; + + isvals[0] = svals[i]; + isvals[1] = NULL; + mr->smr_index( isvals, &ivals ); + idl1 = NULL; + for ( j = 0; ivals[j]; j++ ) { + idl2 = index_read( be, at, mr, + ivals[j]->bv_val ); + tmp = idl1; + idl1 = idl_intersection( be, idl1, idl2 ); + idl_free( idl2 ); + idl_free( tmp ); + } + tmp = idl; + idl = idl_union( be, idl, idl1 ); + idl_free( idl1 ); + idl_free( tmp ); + ber_bvecfree( ivals ); + } + + if ( mr->smr_skeys ) { + ber_bvecfree( svals ); + } + return( idl ); +} + + ID_BLOCK * filter_candidates( Backend *be, @@ -66,6 +126,11 @@ filter_candidates( result = approx_candidates( be, &f->f_ava ); break; + case LDAP_FILTER_EXTENDED: + Debug( LDAP_DEBUG_FILTER, "\tEXTENSIBLE\n", 0, 0, 0 ); + result = extensible_candidates( be, &f->f_mra ); + break; + case LDAP_FILTER_AND: Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 ); result = list_candidates( be, f->f_and, LDAP_FILTER_AND ); @@ -99,13 +164,19 @@ ava_candidates( ) { ID_BLOCK *idl; + AttributeType *at; Debug( LDAP_DEBUG_TRACE, "=> ava_candidates 0x%x\n", type, 0, 0 ); switch ( type ) { case LDAP_FILTER_EQUALITY: - idl = index_read( be, ava->ava_type, INDEX_EQUALITY, - ava->ava_value.bv_val ); + at = at_find( ava->ava_type ); + if ( at && at->sat_equality ) { + idl = index_candidates( be, at, at->sat_equality, + &ava->ava_value ); + } else { + idl = NULL; + } break; case LDAP_FILTER_GE: @@ -132,44 +203,49 @@ presence_candidates( Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 ); - idl = index_read( be, type, 0, "*" ); + idl = index_read( be, at_find( type ), 0, "*" ); Debug( LDAP_DEBUG_TRACE, "<= presence_candidates %ld\n", idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); return( idl ); } +static ID_BLOCK * +extensible_candidates( + Backend *be, + Mra *mra +) +{ + AttributeType *at; + MatchingRule *mr; + ID_BLOCK *idl; + + Debug( LDAP_DEBUG_TRACE, "=> extensible_candidates\n", 0, 0, 0 ); + + at = at_find( mra->mra_type ); + mr = mr_find( mra->mra_rule ); + idl = index_candidates( be, at, mr, &mra->mra_value ); + /* FIXME: what about mra->mra_dnattrs */ + + Debug( LDAP_DEBUG_TRACE, "<= extensible_candidates %ld\n", + idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); + return( idl ); +} + static ID_BLOCK * approx_candidates( Backend *be, Ava *ava ) { - char *w, *c; - ID_BLOCK *idl, *tmp; + AttributeType *at; + ID_BLOCK *idl; Debug( LDAP_DEBUG_TRACE, "=> approx_candidates\n", 0, 0, 0 ); - idl = NULL; - for ( w = first_word( ava->ava_value.bv_val ); w != NULL; - w = next_word( w ) ) { - c = phonetic( w ); - if ( (tmp = index_read( be, ava->ava_type, INDEX_APPROX, c )) - == NULL ) { - free( c ); - idl_free( idl ); - Debug( LDAP_DEBUG_TRACE, "<= approx_candidates NULL\n", - 0, 0, 0 ); - return( NULL ); - } - free( c ); - - if ( idl == NULL ) { - idl = tmp; - } else { - idl = idl_intersection( be, idl, tmp ); - } - } + at = at_find( ava->ava_type ); + idl = index_candidates( be, at, global_mr_approx, + &ava->ava_value ); Debug( LDAP_DEBUG_TRACE, "<= approx_candidates %ld\n", idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); @@ -224,130 +300,16 @@ substring_candidates( ) { int i; - ID_BLOCK *idl, *tmp, *tmp2; + AttributeType *at; + ID_BLOCK *idl; Debug( LDAP_DEBUG_TRACE, "=> substring_candidates\n", 0, 0, 0 ); - idl = NULL; - - /* initial */ - if ( f->f_sub_initial != NULL ) { - if ( (int) strlen( f->f_sub_initial ) < SUBLEN - 1 ) { - idl = idl_allids( be ); - } else if ( (idl = substring_comp_candidates( be, f->f_sub_type, - f->f_sub_initial, '^' )) == NULL ) { - return( NULL ); - } - } - - /* final */ - if ( f->f_sub_final != NULL ) { - if ( (int) strlen( f->f_sub_final ) < SUBLEN - 1 ) { - tmp = idl_allids( be ); - } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type, - f->f_sub_final, '$' )) == NULL ) { - idl_free( idl ); - return( NULL ); - } - - if ( idl == NULL ) { - idl = tmp; - } else { - tmp2 = idl; - idl = idl_intersection( be, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); - } - } - - for ( i = 0; f->f_sub_any != NULL && f->f_sub_any[i] != NULL; i++ ) { - if ( (int) strlen( f->f_sub_any[i] ) < SUBLEN ) { - tmp = idl_allids( be ); - } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type, - f->f_sub_any[i], 0 )) == NULL ) { - idl_free( idl ); - return( NULL ); - } - - if ( idl == NULL ) { - idl = tmp; - } else { - tmp2 = idl; - idl = idl_intersection( be, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); - } - } + at = at_find( f->f_sub_type ); + idl = index_candidates( be, at, global_mr_approx, + &f->f_sub_value ); Debug( LDAP_DEBUG_TRACE, "<= substring_candidates %ld\n", idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); return( idl ); } - -static ID_BLOCK * -substring_comp_candidates( - Backend *be, - char *type, - char *val, - int prepost -) -{ - int i, len; - ID_BLOCK *idl, *tmp, *tmp2; - char *p; - char buf[SUBLEN + 1]; - - Debug( LDAP_DEBUG_TRACE, "=> substring_comp_candidates\n", 0, 0, 0 ); - - len = strlen( val ); - idl = NULL; - - /* prepend ^ for initial substring */ - if ( prepost == '^' ) { - buf[0] = '^'; - for ( i = 0; i < SUBLEN - 1; i++ ) { - buf[i + 1] = val[i]; - } - buf[SUBLEN] = '\0'; - - if ( (idl = index_read( be, type, INDEX_SUB, buf )) == NULL ) { - return( NULL ); - } - } else if ( prepost == '$' ) { - p = val + len - SUBLEN + 1; - for ( i = 0; i < SUBLEN - 1; i++ ) { - buf[i] = p[i]; - } - buf[SUBLEN - 1] = '$'; - buf[SUBLEN] = '\0'; - - if ( (idl = index_read( be, type, INDEX_SUB, buf )) == NULL ) { - return( NULL ); - } - } - - for ( p = val; p < (val + len - SUBLEN + 1); p++ ) { - for ( i = 0; i < SUBLEN; i++ ) { - buf[i] = p[i]; - } - buf[SUBLEN] = '\0'; - - if ( (tmp = index_read( be, type, INDEX_SUB, buf )) == NULL ) { - idl_free( idl ); - return( NULL ); - } - - if ( idl == NULL ) { - idl = tmp; - } else { - tmp2 = idl; - idl = idl_intersection( be, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); - } - } - - Debug( LDAP_DEBUG_TRACE, "<= substring_comp_candidates %ld\n", - idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); - return( idl ); -} diff --git a/servers/slapd/back-ldbm/group.c b/servers/slapd/back-ldbm/group.c index 652892c828..53011bbaed 100644 --- a/servers/slapd/back-ldbm/group.c +++ b/servers/slapd/back-ldbm/group.c @@ -12,6 +12,7 @@ #include "proto-back-ldbm.h" +#ifdef SLAPD_ACLGROUPS /* return 0 IFF op_dn is a value in member attribute * of entry with gr_dn AND that entry has an objectClass * value of groupOfNames @@ -31,6 +32,8 @@ ldbm_back_group( char *matched; Attribute *objectClass; Attribute *member; + AttributeType *at_objectClass; + AttributeType *at_member; int rc; Debug( LDAP_DEBUG_TRACE, @@ -77,6 +80,8 @@ ldbm_back_group( */ rc = 1; + at_objectClass = at_find( "objectClass" ); + at_member = at_find( "member" ); if ((objectClass = attr_find(e->e_attrs, "objectclass")) == NULL) { Debug( LDAP_DEBUG_TRACE, "<= ldbm_back_group: failed to find objectClass\n", 0, 0, 0 ); } @@ -95,12 +100,14 @@ ldbm_back_group( bvMembers.bv_val = op_ndn; bvMembers.bv_len = strlen( op_ndn ); - if (value_find(objectClass->a_vals, &bvObjectClass, SYNTAX_CIS, 1) != 0) { + if (value_find(objectClass->a_vals, &bvObjectClass, + at_objectClass->sat_equality, 1) != 0) { Debug( LDAP_DEBUG_TRACE, "<= ldbm_back_group: failed to find %s in objectClass\n", objectclassValue, 0, 0 ); } - else if (value_find(member->a_vals, &bvMembers, SYNTAX_CIS, 1) != 0) { + else if (value_find(member->a_vals, &bvMembers, + at_member->sat_equality, 1) != 0) { Debug( LDAP_DEBUG_ACL, "<= ldbm_back_group: \"%s\" not in \"%s\": %s\n", op_ndn, gr_ndn, groupattrName ); @@ -121,4 +128,5 @@ ldbm_back_group( Debug( LDAP_DEBUG_ARGS, "ldbm_back_group: rc: %d\n", rc, 0, 0 ); return(rc); } +#endif /* SLAPD_ACLGROUPS */ diff --git a/servers/slapd/back-ldbm/index.c b/servers/slapd/back-ldbm/index.c index 5f8b7cec64..7d17e13dd7 100644 --- a/servers/slapd/back-ldbm/index.c +++ b/servers/slapd/back-ldbm/index.c @@ -12,13 +12,13 @@ static int change_value(Backend *be, struct dbcache *db, - char *type, - int indextype, + AttributeType *at, + MatchingRule *mr, char *val, ID id, int (*idl_func)(Backend *, struct dbcache *, Datum, ID)); -static int index2prefix(int indextype); +static int index2prefix(AttributeType *at, MatchingRule *mr); int index_add_entry( @@ -45,9 +45,8 @@ index_add_entry( /* add the dn to the indexes */ { - char *dn = ch_strdup("dn"); + AttributeType *dn = at_find( "*dn" ); index_change_values( be, dn, bvals, e->e_id, __INDEX_ADD_OP ); - free( dn ); } free( bv.bv_val ); @@ -55,7 +54,11 @@ index_add_entry( /* add each attribute to the indexes */ for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) { - index_change_values( be, ap->a_type, ap->a_vals, e->e_id, + AttributeType *at; + at = at_find( ap->a_type ); + if ( !at ) + continue; + index_change_values( be, at, ap->a_vals, e->e_id, __INDEX_ADD_OP ); } @@ -75,7 +78,10 @@ index_add_mods( for ( ; ml != NULL; ml = ml->ml_next ) { LDAPMod *mod = &ml->ml_mod; - + AttributeType *at; + at = at_find( mod->mod_type ); + if ( !at ) + continue; switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) { case LDAP_MOD_REPLACE: /* XXX: Delete old index data==>problem when this @@ -83,14 +89,14 @@ index_add_mods( */ case LDAP_MOD_ADD: rc = index_change_values( be, - mod->mod_type, + at, mod->mod_bvalues, id, __INDEX_ADD_OP); break; case LDAP_MOD_DELETE: rc = index_change_values( be, - mod->mod_type, + at, mod->mod_bvalues, id, __INDEX_DELETE_OP ); @@ -110,30 +116,30 @@ index_add_mods( ID_BLOCK * index_read( - Backend *be, - char *type, - int indextype, - char *val + Backend *be, + AttributeType *at, + MatchingRule *mr, + char *val ) { struct dbcache *db; Datum key; ID_BLOCK *idl; - int indexmask, syntax; char prefix; char *realval, *tmpval; char buf[BUFSIZ]; - char *at_cn; + int i; ldbm_datum_init( key ); - prefix = index2prefix( indextype ); + at_cn = at_canonical_name( at ); + + prefix = index2prefix( at, mr ); Debug( LDAP_DEBUG_TRACE, "=> index_read( \"%s\" \"%c\" \"%s\" )\n", - type, prefix, val ); + at_cn, prefix, val ); - attr_masks( be->be_private, type, &indexmask, &syntax ); - if ( ! (indextype & indexmask) ) { + if ( prefix == UNKNOWN_PREFIX ) { idl = idl_allids( be ); Debug( LDAP_DEBUG_TRACE, "<= index_read %ld candidates (allids - not indexed)\n", @@ -141,9 +147,6 @@ index_read( return( idl ); } - attr_normalize( type ); - at_cn = at_canonical_name( type ); - if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_WRCREAT )) == NULL ) { Debug( LDAP_DEBUG_ANY, @@ -189,8 +192,8 @@ static int change_value( Backend *be, struct dbcache *db, - char *type, - int indextype, + AttributeType *at, + MatchingRule *mr, char *val, ID id, int (*idl_func)(Backend *, struct dbcache *, Datum, ID) @@ -202,7 +205,7 @@ change_value( char *realval = val; char buf[BUFSIZ]; - char prefix = index2prefix( indextype ); + char prefix = index2prefix( at, mr ); ldbm_datum_init( key ); @@ -245,15 +248,15 @@ change_value( int index_change_values( Backend *be, - char *type, + AttributeType *at, struct berval **vals, ID id, unsigned int op ) { char *val, *p, *code, *w; - unsigned i, j, len; - int indexmask, syntax; + unsigned i, j, len, ind; + MatchingRule **indexes; char buf[SUBLEN + 1]; char vbuf[BUFSIZ]; char *bigbuf; @@ -265,9 +268,11 @@ index_change_values( char *at_cn; /* Attribute canonical name */ int mode; + at_cn = at_canonical_name( at ); + Debug( LDAP_DEBUG_TRACE, "=> index_change_values( \"%s\", %ld, op=%s )\n", - type, id, ((op == __INDEX_ADD_OP) ? "ADD" : "DELETE" ) ); + at_cn, id, ((op == __INDEX_ADD_OP) ? "ADD" : "DELETE" ) ); if (op == __INDEX_ADD_OP) { @@ -286,15 +291,12 @@ index_change_values( } - attr_normalize(type); - attr_masks( be->be_private, type, &indexmask, &syntax ); + attr_indexes( be->be_private, at, &indexes ); - if ( indexmask == 0 ) { + if ( indexes == NULL ) { return( 0 ); } - at_cn = at_canonical_name( type ); - if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, mode )) == NULL ) { Debug( LDAP_DEBUG_ANY, @@ -305,116 +307,23 @@ index_change_values( return( -1 ); } - - for ( i = 0; vals[i] != NULL; i++ ) { - /* - * presence index entry - */ - if ( indexmask & INDEX_PRESENCE ) { - - change_value( be, db, at_cn, INDEX_PRESENCE, - "*", id, idl_funct ); - - } + for ( ind = 0; indexes[ind] != NULL; ind++ ) { + struct berval **ivals; Debug( LDAP_DEBUG_TRACE, - "index_change_values syntax 0x%x syntax bin 0x%x\n", - syntax, SYNTAX_BIN, 0 ); - - if ( syntax & SYNTAX_BIN ) { + "index_change_values syntax %s matching rule %s\n", + syn_canonical_name( at->sat_syntax ), + mr_canonical_name( indexes[ind] ), 0 ); - ldbm_cache_close( be, db ); - return( 0 ); + if ( indexes[ind]->smr_index( vals, &ivals ) == 0 ) { - } - - bigbuf = NULL; - len = vals[i]->bv_len; + for ( i = 0; ivals[i] != NULL; i++ ) { - /* value + null */ - if ( len + 2 > sizeof(vbuf) ) { - bigbuf = (char *) ch_malloc( len + 1 ); - val = bigbuf; - } else { - val = vbuf; - } - (void) memcpy( val, vals[i]->bv_val, len ); - val[len] = '\0'; - - value_normalize( val, syntax ); - - /* value_normalize could change the length of val */ - len = strlen( val ); - - /* - * equality index entry - */ - if ( indexmask & INDEX_EQUALITY ) { - - change_value( be, db, at_cn, INDEX_EQUALITY, - val, id, idl_funct); - - } - - /* - * approximate index entry - */ - if ( indexmask & INDEX_APPROX ) { - for ( w = first_word( val ); w != NULL; - w = next_word( w ) ) { - if ( (code = phonetic( w )) != NULL ) { - change_value( be, - db, - at_cn, - INDEX_APPROX, - code, - id, - idl_funct ); - free( code ); - } - } - } - - /* - * substrings index entry - */ - if ( indexmask & INDEX_SUB ) { - /* leading and trailing */ - if ( len > SUBLEN - 2 ) { - buf[0] = '^'; - for ( j = 0; j < SUBLEN - 1; j++ ) { - buf[j + 1] = val[j]; - } - buf[SUBLEN] = '\0'; - - change_value( be, db, at_cn, INDEX_SUB, - buf, id, idl_funct ); - - p = val + len - SUBLEN + 1; - for ( j = 0; j < SUBLEN - 1; j++ ) { - buf[j] = p[j]; - } - buf[SUBLEN - 1] = '$'; - buf[SUBLEN] = '\0'; - - change_value( be, db, at_cn, INDEX_SUB, - buf, id, idl_funct ); - } - - /* any */ - for ( p = val; p < (val + len - SUBLEN + 1); p++ ) { - for ( j = 0; j < SUBLEN; j++ ) { - buf[j] = p[j]; - } - buf[SUBLEN] = '\0'; - - change_value( be, db, at_cn, INDEX_SUB, - buf, id, idl_funct ); + change_value( be, db, at, indexes[ind], + ivals[i]->bv_val, id, idl_funct ); } - } + ber_bvecfree( ivals ); - if ( bigbuf != NULL ) { - free( bigbuf ); } } ldbm_cache_close( be, db ); @@ -424,23 +333,20 @@ index_change_values( }/* int index_change_values() */ static int -index2prefix( int indextype ) +index2prefix( AttributeType *at, MatchingRule *mr ) { int prefix; + MatchingRule *tmr; + char buf[512]; - switch ( indextype ) { - case INDEX_EQUALITY: + if ( mr == at->sat_equality ) { prefix = EQ_PREFIX; - break; - case INDEX_APPROX: - prefix = APPROX_PREFIX; - break; - case INDEX_SUB: + } else if ( mr == at->sat_substr ) { prefix = SUB_PREFIX; - break; - default: + } else if ( mr == ( tmr = mr_find( "*approx" ) ) ) { + prefix = APPROX_PREFIX; + } else { prefix = UNKNOWN_PREFIX; - break; } return( prefix ); diff --git a/servers/slapd/back-ldbm/modify.c b/servers/slapd/back-ldbm/modify.c index 9ae8220543..df8aca12d9 100644 --- a/servers/slapd/back-ldbm/modify.c +++ b/servers/slapd/back-ldbm/modify.c @@ -33,9 +33,13 @@ add_lastmods( Operation *op, LDAPModList **modlist ) /* remove any attempts by the user to modify these attrs */ for ( m = modlist; *m != NULL; m = &(*m)->ml_next ) { - if ( oc_check_no_usermod_attr( (*m)->ml_type ) ) { + if ( strcasecmp( (*m)->ml_type, "modifytimestamp" ) == 0 || + strcasecmp( (*m)->ml_type, "modifiersname" ) == 0 || + strcasecmp( (*m)->ml_type, "createtimestamp" ) == 0 || + strcasecmp( (*m)->ml_type, "creatorsname" ) == 0 ) { + Debug( LDAP_DEBUG_TRACE, - "add_lastmods: found no user mod attr: %s\n", + "add_lastmods: found lastmod attr: %s\n", (*m)->ml_type, 0, 0 ); tmp = *m; *m = (*m)->ml_next; @@ -106,6 +110,7 @@ int ldbm_modify_internal( LDAPMod *mod; LDAPModList *ml; Attribute *a; + AttributeType *at; if ( ((be->be_lastmod == ON) || ((be->be_lastmod == UNDEFINED)&&(global_lastmod == ON))) @@ -146,8 +151,9 @@ int ldbm_modify_internal( && ((a = attr_find( e->e_attrs, mod->mod_type )) != NULL) ) { + at = at_find( mod->mod_type ); (void) index_change_values( be, - mod->mod_type, + at, a->a_vals, e->e_id, __INDEX_DELETE_OP); @@ -268,12 +274,14 @@ add_values( { int i; Attribute *a; + AttributeType *at; /* check if the values we're adding already exist */ if ( (a = attr_find( e->e_attrs, mod->mod_type )) != NULL ) { + at = at_find( mod->mod_type ); for ( i = 0; mod->mod_bvalues[i] != NULL; i++ ) { if ( value_find( a->a_vals, mod->mod_bvalues[i], - a->a_syntax, 3 ) == 0 ) { + at->sat_equality, 3 ) == 0 ) { return( LDAP_TYPE_OR_VALUE_EXISTS ); } } diff --git a/servers/slapd/back-ldbm/proto-back-ldbm.h b/servers/slapd/back-ldbm/proto-back-ldbm.h index a5066eff8b..8549825312 100644 --- a/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -25,8 +25,7 @@ char *derefDN LDAP_P(( * attr.c */ -void attr_masks LDAP_P(( struct ldbminfo *li, char *type, int *indexmask, - int *syntaxmask )); +void attr_indexes LDAP_P(( struct ldbminfo *li, AttributeType *at, MatchingRule ***indexes )); void attr_index_config LDAP_P(( struct ldbminfo *li, char *fname, int lineno, int argc, char **argv, int init )); #ifdef SLAP_CLEANUP @@ -128,12 +127,12 @@ ID idl_nextid LDAP_P(( ID_BLOCK *idl, ID id )); int index_add_entry LDAP_P(( Backend *be, Entry *e )); int index_add_mods LDAP_P(( Backend *be, LDAPModList *ml, ID id )); -ID_BLOCK * index_read LDAP_P(( Backend *be, char *type, int indextype, char *val )); +ID_BLOCK * index_read LDAP_P(( Backend *be, AttributeType *at, MatchingRule *mr, char *val )); /* Possible operations supported (op) by index_change_values() */ #define __INDEX_ADD_OP 0x0001 #define __INDEX_DELETE_OP 0x0002 int index_change_values LDAP_P(( Backend *be, - char *type, + AttributeType *at, struct berval **vals, ID id, unsigned int op )); diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c index 7ab4f5f761..338606405b 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -264,7 +264,7 @@ ldbm_back_search( } if (e) { switch ( send_search_entry( be, conn, op, e, - attrs, attrsonly, 0 ) ) { + attrs, attrsonly ) ) { case 0: /* entry sent ok */ nentries++; break; @@ -480,10 +480,8 @@ subtree_candidates( f->f_and = (Filter *) ch_malloc( sizeof(Filter) ); f->f_and->f_choice = LDAP_FILTER_SUBSTRINGS; f->f_and->f_sub_type = ch_strdup( "dn" ); - f->f_and->f_sub_initial = NULL; - f->f_and->f_sub_any = NULL; - f->f_and->f_sub_final = ch_strdup( base ); - value_normalize( f->f_and->f_sub_final, SYNTAX_CIS ); + build_substr_value( NULL, NULL, e->e_ndn, + &f->f_and->f_sub_value); f->f_and->f_next = filter; filter = f; } -- 2.39.5