From 1a217516f07a2e09a2dafa2807e97ed09909f10a Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Wed, 11 Jan 2006 19:36:18 +0000 Subject: [PATCH] allow control handlers to be replaced --- servers/slapd/controls.c | 79 ++++++++++++++++++++++++++------------ servers/slapd/proto-slap.h | 5 ++- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 1e768bd11b..426b9cb02c 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -197,21 +197,29 @@ static struct slap_control control_defs[] = { { NULL, 0, 0, NULL, 0, LDAP_SLIST_ENTRY_INITIALIZER(next) } }; +static struct slap_control * +find_ctrl( const char *oid ); + /* * Register a supported control. * * This can be called by an OpenLDAP plugin or, indirectly, by a * SLAPI plugin calling slapi_register_supported_control(). + * + * NOTE: if flags == 1 the control is replaced if already registered; + * otherwise registering an already registered control is not allowed. */ int -register_supported_control(const char *controloid, +register_supported_control2(const char *controloid, slap_mask_t controlmask, char **controlexops, SLAP_CTRL_PARSE_FN *controlparsefn, + unsigned flags, int *controlcid) { - struct slap_control *sc; + struct slap_control *sc = NULL; int i; + BerVarray extendedopsbv = NULL; if ( num_known_controls >= SLAP_MAX_CIDS ) { Debug( LDAP_DEBUG_ANY, "Too many controls registered." @@ -220,11 +228,23 @@ register_supported_control(const char *controloid, return LDAP_OTHER; } - if ( controloid == NULL ) return LDAP_PARAM_ERROR; + if ( controloid == NULL ) { + return LDAP_PARAM_ERROR; + } - /* sanity check - should never happen */ + /* check if already registered */ for ( i = 0; slap_known_controls[ i ]; i++ ) { if ( strcmp( controloid, slap_known_controls[ i ] ) == 0 ) { + if ( flags == 1 ) { + Debug( LDAP_DEBUG_TRACE, + "Control %s already registered; replacing.\n", + controloid, 0, 0 ); + /* (find and) replace existing handler */ + sc = find_ctrl( controloid ); + assert( sc != NULL ); + break; + } + Debug( LDAP_DEBUG_ANY, "Control %s already registered.\n", controloid, 0, 0 ); @@ -232,41 +252,52 @@ register_supported_control(const char *controloid, } } - sc = (struct slap_control *)SLAP_MALLOC( sizeof( *sc ) ); - if ( sc == NULL ) return LDAP_NO_MEMORY; - - sc->sc_oid = ch_strdup( controloid ); - sc->sc_mask = controlmask; + /* turn compatible extended operations into bervals */ if ( controlexops != NULL ) { int i; for ( i = 0; controlexops[ i ]; i++ ); - sc->sc_extendedopsbv = ber_memcalloc( i + 1, sizeof( struct berval ) ); - if ( sc->sc_extendedopsbv == NULL ) { - ch_free( sc ); + extendedopsbv = ber_memcalloc( i + 1, sizeof( struct berval ) ); + if ( extendedopsbv == NULL ) { return LDAP_NO_MEMORY; } for ( i = 0; controlexops[ i ]; i++ ) { - ber_str2bv( controlexops[ i ], 0, 1, &sc->sc_extendedopsbv[ i ] ); + ber_str2bv( controlexops[ i ], 0, 1, &extendedopsbv[ i ] ); + } + } + + if ( sc == NULL ) { + sc = (struct slap_control *)SLAP_MALLOC( sizeof( *sc ) ); + if ( sc == NULL ) { + return LDAP_NO_MEMORY; } + sc->sc_oid = ch_strdup( controloid ); + sc->sc_cid = num_known_controls; + + /* Update slap_known_controls, too. */ + slap_known_controls[num_known_controls - 1] = sc->sc_oid; + slap_known_controls[num_known_controls++] = NULL; + + LDAP_SLIST_NEXT( sc, sc_next ) = NULL; + LDAP_SLIST_INSERT_HEAD( &controls_list, sc, sc_next ); + } else { - sc->sc_extendedopsbv = NULL; + if ( sc->sc_extendedopsbv ) { + ber_bvarray_free( sc->sc_extendedops ); + sc->sc_extendedops = NULL; + } } - sc->sc_extendedops = NULL; - sc->sc_parse = controlparsefn; - - if ( controlcid ) *controlcid = num_known_controls; - sc->sc_cid = num_known_controls; - /* Update slap_known_controls, too. */ - slap_known_controls[num_known_controls-1] = sc->sc_oid; - slap_known_controls[num_known_controls++] = NULL; + sc->sc_extendedopsbv = extendedopsbv; + sc->sc_mask = controlmask; + sc->sc_parse = controlparsefn; + if ( controlcid ) { + *controlcid = sc->sc_cid; + } - LDAP_SLIST_NEXT( sc, sc_next ) = NULL; - LDAP_SLIST_INSERT_HEAD( &controls_list, sc, sc_next ); return LDAP_SUCCESS; } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index eae7835fa6..41ddfe1804 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -558,12 +558,15 @@ LDAP_SLAPD_F (int) get_ctrls LDAP_P(( Operation *op, SlapReply *rs, int senderrors )); -LDAP_SLAPD_F (int) register_supported_control LDAP_P(( +LDAP_SLAPD_F (int) register_supported_control2 LDAP_P(( const char *controloid, slap_mask_t controlmask, char **controlexops, SLAP_CTRL_PARSE_FN *controlparsefn, + unsigned flags, int *controlcid )); +#define register_supported_control(oid, mask, exops, fn, cid) \ + register_supported_control2((oid), (mask), (exops), (fn), 0, (cid)) LDAP_SLAPD_F (int) slap_controls_init LDAP_P ((void)); LDAP_SLAPD_F (void) controls_destroy LDAP_P ((void)); LDAP_SLAPD_F (int) controls_root_dse_info LDAP_P ((Entry *e)); -- 2.39.5