File 0009-unregister_supported_control-backport.dif of Package openldap2

From 601cde61e0ad14e804a4f1bf54b6fac934aaad4b Mon Sep 17 00:00:00 2001
From: ralf <ralf>
Date: Wed, 30 Jun 2010 10:38:01 +0000
Subject: unregister_supported_control() backport

The fix for bnc#648479/ITS#6647 makes use of this call

Original log-message:
new call unregister_supported_control(), will be
needed for cn=config delete support

Also included: use be_ctrls[cid] for counting the number of overlay
instances that have registered the control for a specific BackendDB to make
sure that the control is unregistered only after the last instance calls
overlay_unregister_control().

diff --git a/servers/slapd/backover.c b/servers/slapd/backover.c
index cad81ab..56bcf65 100644
--- a/servers/slapd/backover.c
+++ b/servers/slapd/backover.c
@@ -1076,14 +1076,22 @@ overlay_register_control( BackendDB *be, const char *oid )
 				gotit = 1;
 			}
 
-			bd->be_ctrls[ cid ] = 1;
+			/* overlays can be instanciated multiple times, use
+			 * be_ctrls[ cid ] as an instance counter, so that the
+			 * overlay's controls are only really disabled after the
+			 * last instance called overlay_register_control() */
+			bd->be_ctrls[ cid ]++;
 			bd->be_ctrls[ SLAP_MAX_CIDS ] = 1;
 		}
 
 	}
 	
 	if ( !gotit ) {
-		be->bd_self->be_ctrls[ cid ] = 1;
+		/* overlays can be instanciated multiple times, use
+		 * be_ctrls[ cid ] as an instance counter, so that the
+		 * overlay's controls are only really unregistered after the
+		 * last instance called overlay_register_control() */
+		be->bd_self->be_ctrls[ cid ]++;
 		be->bd_self->be_ctrls[ SLAP_MAX_CIDS ] = 1;
 	}
 
@@ -1091,6 +1099,34 @@ overlay_register_control( BackendDB *be, const char *oid )
 }
 
 void
+overlay_unregister_control( BackendDB *be, const char *oid )
+{
+	int		gotit = 0;
+	int		cid;
+
+	if ( slap_find_control_id( oid, &cid ) == LDAP_CONTROL_NOT_FOUND ) {
+		return;
+	}
+
+	if ( SLAP_ISGLOBALOVERLAY( be ) ) {
+		BackendDB *bd;
+
+		/* remove from all backends... */
+		LDAP_STAILQ_FOREACH( bd, &backendDB, be_next ) {
+			if ( bd == be->bd_self ) {
+				gotit = 1;
+			}
+
+			bd->be_ctrls[ cid ]--;
+		}
+	}
+
+	if ( !gotit ) {
+		be->bd_self->be_ctrls[ cid ]--;
+	}
+}
+
+void
 overlay_destroy_one( BackendDB *be, slap_overinst *on )
 {
 	slap_overinfo *oi = on->on_info;
diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c
index 96df34e..8d079c5 100644
--- a/servers/slapd/controls.c
+++ b/servers/slapd/controls.c
@@ -344,6 +344,38 @@ register_supported_control2(const char *controloid,
 	return LDAP_SUCCESS;
 }
 
+#ifdef SLAP_CONFIG_DELETE
+int
+unregister_supported_control( const char *controloid )
+{
+	struct slap_control *sc;
+	int i;
+
+	if ( controloid == NULL || (sc = find_ctrl( controloid )) == NULL ){
+		return -1;
+	}
+
+	for ( i = 0; slap_known_controls[ i ]; i++ ) {
+		if ( strcmp( controloid, slap_known_controls[ i ] ) == 0 ) {
+			do {
+				slap_known_controls[ i ] = slap_known_controls[ i+1 ];
+			} while ( slap_known_controls[ i++ ] );
+			num_known_controls--;
+			break;
+		}
+	}
+
+	LDAP_SLIST_REMOVE(&controls_list, sc, slap_control, sc_next);
+	ch_free( sc->sc_oid );
+	if ( sc->sc_extendedopsbv != NULL ) {
+		ber_bvarray_free( sc->sc_extendedopsbv );
+	}
+	ch_free( sc );
+
+	return 0;
+}
+#endif /* SLAP_CONFIG_DELETE */
+
 /*
  * One-time initialization of internal controls.
  */
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 4d0e1bb..1aebece 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -657,6 +657,10 @@ LDAP_SLAPD_F (int) register_supported_control2 LDAP_P((
 	int *controlcid ));
 #define register_supported_control(oid, mask, exops, fn, cid) \
 	register_supported_control2((oid), (mask), (exops), (fn), 0, (cid))
+#ifdef SLAP_CONFIG_DELETE
+LDAP_SLAPD_F (int) unregister_supported_control LDAP_P((
+	const char* controloid ));
+#endif /* SLAP_CONFIG_DELETE */
 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));
-- 
1.7.3.4

openSUSE Build Service is sponsored by