X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Fvalsort.c;h=033cbf6d8cb785b85edb36adeec95a53bd56bdc5;hb=52a0d000311d7eda3eb830c7bff75286fe7661fc;hp=894345207015833ef4587ef8a27ae3177c5fc5b8;hpb=f07015dad2d6ccdbe5b8360bfbc601b13baae894;p=openldap diff --git a/servers/slapd/overlays/valsort.c b/servers/slapd/overlays/valsort.c index 8943452070..033cbf6d8c 100644 --- a/servers/slapd/overlays/valsort.c +++ b/servers/slapd/overlays/valsort.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2005 The OpenLDAP Foundation. + * Copyright 2005-2011 The OpenLDAP Foundation. * Portions copyright 2005 Symas Corporation. * All rights reserved. * @@ -152,16 +152,16 @@ valsort_cf_func(ConfigArgs *c) { vitmp.vi_ad = NULL; i = slap_str2ad( c->argv[1], &vitmp.vi_ad, &text ); if ( i ) { - sprintf( c->msg, "<%s> %s", c->argv[0], text ); + snprintf( c->cr_msg, sizeof( c->cr_msg), "<%s> %s", c->argv[0], text ); Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n", - c->log, c->msg, c->argv[1] ); + c->log, c->cr_msg, c->argv[1] ); return(1); } if ( is_at_single_value( vitmp.vi_ad->ad_type )) { - sprintf( c->msg, "<%s> %s is single-valued, ignoring", c->argv[0], + snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> %s is single-valued, ignoring", c->argv[0], vitmp.vi_ad->ad_cname.bv_val ); Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n", - c->log, c->msg, c->argv[1] ); + c->log, c->cr_msg, c->argv[1] ); return(0); } is_numeric = ( vitmp.vi_ad->ad_type->sat_syntax == syn_numericString || @@ -170,34 +170,34 @@ valsort_cf_func(ConfigArgs *c) { ber_str2bv( c->argv[2], 0, 0, &bv ); i = dnNormalize( 0, NULL, NULL, &bv, &vitmp.vi_dn, NULL ); if ( i ) { - sprintf( c->msg, "<%s> unable to normalize DN", c->argv[0] ); + snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to normalize DN", c->argv[0] ); Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n", - c->log, c->msg, c->argv[2] ); + c->log, c->cr_msg, c->argv[2] ); return(1); } i = verb_to_mask( c->argv[3], sorts ); if ( BER_BVISNULL( &sorts[i].word )) { - sprintf( c->msg, "<%s> unrecognized sort type", c->argv[0] ); + snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unrecognized sort type", c->argv[0] ); Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n", - c->log, c->msg, c->argv[3] ); + c->log, c->cr_msg, c->argv[3] ); return(1); } vitmp.vi_sort = sorts[i].mask; if ( sorts[i].mask == VALSORT_WEIGHTED && c->argc == 5 ) { i = verb_to_mask( c->argv[4], sorts ); if ( BER_BVISNULL( &sorts[i].word )) { - sprintf( c->msg, "<%s> unrecognized sort type", c->argv[0] ); + snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unrecognized sort type", c->argv[0] ); Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n", - c->log, c->msg, c->argv[4] ); + c->log, c->cr_msg, c->argv[4] ); return(1); } vitmp.vi_sort |= sorts[i].mask; } if (( vitmp.vi_sort & VALSORT_NUMERIC ) && !is_numeric ) { - sprintf( c->msg, "<%s> numeric sort specified for non-numeric syntax", + snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> numeric sort specified for non-numeric syntax", c->argv[0] ); Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n", - c->log, c->msg, c->argv[1] ); + c->log, c->cr_msg, c->argv[1] ); return(1); } vi = ch_malloc( sizeof(valsort_info) ); @@ -212,7 +212,7 @@ static void do_sort( Operation *op, Attribute *a, int beg, int num, slap_mask_t sort ) { int i, j, gotnvals; - struct berval tmp, ntmp, *vals, *nvals; + struct berval tmp, ntmp, *vals = NULL, *nvals; gotnvals = (a->a_vals != a->a_nvals ); @@ -272,11 +272,13 @@ valsort_response( Operation *op, SlapReply *rs ) valsort_info *vi; Attribute *a; - /* We only want search responses */ - if ( rs->sr_type != REP_SEARCH ) return SLAP_CB_CONTINUE; - - /* If this is a syncrepl response, pass thru unmodified */ - if ( op->o_sync > SLAP_CONTROL_IGNORED ) return SLAP_CB_CONTINUE; + /* If this is not a search response, or it is a syncrepl response, + * or the valsort control wants raw results, pass thru unmodified. + */ + if ( rs->sr_type != REP_SEARCH || + ( _SCM(op->o_sync) > SLAP_CONTROL_IGNORED ) || + ( op->o_ctrlflag[valsort_cid] & SLAP_CONTROL_DATA0)) + return SLAP_CB_CONTINUE; on = (slap_overinst *) op->o_bd->bd_info; vi = on->on_bi.bi_private; @@ -295,16 +297,11 @@ valsort_response( Operation *op, SlapReply *rs ) a = attr_find( rs->sr_entry->e_attrs, vi->vi_ad ); if ( !a ) continue; - if (( rs->sr_flags & ( REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED )) != - ( REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED )) { - rs->sr_entry = entry_dup( rs->sr_entry ); - rs->sr_flags |= REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED; + if ( rs_entry2modifiable( op, rs, on )) { a = attr_find( rs->sr_entry->e_attrs, vi->vi_ad ); } - /* count values */ - for ( n = 0; !BER_BVISNULL( &a->a_vals[n] ); n++ ); - + n = a->a_numvals; if ( vi->vi_sort & VALSORT_WEIGHTED ) { int j, gotnvals; long *index = op->o_tmpalloc( n * sizeof(long), op->o_tmpmemctx ); @@ -312,7 +309,7 @@ valsort_response( Operation *op, SlapReply *rs ) gotnvals = (a->a_vals != a->a_nvals ); for (i=0; ia_nvals[i].bv_val, '{' ); + char *ptr = ber_bvchr( &a->a_nvals[i], '{' ); char *end = NULL; if ( !ptr ) { Debug(LDAP_DEBUG_TRACE, "weights missing from attr %s " @@ -337,7 +334,9 @@ valsort_response( Operation *op, SlapReply *rs ) if ( a->a_vals != a->a_nvals ) { ptr = a->a_vals[i].bv_val; - end = strchr( ptr, '}' ) + 1; + end = ber_bvchr( &a->a_vals[i], '}' ); + assert( end != NULL ); + end++; for (;*end;) *ptr++ = *end++; *ptr = '\0'; @@ -405,7 +404,7 @@ valsort_add( Operation *op, SlapReply *rs ) if ( !a ) continue; for (i=0; !BER_BVISNULL( &a->a_vals[i] ); i++) { - ptr = strchr(a->a_vals[i].bv_val, '{' ); + ptr = ber_bvchr(&a->a_vals[i], '{' ); if ( !ptr ) { Debug(LDAP_DEBUG_TRACE, "weight missing from attribute %s\n", vi->vi_ad->ad_cname.bv_val, 0, 0); @@ -443,13 +442,16 @@ valsort_modify( Operation *op, SlapReply *rs ) if ( !(vi->vi_sort & VALSORT_WEIGHTED )) continue; for (ml = op->orm_modlist; ml; ml=ml->sml_next ) { + /* Must be a Delete Attr op, so no values to consider */ + if ( !ml->sml_values ) + continue; if ( ml->sml_desc == vi->vi_ad ) break; } if ( !ml ) continue; for (i=0; !BER_BVISNULL( &ml->sml_values[i] ); i++) { - ptr = strchr(ml->sml_values[i].bv_val, '{' ); + ptr = ber_bvchr(&ml->sml_values[i], '{' ); if ( !ptr ) { Debug(LDAP_DEBUG_TRACE, "weight missing from attribute %s\n", vi->vi_ad->ad_cname.bv_val, 0, 0); @@ -470,14 +472,28 @@ valsort_modify( Operation *op, SlapReply *rs ) return SLAP_CB_CONTINUE; } +static int +valsort_db_open( + BackendDB *be, + ConfigReply *cr +) +{ + return overlay_register_control( be, LDAP_CONTROL_VALSORT ); +} + static int valsort_destroy( - BackendDB *be + BackendDB *be, + ConfigReply *cr ) { slap_overinst *on = (slap_overinst *)be->bd_info; valsort_info *vi = on->on_bi.bi_private, *next; +#ifdef SLAP_CONFIG_DELETE + overlay_unregister_control( be, LDAP_CONTROL_VALSORT ); +#endif /* SLAP_CONFIG_DELETE */ + for (; vi; vi = next) { next = vi->vi_next; ch_free( vi->vi_dn.bv_val ); @@ -493,24 +509,44 @@ valsort_parseCtrl( SlapReply *rs, LDAPControl *ctrl ) { - if ( ctrl->ldctl_value.bv_len ) { - rs->sr_text = "valSort control value not empty"; + ber_tag_t tag; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + ber_int_t flag = 0; + + if ( BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "valSort control value is absent"; + return LDAP_PROTOCOL_ERROR; + } + + if ( BER_BVISEMPTY( &ctrl->ldctl_value )) { + rs->sr_text = "valSort control value is empty"; return LDAP_PROTOCOL_ERROR; } + + ber_init2( ber, &ctrl->ldctl_value, 0 ); + if (( tag = ber_scanf( ber, "{b}", &flag )) == LBER_ERROR ) { + rs->sr_text = "valSort control: flag decoding error"; + return LDAP_PROTOCOL_ERROR; + } + op->o_ctrlflag[valsort_cid] = ctrl->ldctl_iscritical ? SLAP_CONTROL_CRITICAL : SLAP_CONTROL_NONCRITICAL; + if ( flag ) + op->o_ctrlflag[valsort_cid] |= SLAP_CONTROL_DATA0; return LDAP_SUCCESS; } static slap_overinst valsort; -int valsort_init() +int valsort_initialize( void ) { - int i, rc; + int rc; valsort.on_bi.bi_type = "valsort"; valsort.on_bi.bi_db_destroy = valsort_destroy; + valsort.on_bi.bi_db_open = valsort_db_open; valsort.on_bi.bi_op_add = valsort_add; valsort.on_bi.bi_op_modify = valsort_modify; @@ -523,7 +559,7 @@ int valsort_init() SLAP_CTRL_SEARCH | SLAP_CTRL_HIDE, NULL, valsort_parseCtrl, &valsort_cid ); if ( rc != LDAP_SUCCESS ) { - fprintf( stderr, "Failed to register control %d\n", rc ); + Debug( LDAP_DEBUG_ANY, "Failed to register control %d\n", rc, 0, 0 ); return rc; } @@ -537,7 +573,7 @@ int valsort_init() #if SLAPD_OVER_VALSORT == SLAPD_MOD_DYNAMIC int init_module( int argc, char *argv[]) { - return valsort_init(); + return valsort_initialize(); } #endif