/*
* all known request control OIDs should be added to this list
*/
+/*
+ * NOTE: initialize num_known_controls to 1 so that cid = 0 always
+ * addresses an undefined control; this allows to safely test for
+ * well known controls even if they are not registered, e.g. if
+ * they get moved to modules. An example is sc_LDAPsync, which
+ * is implemented in the syncprov overlay and thus, if configured
+ * as dynamic module, may not be registered. One side effect is that
+ * slap_known_controls[0] == NULL, so it should always be used
+ * starting from 1.
+ * FIXME: should we define the "undefined control" oid?
+ */
char *slap_known_controls[SLAP_MAX_CIDS+1];
-static int num_known_controls;
+static int num_known_controls = 1;
static char *proxy_authz_extops[] = {
LDAP_EXOP_MODIFY_PASSWD,
int *controlcid)
{
struct slap_control *sc;
+ int i;
if ( num_known_controls >= SLAP_MAX_CIDS ) {
Debug( LDAP_DEBUG_ANY, "Too many controls registered."
if ( controloid == NULL ) return LDAP_PARAM_ERROR;
+ /* sanity check - should never happen */
+ for ( i = 0; slap_known_controls[ i ]; i++ ) {
+ if ( strcmp( controloid, slap_known_controls[ i ] ) == 0 ) {
+ Debug( LDAP_DEBUG_ANY,
+ "Control %s already registered.\n",
+ controloid, 0, 0 );
+ return LDAP_PARAM_ERROR;
+ }
+ }
+
sc = (struct slap_control *)SLAP_MALLOC( sizeof( *sc ) );
if ( sc == NULL ) return LDAP_NO_MEMORY;
sc->sc_cid = num_known_controls;
/* Update slap_known_controls, too. */
- slap_known_controls[num_known_controls++] = sc->sc_oid;
- slap_known_controls[num_known_controls] = NULL;
+ 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 NULL;
}
+int
+slap_find_control_id(
+ const char *oid,
+ int *cid )
+{
+ struct slap_control *ctrl = find_ctrl( oid );
+ if ( ctrl ) {
+ if ( cid ) *cid = ctrl->sc_cid;
+ return LDAP_SUCCESS;
+ }
+ return LDAP_CONTROL_NOT_FOUND;
+}
+
void slap_free_ctrls(
Operation *op,
LDAPControl **ctrls )
c->ldctl_iscritical = (crit != 0);
tag = ber_peek_tag( ber, &len );
+ } else {
+ c->ldctl_iscritical = 0;
}
if( tag == LBER_OCTETSTRING ) {
rs->sr_text = "decoding controls error";
goto return_results;
}
+ } else {
+ BER_BVZERO( &c->ldctl_value );
}
Debug( LDAP_DEBUG_TRACE,