mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-21 15:19:34 -05:00
Additional TXN changes
This commit is contained in:
parent
8ac8d70a55
commit
fad69dbef8
3 changed files with 113 additions and 29 deletions
|
|
@ -74,7 +74,13 @@ ldap_txn_end(
|
|||
assert( txnid != NULL );
|
||||
|
||||
txnber = ber_alloc_t( LBER_USE_DER );
|
||||
ber_printf( txnber, "{io}", commit, txnid );
|
||||
|
||||
if( commit ) {
|
||||
ber_printf( txnber, "{o}", txnid );
|
||||
} else {
|
||||
ber_printf( txnber, "{bo}", commit, txnid );
|
||||
}
|
||||
|
||||
ber_flatten( txnber, &txnval );
|
||||
|
||||
rc = ldap_extended_operation( ld, LDAP_EXOP_X_TXN_END,
|
||||
|
|
@ -93,30 +99,23 @@ ldap_txn_end_s(
|
|||
LDAPControl **cctrls,
|
||||
int *retidp )
|
||||
{
|
||||
int rc, msgid;
|
||||
struct berval *retdata = NULL;
|
||||
LDAPMessage *res;
|
||||
int rc;
|
||||
BerElement *txnber = NULL;
|
||||
struct berval *txnval = NULL;
|
||||
|
||||
rc = ldap_txn_end( ld, commit, txnid, sctrls, cctrls, &msgid );
|
||||
if( rc != LDAP_SUCCESS ) return rc;
|
||||
txnber = ber_alloc_t( LBER_USE_DER );
|
||||
|
||||
if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res )
|
||||
== -1 )
|
||||
{
|
||||
return ld->ld_errno;
|
||||
if( commit ) {
|
||||
ber_printf( txnber, "{o}", txnid );
|
||||
} else {
|
||||
ber_printf( txnber, "{bo}", commit, txnid );
|
||||
}
|
||||
|
||||
rc = ldap_parse_extended_result( ld, res, NULL, &retdata, 0 );
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
ldap_msgfree( res );
|
||||
ber_flatten( txnber, &txnval );
|
||||
|
||||
rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_TXN_END,
|
||||
txnval, sctrls, cctrls, NULL, NULL );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* don't bother parsing the retdata (yet) */
|
||||
if( retidp != NULL ) {
|
||||
*retidp = 0;
|
||||
}
|
||||
|
||||
return ldap_result2error( ld, res, 1 );
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2634,6 +2634,10 @@ typedef struct slap_conn {
|
|||
void *c_sasl_extra; /* SASL session extra stuff */
|
||||
struct slap_op *c_sasl_bindop; /* set to current op if it's a bind */
|
||||
|
||||
#ifdef LDAP_X_TXN
|
||||
int c_txn; /* in transaction */
|
||||
#endif
|
||||
|
||||
PagedResultsState c_pagedresults_state; /* paged result state */
|
||||
|
||||
long c_n_ops_received; /* num of ops received (next op_id) */
|
||||
|
|
|
|||
|
|
@ -35,16 +35,17 @@ const struct berval slap_EXOP_TXN_END = BER_BVC(LDAP_EXOP_X_TXN_END);
|
|||
int txn_start_extop(
|
||||
Operation *op, SlapReply *rs )
|
||||
{
|
||||
int rc;
|
||||
struct berval *bv;
|
||||
|
||||
Statslog( LDAP_DEBUG_STATS, "%s TXN START\n",
|
||||
op->o_log_prefix, 0, 0, 0, 0 );
|
||||
|
||||
if( op->ore_reqdata != NULL ) {
|
||||
rs->sr_text = "no request data expected";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
Statslog( LDAP_DEBUG_STATS, "%s TXN START\n",
|
||||
op->o_log_prefix, 0, 0, 0, 0 );
|
||||
|
||||
op->o_bd = op->o_conn->c_authz_backend;
|
||||
if( backend_check_restrictions( op, rs,
|
||||
(struct berval *)&slap_EXOP_TXN_START ) != LDAP_SUCCESS )
|
||||
|
|
@ -52,12 +53,28 @@ int txn_start_extop(
|
|||
return rs->sr_err;
|
||||
}
|
||||
|
||||
/* acquire connection lock */
|
||||
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
|
||||
|
||||
if( op->o_conn->c_txn ) {
|
||||
rs->sr_text = "Too many transactions";
|
||||
rc = LDAP_BUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
++op->o_conn->c_txn;
|
||||
|
||||
bv = (struct berval *) ch_malloc( sizeof (struct berval) );
|
||||
bv->bv_len = 0;
|
||||
bv->bv_val = NULL;
|
||||
|
||||
rs->sr_rspdata = bv;
|
||||
return LDAP_SUCCESS;
|
||||
rc = LDAP_SUCCESS;
|
||||
|
||||
done:
|
||||
/* release connection lock */
|
||||
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
|
||||
return rc;
|
||||
}
|
||||
|
||||
int txn_spec_ctrl(
|
||||
|
|
@ -88,13 +105,25 @@ int txn_spec_ctrl(
|
|||
int txn_end_extop(
|
||||
Operation *op, SlapReply *rs )
|
||||
{
|
||||
int rc;
|
||||
BerElementBuffer berbuf;
|
||||
BerElement *ber = (BerElement *)&berbuf;
|
||||
ber_tag_t tag;
|
||||
ber_len_t len;
|
||||
ber_int_t commit=1;
|
||||
struct berval txnid;
|
||||
|
||||
Statslog( LDAP_DEBUG_STATS, "%s TXN END\n",
|
||||
op->o_log_prefix, 0, 0, 0, 0 );
|
||||
|
||||
if( op->ore_reqdata == NULL ) {
|
||||
rs->sr_text = "request data expected";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
Statslog( LDAP_DEBUG_STATS, "%s TXN END\n",
|
||||
op->o_log_prefix, 0, 0, 0, 0 );
|
||||
if( op->ore_reqdata->bv_len == 0 ) {
|
||||
rs->sr_text = "empty request data";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
op->o_bd = op->o_conn->c_authz_backend;
|
||||
if( backend_check_restrictions( op, rs,
|
||||
|
|
@ -103,8 +132,60 @@ int txn_end_extop(
|
|||
return rs->sr_err;
|
||||
}
|
||||
|
||||
ber_init2( ber, op->ore_reqdata, 0 );
|
||||
|
||||
tag = ber_scanf( ber, "{" /*}*/ );
|
||||
if( tag == LBER_ERROR ) {
|
||||
rs->sr_text = "request data decoding error";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
tag = ber_peek_tag( ber, &len );
|
||||
assert( tag == LBER_BOOLEAN );
|
||||
if( tag == LBER_BOOLEAN ) {
|
||||
tag = ber_scanf( ber, "b", &commit );
|
||||
if( tag == LBER_ERROR ) {
|
||||
rs->sr_text = "request data decoding error";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
tag = ber_scanf( ber, /*{*/ "m}", &txnid );
|
||||
if( tag == LBER_ERROR ) {
|
||||
rs->sr_text = "request data decoding error";
|
||||
return LDAP_PROTOCOL_ERROR;
|
||||
}
|
||||
|
||||
if( txnid.bv_len ) {
|
||||
rs->sr_text = "invalid transaction identifier";
|
||||
return LDAP_X_TXN_ID_INVALID;
|
||||
}
|
||||
|
||||
/* acquire connection lock */
|
||||
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
|
||||
|
||||
if( op->o_conn->c_txn == 0 ) {
|
||||
rs->sr_text = "invalid transaction identifier";
|
||||
rc = LDAP_X_TXN_ID_INVALID;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if( commit ) {
|
||||
rs->sr_text = "not yet implemented";
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
rc = LDAP_UNWILLING_TO_PERFORM;
|
||||
|
||||
} else {
|
||||
rs->sr_text = "transaction aborted";
|
||||
rc = LDAP_SUCCESS;;
|
||||
}
|
||||
|
||||
op->o_conn->c_txn = 0;
|
||||
|
||||
done:
|
||||
/* release connection lock */
|
||||
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* LDAP_X_TXN */
|
||||
|
|
|
|||
Loading…
Reference in a new issue