From 61ee5897e03882d2ed1e6a147f69568e0f12eadb Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Tue, 13 Apr 2004 18:41:00 +0000 Subject: [PATCH] various improvements --- servers/slapd/overlays/lastmod.c | 233 +++++++++++++++++++------------ 1 file changed, 142 insertions(+), 91 deletions(-) diff --git a/servers/slapd/overlays/lastmod.c b/servers/slapd/overlays/lastmod.c index 5ea1a182f2..82021ec63a 100644 --- a/servers/slapd/overlays/lastmod.c +++ b/servers/slapd/overlays/lastmod.c @@ -61,15 +61,16 @@ struct berval lastmodType[] = { }; static struct m_s { - char *name; - char *schema; - slap_mask_t flags; - int offset; + char *name; + char *schema; + slap_mask_t flags; + int offset; } moc[] = { { "lastmod", "( 1.3.6.1.4.1.4203.666.3.13" "NAME 'lastmod' " "DESC 'OpenLDAP per-database last modification monitoring' " - "SUP top STRUCTURAL " + "STRUCTURAL " + "SUP top " "MUST cn " "MAY ( " "lastmodDN " @@ -96,7 +97,7 @@ static struct m_s { "SINGLE-VALUE " "NO-USER-MODIFICATION " "USAGE directoryOperation )", SLAP_AT_HIDE, - offsetof(struct lastmod_schema_t, lms_ad_lastmodType) }, + offsetof( struct lastmod_schema_t, lms_ad_lastmodType ) }, { NULL } }; @@ -108,22 +109,26 @@ static const struct berval *write_exop[] = { static int lastmod_search( Operation *op, SlapReply *rs ) { - slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private; + int rc; + + /* if we get here, it must be a success */ + rs->sr_err = LDAP_SUCCESS; -#if 0 - /* FIXME: can't restore the correct bd_info otherwise - * backend_operational() screws things up */ - op->o_bd->bd_info = (BackendInfo *)on->on_info; -#endif ldap_pvt_thread_mutex_lock( &lmi->lmi_entry_mutex ); - rs->sr_attrs = op->ors_attrs; - rs->sr_flags = 0; - rs->sr_entry = lmi->lmi_e; - rs->sr_err = send_search_entry( op, rs ); - rs->sr_entry = NULL; - rs->sr_flags = 0; - rs->sr_attrs = NULL; + + rc = test_filter( op, lmi->lmi_e, op->oq_search.rs_filter ); + if ( rc == LDAP_COMPARE_TRUE ) { + rs->sr_attrs = op->ors_attrs; + rs->sr_flags = 0; + rs->sr_entry = lmi->lmi_e; + rs->sr_err = send_search_entry( op, rs ); + rs->sr_entry = NULL; + rs->sr_flags = 0; + rs->sr_attrs = NULL; + } + ldap_pvt_thread_mutex_unlock( &lmi->lmi_entry_mutex ); send_ldap_result( op, rs ); @@ -134,13 +139,14 @@ lastmod_search( Operation *op, SlapReply *rs ) static int lastmod_compare( Operation *op, SlapReply *rs ) { - slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private; Attribute *a; ldap_pvt_thread_mutex_lock( &lmi->lmi_entry_mutex ); + if ( get_assert( op ) && - ( test_filter( op, lmi->lmi_e, get_assertion( op )) != LDAP_COMPARE_TRUE )) + ( test_filter( op, lmi->lmi_e, get_assertion( op ) ) != LDAP_COMPARE_TRUE ) ) { rs->sr_err = LDAP_ASSERTION_FAILED; goto return_results; @@ -157,7 +163,7 @@ lastmod_compare( Operation *op, SlapReply *rs ) for ( a = attr_find( lmi->lmi_e->e_attrs, op->oq_compare.rs_ava->aa_desc ); a != NULL; - a = attr_find( a->a_next, op->oq_compare.rs_ava->aa_desc )) + a = attr_find( a->a_next, op->oq_compare.rs_ava->aa_desc ) ) { rs->sr_err = LDAP_COMPARE_FALSE; @@ -172,7 +178,9 @@ lastmod_compare( Operation *op, SlapReply *rs ) } return_results:; + ldap_pvt_thread_mutex_unlock( &lmi->lmi_entry_mutex ); + send_ldap_result( op, rs ); if( rs->sr_err == LDAP_COMPARE_FALSE || rs->sr_err == LDAP_COMPARE_TRUE ) { @@ -185,7 +193,7 @@ return_results:; static int lastmod_exop( Operation *op, SlapReply *rs ) { - slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; /* Temporary */ @@ -201,7 +209,7 @@ lastmod_exop( Operation *op, SlapReply *rs ) static int lastmod_op_func( Operation *op, SlapReply *rs ) { - slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private; unsigned i; @@ -246,12 +254,15 @@ return_referral:; rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, op->ors_scope ); - if (!rs->sr_ref) rs->sr_ref = default_referral; + if ( !rs->sr_ref ) { + rs->sr_ref = default_referral; + } rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); - if (rs->sr_ref != default_referral) - ber_bvarray_free( rs->sr_ref ); + if ( rs->sr_ref != default_referral ) { + ber_bvarray_free( rs->sr_ref ); + } rs->sr_ref = NULL; return -1; @@ -264,10 +275,50 @@ return_error:; return -1; } +static int +best_guess( Operation *op, + struct berval *bv_modifyTimestamp, struct berval *bv_nmodifyTimestamp, + struct berval *bv_modifiersName, struct berval *bv_nmodifiersName ) +{ + struct tm *tm; +#ifdef HAVE_GMTIME_R + struct tm tm_buf; +#endif + char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; + time_t currtime; + + /* best guess */ +#if 0 + currtime = slap_get_time(); +#endif + /* maybe we better use the time the operation was initiated */ + currtime = op->o_time; + +#ifndef HAVE_GMTIME_R + ldap_pvt_thread_mutex_lock( &gmtime_mutex ); + tm = gmtime( &currtime ); +#else /* HAVE_GMTIME_R */ + tm = gmtime_r( &currtime, &tm_buf ); +#endif /* HAVE_GMTIME_R */ + lutil_gentime( tmbuf, sizeof( tmbuf ), tm ); +#ifndef HAVE_GMTIME_R + ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); +#endif + + ber_str2bv( tmbuf, 0, 1, bv_modifyTimestamp ); + ber_dupbv( bv_nmodifyTimestamp, bv_modifyTimestamp ); + + /* best guess */ + ber_dupbv( bv_modifiersName, &op->o_dn ); + ber_dupbv( bv_nmodifiersName, &op->o_ndn ); + + return 0; +} + static int lastmod_update( Operation *op, SlapReply *rs ) { - slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private; Attribute *a; Modifications *ml = NULL; @@ -305,41 +356,26 @@ lastmod_update( Operation *op, SlapReply *rs ) break; case LDAP_REQ_DELETE: - { - struct tm *tm; -#ifdef HAVE_GMTIME_R - struct tm tm_buf; -#endif - char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; - time_t currtime; - lmt = LASTMOD_DELETE; - /* best guess */ - currtime = slap_get_time(); + best_guess( op, &bv_modifyTimestamp, &bv_nmodifyTimestamp, + &bv_modifiersName, &bv_nmodifiersName ); -#ifndef HAVE_GMTIME_R - ldap_pvt_thread_mutex_lock( &gmtime_mutex ); - tm = gmtime( &currtime ); -#else /* HAVE_GMTIME_R */ - tm = gmtime_r( &currtime, &tm_buf ); -#endif /* HAVE_GMTIME_R */ - lutil_gentime( tmbuf, sizeof( tmbuf ), tm ); -#ifndef HAVE_GMTIME_R - ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); -#endif + ber_dupbv( &bv_name, &op->o_req_dn ); + ber_dupbv( &bv_nname, &op->o_req_ndn ); + break; - ber_str2bv( tmbuf, 0, 1, &bv_modifyTimestamp ); - ber_dupbv( &bv_nmodifyTimestamp, &bv_modifyTimestamp ); + case LDAP_REQ_EXTENDED: + lmt = LASTMOD_EXOP; - /* best guess */ - ber_dupbv( &bv_modifiersName, &op->o_dn ); - ber_dupbv( &bv_nmodifiersName, &op->o_ndn ); + /* actually, password change is wrapped around a backend + * call to modify, so it never shows up as an exop... */ + best_guess( op, &bv_modifyTimestamp, &bv_nmodifyTimestamp, + &bv_modifiersName, &bv_nmodifiersName ); ber_dupbv( &bv_name, &op->o_req_dn ); ber_dupbv( &bv_nname, &op->o_req_ndn ); break; - } case LDAP_REQ_MODIFY: lmt = LASTMOD_MODIFY; @@ -374,22 +410,28 @@ lastmod_update( Operation *op, SlapReply *rs ) case LDAP_REQ_MODRDN: lmt = LASTMOD_MODRDN; e = NULL; - if ( on->on_info->oi_orig->bi_entry_get_rw ) { - BackendInfo *bi = op->o_bd->bd_info; - struct berval dn = BER_BVNULL; - if ( op->orr_nnewSup && !BER_BVISNULL( op->orr_nnewSup ) ) { - build_new_dn( &dn, op->orr_nnewSup, &op->orr_nnewrdn, NULL ); + if ( op->orr_newSup && !BER_BVISNULL( op->orr_newSup ) ) { + build_new_dn( &bv_name, op->orr_newSup, &op->orr_newrdn, NULL ); + build_new_dn( &bv_nname, op->orr_nnewSup, &op->orr_nnewrdn, NULL ); - } else { - struct berval pdn; + } else { + struct berval pdn; - dnParent( &op->o_req_ndn, &pdn ); - build_new_dn( &dn, &pdn, &op->orr_nnewrdn, NULL ); - } + dnParent( &op->o_req_dn, &pdn ); + build_new_dn( &bv_name, &pdn, &op->orr_newrdn, NULL ); + + dnParent( &op->o_req_ndn, &pdn ); + build_new_dn( &bv_nname, &pdn, &op->orr_nnewrdn, NULL ); + } + + if ( on->on_info->oi_orig->bi_entry_get_rw ) { + BackendInfo *bi = op->o_bd->bd_info; + int rc; op->o_bd->bd_info = (BackendInfo *)on->on_info->oi_orig; - if ( (*op->o_bd->bd_info->bi_entry_get_rw)( op, &dn, NULL, NULL, 0, &e ) == LDAP_SUCCESS ) { + rc = (*op->o_bd->bd_info->bi_entry_get_rw)( op, &bv_name, NULL, NULL, 0, &e ); + if ( rc == LDAP_SUCCESS ) { a = attr_find( e->e_attrs, slap_schema.si_ad_modifiersName ); if ( a != NULL ) { ber_dupbv( &bv_modifiersName, &a->a_vals[0] ); @@ -405,15 +447,22 @@ lastmod_update( Operation *op, SlapReply *rs ) } } - ber_dupbv( &bv_name, &e->e_name ); - ber_dupbv( &bv_nname, &e->e_nname ); + assert( dn_match( &bv_name, &e->e_name ) ); + assert( dn_match( &bv_nname, &e->e_nname ) ); (*op->o_bd->bd_info->bi_entry_release_rw)( op, e, 0 ); } - ch_free( dn.bv_val ); op->o_bd->bd_info = bi; + + } + + /* if !bi_entry_get_rw || bi_entry_get_rw failed for any reason... */ + if ( e == NULL ) { + best_guess( op, &bv_modifyTimestamp, &bv_nmodifyTimestamp, + &bv_modifiersName, &bv_nmodifiersName ); } + break; default: @@ -446,7 +495,7 @@ lastmod_update( Operation *op, SlapReply *rs ) ch_free( a->a_vals[0].bv_val ); ber_dupbv( &a->a_vals[0], &lastmodType[ lmt ] ); ch_free( a->a_nvals[0].bv_val ); - ber_dupbv( &a->a_vals[0], &lastmodType[ lmt ] ); + ber_dupbv( &a->a_nvals[0], &lastmodType[ lmt ] ); #if 0 fprintf( stderr, "### modifiersName: %s %s\n", bv_modifiersName.bv_val, bv_nmodifiersName.bv_val ); @@ -487,16 +536,22 @@ lastmod_response( Operation *op, SlapReply *rs ) { unsigned int i; - if ( rs->sr_err != LDAP_SUCCESS ) { + /* don't record failed operations */ + switch ( rs->sr_err ) { + case LDAP_SUCCESS: + /* FIXME: other cases? */ + break; + + default: return SLAP_CB_CONTINUE; } + /* record only write operations */ switch ( op->o_tag ) { case LDAP_REQ_ADD: case LDAP_REQ_MODIFY: case LDAP_REQ_MODRDN: case LDAP_REQ_DELETE: - /* FIXME: exop? */ break; case LDAP_REQ_EXTENDED: @@ -513,10 +568,7 @@ lastmod_response( Operation *op, SlapReply *rs ) } process:; - if ( rs->sr_err == LDAP_SUCCESS ) { - /* FIXME: ignore errors */ - (void)lastmod_update( op, rs ); - } + (void)lastmod_update( op, rs ); return SLAP_CB_CONTINUE; } @@ -526,12 +578,12 @@ lastmod_db_init( BackendDB *be ) { - slap_overinst *on = (slap_overinst *) be->bd_info; + slap_overinst *on = (slap_overinst *)be->bd_info; lastmod_info_t *lmi; if ( lastmod_schema.lms_oc_lastmod == NULL ) { - int i; - const char *text; + int i; + const char *text; /* schema integration */ for ( i = 0; mat[i].name; i++ ) { @@ -671,8 +723,8 @@ lastmod_db_init( } } - lmi = (lastmod_info_t *)ch_malloc(sizeof(lastmod_info_t)); - memset(lmi, 0, sizeof(lastmod_info_t)); + lmi = (lastmod_info_t *)ch_malloc( sizeof( lastmod_info_t ) ); + memset( lmi, 0, sizeof( lastmod_info_t ) ); on->on_bi.bi_private = lmi; return 0; @@ -680,14 +732,14 @@ lastmod_db_init( static int lastmod_db_config( - BackendDB *be, - const char *fname, - int lineno, - int argc, - char **argv + BackendDB *be, + const char *fname, + int lineno, + int argc, + char **argv ) { - slap_overinst *on = (slap_overinst *) be->bd_info; + slap_overinst *on = (slap_overinst *)be->bd_info; lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private; if ( strcasecmp( argv[ 0 ], "lastmod-rdnvalue" ) == 0 ) { @@ -755,11 +807,11 @@ lastmod_db_open( "modifyTimestamp: %s\n" "modifiersName: %s\n" "hasSubordinates: FALSE\n", - lmi->lmi_rdnvalue.bv_val, be->be_suffix[0].bv_val, + lmi->lmi_rdnvalue.bv_val, be->be_suffix[ 0 ].bv_val, lastmod_schema.lms_oc_lastmod->soc_cname.bv_val, lastmod_schema.lms_oc_lastmod->soc_cname.bv_val, lmi->lmi_rdnvalue.bv_val, - lastmod_schema.lms_ad_lastmodDN->ad_cname.bv_val, lmi->lmi_rdnvalue.bv_val, be->be_suffix[0].bv_val, + lastmod_schema.lms_ad_lastmodDN->ad_cname.bv_val, lmi->lmi_rdnvalue.bv_val, be->be_suffix[ 0 ].bv_val, lastmod_schema.lms_ad_lastmodType->ad_cname.bv_val, lastmodType[ LASTMOD_ADD ].bv_val, tmbuf, BER_BVISNULL( &be->be_rootdn ) ? "" : be->be_rootdn.bv_val, @@ -768,7 +820,6 @@ lastmod_db_open( #if 0 fprintf( stderr, "# entry:\n%s\n", buf ); - fflush( stderr ); #endif lmi->lmi_e = str2entry( buf ); @@ -786,7 +837,7 @@ lastmod_db_destroy( BackendDB *be ) { - slap_overinst *on = (slap_overinst *) be->bd_info; + slap_overinst *on = (slap_overinst *)be->bd_info; lastmod_info_t *lmi = (lastmod_info_t *)on->on_bi.bi_private; if ( lmi ) { @@ -838,7 +889,7 @@ lastmod_init() #if SLAPD_OVER_LASTMOD == SLAPD_MOD_DYNAMIC int -init_module(int argc, char *argv[]) +init_module( int argc, char *argv[] ) { return lastmod_init(); } -- 2.39.5