X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Fretcode.c;h=4dd568324df2025d446f9aec3f86c272d00f55d6;hb=200af921f4f1de43d89ba587d711ee9fc739e1bb;hp=7ed87d98ce69a5371aa3e7a4c1427bb273148d53;hpb=3d876e0fcc7f7745143d1957ab64712db8caeac0;p=openldap diff --git a/servers/slapd/overlays/retcode.c b/servers/slapd/overlays/retcode.c index 7ed87d98ce..4dd568324d 100644 --- a/servers/slapd/overlays/retcode.c +++ b/servers/slapd/overlays/retcode.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2005-2008 The OpenLDAP Foundation. + * Copyright 2005-2011 The OpenLDAP Foundation. * Portions Copyright 2005 Pierangelo Masarati * All rights reserved. * @@ -165,7 +165,9 @@ retcode_send_onelevel( Operation *op, SlapReply *rs ) rs->sr_entry = &rdi->rdi_e; rs->sr_err = send_search_entry( op, rs ); + rs->sr_flags = 0; rs->sr_entry = NULL; + rs->sr_attrs = NULL; switch ( rs->sr_err ) { case LDAP_UNAVAILABLE: /* connection closed */ @@ -257,6 +259,9 @@ retcode_op_internal( Operation *op, SlapReply *rs ) 1, &op2.ors_filterstr, op2.o_tmpmemctx ); op2.ors_filter = str2filter_x( &op2, op2.ors_filterstr.bv_val ); + /* errAbsObject is defined by this overlay! */ + assert( op2.ors_filter != NULL ); + db.bd_info = on->on_info->oi_orig; op2.o_bd = &db; @@ -273,7 +278,7 @@ retcode_op_internal( Operation *op, SlapReply *rs ) rc = op2.o_bd->be_search( &op2, rs ); op->o_abandon = op2.o_abandon; - filter_free_x( &op2, op2.ors_filter ); + filter_free_x( &op2, op2.ors_filter, 1 ); ber_memfree_x( op2.ors_filterstr.bv_val, op2.o_tmpmemctx ); if ( rdc.rdc_flags == SLAP_CB_CONTINUE ) { @@ -742,12 +747,43 @@ retcode_db_init( BackendDB *be, ConfigReply *cr ) return 0; } +static void +retcode_item_destroy( retcode_item_t *rdi ) +{ + ber_memfree( rdi->rdi_line.bv_val ); + + ber_memfree( rdi->rdi_dn.bv_val ); + ber_memfree( rdi->rdi_ndn.bv_val ); + + if ( !BER_BVISNULL( &rdi->rdi_text ) ) { + ber_memfree( rdi->rdi_text.bv_val ); + } + + if ( !BER_BVISNULL( &rdi->rdi_matched ) ) { + ber_memfree( rdi->rdi_matched.bv_val ); + } + + if ( rdi->rdi_ref ) { + ber_bvarray_free( rdi->rdi_ref ); + } + + BER_BVZERO( &rdi->rdi_e.e_name ); + BER_BVZERO( &rdi->rdi_e.e_nname ); + + entry_clean( &rdi->rdi_e ); + + if ( !BER_BVISNULL( &rdi->rdi_unsolicited_oid ) ) { + ber_memfree( rdi->rdi_unsolicited_oid.bv_val ); + if ( !BER_BVISNULL( &rdi->rdi_unsolicited_data ) ) + ber_memfree( rdi->rdi_unsolicited_data.bv_val ); + } + + ch_free( rdi ); +} enum { RC_PARENT = 1, - RC_ITEM, - RC_INDIR, - RC_SLEEP + RC_ITEM }; static ConfigDriver rc_cf_gen; @@ -758,12 +794,13 @@ static ConfigTable rccfg[] = { "( OLcfgOvAt:20.1 NAME 'olcRetcodeParent' " "DESC '' " "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL }, - { "retcode-item", "rdn> <...", + { "retcode-item", "rdn> <...", 3, 0, 0, ARG_MAGIC|RC_ITEM, rc_cf_gen, "( OLcfgOvAt:20.2 NAME 'olcRetcodeItem' " "DESC '' " + "EQUALITY caseIgnoreMatch " "SYNTAX OMsDirectoryString " - "EQUALITY caseIgnoreMatch )", NULL, NULL }, + "X-ORDERED 'VALUES' )", NULL, NULL }, { "retcode-indir", "on|off", 1, 2, 0, ARG_OFFSET|ARG_ON_OFF, (void *)offsetof(retcode_t, rd_indir), @@ -772,7 +809,7 @@ static ConfigTable rccfg[] = { "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, { "retcode-sleep", "sleeptime", - 2, 2, 0, ARG_OFFSET|ARG_INT|RC_SLEEP, + 2, 2, 0, ARG_OFFSET|ARG_INT, (void *)offsetof(retcode_t, rd_sleep), "( OLcfgOvAt:20.4 NAME 'olcRetcodeSleep' " "DESC '' " @@ -803,7 +840,6 @@ rc_cf_gen( ConfigArgs *c ) int rc = ARG_BAD_CONF; if ( c->op == SLAP_CONFIG_EMIT ) { - struct berval bv; switch( c->type ) { case RC_PARENT: if ( !BER_BVISEMPTY( &rd->rd_pdn )) { @@ -820,9 +856,19 @@ rc_cf_gen( ConfigArgs *c ) case RC_ITEM: { retcode_item_t *rdi; - - for ( rdi = rd->rd_item; rdi; rdi = rdi->rdi_next ) { - ber_bvarray_add( &c->rvalue_vals, &rdi->rdi_line ); + int i; + + for ( rdi = rd->rd_item, i = 0; rdi; rdi = rdi->rdi_next, i++ ) { + char buf[4096]; + struct berval bv; + char *ptr; + + bv.bv_len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i ); + bv.bv_len += rdi->rdi_line.bv_len; + ptr = bv.bv_val = ch_malloc( bv.bv_len + 1 ); + ptr = lutil_strcopy( ptr, buf ); + ptr = lutil_strncopy( ptr, rdi->rdi_line.bv_val, rdi->rdi_line.bv_len ); + ber_bvarray_add( &c->rvalue_vals, &bv ); } rc = 0; } break; @@ -835,7 +881,48 @@ rc_cf_gen( ConfigArgs *c ) return rc; } else if ( c->op == LDAP_MOD_DELETE ) { - return 1; /* FIXME */ + switch( c->type ) { + case RC_PARENT: + if ( rd->rd_pdn.bv_val ) { + ber_memfree ( rd->rd_pdn.bv_val ); + rc = 0; + } + if ( rd->rd_npdn.bv_val ) { + ber_memfree ( rd->rd_npdn.bv_val ); + } + break; + + case RC_ITEM: + if ( c->valx == -1 ) { + retcode_item_t *rdi, *next; + + for ( rdi = rd->rd_item; rdi != NULL; rdi = next ) { + next = rdi->rdi_next; + retcode_item_destroy( rdi ); + } + + } else { + retcode_item_t **rdip, *rdi; + int i; + + for ( rdip = &rd->rd_item, i = 0; i <= c->valx && *rdip; i++, rdip = &(*rdip)->rdi_next ) + ; + if ( *rdip == NULL ) { + return 1; + } + rdi = *rdip; + *rdip = rdi->rdi_next; + + retcode_item_destroy( rdi ); + } + rc = 0; + break; + + default: + assert( 0 ); + break; + } + return rc; /* FIXME */ } switch( c->type ) { @@ -1300,29 +1387,8 @@ retcode_db_destroy( BackendDB *be, ConfigReply *cr ) retcode_item_t *rdi, *next; for ( rdi = rd->rd_item; rdi != NULL; rdi = next ) { - ber_memfree( rdi->rdi_dn.bv_val ); - ber_memfree( rdi->rdi_ndn.bv_val ); - - if ( !BER_BVISNULL( &rdi->rdi_text ) ) { - ber_memfree( rdi->rdi_text.bv_val ); - } - - if ( !BER_BVISNULL( &rdi->rdi_matched ) ) { - ber_memfree( rdi->rdi_matched.bv_val ); - } - - if ( rdi->rdi_ref ) { - ber_bvarray_free( rdi->rdi_ref ); - } - - BER_BVZERO( &rdi->rdi_e.e_name ); - BER_BVZERO( &rdi->rdi_e.e_nname ); - - entry_clean( &rdi->rdi_e ); - next = rdi->rdi_next; - - ch_free( rdi ); + retcode_item_destroy( rdi ); } if ( !BER_BVISNULL( &rd->rd_pdn ) ) {