From 4091381660aa914ca587904f99bae98aa25b6530 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Mon, 28 Feb 2000 21:16:05 +0000 Subject: [PATCH] Yet another round of SLAPD_SCHEMA_NOT_COMPAT changes, including: limited subtype support, modlist handling, filter updates, lastmod attribute handling. --- servers/slapd/acl.c | 21 +--- servers/slapd/ad.c | 68 +++++++---- servers/slapd/add.c | 28 ++++- servers/slapd/attr.c | 35 ++++-- servers/slapd/back-ldbm/compare.c | 39 ++++--- servers/slapd/back-ldbm/external.h | 9 ++ servers/slapd/back-ldbm/tools.c | 38 +++--- servers/slapd/entry.c | 4 +- servers/slapd/filterentry.c | 181 +++++++++++++---------------- servers/slapd/modify.c | 139 +++++++++++++++++----- servers/slapd/proto-slap.h | 11 ++ servers/slapd/result.c | 4 +- servers/slapd/schema_check.c | 6 +- servers/slapd/slap.h | 20 +++- servers/slapd/tools/slapindex.c | 77 +++++++++--- 15 files changed, 435 insertions(+), 245 deletions(-) diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 3cd6d076cd..4be6f7e54b 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -713,12 +713,7 @@ acl_check_modlist( } for ( i = 0; mlist->sml_bvalues[i] != NULL; i++ ) { if ( ! access_allowed( be, conn, op, e, -#ifdef SLAPD_SCHEMA_NOT_COMPAT - &mlist->sml_desc, -#else - mlist->sml_type, -#endif - mlist->sml_bvalues[i], ACL_WRITE ) ) + mlist->sml_desc, mlist->sml_bvalues[i], ACL_WRITE ) ) { return( 0 ); } @@ -728,12 +723,7 @@ acl_check_modlist( case LDAP_MOD_DELETE: if ( mlist->sml_bvalues == NULL ) { if ( ! access_allowed( be, conn, op, e, -#ifdef SLAPD_SCHEMA_NOT_COMPAT - &mlist->sml_desc, -#else - mlist->sml_type, -#endif - NULL, ACL_WRITE ) ) + mlist->sml_desc, NULL, ACL_WRITE ) ) { return( 0 ); } @@ -741,12 +731,7 @@ acl_check_modlist( } for ( i = 0; mlist->sml_bvalues[i] != NULL; i++ ) { if ( ! access_allowed( be, conn, op, e, -#ifdef SLAPD_SCHEMA_NOT_COMPAT - &mlist->sml_desc, -#else - mlist->sml_type, -#endif - mlist->sml_bvalues[i], ACL_WRITE ) ) + mlist->sml_desc, mlist->sml_bvalues[i], ACL_WRITE ) ) { return( 0 ); } diff --git a/servers/slapd/ad.c b/servers/slapd/ad.c index ba5ba09475..fee72fd68a 100644 --- a/servers/slapd/ad.c +++ b/servers/slapd/ad.c @@ -19,6 +19,25 @@ #include "slap.h" #ifdef SLAPD_SCHEMA_NOT_COMPAT +AttributeDescription *ad_dup( + AttributeDescription *desc ) +{ + AttributeDescription *ad; + + if( desc == NULL ) { + return NULL; + } + + ad = (AttributeDescription *) ch_malloc( sizeof(AttributeDescription) ); + + *ad = *desc; + + ad->ad_cname = ber_bvdup( ad->ad_cname ); + ad->ad_lang = ch_strdup( ad->ad_lang ); + + return ad; +} + void ad_free( AttributeDescription *ad, int freeit ) { @@ -171,6 +190,29 @@ done: return rtn; } +int is_ad_subtype( + AttributeDescription *sub, + AttributeDescription *super +) +{ + if( !is_at_subtype( sub->ad_type, super->ad_type ) ) { + return 0; + } + + if( super->ad_flags && ( super->ad_flags == sub->ad_flags )) { + return 0; + } + + if( super->ad_lang != NULL && ( sub->ad_lang == NULL + || strcasecmp( super->ad_lang, sub->ad_lang ))) + { + return 0; + } + + return 1; +} + + int ad_inlist( AttributeDescription *desc, char **attrs ) @@ -179,31 +221,17 @@ int ad_inlist( for( i=0; attrs[i] != NULL; i++ ) { AttributeDescription *ad = NULL; char *text; - int rc = slap_str2ad( attrs[i], &ad, &text ); - - if( rc != LDAP_SUCCESS ) { - goto cont; - } + int rc; + + rc = slap_str2ad( attrs[i], &ad, &text ); - if( !is_at_subtype( desc->ad_type, ad->ad_type ) ) { - goto cont; - } + if( rc != LDAP_SUCCESS ) continue; - if( ad->ad_flags && ( ad->ad_flags == desc->ad_flags )) { - goto cont; - } - - if( ad->ad_lang != NULL && ( desc->ad_lang == NULL - || strcasecmp( ad->ad_lang, desc->ad_lang ))) - { - goto cont; - } + rc = is_ad_subtype( desc, ad ); ad_free( ad, 1 ); - return 1; -cont: - ad_free( ad, 1 ); + if( rc ) return 1; } return 0; diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 3eabc95d5b..e7c6a82f42 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -306,8 +306,32 @@ static int slap_mods2entry( Entry **e, char **text ) { - *text = "Not yet implemented"; - return LDAP_NOT_SUPPORTED; + Attribute **tail = &(*e)->e_attrs; + assert( *tail == NULL ); + + for( ; mods != NULL; mods = mods->sml_next ) { + Attribute *attr; + + assert( mods->sml_op == LDAP_MOD_ADD ); + + attr = attr_find( (*e)->e_attrs, mods->sml_desc ); + + if( attr != NULL ) { + *text = "Attribute provided more than once"; + return LDAP_OPERATIONS_ERROR; + } + + attr = ch_calloc( 1, sizeof(Attribute) ); + + /* should check for duplicates */ + attr->a_vals = mods->sml_bvalues; + mods->sml_bvalues = NULL; + + *tail = attr; + tail = &attr->a_next; + } + + return LDAP_SUCCESS; } #else diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index 601e68c05f..6142407888 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -30,7 +30,7 @@ void attr_free( Attribute *a ) { #ifdef SLAPD_SCHEMA_NOT_COMPAT - ad_free( &a->a_desc, 0 ); + ad_free( a->a_desc, 1 ); #else free( a->a_type ); #endif @@ -79,9 +79,7 @@ Attribute *attr_dup( Attribute *a ) } #ifdef SLAPD_SCHEMA_NOT_COMPAT - tmp->a_desc = a->a_desc; - tmp->a_desc.ad_cname = ber_bvdup( a->a_desc.ad_cname ); - tmp->a_desc.ad_lang = ch_strdup( a->a_desc.ad_lang ); + tmp->a_desc = ad_dup( a->a_desc ); #else tmp->a_type = ch_strdup( a->a_type ); tmp->a_syntax = a->a_syntax; @@ -210,6 +208,28 @@ attr_merge( return( value_add( &(*a)->a_vals, vals ) ); } +#ifdef SLAPD_SCHEMA_NOT_COMPAT +/* + * attrs_find - find attribute(s) by AttributeDescription + * returns next attribute which is subtype of provided description. + */ + +Attribute * +attrs_find( + Attribute *a, + AttributeDescription *desc +) +{ + for ( ; a != NULL; a = a->a_next ) { + if ( is_ad_subtype( a->a_desc, desc ) == 0 ) { + return( a ); + } + } + + return( NULL ); +} +#endif + /* * attr_find - find attribute by type */ @@ -226,12 +246,13 @@ attr_find( { for ( ; a != NULL; a = a->a_next ) { #ifdef SLAPD_SCHEMA_NOT_COMPAT - /* not yet implemented */ + if ( ad_cmp( a->a_desc, desc ) == 0 ) #else - if ( strcasecmp( a->a_type, type ) == 0 ) { + if ( strcasecmp( a->a_type, type ) == 0 ) +#endif + { return( a ); } -#endif } return( NULL ); diff --git a/servers/slapd/back-ldbm/compare.c b/servers/slapd/back-ldbm/compare.c index f594a2b83b..9c5bacaabc 100644 --- a/servers/slapd/back-ldbm/compare.c +++ b/servers/slapd/back-ldbm/compare.c @@ -94,30 +94,39 @@ ldbm_back_compare( goto return_results; } + rc = LDAP_NO_SUCH_ATTRIBUTE; + #ifdef SLAPD_SCHEMA_NOT_COMPAT - if ( (a = attr_find( e->e_attrs, ava->aa_desc )) == NULL ) + for(a = attrs_find( e->e_attrs, ava->aa_desc ); + a != NULL; + a = attrs_find( a, ava->aa_desc )) #else - if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) + if ((a = attr_find( e->e_attrs, ava->ava_type )) != NULL ) #endif { - send_ldap_result( conn, op, LDAP_NO_SUCH_ATTRIBUTE, - NULL, NULL, NULL, NULL ); - rc = 1; - goto return_results; - } + rc = LDAP_COMPARE_FALSE; #ifdef SLAPD_SCHEMA_NOT_COMPAT - /* not yet implemented */ + /* not yet implemented */ #else - if ( value_find( a->a_vals, &ava->ava_value, a->a_syntax, 1 ) == 0 ) - send_ldap_result( conn, op, LDAP_COMPARE_TRUE, - NULL, NULL, NULL, NULL ); - else + if ( value_find( a->a_vals, &ava->ava_value, a->a_syntax, 1 ) == 0 ) #endif - send_ldap_result( conn, op, LDAP_COMPARE_FALSE, - NULL, NULL, NULL, NULL ); + { + rc = LDAP_COMPARE_TRUE; +#ifdef SLAPD_SCHEMA_NOT_COMPAT + break; +#endif + } + + } + + send_ldap_result( conn, op, rc, + NULL, NULL, NULL, NULL ); + + if( rc != LDAP_NO_SUCH_ATTRIBUTE ) { + rc = 0; + } - rc = 0; return_results:; cache_return_entry_r( &li->li_cache, e ); diff --git a/servers/slapd/back-ldbm/external.h b/servers/slapd/back-ldbm/external.h index e58b4c57b7..ef617fb737 100644 --- a/servers/slapd/back-ldbm/external.h +++ b/servers/slapd/back-ldbm/external.h @@ -92,9 +92,18 @@ extern ID ldbm_tool_entry_first LDAP_P(( BackendDB *be )); extern ID ldbm_tool_entry_next LDAP_P(( BackendDB *be )); extern Entry* ldbm_tool_entry_get LDAP_P(( BackendDB *be, ID id )); extern ID ldbm_tool_entry_put LDAP_P(( BackendDB *be, Entry *e )); + +#ifdef SLAPD_SCHEMA_NOT_COMPAT +extern int ldbm_tool_index_attr LDAP_P(( BackendDB *be, + AttributeDescription* desc )); +extern int ldbm_tool_index_change LDAP_P(( BackendDB *be, + AttributeDescription* desc, + struct berval **bv, ID id, int op )); +#else extern int ldbm_tool_index_attr LDAP_P(( BackendDB *be, char* type )); extern int ldbm_tool_index_change LDAP_P(( BackendDB *be, char* type, struct berval **bv, ID id, int op )); +#endif extern int ldbm_tool_sync LDAP_P(( BackendDB *be )); diff --git a/servers/slapd/back-ldbm/tools.c b/servers/slapd/back-ldbm/tools.c index 03821ebf44..255ade0953 100644 --- a/servers/slapd/back-ldbm/tools.c +++ b/servers/slapd/back-ldbm/tools.c @@ -194,35 +194,21 @@ ID ldbm_tool_entry_put( int ldbm_tool_index_attr( BackendDB *be, - char* type ) +#ifdef SLAPD_SCHEMA_NOT_COMPAT + AttributeDescription *desc +#else + char* type +#endif +) { static DBCache *db = NULL; int indexmask; char * at_cn; -#ifdef SLAPD_SCHEMA_NOT_COMPAT - AttributeType *at; -#endif assert( slapMode & SLAP_TOOL_MODE ); #ifdef SLAPD_SCHEMA_NOT_COMPAT - at = at_find( type ); - - if( at == NULL ) { - Debug( LDAP_DEBUG_ANY, - "<= index_attr NULL (could not find attribute type %s)\n", - type, 0, 0 ); - return 0; - } - - at_cn = at_canonical_name( at ); - - if( at_cn == NULL ) { - Debug( LDAP_DEBUG_ANY, - "<= index_attr NULL (attribute type %s (%s) has no canonical name)\n", - at->sat_oid, type, 0 ); - return 0; - } + at_cn = desc->ad_cname->bv_val; #else attr_normalize( type ); at_cn = at_canonical_name( type ); @@ -234,7 +220,7 @@ int ldbm_tool_index_attr( return 0; } #endif - + assert( at_cn != NULL ); attr_mask( be->be_private, at_cn, &indexmask ); if ( (db = ldbm_cache_open( be, at_cn, LDBM_SUFFIX, LDBM_NEWDB )) @@ -253,11 +239,19 @@ int ldbm_tool_index_attr( int ldbm_tool_index_change( BackendDB *be, +#ifdef SLAPD_SCHEMA_NOT_COMPAT + AttributeDescription *desc, +#else char* type, +#endif struct berval **bv, ID id, int op ) { +#ifdef SLAPD_SCHEMA_NOT_COMPAT + char *type = desc->ad_cname->bv_val; +#endif + assert( slapMode & SLAP_TOOL_MODE ); index_change_values( be, diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index c4afaae0f4..8fb1680c00 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -201,14 +201,14 @@ entry2str( for ( i = 0; a->a_vals[i] != NULL; i++ ) { bv = a->a_vals[i]; #ifdef SLAPD_SCHEMA_NOT_COMPAT - tmplen = a->a_desc.ad_cname->bv_len; + tmplen = a->a_desc->ad_cname->bv_len; #else tmplen = strlen( a->a_type ); #endif MAKE_SPACE( LDIF_SIZE_NEEDED( tmplen, bv->bv_len )); ldif_sput( (char **) &ecur, LDIF_PUT_VALUE, #ifdef SLAPD_SCHEMA_NOT_COMPAT - a->a_desc.ad_cname->bv_val, + a->a_desc->ad_cname->bv_val, #else a->a_type, #endif diff --git a/servers/slapd/filterentry.c b/servers/slapd/filterentry.c index 9497b1f54f..2732730eaf 100644 --- a/servers/slapd/filterentry.c +++ b/servers/slapd/filterentry.c @@ -153,14 +153,16 @@ test_filter( } break; +#ifdef SLAPD_EXT_FILTERS case LDAP_FILTER_EXT: Debug( LDAP_DEBUG_FILTER, " EXT\n", 0, 0, 0 ); -#if SLAPD_SCHEMA_NOT_COMPAT && notyet +#if SLAPD_SCHEMA_NOT_COMPAT rc = test_mra_filter( be, conn, op, e, f->f_mra ); #else rc = -1; #endif break; +#endif case 0: Debug( LDAP_DEBUG_FILTER, " UNDEFINED\n", 0, 0, 0 ); @@ -208,63 +210,52 @@ test_ava_filter( } #ifdef SLAPD_SCHEMA_NOT_COMPAT - if ( (a = attr_find( e->e_attrs, ava->aa_desc )) == NULL ) + for(a = attrs_find( e->e_attrs, ava->aa_desc ); + a != NULL; + a = attrs_find( a, ava->aa_desc ) ) #else - if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) + a = attr_find( e->e_attrs, ava->ava_type ); + if ( a != NULL ) #endif { - return LDAP_COMPARE_FALSE; - } - -#ifdef SLAPD_SCHEMA_NOT_COMPAT - /* not yet implemented */ -#else - if ( a->a_syntax == 0 ) { - a->a_syntax = attr_syntax( ava->ava_type ); - } +#ifndef SLAPD_SCHEMA_NOT_COMPAT + if ( a->a_syntax == 0 ) { + a->a_syntax = attr_syntax( ava->ava_type ); + } #endif - for ( i = 0; a->a_vals[i] != NULL; i++ ) { -#ifdef SLAPD_SCHEMA_NOT_COMPAT - int rc = -1; - - switch ( type ) { - case LDAP_FILTER_EQUALITY: - break; - case LDAP_FILTER_APPROX: - break; - - case LDAP_FILTER_GE: - case LDAP_FILTER_LE: - break; - } + for ( i = 0; a->a_vals[i] != NULL; i++ ) { + int rc; - if( rc == LDAP_COMPARE_TRUE ) return LDAP_COMPARE_TRUE; +#ifdef SLAPD_SCHEMA_NOT_COMPAT + /* not yet implemented */ + rc = 0; #else - int rc = value_cmp( a->a_vals[i], &ava->ava_value, a->a_syntax, - 3 ); + rc = value_cmp( a->a_vals[i], &ava->ava_value, a->a_syntax, + 3 ); +#endif - switch ( type ) { - case LDAP_FILTER_EQUALITY: - case LDAP_FILTER_APPROX: - if ( rc == 0 ) { - return LDAP_COMPARE_TRUE; - } - break; + switch ( type ) { + case LDAP_FILTER_EQUALITY: + case LDAP_FILTER_APPROX: + if ( rc == 0 ) { + return LDAP_COMPARE_TRUE; + } + break; - case LDAP_FILTER_GE: - if ( rc >= 0 ) { - return LDAP_COMPARE_TRUE; - } - break; + case LDAP_FILTER_GE: + if ( rc >= 0 ) { + return LDAP_COMPARE_TRUE; + } + break; - case LDAP_FILTER_LE: - if ( rc <= 0 ) { - return LDAP_COMPARE_TRUE; + case LDAP_FILTER_LE: + if ( rc <= 0 ) { + return LDAP_COMPARE_TRUE; + } + break; } - break; } -#endif } return( LDAP_COMPARE_FALSE ); @@ -280,31 +271,25 @@ test_presence_filter( #ifdef SLAPD_SCHEMA_NOT_COMPAT AttributeDescription *desc #else - char *type + char *desc #endif ) { -#ifdef SLAPD_SCHEMA_NOT_COMPAT if ( be != NULL && ! access_allowed( be, conn, op, e, desc, NULL, ACL_SEARCH ) ) -#else - if ( be != NULL && ! access_allowed( be, conn, op, e, - type, NULL, ACL_SEARCH ) ) -#endif { return( -2 ); } #ifdef SLAPD_SCHEMA_NOT_COMPAT - return attr_find( e->e_attrs, desc ) != NULL + return attrs_find( e->e_attrs, desc ) != NULL #else - return attr_find( e->e_attrs, type ) != NULL + return attr_find( e->e_attrs, desc ) != NULL #endif ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE; } #ifndef SLAPD_SCHEMA_NOT_COMPAT - static int test_approx_filter( Backend *be, @@ -324,64 +309,62 @@ test_approx_filter( return( -2 ); } - if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) { - return LDAP_COMPARE_FALSE; - } - - /* for each value in the attribute */ - for ( i = 0; a->a_vals[i] != NULL; i++ ) { - /* - * try to match words in the filter value in order - * in the attribute value. - */ - - w2 = a->a_vals[i]->bv_val; - /* for each word in the filter value */ - for ( w1 = first_word( ava->ava_value.bv_val ); w1 != NULL; - w1 = next_word( w1 ) ) { - if ( (c1 = phonetic( w1 )) == NULL ) { - break; - } - + a = attr_find( e->e_attrs, ava->ava_type ); + if ( a != NULL ) { + /* for each value in the attribute */ + for ( i = 0; a->a_vals[i] != NULL; i++ ) { /* - * for each word in the attribute value from - * where we left off... + * try to match words in the filter value in order + * in the attribute value. */ - for ( w2 = first_word( w2 ); w2 != NULL; - w2 = next_word( w2 ) ) { - c2 = phonetic( w2 ); - if ( strcmp( c1, c2 ) == 0 ) { + + w2 = a->a_vals[i]->bv_val; + /* for each word in the filter value */ + for ( w1 = first_word( ava->ava_value.bv_val ); w1 != NULL; + w1 = next_word( w1 ) ) { + if ( (c1 = phonetic( w1 )) == NULL ) { + break; + } + + /* + * for each word in the attribute value from + * where we left off... + */ + for ( w2 = first_word( w2 ); w2 != NULL; + w2 = next_word( w2 ) ) { + c2 = phonetic( w2 ); + if ( strcmp( c1, c2 ) == 0 ) { + free( c2 ); + break; + } free( c2 ); + } + free( c1 ); + + /* + * if we stopped because we ran out of words + * before making a match, go on to the next + * value. otherwise try to keep matching + * words in this value from where we left off. + */ + if ( w2 == NULL ) { break; + } else { + w2 = next_word( w2 ); } - free( c2 ); } - free( c1 ); - /* - * if we stopped because we ran out of words - * before making a match, go on to the next - * value. otherwise try to keep matching - * words in this value from where we left off. + * if we stopped because we ran out of words we + * have a match. */ - if ( w2 == NULL ) { - break; - } else { - w2 = next_word( w2 ); + if ( w1 == NULL ) { + return LDAP_COMPARE_TRUE; } } - /* - * if we stopped because we ran out of words we - * have a match. - */ - if ( w1 == NULL ) { - return LDAP_COMPARE_TRUE; - } } return LDAP_COMPARE_FALSE; } - #endif static int diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index 6a091444a5..8760244da1 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -117,35 +117,38 @@ do_modify( goto cleanup; } - (*modtail)->ml_op = mop; - - if ( (*modtail)->ml_op != LDAP_MOD_ADD && - (*modtail)->ml_op != LDAP_MOD_DELETE && - (*modtail)->ml_op != LDAP_MOD_REPLACE ) - { - Debug( LDAP_DEBUG_ANY, - "do_modify: invalid modify operation (%ld)\n", - (long) (*modtail)->ml_op, 0, 0 ); - send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, - NULL, "unrecognized modify operation", NULL, NULL ); - rc = LDAP_PROTOCOL_ERROR; - goto cleanup; - } + switch( mop ) { + case LDAP_MOD_ADD: + if ( (*modtail)->ml_bvalues == NULL ) { + Debug( LDAP_DEBUG_ANY, + "do_modify: modify/add operation (%ld) requires values\n", + (long) mop, 0, 0 ); + send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, + NULL, "modify/add operation requires values", + NULL, NULL ); + rc = LDAP_PROTOCOL_ERROR; + goto cleanup; + } - if ( (*modtail)->ml_bvalues == NULL && ( - (*modtail)->ml_op != LDAP_MOD_REPLACE && - (*modtail)->ml_op != LDAP_MOD_DELETE ) ) - { - Debug( LDAP_DEBUG_ANY, - "do_modify: invalid modify operation (%ld) without values\n", - (long) (*modtail)->ml_op, 0, 0 ); - send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, - NULL, "unrecognized modify operation without values", - NULL, NULL ); - rc = LDAP_PROTOCOL_ERROR; - goto cleanup; + /* fall through */ + + case LDAP_MOD_DELETE: + case LDAP_MOD_REPLACE: + break; + + default: { + Debug( LDAP_DEBUG_ANY, + "do_modify: invalid modify operation (%ld)\n", + (long) mop, 0, 0 ); + send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, + NULL, "unrecognized modify operation", NULL, NULL ); + rc = LDAP_PROTOCOL_ERROR; + goto cleanup; + } } + (*modtail)->ml_op = mop; + #ifndef SLAPD_SCHEMA_NOT_COMPAT attr_normalize( (*modtail)->ml_type ); #endif @@ -307,7 +310,7 @@ int slap_modlist2mods( mod = (Modifications *) ch_calloc( 1, sizeof(Modifications) ); - ad = &mod->sml_desc; + ad = mod->sml_desc; /* convert to attribute description */ rc = slap_str2ad( ml->ml_type, &ad, text ); @@ -379,10 +382,86 @@ int slap_modlist2mods( int slap_mods_opattrs( Operation *op, - Modifications **modlist, + Modifications **modtail, char **text ) { - /* not yet implemented */ + int rc; + struct berval name, timestamp; + time_t now = slap_get_time(); + char timebuf[22]; + struct tm *ltm; + Modifications *mod; + AttributeDescription *ad; + + int mop = op->o_tag == LDAP_REQ_ADD + ? LDAP_MOD_ADD : LDAP_MOD_REPLACE; + + ldap_pvt_thread_mutex_lock( &gmtime_mutex ); + ltm = gmtime( &now ); + strftime( timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", ltm ); + ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); + timestamp.bv_val = timebuf; + timestamp.bv_len = strlen(timebuf); + + if( op->o_dn == NULL || op->o_dn[0] == '\0' ) { + name.bv_val = ""; + name.bv_len = sizeof("")-1; + } else { + name.bv_val = op->o_dn; + name.bv_len = strlen( op->o_dn ); + } + + if( op->o_tag == LDAP_REQ_ADD ) { + rc = slap_str2ad( "creatorsName", &ad, text ); + if( rc == LDAP_SUCCESS ) { + mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_desc = ad; + mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); + mod->sml_bvalues[0] = ber_bvdup( &name ); + mod->sml_bvalues[1] = NULL; + + *modtail = mod; + modtail = &mod->sml_next; + } + + rc = slap_str2ad( "createTimeStamp", &ad, text ); + if( rc == LDAP_SUCCESS ) { + mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_desc = ad; + mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); + mod->sml_bvalues[0] = ber_bvdup( ×tamp ); + mod->sml_bvalues[1] = NULL; + *modtail = mod; + modtail = &mod->sml_next; + } + } + + rc = slap_str2ad( "modifiersName", &ad, text ); + if( rc == LDAP_SUCCESS ) { + mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_desc = ad; + mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); + mod->sml_bvalues[0] = ber_bvdup( &name ); + mod->sml_bvalues[1] = NULL; + *modtail = mod; + modtail = &mod->sml_next; + } + + rc = slap_str2ad( "modifyTimeStamp", &ad, text ); + if( rc == LDAP_SUCCESS ) { + mod = (Modifications *) ch_calloc( 1, sizeof( Modifications ) ); + mod->sml_op = mop; + mod->sml_desc = ad; + mod->sml_bvalues = (struct berval **) malloc( 2 * sizeof( struct berval * ) ); + mod->sml_bvalues[0] = ber_bvdup( ×tamp ); + mod->sml_bvalues[1] = NULL; + *modtail = mod; + modtail = &mod->sml_next; + } + return LDAP_SUCCESS; } @@ -449,7 +528,7 @@ slap_mod_free( ) { #ifdef SLAPD_SCHEMA_NOT_COMPAT - ad_free( &mod->sm_desc, 0 ); + ad_free( mod->sm_desc, 1 ); #else if (mod->sm_desc) { free( mod->sm_desc ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 946189cf30..a199abcf54 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -21,10 +21,20 @@ LIBSLAPD_F (int) slap_bv2ad LDAP_P(( AttributeDescription **ad, char **text )); +LIBSLAPD_F (AttributeDescription *) ad_dup LDAP_P(( + AttributeDescription *desc )); + LIBSLAPD_F (void) ad_free LDAP_P(( AttributeDescription *desc, int freeit )); +#define ad_cmp(l,r) ( strcasecmp( \ + (l)->ad_cname->bv_val, (r)->ad_cname->bv_val )) + +LIBSLAPD_F (int) is_ad_subtype LDAP_P(( + AttributeDescription *sub, + AttributeDescription *super )); + LIBSLAPD_F (int) ad_inlist LDAP_P(( AttributeDescription *desc, char **attrs )); @@ -108,6 +118,7 @@ LIBSLAPD_F (int) attr_merge LDAP_P(( Entry *e, const char *type, struct berval **vals )); #ifdef SLAPD_SCHEMA_NOT_COMPAT +LIBSLAPD_F (Attribute *) attrs_find LDAP_P(( Attribute *a, AttributeDescription *desc )); LIBSLAPD_F (Attribute *) attr_find LDAP_P(( Attribute *a, AttributeDescription *desc )); LIBSLAPD_F (int) attr_delete LDAP_P(( Attribute **attrs, AttributeDescription *desc )); #else diff --git a/servers/slapd/result.c b/servers/slapd/result.c index b76c128805..6ea2c94fd6 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -676,7 +676,7 @@ send_search_entry( for ( a = e->e_attrs; a != NULL; a = a->a_next ) { #ifdef SLAPD_SCHEMA_NOT_COMPAT - AttributeDescription *desc = &a->a_desc; + AttributeDescription *desc = a->a_desc; #else char *desc = a->a_type; #endif @@ -761,7 +761,7 @@ send_search_entry( for (a = aa ; a == NULL; a = a->a_next ) { #ifdef SLAPD_SCHEMA_NOT_COMPAT - AttributeDescription *desc = &a->a_desc; + AttributeDescription *desc = a->a_desc; #else char *desc = a->a_type; #endif diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c index cd328eed6a..5e435493af 100644 --- a/servers/slapd/schema_check.c +++ b/servers/slapd/schema_check.c @@ -82,10 +82,10 @@ schema_check_entry( Entry *e ) /* check that each attr in the entry is allowed by some oc */ for ( a = e->e_attrs; a != NULL; a = a->a_next ) { #ifdef SLAPD_SCHEMA_NOT_COMPAT - if ( oc_check_allowed( a->a_desc.ad_type, aoc->a_vals ) != 0 ) { + if ( oc_check_allowed( a->a_desc->ad_type, aoc->a_vals ) != 0 ) { Debug( LDAP_DEBUG_ANY, "Entry (%s), attr \"%s\" not allowed\n", - e->e_dn, a->a_desc.ad_cname->bv_val, 0 ); + e->e_dn, a->a_desc->ad_cname->bv_val, 0 ); ret = 1; } #else @@ -129,7 +129,7 @@ oc_check_required( Entry *e, struct berval *ocname ) /* see if it's in the entry */ for ( a = e->e_attrs; a != NULL; a = a->a_next ) { #ifdef SLAPD_SCHEMA_NOT_COMPAT - if( a->a_desc.ad_type == at ) { + if( a->a_desc->ad_type == at ) { break; } #else diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 75a4241d64..3ac6b2a9a9 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -422,7 +422,7 @@ typedef struct slap_filter { */ typedef struct slap_attr { #ifdef SLAPD_SCHEMA_NOT_COMPAT - AttributeDescription a_desc; + AttributeDescription *a_desc; #else char *a_type; /* description */ int a_syntax; @@ -474,14 +474,13 @@ typedef struct slap_entry { #ifdef SLAPD_SCHEMA_NOT_COMPAT typedef struct slap_mod { int sm_op; - AttributeDescription sm_desc; + AttributeDescription *sm_desc; struct berval **sm_bvalues; } Modification; #else #define Modification LDAPMod #define sm_op mod_op #define sm_desc mod_type -#define sm_type mod_type #define sm_bvalues mod_bvalues #endif @@ -491,7 +490,7 @@ typedef struct slap_mod_list { #define sml_desc sml_mod.sm_desc #define sml_bvalues sml_mod.sm_bvalues #ifndef SLAPD_SCHEMA_NOT_COMPAT -#define sml_type sml_mod.sm_type +#define sml_type sml_mod.sm_desc #endif struct slap_mod_list *sml_next; } Modifications; @@ -898,9 +897,18 @@ struct slap_backend_info { ID (*bi_tool_entry_next) LDAP_P(( BackendDB *be )); Entry* (*bi_tool_entry_get) LDAP_P(( BackendDB *be, ID id )); ID (*bi_tool_entry_put) LDAP_P(( BackendDB *be, Entry *e )); - int (*bi_tool_index_attr) LDAP_P(( BackendDB *be, char* type )); - int (*bi_tool_index_change) LDAP_P(( BackendDB *be, char* type, +#ifdef SLAPD_SCHEMA_NOT_COMPAT + int (*bi_tool_index_attr) LDAP_P(( BackendDB *be, + AttributeDescription *desc )); + int (*bi_tool_index_change) LDAP_P(( BackendDB *be, + AttributeDescription *desc, struct berval **bv, ID id, int op )); +#else + int (*bi_tool_index_attr) LDAP_P(( BackendDB *be, + char* type )); + int (*bi_tool_index_change) LDAP_P(( BackendDB *be, + char* type, struct berval **bv, ID id, int op )); +#endif int (*bi_tool_sync) LDAP_P(( BackendDB *be )); #ifdef HAVE_CYRUS_SASL diff --git a/servers/slapd/tools/slapindex.c b/servers/slapd/tools/slapindex.c index a3e33cadf3..1f3bdc1c03 100644 --- a/servers/slapd/tools/slapindex.c +++ b/servers/slapd/tools/slapindex.c @@ -20,6 +20,12 @@ int main( int argc, char **argv ) { char *type; +#ifdef SLAPD_SCHEMA_NOT_COMPAT + AttributeDescription *desc; + char *text; +#else + char *desc; +#endif ID id; int rc = EXIT_SUCCESS; @@ -40,11 +46,24 @@ main( int argc, char **argv ) #ifdef SLAPD_SCHEMA_NOT_COMPAT type = argv[argc - 1]; + + if( strcasecmp( type, "dn" ) == 0 ) { + desc = NULL; + + } else { + rc = slap_str2ad( type, &desc, &text ); + + if( rc != LDAP_SUCCESS ) { + fprintf( stderr, "%s: unrecognized attribute type: %s\n", + progname, text ); + exit( EXIT_FAILURE ); + } + } #else - type = attr_normalize( argv[argc - 1] ); + desc = type = attr_normalize( argv[argc - 1] ); #endif - if ( !be->be_index_attr( be, type ) ) { + if ( !be->be_index_attr( be, desc ) ) { fprintf( stderr, "attribute type \"%s\": no indices to generate\n", type ); exit( EXIT_FAILURE ); @@ -78,7 +97,12 @@ main( int argc, char **argv ) id, e->e_dn ); } - if( strcasecmp( type, "dn" ) == 0 ) { +#ifdef SLAPD_SCHEMA_NOT_COMPAT + if( desc == NULL ) +#else + if( strcasecmp( type, "dn" ) == 0 ) +#endif + { bv.bv_val = e->e_ndn; bv.bv_len = strlen( bv.bv_val ); bvals[0] = &bv; @@ -86,31 +110,46 @@ main( int argc, char **argv ) values = bvals; - } else { - Attribute *attr = attr_find( e->e_attrs, type ); + if ( be->be_index_change( be, + desc, values, id, SLAP_INDEX_ADD_OP ) ) + { + rc = EXIT_FAILURE; - if( attr == NULL ) { - entry_free( e ); - continue; + if( !continuemode ) { + entry_free( e ); + break; + } } - values = attr->a_vals; - } - - if ( be->be_index_change( be, - type, values, id, SLAP_INDEX_ADD_OP ) ) - { - rc = EXIT_FAILURE; - - if( !continuemode ) { - entry_free( e ); - break; + } else { + Attribute *attr; + +#ifdef SLAPD_SCHEMA_NOT_COMPAT + for( attr = attrs_find( e->e_attrs, desc ); + attr != NULL; + attr = attrs_find( attr, desc ) ) +#else + if (( attr = attr_find( e->e_attrs, type )) != NULL ) +#endif + { + + if ( be->be_index_change( be, + desc, attr->a_vals, id, SLAP_INDEX_ADD_OP ) ) + { + rc = EXIT_FAILURE; + + if( !continuemode ) { + entry_free( e ); + goto done; + } + } } } entry_free( e ); } +done: (void) be->be_entry_close( be ); slap_tool_destroy(); -- 2.39.5