From: Howard Chu Date: Thu, 13 Oct 2005 11:58:44 +0000 (+0000) Subject: Move CSN invocations to backends X-Git-Tag: OPENLDAP_REL_ENG_2_2_MP~277 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=7dcb68f6fa4bcdb3fbd883d9149ec4c23713d1c9;p=openldap Move CSN invocations to backends --- diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index f224e68e8a..8bff33752d 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -2603,7 +2603,7 @@ acl_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de op2.o_tag = LDAP_REQ_SEARCH; op2.o_ndn = op2.o_bd->be_rootndn; op2.o_callback = &cb; - op2.o_time = slap_get_time(); + slap_op_time( &op2.o_time, &op2.o_tincr ); op2.o_do_not_cache = 1; op2.o_is_auth_check = 0; ber_dupbv_x( &op2.o_req_dn, &op2.o_req_ndn, cp->asc_op->o_tmpmemctx ); diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 7df87348aa..250da6093a 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -30,6 +30,7 @@ #include #include +#include "lutil.h" #include "slap.h" int @@ -192,8 +193,6 @@ do_add( Operation *op, SlapReply *rs ) } done:; - slap_graduate_commit_csn( op ); - if ( modlist != NULL ) { slap_mods_free( modlist, 0 ); } @@ -312,14 +311,6 @@ fe_op_add( Operation *op, SlapReply *rs ) } - rs->sr_err = slap_mods_opattrs( op, modlist, - modtail, &rs->sr_text, - textbuf, textlen, 1 ); - if ( rs->sr_err != LDAP_SUCCESS ) { - send_ldap_result( op, rs ); - goto done; - } - /* check for duplicate values */ rs->sr_err = slap_mods_no_repl_user_mod_check( op, modlist, &rs->sr_text, textbuf, textlen ); @@ -626,3 +617,119 @@ slap_entry2mods( return LDAP_SUCCESS; } +int slap_add_opattrs( + Operation *op, + const char **text, + char *textbuf, + size_t textlen, + int manage_ctxcsn ) +{ + struct berval name, timestamp, csn = BER_BVNULL; + struct berval nname, tmp; + char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; + char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; + Attribute *a; + + a = attr_find( op->ora_e->e_attrs, + slap_schema.si_ad_structuralObjectClass ); + + if ( !a ) { + Attribute *oc; + int rc; + + oc = attr_find( op->ora_e->e_attrs, slap_schema.si_ad_objectClass ); + if ( oc ) { + rc = structural_class( oc->a_vals, &tmp, NULL, text, + textbuf, textlen ); + if( rc != LDAP_SUCCESS ) return rc; + + attr_merge_one( op->ora_e, slap_schema.si_ad_structuralObjectClass, + &tmp, NULL ); + } + } + + if ( SLAP_LASTMOD( op->o_bd ) ) { + char *ptr; + timestamp.bv_val = timebuf; + if ( BER_BVISEMPTY( &op->o_csn )) { + if ( SLAP_SHADOW( op->o_bd )) + manage_ctxcsn = 0; + csn.bv_val = csnbuf; + csn.bv_len = sizeof(csnbuf); + slap_get_csn( op, &csn, manage_ctxcsn ); + } else { + csn = op->o_csn; + } + ptr = strchr( csn.bv_val, '#' ); + if ( ptr ) { + timestamp.bv_len = ptr - csn.bv_val; + if ( timestamp.bv_len >= sizeof(timebuf) ) + timestamp.bv_len = sizeof(timebuf) - 1; + strncpy( timebuf, csn.bv_val, timestamp.bv_len ); + timebuf[timestamp.bv_len] = '\0'; + } else { + time_t now = slap_get_time(); + + timestamp.bv_len = sizeof(timebuf); + + slap_timestamp( &now, ×tamp ); + } + + if ( BER_BVISEMPTY( &op->o_dn ) ) { + BER_BVSTR( &name, SLAPD_ANONYMOUS ); + nname = name; + } else { + name = op->o_dn; + nname = op->o_ndn; + } + + a = attr_find( op->ora_e->e_attrs, + slap_schema.si_ad_entryUUID ); + if ( !a ) { + char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ]; + + tmp.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) ); + tmp.bv_val = uuidbuf; + + attr_merge_normalize_one( op->ora_e, + slap_schema.si_ad_entryUUID, &tmp, op->o_tmpmemctx ); + } + + a = attr_find( op->ora_e->e_attrs, + slap_schema.si_ad_creatorsName ); + if ( !a ) { + attr_merge_one( op->ora_e, + slap_schema.si_ad_creatorsName, &name, &nname ); + } + + a = attr_find( op->ora_e->e_attrs, + slap_schema.si_ad_createTimestamp ); + if ( !a ) { + attr_merge_one( op->ora_e, + slap_schema.si_ad_createTimestamp, ×tamp, NULL ); + } + + a = attr_find( op->ora_e->e_attrs, + slap_schema.si_ad_entryCSN ); + if ( !a ) { + attr_merge_one( op->ora_e, + slap_schema.si_ad_entryCSN, &csn, NULL ); + } + + a = attr_find( op->ora_e->e_attrs, + slap_schema.si_ad_modifiersName ); + if ( !a ) { + attr_merge_one( op->ora_e, + slap_schema.si_ad_modifiersName, &name, &nname ); + } + + a = attr_find( op->ora_e->e_attrs, + slap_schema.si_ad_modifyTimestamp ); + if ( !a ) { + attr_merge_one( op->ora_e, + slap_schema.si_ad_modifyTimestamp, ×tamp, NULL ); + } + + } + return LDAP_SUCCESS; +} diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 227652077e..16861df670 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -51,6 +51,8 @@ bdb_add(Operation *op, SlapReply *rs ) ctrls[num_ctrls] = 0; + slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 ); + /* check entry's schema */ rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL, get_manageDIT(op), &rs->sr_text, textbuf, textlen ); @@ -170,14 +172,8 @@ retry: /* transaction retry */ "does not exist\n", 0, 0, 0 ); rs->sr_err = LDAP_REFERRAL; - send_ldap_result( op, rs ); - - ber_bvarray_free( rs->sr_ref ); - op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - - goto done; + rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; + goto return_results; } rs->sr_err = access_allowed( op, p, @@ -221,22 +217,18 @@ retry: /* transaction retry */ if ( is_entry_referral( p ) ) { /* parent is a referral, don't allow add */ - rs->sr_matched = p->e_name.bv_val; + rs->sr_matched = ber_strdup_x( p->e_name.bv_val, + op->o_tmpmemctx ); rs->sr_ref = get_entry_referrals( op, p ); - + bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); + p = NULL; Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_add) ": parent is referral\n", 0, 0, 0 ); rs->sr_err = LDAP_REFERRAL; - send_ldap_result( op, rs ); - - ber_bvarray_free( rs->sr_ref ); - bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - p = NULL; - goto done; + rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; + goto return_results; } #ifdef BDB_SUBENTRIES @@ -430,14 +422,9 @@ retry: /* transaction retry */ return_results: send_ldap_result( op, rs ); + if ( !SLAP_SHADOW( op->o_bd )) + slap_graduate_commit_csn( op ); - if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) { - ldap_pvt_thread_yield(); - TXN_CHECKPOINT( bdb->bi_dbenv, - bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); - } - -done: if( ltid != NULL ) { TXN_ABORT( ltid ); op->o_private = NULL; @@ -447,5 +434,11 @@ done: slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); slap_sl_free( *postread_ctrl, op->o_tmpmemctx ); } + + if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) { + ldap_pvt_thread_yield(); + TXN_CHECKPOINT( bdb->bi_dbenv, + bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); + } return rs->sr_err; } diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 16e42d9bb1..5e70633adf 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -19,6 +19,7 @@ #include #include +#include "lutil.h" #include "back-bdb.h" int @@ -56,6 +57,16 @@ bdb_delete( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n", op->o_req_dn.bv_val, 0, 0 ); + /* allocate CSN */ + if ( !SLAP_SHADOW( op->o_bd )) { + struct berval csn; + char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; + + csn.bv_val = csnbuf; + csn.bv_len = sizeof(csnbuf); + slap_get_csn( op, &csn, 1 ); + } + if( 0 ) { retry: /* transaction retry */ if( e != NULL ) { @@ -161,17 +172,8 @@ retry: /* transaction retry */ } rs->sr_err = LDAP_REFERRAL; - send_ldap_result( op, rs ); - - if ( rs->sr_ref != default_referral ) { - ber_bvarray_free( rs->sr_ref ); - } - free( (char *)rs->sr_matched ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - - rs->sr_err = -1; - goto done; + rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; + goto return_results; } rc = bdb_cache_find_id( op, ltid, eip->bei_id, &eip, 0, locker, &plock ); @@ -291,15 +293,9 @@ retry: /* transaction retry */ 0, 0, 0 ); rs->sr_err = LDAP_REFERRAL; - rs->sr_matched = e->e_name.bv_val; - send_ldap_result( op, rs ); - - ber_bvarray_free( rs->sr_ref ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - - rs->sr_err = 1; - goto done; + rs->sr_matched = ch_strdup( e->e_name.bv_val ); + rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; + goto return_results; } /* pre-read */ @@ -487,19 +483,10 @@ retry: /* transaction retry */ if( num_ctrls ) rs->sr_ctrls = ctrls; return_results: - send_ldap_result( op, rs ); - - if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) { - ldap_pvt_thread_yield(); - TXN_CHECKPOINT( bdb->bi_dbenv, - bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); - } - if ( rs->sr_err == LDAP_SUCCESS && parent_is_glue && parent_is_leaf ) { op->o_delete_glue_parent = 1; } -done: if ( p ) bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p); @@ -518,9 +505,19 @@ done: op->o_private = NULL; } + send_ldap_result( op, rs ); + if ( !SLAP_SHADOW( op->o_bd )) + slap_graduate_commit_csn( op ); + if( preread_ctrl != NULL ) { slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx ); slap_sl_free( *preread_ctrl, op->o_tmpmemctx ); } + + if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) { + ldap_pvt_thread_yield(); + TXN_CHECKPOINT( bdb->bi_dbenv, + bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 ); + } return rs->sr_err; } diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index e680de5ef2..00d314e7a5 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -289,6 +289,9 @@ bdb_modify( Operation *op, SlapReply *rs ) ctrls[num_ctrls] = NULL; + if ( !SLAP_SHADOW( op->o_bd )) + slap_mods_opattrs( op, op->orm_modlist, 1 ); + if( 0 ) { retry: /* transaction retry */ if ( dummy.e_attrs ) { @@ -573,6 +576,8 @@ return_results: attrs_free( dummy.e_attrs ); } send_ldap_result( op, rs ); + if ( !SLAP_SHADOW( op->o_bd )) + slap_graduate_commit_csn( op ); if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) { ldap_pvt_thread_yield(); diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c index 413d292508..0f98eca3d0 100644 --- a/servers/slapd/back-ldbm/add.c +++ b/servers/slapd/back-ldbm/add.c @@ -25,6 +25,16 @@ #include "back-ldbm.h" #include "proto-back-ldbm.h" +static int +ldbm_csn_cb( + Operation *op, + SlapReply *rs ) +{ + op->o_callback = op->o_callback->sc_next; + slap_graduate_commit_csn( op ); + return SLAP_CB_CONTINUE; +} + int ldbm_back_add( Operation *op, @@ -38,6 +48,7 @@ ldbm_back_add( AttributeDescription *entry = slap_schema.si_ad_entry; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; + slap_callback cb = { NULL }; #ifdef LDBM_SUBENTRIES int subentry; #endif @@ -45,6 +56,12 @@ ldbm_back_add( Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", op->o_req_dn.bv_val, 0, 0); + slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 ); + + cb.sc_cleanup = ldbm_csn_cb; + cb.sc_next = op->o_callback; + op->o_callback = &cb; + rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL, get_manageDIT(op), &rs->sr_text, textbuf, textlen ); diff --git a/servers/slapd/back-ldbm/delete.c b/servers/slapd/back-ldbm/delete.c index 6db0d31dbf..36232ecb10 100644 --- a/servers/slapd/back-ldbm/delete.c +++ b/servers/slapd/back-ldbm/delete.c @@ -44,6 +44,16 @@ ldbm_back_delete( /* grab giant lock for writing */ ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); + /* allocate CSN */ + if ( !SLAP_SHADOW( op->o_bd )) { + struct berval csn; + char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; + + csn.bv_val = csnbuf; + csn.bv_len = sizeof(csnbuf); + slap_get_csn( op, &csn, 1 ); + } + /* get entry with writer lock */ e = dn2entry_w( op->o_bd, &op->o_req_ndn, &matched ); @@ -64,16 +74,9 @@ ldbm_back_delete( &op->o_req_dn, LDAP_SCOPE_DEFAULT ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - rs->sr_err = LDAP_REFERRAL; - send_ldap_result( op, rs ); - - if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref ); - free( (char *)rs->sr_matched ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - return( -1 ); + rs->sr_flags |= REP_MATCHED_MUST_BE_FREED | REP_REF_MUSTBEFREED; + goto return_results; } /* check entry for "entry" acl */ @@ -83,10 +86,8 @@ ldbm_back_delete( "<=- ldbm_back_delete: no write access to entry\n", 0, 0, 0 ); - send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, - "no write access to entry" ); - - rc = LDAP_INSUFFICIENT_ACCESS; + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + rs->sr_text = "no write access to entry"; goto return_results; } @@ -99,13 +100,8 @@ ldbm_back_delete( 0, 0 ); rs->sr_err = LDAP_REFERRAL; - rs->sr_matched = e->e_name.bv_val; - send_ldap_result( op, rs ); - - if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - rc = LDAP_REFERRAL; + rs->sr_matched = ch_strdup( e->e_name.bv_val ); + rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; goto return_results; } @@ -113,8 +109,8 @@ ldbm_back_delete( Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: non leaf %s\n", op->o_req_dn.bv_val, 0, 0); - send_ldap_error( op, rs, LDAP_NOT_ALLOWED_ON_NONLEAF, - "subordinate objects must be deleted first"); + rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF; + rs->sr_text = "subordinate objects must be deleted first"; goto return_results; } @@ -126,8 +122,8 @@ ldbm_back_delete( "<=- ldbm_back_delete: parent does not exist\n", 0, 0, 0); - send_ldap_error( op, rs, LDAP_OTHER, - "could not locate parent of entry" ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "could not locate parent of entry"; goto return_results; } @@ -139,8 +135,8 @@ ldbm_back_delete( "<=- ldbm_back_delete: no access to parent\n", 0, 0, 0 ); - send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, - "no write access to parent" ); + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + rs->sr_text = "no write access to parent"; goto return_results; } @@ -161,8 +157,8 @@ ldbm_back_delete( "<=- ldbm_back_delete: no " "access to parent\n", 0, 0, 0 ); - send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, - "no write access to parent" ); + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; + rs->sr_text = "no write access to parent"; goto return_results; } @@ -171,9 +167,7 @@ ldbm_back_delete( "<=- ldbm_back_delete: no parent & " "not root\n", 0, 0, 0); - send_ldap_error( op, rs, - LDAP_INSUFFICIENT_ACCESS, - NULL ); + rs->sr_err = LDAP_INSUFFICIENT_ACCESS; goto return_results; } } @@ -185,8 +179,8 @@ ldbm_back_delete( "<=- ldbm_back_delete: operations error %s\n", op->o_req_dn.bv_val, 0, 0); - send_ldap_error( op, rs, LDAP_OTHER, - "DN index delete failed" ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "DN index delete failed"; goto return_results; } @@ -196,8 +190,8 @@ ldbm_back_delete( "<=- ldbm_back_delete: operations error %s\n", op->o_req_dn.bv_val, 0, 0); - send_ldap_error( op, rs, LDAP_OTHER, - "entry delete failed" ); + rs->sr_err = LDAP_OTHER; + rs->sr_text = "entry delete failed"; goto return_results; } @@ -205,19 +199,25 @@ ldbm_back_delete( (void) index_entry_del( op, e ); rs->sr_err = LDAP_SUCCESS; - send_ldap_result( op, rs ); - rc = LDAP_SUCCESS; return_results:; + rc = rs->sr_err; + if( p != NULL ) { /* free parent and writer lock */ cache_return_entry_w( &li->li_cache, p ); } - /* free entry and writer lock */ - cache_return_entry_w( &li->li_cache, e ); + if ( e != NULL ) { + /* free entry and writer lock */ + cache_return_entry_w( &li->li_cache, e ); + } ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); + send_ldap_result( op, rs ); + if ( !SLAP_SHADOW( op->o_bd )) + slap_graduate_commit_csn( op ); + return rc; } diff --git a/servers/slapd/back-ldbm/modify.c b/servers/slapd/back-ldbm/modify.c index 2dd696919f..1df17bd4f7 100644 --- a/servers/slapd/back-ldbm/modify.c +++ b/servers/slapd/back-ldbm/modify.c @@ -241,6 +241,9 @@ ldbm_back_modify( Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0); + if ( !SLAP_SHADOW( op->o_bd )) + slap_mods_opattrs( op, op->orm_modlist, 1 ); + /* grab giant lock for writing */ ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock); @@ -250,7 +253,7 @@ ldbm_back_modify( /* FIXME: dn2entry() should return non-glue entry */ if (( e == NULL ) || ( !manageDSAit && e && is_entry_glue( e ))) { if ( matched != NULL ) { - rs->sr_matched = ch_strdup( matched->e_dn ); + rs->sr_matched = ber_strdup_x( matched->e_dn, op->o_tmpmemctx ); rs->sr_ref = is_entry_referral( matched ) ? get_entry_referrals( op, matched ) : NULL; @@ -260,16 +263,9 @@ ldbm_back_modify( &op->o_req_dn, LDAP_SCOPE_DEFAULT ); } - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); rs->sr_err = LDAP_REFERRAL; - send_ldap_result( op, rs ); - - if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref ); - free( (char *)rs->sr_matched ); - - rs->sr_ref = NULL; - rs->sr_matched = NULL; - return rs->sr_err; + rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; + goto return_results; } if ( !manageDSAit && is_entry_referral( e ) ) @@ -282,47 +278,31 @@ ldbm_back_modify( 0, 0 ); rs->sr_err = LDAP_REFERRAL; - rs->sr_matched = e->e_name.bv_val; - send_ldap_result( op, rs ); - - if ( rs->sr_ref ) ber_bvarray_free( rs->sr_ref ); - rs->sr_ref = NULL; - rs->sr_matched = NULL; - goto error_return; + rs->sr_matched = ber_strdup_x( e->e_name.bv_val, op->o_tmpmemctx ); + rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED; + goto return_results; } /* Modify the entry */ rs->sr_err = ldbm_modify_internal( op, op->oq_modify.rs_modlist, e, &rs->sr_text, textbuf, textlen ); - if( rs->sr_err != LDAP_SUCCESS ) { - if( rs->sr_err != SLAPD_ABANDON ) { - send_ldap_result( op, rs ); - } - - goto error_return; - } - /* change the entry itself */ - if ( id2entry_add( op->o_bd, e ) != 0 ) { - send_ldap_error( op, rs, LDAP_OTHER, - "id2entry failure" ); - rs->sr_err = LDAP_OTHER; - goto error_return; + if( rs->sr_err == LDAP_SUCCESS ) { + if ( id2entry_add( op->o_bd, e ) != 0 ) { + rs->sr_err = LDAP_OTHER; + rs->sr_text = "id2entry failure"; + } } - rs->sr_text = NULL; - send_ldap_error( op, rs, LDAP_SUCCESS, - NULL ); - +return_results:; cache_return_entry_w( &li->li_cache, e ); ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); - return LDAP_SUCCESS; + send_ldap_result( op, rs ); + if ( !SLAP_SHADOW( op->o_bd )) + slap_graduate_commit_csn( op ); -error_return:; - cache_return_entry_w( &li->li_cache, e ); - ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); rs->sr_text = NULL; return rs->sr_err; } diff --git a/servers/slapd/back-ldif/ldif.c b/servers/slapd/back-ldif/ldif.c index e6dd8a78f9..0b566f5b75 100644 --- a/servers/slapd/back-ldif/ldif.c +++ b/servers/slapd/back-ldif/ldif.c @@ -767,6 +767,8 @@ static int ldif_back_add(Operation *op, SlapReply *rs) { int statres; char textbuf[SLAP_TEXT_BUFLEN]; + slap_add_opattrs( op, &rs->sr_text, textbuf, sizeof( textbuf ), 1 ); + rs->sr_err = entry_schema_check(op, e, NULL, 0, &rs->sr_text, textbuf, sizeof( textbuf ) ); if ( rs->sr_err != LDAP_SUCCESS ) goto send_res; @@ -815,6 +817,8 @@ static int ldif_back_add(Operation *op, SlapReply *rs) { send_res: send_ldap_result(op, rs); + if ( !SLAP_SHADOW( op->o_bd )) + slap_graduate_commit_csn( op ); return 0; } @@ -825,6 +829,9 @@ static int ldif_back_modify(Operation *op, SlapReply *rs) { Entry * entry = NULL; int spew_res; + if ( !SLAP_SHADOW( op->o_bd )) + slap_mods_opattrs( op, op->orm_modlist, 1 ); + ldap_pvt_thread_mutex_lock(&ni->li_mutex); dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &path); @@ -853,6 +860,8 @@ static int ldif_back_modify(Operation *op, SlapReply *rs) { rs->sr_text = NULL; ldap_pvt_thread_mutex_unlock(&ni->li_mutex); send_ldap_result(op, rs); + if ( !SLAP_SHADOW( op->o_bd )) + slap_graduate_commit_csn( op ); return 0; } @@ -861,6 +870,15 @@ static int ldif_back_delete(Operation *op, SlapReply *rs) { struct berval path = BER_BVNULL; int res = 0; + if ( !SLAP_SHADOW( op->o_bd )) { + struct berval csn; + char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; + + csn.bv_val = csnbuf; + csn.bv_len = sizeof( csnbuf ); + slap_get_csn( op, &csn, 1 ); + } + ldap_pvt_thread_mutex_lock(&ni->li_mutex); dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &path); @@ -885,6 +903,8 @@ static int ldif_back_delete(Operation *op, SlapReply *rs) { SLAP_FREE(path.bv_val); ldap_pvt_thread_mutex_unlock(&ni->li_mutex); send_ldap_result(op, rs); + if ( !SLAP_SHADOW( op->o_bd )) + slap_graduate_commit_csn( op ); return 0; } diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index 548bfd835e..6656b774f3 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -936,9 +936,11 @@ backsql_add( Operation *op, SlapReply *rs ) */ if ( op->o_sync ) { char buf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; - struct berval csn = BER_BVNULL; + struct berval csn; - slap_get_csn( op, buf, sizeof( buf ), &csn, 1 ); + csn.bv_val = buf; + csn.bv_len = sizeof( buf ); + slap_get_csn( op, &csn, 1 ); rs->sr_err = LDAP_SUCCESS; send_ldap_result( op, rs ); diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c index 306e557d02..a6aca06c96 100644 --- a/servers/slapd/back-sql/modrdn.c +++ b/servers/slapd/back-sql/modrdn.c @@ -438,6 +438,7 @@ backsql_modrdn( Operation *op, SlapReply *rs ) oc = backsql_id2oc( bi, e_id.eid_oc_id ); rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id, mod ); + slap_graduate_commit_csn( op ); if ( rs->sr_err != LDAP_SUCCESS ) { e = &r; goto done; diff --git a/servers/slapd/back-sql/operational.c b/servers/slapd/back-sql/operational.c index 6edde629ca..1423e2156a 100644 --- a/servers/slapd/back-sql/operational.c +++ b/servers/slapd/back-sql/operational.c @@ -91,7 +91,9 @@ backsql_operational_entryCSN( Operation *op ) } else #endif /* BACKSQL_SYNCPROV */ { - slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 ); + entryCSN.bv_val = csnbuf; + entryCSN.bv_len = sizeof( csnbuf ); + slap_get_csn( op, &entryCSN, 0 ); } ber_dupbv( &a->a_vals[ 0 ], &entryCSN ); diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index aa8f1bb2b6..309d82fa1d 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -2138,7 +2138,7 @@ connection_fake_init( op->o_connid = op->o_conn->c_connid; connection_init_log_prefix( op ); - op->o_time = slap_get_time(); + slap_op_time( &op->o_time, &op->o_tincr ); } void diff --git a/servers/slapd/ctxcsn.c b/servers/slapd/ctxcsn.c index 6d29007b58..87d8cbc371 100644 --- a/servers/slapd/ctxcsn.c +++ b/servers/slapd/ctxcsn.c @@ -100,6 +100,9 @@ slap_graduate_commit_csn( Operation *op ) if ( csne->ce_opid == op->o_opid && csne->ce_connid == op->o_connid ) { LDAP_TAILQ_REMOVE( op->o_bd->be_pending_csn_list, csne, ce_csn_link ); + if ( op->o_csn.bv_val == csne->ce_csn.bv_val ) { + BER_BVZERO( &op->o_csn ); + } ch_free( csne->ce_csn.bv_val ); ch_free( csne ); break; @@ -163,6 +166,7 @@ slap_queue_csn( ldap_pvt_thread_mutex_lock( op->o_bd->be_pcl_mutexp ); ber_dupbv( &pending->ce_csn, csn ); + op->o_csn = pending->ce_csn; pending->ce_connid = op->o_connid; pending->ce_opid = op->o_opid; pending->ce_state = SLAP_CSN_PENDING; @@ -174,8 +178,6 @@ slap_queue_csn( int slap_get_csn( Operation *op, - char *csnbuf, - int len, struct berval *csn, int manage_ctxcsn ) { @@ -184,11 +186,10 @@ slap_get_csn( #ifndef HAVE_GMTIME_R ldap_pvt_thread_mutex_lock( &gmtime_mutex ); #endif - csn->bv_len = lutil_csnstr( csnbuf, len, 0, 0 ); + csn->bv_len = lutil_csnstr( csn->bv_val, csn->bv_len, 0, 0 ); #ifndef HAVE_GMTIME_R ldap_pvt_thread_mutex_unlock( &gmtime_mutex ); #endif - csn->bv_val = csnbuf; if ( manage_ctxcsn ) slap_queue_csn( op, csn ); diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index 51bb8d7902..078505cd22 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -91,8 +91,6 @@ do_delete( rs->sr_err = frontendDB->be_delete( op, rs ); cleanup:; - slap_graduate_commit_csn( op ); - op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); return rs->sr_err; @@ -174,12 +172,6 @@ fe_op_delete( Operation *op, SlapReply *rs ) op->o_bd = op_be; - if ( !repl_user ) { - struct berval csn = BER_BVNULL; - char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE]; - slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, 1 ); - } - #ifdef SLAPD_MULTIMASTER if ( !op->o_bd->be_update_ndn.bv_len || !repl_user ) #endif diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index ca628ef5ff..4473e1b7da 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -200,8 +200,6 @@ do_modify( rs->sr_err = frontendDB->be_modify( op, rs ); cleanup: - slap_graduate_commit_csn( op ); - op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); if ( op->orm_modlist != NULL ) slap_mods_free( op->orm_modlist, 1 ); @@ -388,22 +386,6 @@ fe_op_modify( Operation *op, SlapReply *rs ) } } - if ( !repl_user ) { - for( modtail = &modlist; - *modtail != NULL; - modtail = &(*modtail)->sml_next ) - { - /* empty */ - } - - rs->sr_err = slap_mods_opattrs( op, modlist, modtail, - &rs->sr_text, textbuf, textlen, 1 ); - if( rs->sr_err != LDAP_SUCCESS ) { - send_ldap_result( op, rs ); - goto cleanup; - } - } - op->orm_modlist = modlist; #ifdef SLAPD_MULTIMASTER if ( !repl_user ) @@ -825,35 +807,43 @@ void slap_timestamp( time_t *tm, struct berval *bv ) #endif } -int slap_mods_opattrs( +/* modify only calls this for non-replicas. modrdn always calls. + */ +void slap_mods_opattrs( Operation *op, Modifications *mods, - Modifications **modtail, - const char **text, - char *textbuf, size_t textlen, int manage_ctxcsn ) { - struct berval name, timestamp, csn; + struct berval name, timestamp, csn = BER_BVNULL; struct berval nname; char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; - Modifications *mod; - - int mop = op->o_tag == LDAP_REQ_ADD - ? LDAP_MOD_ADD : LDAP_MOD_REPLACE; - - assert( modtail != NULL ); - assert( *modtail == NULL ); + Modifications *mod, **modtail; if ( SLAP_LASTMOD( op->o_bd ) ) { - time_t now = slap_get_time(); - - slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, manage_ctxcsn ); - + char *ptr; timestamp.bv_val = timebuf; - timestamp.bv_len = sizeof(timebuf); + if ( BER_BVISEMPTY( &op->o_csn )) { + csn.bv_val = csnbuf; + csn.bv_len = sizeof( csnbuf ); + slap_get_csn( op, &csn, manage_ctxcsn ); + } else { + csn = op->o_csn; + } + ptr = strchr( csn.bv_val, '#' ); + if ( ptr ) { + timestamp.bv_len = ptr - csn.bv_val; + if ( timestamp.bv_len >= sizeof( timebuf )) + timestamp.bv_len = sizeof( timebuf ) - 1; + strncpy( timebuf, csn.bv_val, timestamp.bv_len ); + timebuf[timestamp.bv_len] = '\0'; + } else { + time_t now = slap_get_time(); - slap_timestamp( &now, ×tamp ); + timestamp.bv_len = sizeof(timebuf); + + slap_timestamp( &now, ×tamp ); + } if ( BER_BVISEMPTY( &op->o_dn ) ) { BER_BVSTR( &name, SLAPD_ANONYMOUS ); @@ -862,146 +852,13 @@ int slap_mods_opattrs( name = op->o_dn; nname = op->o_ndn; } - } - - if ( op->o_tag == LDAP_REQ_ADD ) { - struct berval tmpval; - - mod = *modtail; - if ( get_manageDIT( op ) ) { - for ( mod = mods; mod != *modtail; mod = mod->sml_next ) { - if ( mod->sml_desc == slap_schema.si_ad_structuralObjectClass ) { - break; - } - } - - } - - if ( mod == *modtail ) { - int rc = mods_structural_class( mods, &tmpval, - text, textbuf, textlen ); - if( rc != LDAP_SUCCESS ) return rc; - - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_flags = SLAP_MOD_INTERNAL; - mod->sml_next = NULL; - BER_BVZERO( &mod->sml_type ); - mod->sml_desc = slap_schema.si_ad_structuralObjectClass; - mod->sml_values = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], &tmpval ); - BER_BVZERO( &mod->sml_values[1] ); - assert( !BER_BVISNULL( &mod->sml_values[0] ) ); - mod->sml_nvalues = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_nvalues[0], &tmpval ); - BER_BVZERO( &mod->sml_nvalues[1] ); - assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) ); - *modtail = mod; - modtail = &mod->sml_next; - } - if ( SLAP_LASTMOD( op->o_bd ) ) { - mod = *modtail; - if ( get_manageDIT( op ) ) { - for ( mod = mods; mod != *modtail; mod = mod->sml_next ) { - if ( mod->sml_desc == slap_schema.si_ad_entryUUID ) { - break; - } - } - } - - if ( mod == *modtail ) { - char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ]; - - tmpval.bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) ); - tmpval.bv_val = uuidbuf; - - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_flags = SLAP_MOD_INTERNAL; - mod->sml_next = NULL; - BER_BVZERO( &mod->sml_type ); - mod->sml_desc = slap_schema.si_ad_entryUUID; - mod->sml_values = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], &tmpval ); - BER_BVZERO( &mod->sml_values[1] ); - assert( !BER_BVISNULL( &mod->sml_values[0] ) ); - mod->sml_nvalues = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - (*mod->sml_desc->ad_type->sat_equality->smr_normalize)( - SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, - mod->sml_desc->ad_type->sat_syntax, - mod->sml_desc->ad_type->sat_equality, - mod->sml_values, mod->sml_nvalues, NULL ); - BER_BVZERO( &mod->sml_nvalues[1] ); - *modtail = mod; - modtail = &mod->sml_next; - } - - mod = *modtail; - if ( get_manageDIT( op ) ) { - for ( mod = mods; mod != *modtail; mod = mod->sml_next ) { - if ( mod->sml_desc == slap_schema.si_ad_creatorsName ) { - break; - } - } - } - - if ( mod == *modtail ) { - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_flags = SLAP_MOD_INTERNAL; - mod->sml_next = NULL; - BER_BVZERO( &mod->sml_type ); - mod->sml_desc = slap_schema.si_ad_creatorsName; - mod->sml_values = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], &name ); - BER_BVZERO( &mod->sml_values[1] ); - assert( !BER_BVISNULL( &mod->sml_values[0] ) ); - mod->sml_nvalues = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_nvalues[0], &nname ); - BER_BVZERO( &mod->sml_nvalues[1] ); - assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) ); - *modtail = mod; - modtail = &mod->sml_next; - } - - mod = *modtail; - if ( get_manageDIT( op ) ) { - for ( mod = mods; mod != *modtail; mod = mod->sml_next ) { - if ( mod->sml_desc == slap_schema.si_ad_createTimestamp ) { - break; - } - } - } - - if ( mod == *modtail ) { - mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; - mod->sml_flags = SLAP_MOD_INTERNAL; - mod->sml_next = NULL; - BER_BVZERO( &mod->sml_type ); - mod->sml_desc = slap_schema.si_ad_createTimestamp; - mod->sml_values = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); - ber_dupbv( &mod->sml_values[0], ×tamp ); - BER_BVZERO( &mod->sml_values[1] ); - assert( !BER_BVISNULL( &mod->sml_values[0] ) ); - mod->sml_nvalues = NULL; - *modtail = mod; - modtail = &mod->sml_next; - } - } - } + for ( mod = mods; mod->sml_next; mod = mod->sml_next ) + ; + modtail = &mod->sml_next; - if ( SLAP_LASTMOD( op->o_bd ) ) { mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; + mod->sml_op = LDAP_MOD_REPLACE; mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_next = NULL; BER_BVZERO( &mod->sml_type ); @@ -1016,7 +873,7 @@ int slap_mods_opattrs( mod = *modtail; if ( get_manageDIT( op ) ) { - for ( mod = mods; mod != *modtail; mod = mod->sml_next ) { + for ( mod = mods; mod->sml_next; mod = mod->sml_next ) { if ( mod->sml_desc == slap_schema.si_ad_modifiersName ) { break; } @@ -1025,7 +882,7 @@ int slap_mods_opattrs( if ( mod == *modtail ) { mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; + mod->sml_op = LDAP_MOD_REPLACE; mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_next = NULL; BER_BVZERO( &mod->sml_type ); @@ -1045,7 +902,7 @@ int slap_mods_opattrs( mod = *modtail; if ( get_manageDIT( op ) ) { - for ( mod = mods; mod != *modtail; mod = mod->sml_next ) { + for ( mod = mods; mod->sml_next; mod = mod->sml_next ) { if ( mod->sml_desc == slap_schema.si_ad_modifyTimestamp ) { break; } @@ -1054,7 +911,7 @@ int slap_mods_opattrs( if ( mod == *modtail ) { mod = (Modifications *) ch_malloc( sizeof( Modifications ) ); - mod->sml_op = mop; + mod->sml_op = LDAP_MOD_REPLACE; mod->sml_flags = SLAP_MOD_INTERNAL; mod->sml_next = NULL; BER_BVZERO( &mod->sml_type ); @@ -1064,12 +921,7 @@ int slap_mods_opattrs( BER_BVZERO( &mod->sml_values[1] ); assert( !BER_BVISNULL( &mod->sml_values[0] ) ); mod->sml_nvalues = NULL; - *modtail = mod; - modtail = &mod->sml_next; } } - - *modtail = NULL; - return LDAP_SUCCESS; } diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index f54f714103..496abe34d7 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -178,8 +178,6 @@ do_modrdn( rs->sr_err = frontendDB->be_modrdn( op, rs ); cleanup: - slap_graduate_commit_csn( op ); - op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); @@ -386,7 +384,6 @@ slap_modrdn2mods( Modifications **pmod ) { Modifications *mod = NULL; - Modifications **modtail = &mod; int a_cnt, d_cnt; int repl_user; @@ -506,18 +503,7 @@ slap_modrdn2mods( done: if ( rs->sr_err == LDAP_SUCCESS && !repl_user ) { - char textbuf[ SLAP_TEXT_BUFLEN ]; - size_t textlen = sizeof textbuf; - - for( modtail = &mod; - *modtail != NULL; - modtail = &(*modtail)->sml_next ) - { - /* empty */ - } - - rs->sr_err = slap_mods_opattrs( op, mod, modtail, - &rs->sr_text, textbuf, textlen, 1 ); + slap_mods_opattrs( op, mod, 1 ); } /* LDAP v2 supporting correct attribute handling. */ diff --git a/servers/slapd/operation.c b/servers/slapd/operation.c index f8ecf3b920..68ee4d198a 100644 --- a/servers/slapd/operation.c +++ b/servers/slapd/operation.c @@ -112,6 +112,21 @@ slap_op_free( Operation *op ) ldap_pvt_thread_mutex_unlock( &slap_op_mutex ); } +void +slap_op_time(time_t *t, int *nop) +{ + *t = slap_get_time(); + ldap_pvt_thread_mutex_lock( &slap_op_mutex ); + if ( *t == last_time ) { + *nop = ++last_incr; + } else { + last_time = *t; + last_incr = 0; + *nop = 0; + } + ldap_pvt_thread_mutex_unlock( &slap_op_mutex ); +} + Operation * slap_op_alloc( BerElement *ber, @@ -139,13 +154,7 @@ slap_op_alloc( op->o_msgid = msgid; op->o_tag = tag; - op->o_time = slap_get_time(); - if ( op->o_time == last_time ) { - op->o_tincr = ++last_incr; - } else { - last_time = op->o_time; - last_incr = 0; /* o_tincr is alredy zero */ - } + slap_op_time( &op->o_time, &op->o_tincr ); op->o_opid = id; op->o_res_ber = NULL; diff --git a/servers/slapd/overlays/accesslog.c b/servers/slapd/overlays/accesslog.c index 9da3a59b30..9b35ac8805 100644 --- a/servers/slapd/overlays/accesslog.c +++ b/servers/slapd/overlays/accesslog.c @@ -58,6 +58,8 @@ typedef struct log_info { int li_cycle; struct re_s *li_task; int li_success; + ldap_pvt_thread_mutex_t li_op_mutex; + ldap_pvt_thread_mutex_t li_log_mutex; } log_info; static ConfigDriver log_cf_gen; @@ -735,11 +737,11 @@ static int accesslog_response(Operation *op, SlapReply *rs) { Modifications *m; struct berval *b; time_t endtime; - int i; + int i, nop; int logop; slap_verbmasks *lo; Entry *e; - char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE]; + char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE+8]; struct berval bv; char *ptr; BerVarray vals; @@ -749,9 +751,6 @@ static int accesslog_response(Operation *op, SlapReply *rs) { if ( rs->sr_type != REP_RESULT && rs->sr_type != REP_EXTENDED ) return SLAP_CB_CONTINUE; - if ( li->li_success && rs->sr_err != LDAP_SUCCESS ) - return SLAP_CB_CONTINUE; - switch ( op->o_tag ) { case LDAP_REQ_ADD: logop = LOG_EN_ADD; break; case LDAP_REQ_DELETE: logop = LOG_EN_DELETE; break; @@ -769,15 +768,25 @@ static int accesslog_response(Operation *op, SlapReply *rs) { if ( !( li->li_ops & lo->mask )) return SLAP_CB_CONTINUE; - endtime = slap_get_time(); + if ( lo->mask & LOG_OP_WRITES ) { + ldap_pvt_thread_mutex_lock( &li->li_log_mutex ); + ldap_pvt_thread_mutex_unlock( &li->li_op_mutex ); + } + + if ( li->li_success && rs->sr_err != LDAP_SUCCESS ) + goto done; + + slap_op_time( &endtime, &nop ); e = accesslog_entry( op, logop ); bv.bv_val = timebuf; bv.bv_len = sizeof(timebuf); slap_timestamp( &endtime, &bv ); + sprintf( bv.bv_val + bv.bv_len-1, ".%06dZ", nop ); + bv.bv_len += 7; - attr_merge_one( e, ad_reqEnd, &bv, NULL ); + attr_merge_normalize_one( e, ad_reqEnd, &bv, op->o_tmpmemctx ); attr_merge_one( e, ad_reqDN, &op->o_req_dn, &op->o_req_ndn ); @@ -980,16 +989,30 @@ static int accesslog_response(Operation *op, SlapReply *rs) { op2.ora_e = e; op2.o_callback = &nullsc; - if ( lo->mask & LOG_OP_WRITES ) { - slap_get_commit_csn( op, NULL, &bv ); - attr_merge_one( e, slap_schema.si_ad_entryCSN, &bv, NULL ); - slap_queue_csn( &op2, &bv ); + if (( lo->mask & LOG_OP_WRITES ) && !BER_BVISEMPTY( &op->o_csn )) { + slap_queue_csn( &op2, &op->o_csn ); } op2.o_bd->be_add( &op2, &rs2 ); - slap_graduate_commit_csn( &op2 ); entry_free( e ); +done: + ldap_pvt_thread_mutex_unlock( &li->li_log_mutex ); + return SLAP_CB_CONTINUE; +} + +static int +accesslog_op_mod( Operation *op, SlapReply *rs ) +{ + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + log_info *li = on->on_bi.bi_private; + + if ( li->li_ops & LOG_OP_WRITES ) { + /* FIXME: this needs to be a recursive mutex to allow + * overlays like refint to keep working. + */ + ldap_pvt_thread_mutex_lock( &li->li_op_mutex ); + } return SLAP_CB_CONTINUE; } @@ -1076,6 +1099,8 @@ accesslog_db_init( log_info *li = ch_calloc(1, sizeof(log_info)); on->on_bi.bi_private = li; + ldap_pvt_thread_mutex_init( &li->li_op_mutex ); + ldap_pvt_thread_mutex_init( &li->li_log_mutex ); return 0; } @@ -1087,6 +1112,8 @@ accesslog_db_destroy( slap_overinst *on = (slap_overinst *)be->bd_info; log_info *li = on->on_bi.bi_private; + ldap_pvt_thread_mutex_destroy( &li->li_log_mutex ); + ldap_pvt_thread_mutex_destroy( &li->li_op_mutex ); free( li ); return LDAP_SUCCESS; } @@ -1099,6 +1126,10 @@ int accesslog_init() accesslog.on_bi.bi_db_init = accesslog_db_init; accesslog.on_bi.bi_db_destroy = accesslog_db_destroy; + accesslog.on_bi.bi_op_add = accesslog_op_mod; + accesslog.on_bi.bi_op_delete = accesslog_op_mod; + accesslog.on_bi.bi_op_modify = accesslog_op_mod; + accesslog.on_bi.bi_op_modrdn = accesslog_op_mod; accesslog.on_bi.bi_op_unbind = accesslog_unbind; accesslog.on_bi.bi_op_abandon = accesslog_abandon; accesslog.on_response = accesslog_response; diff --git a/servers/slapd/overlays/lastmod.c b/servers/slapd/overlays/lastmod.c index 07e06eb0d2..63a30e6301 100644 --- a/servers/slapd/overlays/lastmod.c +++ b/servers/slapd/overlays/lastmod.c @@ -370,7 +370,9 @@ best_guess( Operation *op, char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; struct berval entryCSN; - slap_get_csn( NULL, csnbuf, sizeof(csnbuf), &entryCSN, 0 ); + entryCSN.bv_val = csnbuf; + entryCSN.bv_len = sizeof( csnbuf ); + slap_get_csn( NULL, &entryCSN, 0 ); ber_dupbv( bv_entryCSN, &entryCSN ); ber_dupbv( bv_nentryCSN, &entryCSN ); @@ -909,7 +911,9 @@ lastmod_db_open( timestamp.bv_len = sizeof(tmbuf); slap_timestamp( &starttime, ×tamp ); - slap_get_csn( NULL, csnbuf, sizeof(csnbuf), &entryCSN, 0 ); + entryCSN.bv_val = csnbuf; + entryCSN.bv_len = sizeof( csnbuf ); + slap_get_csn( NULL, &entryCSN, 0 ); if ( BER_BVISNULL( &lmi->lmi_rdnvalue ) ) { ber_str2bv( "Lastmod", 0, 1, &lmi->lmi_rdnvalue ); diff --git a/servers/slapd/overlays/refint.c b/servers/slapd/overlays/refint.c index 41e1cbc9cf..9004f902f9 100644 --- a/servers/slapd/overlays/refint.c +++ b/servers/slapd/overlays/refint.c @@ -621,10 +621,6 @@ refint_response( */ for(dp = dd.mods; dp; dp = dp->next) { - Modifications **tail, *m; - - for(m = dp->mm; m && m->sml_next; m = m->sml_next); - tail = &m->sml_next; nop.o_req_dn = dp->dn; nop.o_req_ndn = dp->dn; nop.o_bd = select_backend(&dp->dn, 0, 1); @@ -637,8 +633,6 @@ refint_response( nop.orm_modlist = dp->mm; /* callback did all the work */ nop.o_dn = refint_dn; nop.o_ndn = refint_dn; - rs->sr_err = slap_mods_opattrs( &nop, nop.orm_modlist, - tail, &rs->sr_text, NULL, 0, 1 ); nop.o_dn = nop.o_bd->be_rootdn; nop.o_ndn = nop.o_bd->be_rootndn; if(rs->sr_err != LDAP_SUCCESS) goto done; diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 4070d5dd09..38946321c1 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -2275,8 +2275,8 @@ syncprov_db_open( } if ( BER_BVISEMPTY( &si->si_ctxcsn ) ) { - slap_get_csn( op, si->si_ctxcsnbuf, sizeof(si->si_ctxcsnbuf), - &si->si_ctxcsn, 0 ); + si->si_ctxcsn.bv_len = sizeof( si->si_ctxcsnbuf ); + slap_get_csn( op, &si->si_ctxcsn, 0 ); } /* If our ctxcsn is different from what was read from the root diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index 4c69a2e6b5..fee10439dd 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -273,12 +273,7 @@ old_good: cb2.sc_private = qpw; /* let Modify know this was pwdMod, * if it cares... */ - rs->sr_err = slap_mods_opattrs( op, ml, qpw->rs_modtail, &rs->sr_text, - NULL, 0, 1 ); - - if ( rs->sr_err == LDAP_SUCCESS ) { - rs->sr_err = op->o_bd->be_modify( op, rs ); - } + rs->sr_err = op->o_bd->be_modify( op, rs ); if ( rs->sr_err == LDAP_SUCCESS ) { rs->sr_rspdata = rsp; } else if ( rsp ) { diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 995bc05359..6369ef409d 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -206,6 +206,12 @@ LDAP_SLAPD_F (int) slap_mods2entry LDAP_P(( Modifications *mods, Entry **e, LDAP_SLAPD_F (int) slap_entry2mods LDAP_P(( Entry *e, Modifications **mods, const char **text, char *textbuf, size_t textlen )); +LDAP_SLAPD_F( int ) slap_add_opattrs( + Operation *op, + const char **text, + char *textbuf, size_t textlen, + int manage_ctxcsn ); + /* * at.c @@ -697,7 +703,7 @@ LDAP_SLAPD_F (void) slap_get_commit_csn LDAP_P(( LDAP_SLAPD_F (void) slap_rewind_commit_csn LDAP_P(( Operation * )); LDAP_SLAPD_F (void) slap_graduate_commit_csn LDAP_P(( Operation * )); LDAP_SLAPD_F (Entry *) slap_create_context_csn_entry LDAP_P(( Backend *, struct berval *)); -LDAP_SLAPD_F (int) slap_get_csn LDAP_P(( Operation *, char *, int, struct berval *, int )); +LDAP_SLAPD_F (int) slap_get_csn LDAP_P(( Operation *, struct berval *, int )); LDAP_SLAPD_F (void) slap_queue_csn LDAP_P(( Operation *, struct berval * )); /* @@ -1041,12 +1047,9 @@ LDAP_SLAPD_F( void ) slap_timestamp( time_t *tm, struct berval *bv ); -LDAP_SLAPD_F( int ) slap_mods_opattrs( +LDAP_SLAPD_F( void ) slap_mods_opattrs( Operation *op, Modifications *mods, - Modifications **modlist, - const char **text, - char *textbuf, size_t textlen, int manage_ctxcsn ); /* @@ -1210,6 +1213,7 @@ LDAP_SLAPD_F (int) parse_oidm LDAP_P(( LDAP_SLAPD_F (void) slap_op_init LDAP_P(( void )); LDAP_SLAPD_F (void) slap_op_destroy LDAP_P(( void )); LDAP_SLAPD_F (void) slap_op_free LDAP_P(( Operation *op )); +LDAP_SLAPD_F (void) slap_op_time LDAP_P(( time_t *t, int *n )); LDAP_SLAPD_F (Operation *) slap_op_alloc LDAP_P(( BerElement *ber, ber_int_t msgid, ber_tag_t tag, ber_int_t id )); diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index 66c591a956..394c0a0871 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -374,7 +374,7 @@ slap_auxprop_lookup( op.o_tag = LDAP_REQ_SEARCH; op.o_ndn = conn->c_ndn; op.o_callback = &cb; - op.o_time = slap_get_time(); + slap_op_time( &op.o_time, &op.o_tincr ); op.o_do_not_cache = 1; op.o_is_auth_check = 1; op.o_req_dn = op.o_req_ndn; @@ -472,22 +472,17 @@ slap_auxprop_store( &text, textbuf, textlen ); if ( rc == LDAP_SUCCESS ) { - rc = slap_mods_opattrs( &op, modlist, modtail, - &text, textbuf, textlen, 1 ); - - if ( rc == LDAP_SUCCESS ) { - op.o_hdr = conn->c_sasl_bindop->o_hdr; - op.o_tag = LDAP_REQ_MODIFY; - op.o_ndn = op.o_req_ndn; - op.o_callback = &cb; - op.o_time = slap_get_time(); - op.o_do_not_cache = 1; - op.o_is_auth_check = 1; - op.o_req_dn = op.o_req_ndn; - op.orm_modlist = modlist; - - rc = op.o_bd->be_modify( &op, &rs ); - } + op.o_hdr = conn->c_sasl_bindop->o_hdr; + op.o_tag = LDAP_REQ_MODIFY; + op.o_ndn = op.o_req_ndn; + op.o_callback = &cb; + slap_op_time( &op.o_time, &op.o_tincr ); + op.o_do_not_cache = 1; + op.o_is_auth_check = 1; + op.o_req_dn = op.o_req_ndn; + op.orm_modlist = modlist; + + rc = op.o_bd->be_modify( &op, &rs ); } } slap_mods_free( modlist, 1 ); diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index d2d2facdad..a7ef89783d 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -1831,7 +1831,7 @@ exact_match: op.o_tag = LDAP_REQ_SEARCH; op.o_ndn = *authc; op.o_callback = &cb; - op.o_time = slap_get_time(); + slap_op_time( &op.o_time, &op.o_tincr ); op.o_do_not_cache = 1; op.o_is_auth_check = 1; /* use req_ndn as req_dn instead of non-pretty base of uri */ @@ -1999,7 +1999,7 @@ slap_sasl2dn( op.o_tag = LDAP_REQ_SEARCH; op.o_ndn = opx->o_conn->c_ndn; op.o_callback = &cb; - op.o_time = slap_get_time(); + slap_op_time( &op.o_time, &op.o_tincr ); op.o_do_not_cache = 1; op.o_is_auth_check = 1; op.ors_deref = LDAP_DEREF_NEVER; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index a0c66a555c..30dbdc3582 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -2553,6 +2553,7 @@ typedef struct slap_op { BerElement *o_res_ber; /* ber of the CLDAP reply or readback control */ slap_callback *o_callback; /* callback pointers */ LDAPControl **o_ctrls; /* controls */ + struct berval o_csn; void *o_private; /* anything the backend needs */ diff --git a/servers/slapd/slapi/slapi_ops.c b/servers/slapd/slapi/slapi_ops.c index 3820f57af2..376fd48abb 100644 --- a/servers/slapd/slapi/slapi_ops.c +++ b/servers/slapd/slapi/slapi_ops.c @@ -409,7 +409,6 @@ slapi_delete_internal_pb( Slapi_PBlock *pb ) PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_DELETE ); slapi_int_func_internal_pb( pb, op_delete ); - slap_graduate_commit_csn( pb->pb_op ); return 0; } @@ -492,7 +491,6 @@ slapi_add_internal_pb( Slapi_PBlock *pb ) } cleanup: - slap_graduate_commit_csn( pb->pb_op ); if ( pb->pb_op->ora_e != NULL ) { slapi_entry_free( pb->pb_op->ora_e ); @@ -524,7 +522,6 @@ slapi_modrdn_internal_pb( Slapi_PBlock *pb ) slapi_int_func_internal_pb( pb, op_modrdn ); cleanup: - slap_graduate_commit_csn( pb->pb_op ); return 0; } @@ -561,7 +558,6 @@ slapi_modify_internal_pb( Slapi_PBlock *pb ) slapi_int_func_internal_pb( pb, op_modify ); cleanup: - slap_graduate_commit_csn( pb->pb_op ); return 0; } diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index deeacc5f49..250e06910d 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -1633,6 +1633,11 @@ syncrepl_entry( switch ( syncstate ) { case LDAP_SYNC_ADD: case LDAP_SYNC_MODIFY: + { + Attribute *a = attr_find( entry->e_attrs, slap_schema.si_ad_entryCSN ); + if ( a ) + op->o_csn = a->a_vals[0]; + } retry_add:; if ( BER_BVISNULL( &dni.dn )) { @@ -1852,6 +1857,7 @@ done : if ( !BER_BVISNULL( &dni.dn ) ) { op->o_tmpfree( dni.dn.bv_val, op->o_tmpmemctx ); } + BER_BVZERO( &op->o_csn ); return ret; }