From 11f474385a9abfab2d67ac2c8dcc412887b44a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Mon, 25 Sep 2017 11:09:04 +0100 Subject: [PATCH] Exop support At the moment, no exops are processed internally, all are passed on unchanged. --- servers/lloadd/Makefile.in | 2 +- servers/lloadd/client.c | 3 + servers/lloadd/extended.c | 107 ++++++++++++++++++++++++++++++++++++ servers/lloadd/init.c | 2 + servers/lloadd/proto-slap.h | 8 +++ servers/lloadd/slap.h | 4 ++ 6 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 servers/lloadd/extended.c diff --git a/servers/lloadd/Makefile.in b/servers/lloadd/Makefile.in index 6f34aebf5f..2a289f5e8e 100644 --- a/servers/lloadd/Makefile.in +++ b/servers/lloadd/Makefile.in @@ -23,7 +23,7 @@ NT_OBJS = nt_svc.o ../../libraries/liblutil/slapdmsg.res SRCS = main.c globals.c backend.c bind.c config.c connection.c client.c \ daemon.c ch_malloc.c init.c operation.c user.c sl_malloc.c \ - upstream.c value.c libevent_support.c \ + upstream.c value.c libevent_support.c extended.c \ $(@PLAT@_SRCS) OBJS = $(patsubst %.c,%.o,$(SRCS)) $(@PLAT@_OBJS) diff --git a/servers/lloadd/client.c b/servers/lloadd/client.c index 189f895863..d73844d4d5 100644 --- a/servers/lloadd/client.c +++ b/servers/lloadd/client.c @@ -65,6 +65,9 @@ handle_one_request( Connection *c ) * ExOps (esp. Cancel) will be different */ handler = request_abandon; break; + case LDAP_REQ_EXTENDED: + handler = request_extended; + break; default: if ( c->c_state == SLAP_C_BINDING ) { return operation_send_reject_locked( diff --git a/servers/lloadd/extended.c b/servers/lloadd/extended.c new file mode 100644 index 0000000000..52c45fa1d9 --- /dev/null +++ b/servers/lloadd/extended.c @@ -0,0 +1,107 @@ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2020 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + +#include "portable.h" + +#include + +#include "lutil.h" +#include "slap.h" + +Avlnode *lload_exop_handlers = NULL; + +int +request_extended( Connection *c, Operation *op ) +{ + ExopHandler *handler, needle = {}; + BerElement *copy; + struct berval bv; + ber_tag_t tag; + + if ( (copy = ber_alloc()) == NULL ) { + if ( operation_send_reject_locked( + op, LDAP_OTHER, "internal error", 0 ) == LDAP_SUCCESS ) { + CONNECTION_DESTROY(c); + } + return -1; + } + + ber_init2( copy, &op->o_request, 0 ); + + tag = ber_skip_element( copy, &bv ); + if ( tag != LDAP_TAG_EXOP_REQ_OID ) { + Debug( LDAP_DEBUG_STATS, "request_extended: " + "no OID present in extended request\n" ); + return operation_send_reject_locked( + op, LDAP_PROTOCOL_ERROR, "decoding error", 0 ); + } + + needle.oid = bv; + + handler = avl_find( lload_exop_handlers, &needle, exop_handler_cmp ); + if ( handler ) { + Debug( LDAP_DEBUG_TRACE, "request_extended: " + "handling exop OID %.*s internally\n", + (int)bv.bv_len, bv.bv_val ); + ber_free( copy, 0 ); + return handler->func( c, op ); + } + ber_free( copy, 0 ); + + if ( c->c_state == SLAP_C_BINDING ) { + return operation_send_reject_locked( + op, LDAP_PROTOCOL_ERROR, "bind in progress", 0 ); + } + return request_process( c, op ); +} + +ExopHandler lload_exops[] = { { BER_BVNULL } +}; + +int +exop_handler_cmp( const void *left, const void *right ) +{ + const struct lload_exop_handlers_t *l = left, *r = right; + return ber_bvcmp( &l->oid, &r->oid ); +} + +int +lload_register_exop_handlers( struct lload_exop_handlers_t *handler ) +{ + for ( ; !BER_BVISNULL( &handler->oid ); handler++ ) { + Debug( LDAP_DEBUG_TRACE, "lload_register_exop_handlers: " + "registering handler for exop oid=%s\n", + handler->oid.bv_val ); + if ( avl_insert( &lload_exop_handlers, handler, exop_handler_cmp, + avl_dup_error ) ) { + Debug( LDAP_DEBUG_ANY, "lload_register_exop_handlers: " + "failed to register handler for exop oid=%s\n", + handler->oid.bv_val ); + return -1; + } + } + + return LDAP_SUCCESS; +} + +int +lload_exop_init( void ) +{ + if ( lload_register_exop_handlers( lload_exops ) ) { + return -1; + } + + return LDAP_SUCCESS; +} diff --git a/servers/lloadd/init.c b/servers/lloadd/init.c index af0cae7a28..0bac2b4bf9 100644 --- a/servers/lloadd/init.c +++ b/servers/lloadd/init.c @@ -101,6 +101,8 @@ slap_init( int mode, const char *name ) ldap_pvt_thread_mutex_init( &backend_mutex ); ldap_pvt_thread_mutex_init( &clients_mutex ); + lload_exop_init(); + break; default: diff --git a/servers/lloadd/proto-slap.h b/servers/lloadd/proto-slap.h index 83cd1f7dba..fc2cb30db7 100644 --- a/servers/lloadd/proto-slap.h +++ b/servers/lloadd/proto-slap.h @@ -121,6 +121,14 @@ LDAP_SLAPD_V (int) slapd_tcp_wmem; ( ( (bv1)->bv_len == (bv2)->bv_len ) && \ ( memcmp( (bv1)->bv_val, (bv2)->bv_val, (bv1)->bv_len ) == 0 ) ) +/* + * extended.c + */ +LDAP_SLAPD_V (Avlnode *) lload_exop_handlers; +LDAP_SLAPD_F (int) exop_handler_cmp( const void *l, const void *r ); +LDAP_SLAPD_F (int) request_extended( Connection *c, Operation *op ); +LDAP_SLAPD_F (int) lload_exop_init( void ); + /* * globals.c */ diff --git a/servers/lloadd/slap.h b/servers/lloadd/slap.h index 4b4e89ba96..bd3d327740 100644 --- a/servers/lloadd/slap.h +++ b/servers/lloadd/slap.h @@ -282,6 +282,10 @@ struct Backend { typedef int (*OperationHandler)( Operation *op, BerElement *ber ); typedef int (*RequestHandler)( Connection *c, Operation *op ); +typedef struct lload_exop_handlers_t { + struct berval oid; + RequestHandler func; +} ExopHandler; typedef int (*CONNECTION_PDU_CB)( Connection *c ); typedef void (*CONNECTION_DESTROY_CB)( Connection *c );