allow control handlers to be replaced

This commit is contained in:
Pierangelo Masarati 2006-01-11 19:36:18 +00:00
parent 9795721f7a
commit 1a217516f0
2 changed files with 59 additions and 25 deletions

View file

@ -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_extendedopsbv = extendedopsbv;
sc->sc_mask = controlmask;
sc->sc_parse = controlparsefn;
if ( controlcid ) {
*controlcid = sc->sc_cid;
}
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;
LDAP_SLIST_NEXT( sc, sc_next ) = NULL;
LDAP_SLIST_INSERT_HEAD( &controls_list, sc, sc_next );
return LDAP_SUCCESS;
}

View file

@ -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));