X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Faccesslog.c;h=a6b261377b4366534665f86e92f1cb7afeda4e6c;hb=996be22a8c966521eb8e277a95051be317de247f;hp=90205ca45c67852e3e158ff562c912bc70f076bf;hpb=6cc8b49819977fc4d3e463643c6521eba03b5ea8;p=openldap diff --git a/servers/slapd/overlays/accesslog.c b/servers/slapd/overlays/accesslog.c index 90205ca45c..a6b261377b 100644 --- a/servers/slapd/overlays/accesslog.c +++ b/servers/slapd/overlays/accesslog.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2005-2007 The OpenLDAP Foundation. + * Copyright 2005-2008 The OpenLDAP Foundation. * Portions copyright 2004-2005 Symas Corporation. * All rights reserved. * @@ -67,7 +67,6 @@ typedef struct log_info { Entry *li_old; log_attr *li_oldattrs; int li_success; - int li_unlock; ldap_pvt_thread_rmutex_t li_op_rmutex; ldap_pvt_thread_mutex_t li_log_mutex; } log_info; @@ -535,17 +534,17 @@ log_age_unparse( int age, struct berval *agebv, size_t size ) if ( dd ) { len = snprintf( ptr, size, "%d+", dd ); - assert( len >= 0 && len < size ); + assert( len >= 0 && (unsigned) len < size ); size -= len; ptr += len; } len = snprintf( ptr, size, "%02d:%02d", hh, mm ); - assert( len >= 0 && len < size ); + assert( len >= 0 && (unsigned) len < size ); size -= len; ptr += len; if ( ss ) { len = snprintf( ptr, size, ":%02d", ss ); - assert( len >= 0 && len < size ); + assert( len >= 0 && (unsigned) len < size ); size -= len; ptr += len; } @@ -569,19 +568,22 @@ static int log_old_lookup( Operation *op, SlapReply *rs ) { purge_data *pd = op->o_callback->sc_private; + Attribute *a; if ( rs->sr_type != REP_SEARCH) return 0; if ( slapd_shutdown ) return 0; - /* Remember old CSN */ - if ( pd->csn.bv_val[0] == '\0' ) { - Attribute *a = attr_find( rs->sr_entry->e_attrs, - slap_schema.si_ad_entryCSN ); - if ( a ) { - int len = a->a_vals[0].bv_len; - if ( len > pd->csn.bv_len ) - len = pd->csn.bv_len; + /* Remember max CSN: should always be the last entry + * seen, since log entries are ordered chronologically... + */ + a = attr_find( rs->sr_entry->e_attrs, + slap_schema.si_ad_entryCSN ); + if ( a ) { + ber_len_t len = a->a_vals[0].bv_len; + if ( len > pd->csn.bv_len ) + len = pd->csn.bv_len; + if ( memcmp( a->a_vals[0].bv_val, pd->csn.bv_val, len ) > 0 ) { AC_MEMCPY( pd->csn.bv_val, a->a_vals[0].bv_val, len ); pd->csn.bv_len = len; } @@ -657,6 +659,7 @@ accesslog_purge( void *ctx, void *arg ) if ( pd.used ) { int i; + /* delete the expired entries */ op->o_tag = LDAP_REQ_DELETE; op->o_callback = &nullsc; op->o_csn = pd.csn; @@ -671,6 +674,33 @@ accesslog_purge( void *ctx, void *arg ) } ch_free( pd.ndn ); ch_free( pd.dn ); + + { + Modifications mod; + struct berval bv[2]; + /* update context's entryCSN to reflect oldest CSN */ + mod.sml_numvals = 1; + mod.sml_values = bv; + bv[0] = pd.csn; + BER_BVZERO(&bv[1]); + mod.sml_nvalues = NULL; + mod.sml_desc = slap_schema.si_ad_entryCSN; + mod.sml_op = LDAP_MOD_REPLACE; + mod.sml_flags = SLAP_MOD_INTERNAL; + mod.sml_next = NULL; + + op->o_tag = LDAP_REQ_MODIFY; + op->orm_modlist = &mod; + op->orm_no_opattrs = 1; + op->o_req_dn = li->li_db->be_suffix[0]; + op->o_req_ndn = li->li_db->be_nsuffix[0]; + op->o_no_schema_check = 1; + op->o_managedsait = SLAP_CONTROL_NONCRITICAL; + op->o_bd->be_modify( op, &rs ); + if ( mod.sml_next ) { + slap_mods_free( mod.sml_next, 1 ); + } + } } ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); @@ -770,9 +800,11 @@ log_cf_gen(ConfigArgs *c) if ( li->li_task ) { struct re_s *re = li->li_task; li->li_task = NULL; + ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re )) ldap_pvt_runqueue_stoptask( &slapd_rq, re ); ldap_pvt_runqueue_remove( &slapd_rq, re ); + ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } li->li_age = 0; li->li_cycle = 0; @@ -844,12 +876,15 @@ log_cf_gen(ConfigArgs *c) struct re_s *re = li->li_task; if ( re ) re->interval.tv_sec = li->li_cycle; - else + else { + ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); li->li_task = ldap_pvt_runqueue_insert( &slapd_rq, li->li_cycle, accesslog_purge, li, "accesslog_purge", li->li_db ? li->li_db->be_suffix[0].bv_val : c->be->be_suffix[0].bv_val ); + ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); + } } } break; @@ -898,7 +933,7 @@ logSchemaControlValidate( struct berval *valp ) { struct berval val, bv; - int i; + ber_len_t i; int rc = LDAP_SUCCESS; assert( valp != NULL ); @@ -1120,7 +1155,7 @@ accesslog_ctrls( } if ( !BER_BVISNULL( &ctrls[ i ]->ldctl_value ) ) { - int j; + ber_len_t j; ptr = lutil_strcopy( ptr, " controlValue \"" ); for ( j = 0; j < ctrls[ i ]->ldctl_value.bv_len; j++ ) @@ -1339,10 +1374,17 @@ static int accesslog_response(Operation *op, SlapReply *rs) { return SLAP_CB_CONTINUE; if ( lo->mask & LOG_OP_WRITES ) { + slap_callback *cb; ldap_pvt_thread_mutex_lock( &li->li_log_mutex ); old = li->li_old; li->li_old = NULL; - li->li_unlock = 0; + /* Disarm mod_cleanup */ + for ( cb = op->o_callback; cb; cb = cb->sc_next ) { + if ( cb->sc_private == (void *)on ) { + cb->sc_private = NULL; + break; + } + } ldap_pvt_thread_rmutex_unlock( &li->li_op_rmutex, op->o_tid ); } @@ -1358,7 +1400,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) { attr_merge_one( e, ad_reqMessage, &bv, NULL ); } bv.bv_len = snprintf( timebuf, sizeof( timebuf ), "%d", rs->sr_err ); - if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) { + if ( bv.bv_len < sizeof( timebuf ) ) { bv.bv_val = timebuf; attr_merge_one( e, ad_reqResult, &bv, NULL ); } @@ -1575,17 +1617,17 @@ static int accesslog_response(Operation *op, SlapReply *rs) { } bv.bv_val = timebuf; bv.bv_len = snprintf( bv.bv_val, sizeof( timebuf ), "%d", rs->sr_nentries ); - if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) { + if ( bv.bv_len < sizeof( timebuf ) ) { attr_merge_one( e, ad_reqEntries, &bv, NULL ); } /* else? */ bv.bv_len = snprintf( bv.bv_val, sizeof( timebuf ), "%d", op->ors_tlimit ); - if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) { + if ( bv.bv_len < sizeof( timebuf ) ) { attr_merge_one( e, ad_reqTimeLimit, &bv, NULL ); } /* else? */ bv.bv_len = snprintf( bv.bv_val, sizeof( timebuf ), "%d", op->ors_slimit ); - if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) { + if ( bv.bv_len < sizeof( timebuf ) ) { attr_merge_one( e, ad_reqSizeLimit, &bv, NULL ); } /* else? */ break; @@ -1593,7 +1635,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) { case LOG_EN_BIND: bv.bv_val = timebuf; bv.bv_len = snprintf( bv.bv_val, sizeof( timebuf ), "%d", op->o_protocol ); - if ( bv.bv_len >= 0 && bv.bv_len < sizeof( timebuf ) ) { + if ( bv.bv_len < sizeof( timebuf ) ) { attr_merge_one( e, ad_reqVersion, &bv, NULL ); } /* else? */ if ( op->orb_method == LDAP_AUTH_SIMPLE ) { @@ -1693,12 +1735,11 @@ accesslog_mod_cleanup( Operation *op, SlapReply *rs ) { slap_callback *sc = op->o_callback; slap_overinst *on = sc->sc_private; - log_info *li = on->on_bi.bi_private; op->o_callback = sc->sc_next; op->o_tmpfree( sc, op->o_tmpmemctx ); - if ( li->li_unlock ) { + if ( on ) { BackendInfo *bi = op->o_bd->bd_info; op->o_bd->bd_info = (BackendInfo *)on; accesslog_response( op, rs ); @@ -1714,15 +1755,15 @@ accesslog_op_mod( Operation *op, SlapReply *rs ) log_info *li = on->on_bi.bi_private; if ( li->li_ops & LOG_OP_WRITES ) { - slap_callback *cb = op->o_tmpalloc( sizeof( slap_callback ), op->o_tmpmemctx ); + slap_callback *cb = op->o_tmpalloc( sizeof( slap_callback ), op->o_tmpmemctx ), *cb2; cb->sc_cleanup = accesslog_mod_cleanup; cb->sc_response = NULL; cb->sc_private = on; - cb->sc_next = op->o_callback; - op->o_callback = cb; + cb->sc_next = NULL; + for ( cb2 = op->o_callback; cb2->sc_next; cb2 = cb2->sc_next ); + cb2->sc_next = cb; ldap_pvt_thread_rmutex_lock( &li->li_op_rmutex, op->o_tid ); - li->li_unlock = 1; if ( li->li_oldf && ( op->o_tag == LDAP_REQ_DELETE || op->o_tag == LDAP_REQ_MODIFY || ( op->o_tag == LDAP_REQ_MODRDN && li->li_oldattrs ))) { @@ -1797,7 +1838,7 @@ accesslog_abandon( Operation *op, SlapReply *rs ) e = accesslog_entry( op, rs, LOG_EN_ABANDON, &op2 ); bv.bv_val = buf; bv.bv_len = snprintf( buf, sizeof( buf ), "%d", op->orn_msgid ); - if ( bv.bv_len >= 0 && bv.bv_len < sizeof( buf ) ) { + if ( bv.bv_len < sizeof( buf ) ) { attr_merge_one( e, ad_reqId, &bv, NULL ); } /* else? */ @@ -1826,6 +1867,9 @@ accesslog_operational( Operation *op, SlapReply *rs ) slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; log_info *li = on->on_bi.bi_private; + if ( op->o_sync != SLAP_CONTROL_NONE ) + return SLAP_CB_CONTINUE; + if ( rs->sr_entry != NULL && dn_match( &op->o_bd->be_nsuffix[0], &rs->sr_entry->e_nname ) ) { @@ -2014,8 +2058,10 @@ accesslog_db_open( ber_dupbv( &li->li_db->be_rootndn, li->li_db->be_nsuffix ); } + ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); ldap_pvt_runqueue_insert( &slapd_rq, 3600, accesslog_db_root, on, "accesslog_db_root", li->li_db->be_suffix[0].bv_val ); + ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); return 0; }