/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2014 The OpenLDAP Foundation.
+ * Copyright 1998-2018 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#ifdef SLAP_CONTROL_X_WHATFAILED
static SLAP_CTRL_PARSE_FN parseWhatFailed;
#endif
+#ifdef SLAP_CONTROL_X_LAZY_COMMIT
+static SLAP_CTRL_PARSE_FN parseLazyCommit;
+#endif
#undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
NULL, NULL,
parseWhatFailed, LDAP_SLIST_ENTRY_INITIALIZER(next) },
#endif
+#ifdef SLAP_CONTROL_X_LAZY_COMMIT
+ { LDAP_CONTROL_X_LAZY_COMMIT,
+ (int)offsetof(struct slap_control_ids, sc_lazyCommit),
+ SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE,
+ NULL, NULL,
+ parseLazyCommit, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#endif
{ NULL, 0, 0, NULL, 0, NULL, LDAP_SLIST_ENTRY_INITIALIZER(next) }
};
} else {
if ( sc->sc_extendedopsbv ) {
- /* FIXME: in principle, we should rather merge
- * existing extops with those supported by the
- * new control handling implementation.
- * In fact, whether a control is compatible with
- * an extop should not be a matter of implementation.
- * We likely also need a means for a newly
- * registered extop to declare that it is
- * comptible with an already registered control.
- */
ber_bvarray_free( sc->sc_extendedopsbv );
sc->sc_extendedopsbv = NULL;
sc->sc_extendedops = NULL;
}
#endif /* SLAP_CONFIG_DELETE */
+int
+register_control_exop( const char *controloid, char *exopoid )
+{
+ struct slap_control *sc = NULL;
+ BerVarray extendedopsbv;
+ char **extendedops;
+ int i;
+
+ if ( controloid == NULL || exopoid == NULL ) {
+ return LDAP_PARAM_ERROR;
+ }
+
+ for ( i = 0; slap_known_controls[ i ]; i++ ) {
+ if ( strcmp( controloid, slap_known_controls[ i ] ) == 0 ) {
+ sc = find_ctrl( controloid );
+ assert( sc != NULL );
+ break;
+ }
+ }
+
+ if ( !sc ) {
+ Debug( LDAP_DEBUG_ANY, "register_control_exop: "
+ "Control %s not registered.\n",
+ controloid, 0, 0 );
+ return LDAP_PARAM_ERROR;
+ }
+
+ for ( i = 0; sc->sc_extendedops && sc->sc_extendedops[ i ]; i++ ) {
+ if ( strcmp( exopoid, sc->sc_extendedops[ i ] ) == 0 ) {
+ return LDAP_SUCCESS;
+ }
+ }
+
+ extendedops = ber_memrealloc( sc->sc_extendedops, (i + 2) * sizeof( char * ) );
+ if ( extendedops == NULL ) {
+ return LDAP_NO_MEMORY;
+ }
+ sc->sc_extendedops = extendedops;
+
+ extendedopsbv = ber_memrealloc( sc->sc_extendedopsbv, (i + 2) * sizeof( struct berval ) );
+ if ( extendedopsbv == NULL ) {
+ return LDAP_NO_MEMORY;
+ }
+ sc->sc_extendedopsbv = extendedopsbv;
+
+ extendedops[ i ] = exopoid;
+ extendedops[ i+1 ] = NULL;
+
+ ber_str2bv( exopoid, 0, 1, &extendedopsbv[ i ] );
+ BER_BVZERO( &extendedopsbv[ i+1 ] );
+
+ return LDAP_SUCCESS;
+}
+
/*
* One-time initialization of internal controls.
*/
} else if( c->ldctl_oid == NULL ) {
Debug( LDAP_DEBUG_TRACE,
- "get_ctrls: conn %lu got emtpy OID.\n",
+ "get_ctrls: conn %lu got empty OID.\n",
op->o_connid, 0, 0 );
slap_free_ctrls( op, op->o_ctrls );
}
if( op->o_assertion != NULL ) {
filter_free_x( op, op->o_assertion, 1 );
+ op->o_assertion = NULL;
}
return rs->sr_err;
}
return LDAP_PROTOCOL_ERROR;
}
- if ( BER_BVISNULL( &ctrl->ldctl_value )) {
- rs->sr_text = "domainScope control value not empty";
+ if ( !BER_BVISNULL( &ctrl->ldctl_value )) {
+ rs->sr_text = "domainScope control value not absent";
return LDAP_PROTOCOL_ERROR;
}
return rc;
}
#endif
+
+#ifdef SLAP_CONTROL_X_LAZY_COMMIT
+static int parseLazyCommit(
+ Operation *op,
+ SlapReply *rs,
+ LDAPControl *ctrl )
+{
+ if ( op->o_lazyCommit != SLAP_CONTROL_NONE ) {
+ rs->sr_text = "\"Lazy Commit?\" control specified multiple times";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ if ( !BER_BVISNULL( &ctrl->ldctl_value )) {
+ rs->sr_text = "\"Lazy Commit?\" control value not absent";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ op->o_lazyCommit = ctrl->ldctl_iscritical
+ ? SLAP_CONTROL_CRITICAL
+ : SLAP_CONTROL_NONCRITICAL;
+
+ return LDAP_SUCCESS;
+}
+#endif