[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
LDAP cancel operation (ITS#2287)
Full_Name: Jong Hyuk Choi
Version: HEAD
OS: Linux RH 7.3
URL:
Submission from: (NULL) (129.34.20.17)
The following is an implementation of the LDAP cancel operation
described in http://www.ietf.org/internet-drafts/draft-zeilenga-ldap-cancel-07.txt
I'll commit it unless major issues arise.
- Jong
========================================================================
diff -Naurp --exclude CVS --exclude TAGS ldap/include/ldap.h
ldap-cancel/include/ldap.h
--- ldap/include/ldap.h Thu Jan 23 10:11:19 2003
+++ ldap-cancel/include/ldap.h Thu Jan 23 10:27:52 2003
@@ -486,6 +486,17 @@ typedef struct ldapcontrol {
#define LDAP_CUP_DEFAULT_SEND_COOKIE_INTERVAL 0x01
#endif /* LDAP_CLIENT_UPDATE */
+/* resultCode for Cancel Response */
+#define LDAP_CANCELLED 0x68
+#define LDAP_NO_SUCH_OPERATION 0x69
+#define LDAP_TOO_LATE 0x6a
+#define LDAP_CANNOT_CANCEL 0x6b
+
+#define LDAP_CANCEL_NONE 0x00
+#define LDAP_CANCEL_REQ 0x01
+#define LDAP_CANCEL_ACK 0x02
+#define LDAP_CANCEL_NOTDONE 0x03
+
/*
* This structure represents both ldap messages and ldap responses.
* These are really the same, except in the case of search responses,
diff -Naurp --exclude CVS --exclude TAGS ldap/libraries/libldap/Makefile.in
ldap-cancel/libraries/libldap/Makefile.in
--- ldap/libraries/libldap/Makefile.in Fri Jan 3 14:20:51 2003
+++ ldap-cancel/libraries/libldap/Makefile.in Thu Jan 23 10:23:08 2003
@@ -16,7 +16,8 @@ SRCS = bind.c open.c result.c error.c co
getdn.c getentry.c getattr.c getvalues.c addentry.c \
request.c os-ip.c url.c sortctrl.c vlvctrl.c \
init.c options.c print.c string.c util-int.c schema.c \
- charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c
+ charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \
+ cancel.c
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
controls.lo messages.lo references.lo extended.lo cyrus.lo \
modify.lo add.lo modrdn.lo delete.lo abandon.lo cache.lo \
@@ -25,7 +26,8 @@ OBJS = bind.lo open.lo result.lo error.l
getdn.lo getentry.lo getattr.lo getvalues.lo addentry.lo \
request.lo os-ip.lo url.lo sortctrl.lo vlvctrl.lo \
init.lo options.lo print.lo string.lo util-int.lo schema.lo \
- charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo
+ charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \
+ cancel.lo
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
diff -Naurp --exclude CVS --exclude TAGS ldap/libraries/libldap/cancel.c
ldap-cancel/libraries/libldap/cancel.c
--- ldap/libraries/libldap/cancel.c Wed Dec 31 19:00:00 1969
+++ ldap-cancel/libraries/libldap/cancel.c Thu Jan 23 11:00:20 2003
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+/*
+ * LDAPv3 Cancel Operation Request
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/stdlib.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
+#include "ldap-int.h"
+#include "ldap_log.h"
+
+int
+ldap_cancel(
+ LDAP *ld,
+ int cancelid,
+ LDAPControl **sctrls,
+ LDAPControl **cctrls,
+ int *msgidp )
+{
+ BerElement *cancelidber = NULL;
+ struct berval *cancelidvalp = NULL;
+ int rc;
+
+ cancelidber = ber_alloc_t( LBER_USE_DER );
+ ber_printf( cancelidber, "{i}", cancelid );
+ ber_flatten( cancelidber, &cancelidvalp );
+ rc = ldap_extended_operation( ld, LDAP_EXOP_X_CANCEL,
+ cancelidvalp, sctrls, cctrls, msgidp );
+ ber_free( cancelidber, 1 );
+ return rc;
+}
+
+int
+ldap_cancel_s(
+ LDAP *ld,
+ int cancelid,
+ LDAPControl **sctrls,
+ LDAPControl **cctrls )
+{
+ BerElement *cancelidber = NULL;
+ struct berval *cancelidvalp = NULL;
+ int rc;
+
+ cancelidber = ber_alloc_t( LBER_USE_DER );
+ ber_printf( cancelidber, "{i}", cancelid );
+ ber_flatten( cancelidber, &cancelidvalp );
+ rc = ldap_extended_operation_s( ld, LDAP_EXOP_X_CANCEL,
+ cancelidvalp, sctrls, cctrls, NULL, NULL );
+ ber_free( cancelidber, 1 );
+ return rc;
+}
diff -Naurp --exclude CVS --exclude TAGS ldap/servers/slapd/Makefile.in
ldap-cancel/servers/slapd/Makefile.in
--- ldap/servers/slapd/Makefile.in Sun Jan 19 16:43:29 2003
+++ ldap-cancel/servers/slapd/Makefile.in Thu Jan 23 10:23:09 2003
@@ -19,7 +19,7 @@ SRCS = main.c daemon.c connection.c sear
schemaparse.c ad.c at.c mr.c syntax.c oc.c saslauthz.c \
oidm.c starttls.c index.c sets.c referral.c \
root_dse.c sasl.c module.c suffixalias.c mra.c mods.c \
- limits.c backglue.c operational.c matchedValues.c \
+ limits.c backglue.c operational.c matchedValues.c cancel.c \
$(@PLAT@_SRCS)
OBJS = main.o daemon.o connection.o search.o filter.o add.o cr.o \
@@ -32,7 +32,7 @@ OBJS = main.o daemon.o connection.o sear
schemaparse.o ad.o at.o mr.o syntax.o oc.o saslauthz.o \
oidm.o starttls.o index.o sets.o referral.o \
root_dse.o sasl.o module.o suffixalias.o mra.o mods.o \
- limits.o backglue.o operational.o matchedValues.o \
+ limits.o backglue.o operational.o matchedValues.o cancel.o \
$(@PLAT@_OBJS)
LDAP_INCDIR= ../../include -Islapi
diff -Naurp --exclude CVS --exclude TAGS ldap/servers/slapd/back-bdb/search.c
ldap-cancel/servers/slapd/back-bdb/search.c
--- ldap/servers/slapd/back-bdb/search.c Sun Jan 19 07:10:18 2003
+++ ldap-cancel/servers/slapd/back-bdb/search.c Thu Jan 23 10:23:09 2003
@@ -433,6 +433,15 @@ loop_begin:
goto done;
}
+ if ( op->o_cancel ) {
+ assert( op->o_cancel == LDAP_CANCEL_REQ );
+ rc = 0;
+ send_search_result( conn, op, LDAP_CANCELLED,
+ NULL, NULL, NULL, NULL, 0 );
+ op->o_cancel = LDAP_CANCEL_ACK;
+ goto done;
+ }
+
/* check time limit */
if ( tlimit != -1 && slap_get_time() > stoptime ) {
send_search_result( conn, op, rc = LDAP_TIMELIMIT_EXCEEDED,
diff -Naurp --exclude CVS --exclude TAGS ldap/servers/slapd/backend.c
ldap-cancel/servers/slapd/backend.c
--- ldap/servers/slapd/backend.c Mon Jan 20 20:46:55 2003
+++ ldap-cancel/servers/slapd/backend.c Thu Jan 23 10:23:09 2003
@@ -870,6 +870,13 @@ backend_check_restrictions(
}
}
+ {
+ struct berval bv = BER_BVC( LDAP_EXOP_X_CANCEL );
+ if ( bvmatch( opdata, &bv ) ) {
+ break;
+ }
+ }
+
/* treat everything else as a modify */
opflag = SLAP_RESTRICT_OP_MODIFY;
updateop++;
diff -Naurp --exclude CVS --exclude TAGS ldap/servers/slapd/cancel.c
ldap-cancel/servers/slapd/cancel.c
--- ldap/servers/slapd/cancel.c Wed Dec 31 19:00:00 1969
+++ ldap-cancel/servers/slapd/cancel.c Thu Jan 23 10:59:36 2003
@@ -0,0 +1,114 @@
+/* cancel.c - LDAP cancel extended operation */
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/krb.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+
+#include "slap.h"
+
+#include <lber_pvt.h>
+#include <lutil.h>
+
+int cancel_extop(
+ Connection *conn,
+ Operation *op,
+ const char *reqoid,
+ struct berval *reqdata,
+ char **rspoid,
+ struct berval **rspdata,
+ LDAPControl ***rspctrls,
+ const char **text,
+ BerVarray *refs )
+{
+ Backend *be;
+ int rc;
+ int found = 0;
+ int opid;
+ BerElement *ber;
+
+ assert( reqoid != NULL );
+ assert( strcmp( LDAP_EXOP_X_CANCEL, reqoid ) == 0 );
+
+ if ( reqdata == NULL ) {
+ *text = "no message ID supplied";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ ber = ber_init( reqdata );
+ if ( ber == NULL ) {
+ *text = "internal error";
+ return LDAP_OTHER;
+ }
+
+ if ( ber_scanf( ber, "{i}", &opid ) == LBER_ERROR ) {
+ *text = "message ID parse failed";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ (void) ber_free( ber, 1 );
+
+ if ( opid <= 0 ) {
+ *text = "message ID invalid";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+ LDAP_STAILQ_FOREACH( op, &conn->c_pending_ops, o_next ) {
+ if ( op->o_msgid == opid ) {
+ LDAP_STAILQ_REMOVE( &conn->c_pending_ops, op, slap_op, o_next );
+ slap_op_free( op );
+ found = 1;
+ break;
+ }
+ }
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+ if ( found )
+ return LDAP_SUCCESS;
+
+ found = 0;
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+ LDAP_STAILQ_FOREACH( op, &conn->c_ops, o_next ) {
+ if ( op->o_msgid == opid ) {
+ found = 1;
+ break;
+ }
+ }
+
+ if ( !found ) {
+ *text = "message ID not found";
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ return LDAP_NO_SUCH_OPERATION;
+ }
+
+ if ( op->o_cancel != LDAP_CANCEL_NONE ) {
+ *text = "message ID already being cancelled";
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ op->o_cancel = LDAP_CANCEL_REQ;
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+ while ( op->o_cancel == LDAP_CANCEL_REQ ) {
+ ldap_pvt_thread_yield();
+ }
+
+ if ( op->o_cancel == LDAP_CANCEL_ACK ) {
+ rc = LDAP_SUCCESS;
+ } else {
+ rc = op->o_cancel;
+ op->o_cancel = LDAP_CANCEL_NOTDONE;
+ }
+
+ return rc;
+}
diff -Naurp --exclude CVS --exclude TAGS ldap/servers/slapd/connection.c
ldap-cancel/servers/slapd/connection.c
--- ldap/servers/slapd/connection.c Thu Jan 23 10:11:19 2003
+++ ldap-cancel/servers/slapd/connection.c Thu Jan 23 10:30:02 2003
@@ -1024,6 +1024,15 @@ operations_error:
#endif /* SLAPD_MONITOR */
ldap_pvt_thread_mutex_unlock( &num_ops_mutex );
+ if ( arg->co_op->o_cancel == LDAP_CANCEL_REQ )
+ arg->co_op->o_cancel = LDAP_TOO_LATE;
+
+ while ( arg->co_op->o_cancel != LDAP_CANCEL_NONE &&
+ arg->co_op->o_cancel != LDAP_CANCEL_ACK &&
+ arg->co_op->o_cancel != LDAP_CANCEL_NOTDONE ) {
+ ldap_pvt_thread_yield();
+ }
+
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
conn->c_n_ops_executing--;
diff -Naurp --exclude CVS --exclude TAGS ldap/servers/slapd/extended.c
ldap-cancel/servers/slapd/extended.c
--- ldap/servers/slapd/extended.c Tue Jan 21 03:42:26 2003
+++ ldap-cancel/servers/slapd/extended.c Thu Jan 23 10:23:09 2003
@@ -64,6 +64,7 @@ static struct {
#endif
{ BVC(LDAP_EXOP_MODIFY_PASSWD), passwd_extop },
{ BVC(LDAP_EXOP_X_WHO_AM_I), whoami_extop },
+ { BVC(LDAP_EXOP_X_CANCEL), cancel_extop },
{ {0,NULL}, NULL }
};
diff -Naurp --exclude CVS --exclude TAGS ldap/servers/slapd/proto-slap.h
ldap-cancel/servers/slapd/proto-slap.h
--- ldap/servers/slapd/proto-slap.h Thu Jan 23 10:11:20 2003
+++ ldap-cancel/servers/slapd/proto-slap.h Thu Jan 23 10:31:18 2003
@@ -475,6 +475,11 @@ LDAP_SLAPD_F (int) extops_kill LDAP_P((
LDAP_SLAPD_F (struct berval *) get_supported_extop LDAP_P((int index));
/*
+ * cancel.c
+ */
+LDAP_SLAPD_F ( SLAP_EXTOP_MAIN_FN ) cancel_extop;
+
+/*
* filter.c
*/
LDAP_SLAPD_F (int) get_filter LDAP_P((
diff -Naurp --exclude CVS --exclude TAGS ldap/servers/slapd/slap.h
ldap-cancel/servers/slapd/slap.h
--- ldap/servers/slapd/slap.h Thu Jan 23 10:11:20 2003
+++ ldap-cancel/servers/slapd/slap.h Thu Jan 23 10:31:53 2003
@@ -1661,6 +1661,7 @@ typedef struct slap_op {
ldap_pvt_thread_t o_tid; /* thread handling this op */
volatile sig_atomic_t o_abandon; /* abandon flag */
+ volatile sig_atomic_t o_cancel; /* cancel flag */
char o_do_not_cache; /* don't cache from this op */
diff -Naurp --exclude CVS --exclude TAGS ldap/servers/slapd/tools/Makefile.in
ldap-cancel/servers/slapd/tools/Makefile.in
--- ldap/servers/slapd/tools/Makefile.in Sun Jan 19 16:43:29 2003
+++ ldap-cancel/servers/slapd/tools/Makefile.in Thu Jan 23 10:23:09 2003
@@ -45,7 +45,8 @@ SLAPD_OBJS = ../config.o ../ch_malloc.o
../entry.o ../dn.o ../filter.o ../str2filter.o ../ava.o \
../init.o ../controls.o ../kerberos.o ../passwd.o \
../index.o ../extended.o ../starttls.o ../sets.o ../mra.o \
- ../referral.o ../backglue.o ../oidm.o ../mods.o ../operation.o
+ ../referral.o ../backglue.o ../oidm.o ../mods.o ../operation.o \
+ ../cancel.o
SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o