1 /* cancel.c - LDAP cancel extended operation */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/cancel.c,v 1.23.2.4 2008/02/11 23:26:43 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
21 #include <ac/socket.h>
22 #include <ac/string.h>
23 #include <ac/unistd.h>
30 const struct berval slap_EXOP_CANCEL
= BER_BVC(LDAP_EXOP_CANCEL
);
32 int cancel_extop( Operation
*op
, SlapReply
*rs
)
39 assert( ber_bvcmp( &slap_EXOP_CANCEL
, &op
->ore_reqoid
) == 0 );
41 if ( op
->ore_reqdata
== NULL
) {
42 rs
->sr_text
= "no message ID supplied";
43 return LDAP_PROTOCOL_ERROR
;
46 ber
= ber_init( op
->ore_reqdata
);
48 rs
->sr_text
= "internal error";
52 if ( ber_scanf( ber
, "{i}", &opid
) == LBER_ERROR
) {
53 rs
->sr_text
= "message ID parse failed";
54 return LDAP_PROTOCOL_ERROR
;
57 (void) ber_free( ber
, 1 );
59 Statslog( LDAP_DEBUG_STATS
, "%s CANCEL msg=%d\n",
60 op
->o_log_prefix
, opid
, 0, 0, 0 );
63 rs
->sr_text
= "message ID invalid";
64 return LDAP_PROTOCOL_ERROR
;
67 ldap_pvt_thread_mutex_lock( &op
->o_conn
->c_mutex
);
68 LDAP_STAILQ_FOREACH( o
, &op
->o_conn
->c_pending_ops
, o_next
) {
69 if ( o
->o_msgid
== opid
) {
70 LDAP_STAILQ_REMOVE( &op
->o_conn
->c_pending_ops
, o
, Operation
, o_next
);
71 LDAP_STAILQ_NEXT(o
, o_next
) = NULL
;
72 op
->o_conn
->c_n_ops_pending
--;
73 slap_op_free( o
, NULL
);
74 ldap_pvt_thread_mutex_unlock( &op
->o_conn
->c_mutex
);
79 LDAP_STAILQ_FOREACH( o
, &op
->o_conn
->c_ops
, o_next
) {
80 if ( o
->o_msgid
== opid
) {
86 ldap_pvt_thread_mutex_unlock( &op
->o_conn
->c_mutex
);
89 if ( o
->o_cancel
!= SLAP_CANCEL_NONE
) {
90 rs
->sr_text
= "message ID already being cancelled";
91 return LDAP_PROTOCOL_ERROR
;
94 o
->o_cancel
= SLAP_CANCEL_REQ
;
96 LDAP_STAILQ_FOREACH( op
->o_bd
, &backendDB
, be_next
) {
97 if( !op
->o_bd
->be_cancel
) continue;
99 op
->oq_cancel
.rs_msgid
= opid
;
100 if ( op
->o_bd
->be_cancel( op
, rs
) == LDAP_SUCCESS
) {
105 while ( o
->o_cancel
== SLAP_CANCEL_REQ
) {
106 ldap_pvt_thread_yield();
109 if ( o
->o_cancel
== SLAP_CANCEL_ACK
) {
115 o
->o_cancel
= SLAP_CANCEL_DONE
;
117 rs
->sr_text
= "message ID not found";
118 rc
= LDAP_NO_SUCH_OPERATION
;