#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,
* 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 );
}
}
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 <matchingrule>\n" );
+ }
}
+ default_indexes[j] = NULL;
}
void
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 <matchingrule>\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;
"%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;
/* 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
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,
Operation *op,
char *dn,
int method,
- char *mech,
struct berval *cred,
char** edn
)
/* 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 );
}
/* 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 ) {
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 );
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 );
#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,
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" );
char *matched;
Entry *e;
Attribute *a;
+ AttributeType *at;
int rc;
/* get entry with reader lock */
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, "", "" );
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.
* >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,
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 );
)
{
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:
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 );
)
{
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 );
-}
#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
char *matched;
Attribute *objectClass;
Attribute *member;
+ AttributeType *at_objectClass;
+ AttributeType *at_member;
int rc;
Debug( LDAP_DEBUG_TRACE,
*/
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 );
}
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 );
Debug( LDAP_DEBUG_ARGS, "ldbm_back_group: rc: %d\n", rc, 0, 0 );
return(rc);
}
+#endif /* SLAPD_ACLGROUPS */
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(
/* 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 );
/* 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 );
}
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
*/
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 );
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",
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,
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)
char *realval = val;
char buf[BUFSIZ];
- char prefix = index2prefix( indextype );
+ char prefix = index2prefix( at, mr );
ldbm_datum_init( key );
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;
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) {
}
- 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,
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 );
}/* 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 );
/* 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;
LDAPMod *mod;
LDAPModList *ml;
Attribute *a;
+ AttributeType *at;
if ( ((be->be_lastmod == ON)
|| ((be->be_lastmod == UNDEFINED)&&(global_lastmod == ON)))
&& ((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);
{
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 );
}
}
* 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
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 ));
}
if (e) {
switch ( send_search_entry( be, conn, op, e,
- attrs, attrsonly, 0 ) ) {
+ attrs, attrsonly ) ) {
case 0: /* entry sent ok */
nentries++;
break;
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;
}