From: Howard Chu Date: Thu, 27 Apr 2006 00:01:20 +0000 (+0000) Subject: Implement reqOld support X-Git-Tag: OPENLDAP_REL_ENG_2_4_1ALPHA~2^2~139 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=4f1e154c1253211ffb93d6b8d4864e377e5139fe;p=openldap Implement reqOld support --- diff --git a/servers/slapd/overlays/accesslog.c b/servers/slapd/overlays/accesslog.c index 3600b3591d..f134ed1d1f 100644 --- a/servers/slapd/overlays/accesslog.c +++ b/servers/slapd/overlays/accesslog.c @@ -57,6 +57,8 @@ typedef struct log_info { int li_age; int li_cycle; struct re_s *li_task; + Filter *li_filter; + Entry *li_old; int li_success; ldap_pvt_thread_mutex_t li_op_mutex; ldap_pvt_thread_mutex_t li_log_mutex; @@ -68,7 +70,8 @@ enum { LOG_DB = 1, LOG_OPS, LOG_PURGE, - LOG_SUCCESS + LOG_SUCCESS, + LOG_FILTER }; static ConfigTable log_cfats[] = { @@ -90,6 +93,10 @@ static ConfigTable log_cfats[] = { log_cf_gen, "( OLcfgOvAt:4.4 NAME 'olcAccessLogSuccess' " "DESC 'Log successful ops only' " "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, + { "logoldfilter", NULL, 2, 2, 0, ARG_MAGIC|LOG_FILTER, + log_cf_gen, "( OLcfgOvAt:4.5 NAME 'olcAccessLogOldFilter' " + "DESC 'Log old values when modifying entries matching the filter' " + "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, { NULL } }; @@ -99,7 +106,8 @@ static ConfigOCs log_cfocs[] = { "DESC 'Access log configuration' " "SUP olcOverlayConfig " "MUST olcAccessLogDB " - "MAY ( olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogSuccess ) )", + "MAY ( olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogSuccess $ " + "olcAccessLogOldFilter ) )", Cft_Overlay, log_cfats }, { NULL } }; @@ -605,6 +613,14 @@ log_cf_gen(ConfigArgs *c) else rc = 1; break; + case LOG_FILTER: + if ( li->li_filter ) { + filter2bv( li->li_filter, &agebv ); + value_add_one( &c->rvalue_vals, &agebv ); + } + else + rc = 1; + break; } break; case LDAP_MOD_DELETE: @@ -635,6 +651,12 @@ log_cf_gen(ConfigArgs *c) case LOG_SUCCESS: li->li_success = 0; break; + case LOG_FILTER: + if ( li->li_filter ) { + filter_free( li->li_filter ); + li->li_filter = NULL; + } + break; } break; default: @@ -680,6 +702,12 @@ log_cf_gen(ConfigArgs *c) case LOG_SUCCESS: li->li_success = c->value_int; break; + case LOG_FILTER: + li->li_filter = str2filter( c->argv[1] ); + if ( !li->li_filter ) { + sprintf( c->msg, "bad filter!" ); + rc = 1; + } } break; } @@ -782,6 +810,24 @@ static struct berval derefs[] = { static struct berval simple = BER_BVC("SIMPLE"); +static void accesslog_val2val(AttributeDescription *ad, struct berval *val, + char c_op, struct berval *dst) { + char *ptr; + + dst->bv_len = ad->ad_cname.bv_len + val->bv_len + 2; + if ( c_op ) dst->bv_len++; + + dst->bv_val = ch_malloc( dst->bv_len+1 ); + + ptr = lutil_strcopy( dst->bv_val, ad->ad_cname.bv_val ); + *ptr++ = ':'; + if ( c_op ) + *ptr++ = c_op; + *ptr++ = ' '; + AC_MEMCPY( ptr, val->bv_val, val->bv_len ); + dst->bv_val[dst->bv_len] = '\0'; +} + static int accesslog_response(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; log_info *li = on->on_bi.bi_private; @@ -791,7 +837,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) { int i; int logop; slap_verbmasks *lo; - Entry *e; + Entry *e, *old = NULL; char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE+8]; struct berval bv; char *ptr; @@ -821,6 +867,8 @@ static int accesslog_response(Operation *op, SlapReply *rs) { if ( lo->mask & LOG_OP_WRITES ) { ldap_pvt_thread_mutex_lock( &li->li_log_mutex ); + old = li->li_old; + li->li_old = NULL; ldap_pvt_thread_mutex_unlock( &li->li_op_mutex ); } @@ -844,9 +892,22 @@ static int accesslog_response(Operation *op, SlapReply *rs) { switch( logop ) { case LOG_EN_ADD: + case LOG_EN_DELETE: { + char c_op; + Entry *e2; + + if ( logop == LOG_EN_ADD ) { + e2 = op->ora_e; + c_op = '+'; + } else { + if ( !old ) + break; + e2 = old; + c_op = 0; + } /* count all the vals */ i = 0; - for ( a=op->ora_e->e_attrs; a; a=a->a_next ) { + for ( a=e2->e_attrs; a; a=a->a_next ) { if ( a->a_vals ) { for (b=a->a_vals; !BER_BVISNULL( b ); b++) { i++; @@ -855,32 +916,21 @@ static int accesslog_response(Operation *op, SlapReply *rs) { } vals = ch_malloc( (i+1) * sizeof( struct berval )); i = 0; - for ( a=op->ora_e->e_attrs; a; a=a->a_next ) { + for ( a=e2->e_attrs; a; a=a->a_next ) { if ( a->a_vals ) { for (b=a->a_vals; !BER_BVISNULL( b ); b++,i++) { - vals[i].bv_len = a->a_desc->ad_cname.bv_len + b->bv_len +3; - vals[i].bv_val = ch_malloc( vals[i].bv_len+1 ); - ptr = lutil_strcopy( vals[i].bv_val, - a->a_desc->ad_cname.bv_val ); - *ptr++ = ':'; - *ptr++ = '+'; - *ptr++ = ' '; - AC_MEMCPY( ptr, b->bv_val, b->bv_len ); - vals[i].bv_val[vals[i].bv_len] = '\0'; + accesslog_val2val( a->a_desc, b, c_op, &vals[i] ); } } } vals[i].bv_val = NULL; vals[i].bv_len = 0; - a = attr_alloc( ad_reqMod ); + a = attr_alloc( logop == LOG_EN_ADD ? ad_reqMod : ad_reqOld ); a->a_vals = vals; a->a_nvals = vals; last_attr->a_next = a; break; - - case LOG_EN_DELETE: - /* needs nothing else */ - break; + } case LOG_EN_MODIFY: /* count all the mods */ @@ -896,15 +946,24 @@ static int accesslog_response(Operation *op, SlapReply *rs) { } vals = ch_malloc( (i+1) * sizeof( struct berval )); i = 0; + + /* Zero flags on old entry */ + if ( old ) { + for ( a=old->e_attrs; a; a=a->a_next ) + a->a_flags = 0; + } + for ( m=op->orm_modlist; m; m=m->sml_next ) { + /* Mark this attribute as modified */ + if ( old ) { + a = attr_find( old->e_attrs, m->sml_desc ); + if ( a ) + a->a_flags = 1; + } if ( m->sml_values ) { for (b=m->sml_values; !BER_BVISNULL( b ); b++,i++) { char c_op; - vals[i].bv_len = m->sml_desc->ad_cname.bv_len + b->bv_len +3; - vals[i].bv_val = ch_malloc( vals[i].bv_len+1 ); - ptr = lutil_strcopy( vals[i].bv_val, - m->sml_desc->ad_cname.bv_val ); - *ptr++ = ':'; + switch( m->sml_op ) { case LDAP_MOD_ADD: c_op = '+'; break; case LDAP_MOD_DELETE: c_op = '-'; break; @@ -917,10 +976,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) { */ default: c_op = '?'; break; } - *ptr++ = c_op; - *ptr++ = ' '; - AC_MEMCPY( ptr, b->bv_val, b->bv_len ); - vals[i].bv_val[vals[i].bv_len] = '\0'; + accesslog_val2val( m->sml_desc, b, c_op, &vals[i] ); } } else if ( m->sml_op == LDAP_MOD_DELETE ) { vals[i].bv_len = m->sml_desc->ad_cname.bv_len + 2; @@ -939,6 +995,34 @@ static int accesslog_response(Operation *op, SlapReply *rs) { a->a_vals = vals; a->a_nvals = vals; last_attr->a_next = a; + + if ( old ) { + last_attr = a; + /* count all the vals */ + i = 0; + for ( a=old->e_attrs; a; a=a->a_next ) { + if ( a->a_vals && a->a_flags ) { + for (b=a->a_vals; !BER_BVISNULL( b ); b++) { + i++; + } + } + } + vals = ch_malloc( (i+1) * sizeof( struct berval )); + i = 0; + for ( a=old->e_attrs; a; a=a->a_next ) { + if ( a->a_vals && a->a_flags ) { + for (b=a->a_vals; !BER_BVISNULL( b ); b++,i++) { + accesslog_val2val( a->a_desc, b, 0, &vals[i] ); + } + } + } + vals[i].bv_val = NULL; + vals[i].bv_len = 0; + a = attr_alloc( ad_reqOld ); + a->a_vals = vals; + a->a_nvals = vals; + last_attr->a_next = a; + } break; case LOG_EN_MODRDN: @@ -1043,6 +1127,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) { entry_free( e ); done: + if ( old ) entry_free( old ); ldap_pvt_thread_mutex_unlock( &li->li_log_mutex ); return SLAP_CB_CONTINUE; } @@ -1099,6 +1184,20 @@ accesslog_op_mod( Operation *op, SlapReply *rs ) * overlays like refint to keep working. */ ldap_pvt_thread_mutex_lock( &li->li_op_mutex ); + if ( li->li_filter && ( op->o_tag == LDAP_REQ_DELETE || + op->o_tag == LDAP_REQ_MODIFY )) { + int rc; + Entry *e; + + op->o_bd->bd_info = on->on_info->oi_orig; + rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e ); + if ( e ) { + if ( test_filter( op, e, li->li_filter ) == LDAP_COMPARE_TRUE ) + li->li_old = entry_dup( e ); + be_entry_release_rw( op, e, 0 ); + } + op->o_bd->bd_info = (BackendInfo *)on; + } } return SLAP_CB_CONTINUE; }