On 8.6.2016 15:44, Petr Spacek wrote:
> Hello,
> 
> this patch set implements forwarder configuration in idnsServerConfigObject.
> 
> https://fedorahosted.org/bind-dyndb-ldap/ticket/162

This version of patch set fixes race condition caused by improper ISC task
handling for update_serverconfig event.

-- 
Petr^2 Spacek
From 5fc2de3c7e43acc0cb776006b62d8d88a22f2d44 Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Tue, 7 Jun 2016 12:40:03 +0200
Subject: [PATCH] Add server_ldap_settings layer to tree of setting objects.

Data are not loaded from LDAP yet so this commit has no user-visible
impact.

https://fedorahosted.org/bind-dyndb-ldap/ticket/162
---
 src/ldap_helper.c | 56 +++++++++++++++++++++++++++++++++++++++++++------------
 src/settings.c    |  1 +
 src/settings.h    |  1 +
 3 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index c7a4c04e37cd2ef872efc0849bec7782fd024730..471f8a3d5191b47bbde99d77774f55bc4462b8e3 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -156,6 +156,7 @@ struct ldap_instance {
 	settings_set_t		*local_settings;
 	settings_set_t		*global_settings;
 	settings_set_t		empty_fwdz_settings;
+	settings_set_t		*server_ldap_settings;
 
 	sync_ctx_t		*sctx;
 	mldapdb_t		*mldapdb;
@@ -244,6 +245,7 @@ static const setting_t settings_local_default[] = {
 	 * during start up to allow settings_set_isfilled() to pass.*/
 	{ "forward_policy",		no_default_string	},
 	{ "forwarders",			no_default_string	},
+	{ "server_id",			no_default_string	},
 	end_of_settings
 };
 
@@ -256,6 +258,14 @@ static setting_t settings_global_default[] = {
 	end_of_settings
 };
 
+/** Server-specific config from idnsServerConfig object. */
+static setting_t settings_server_ldap_default[] = {
+	{ "fake_mname",		no_default_string	},
+	{ "forwarders",		no_default_string	},
+	{ "forward_policy",	no_default_string	},
+	end_of_settings
+};
+
 static setting_t settings_fwdz_defaults[] = {
 	{ "forward_policy",	no_default_string	},
 	{ "forwarders",		no_default_string	},
@@ -516,6 +526,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
 	isc_uint32_t connections;
 	char settings_name[PRINT_BUFF_SIZE];
 	ldap_globalfwd_handleez_t *gfwdevent = NULL;
+	const char *server_id = NULL;
 
 	REQUIRE(ldap_instp != NULL && *ldap_instp == NULL);
 
@@ -600,17 +611,35 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name,
 	if (settings_set_isfilled(ldap_inst->global_settings) != ISC_TRUE)
 		CLEANUP_WITH(ISC_R_FAILURE);
 
+	/* zero-length server_id means undefined value */
+	CHECK(setting_get_str("server_id", ldap_inst->local_settings,
+			      &server_id));
+	if (strlen(server_id) == 0)
+		isc_string_printf_truncate(settings_name, PRINT_BUFF_SIZE,
+					   SETTING_SET_NAME_SERVER
+					   " for undefined server_id");
+	else
+		isc_string_printf_truncate(settings_name, PRINT_BUFF_SIZE,
+					   SETTING_SET_NAME_SERVER
+					   " for server id %s", server_id);
+
+	CHECK(settings_set_create(mctx, settings_server_ldap_default,
+	      sizeof(settings_server_ldap_default), settings_name,
+	      ldap_inst->global_settings, &ldap_inst->server_ldap_settings));
+	if (settings_set_isfilled(ldap_inst->server_ldap_settings) != ISC_TRUE)
+		CLEANUP_WITH(ISC_R_FAILURE);
+
 	ldap_inst->empty_fwdz_settings = (settings_set_t) {
 			NULL,
 			"dummy LDAP zone forwarding settings",
-			ldap_inst->global_settings,
+			ldap_inst->server_ldap_settings,
 			NULL,
 			(setting_t *) &settings_fwdz_defaults[0]
 	};
 
 	CHECK(setting_get_uint("connections", ldap_inst->local_settings, &connections));
 
-	CHECK(zr_create(mctx, ldap_inst, ldap_inst->global_settings,
+	CHECK(zr_create(mctx, ldap_inst, ldap_inst->server_ldap_settings,
 			&ldap_inst->zone_register));
 	CHECK(fwdr_create(ldap_inst->mctx, &ldap_inst->fwd_register));
 	CHECK(mldap_new(mctx, &ldap_inst->mldapdb));
@@ -682,6 +711,7 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
 
 	settings_set_free(&ldap_inst->global_settings);
 	settings_set_free(&ldap_inst->local_settings);
+	settings_set_free(&ldap_inst->server_ldap_settings);
 
 	sync_ctx_free(&ldap_inst->sctx);
 	/* zero out error counter (and do nothing other than that) */
@@ -1439,7 +1469,7 @@ ldap_parse_fwd_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
 	}
 
 	CHECK(settings_set_create(inst->mctx, settings_fwdz_defaults, sizeof(settings_fwdz_defaults),
-				  "fake fwdz settings", inst->global_settings,
+				  "fake fwdz settings", inst->server_ldap_settings,
 				  &fwdz_settings));
 	result = fwd_parse_ldap(entry, fwdz_settings);
 	if (result == ISC_R_IGNORE) {
@@ -2392,31 +2422,31 @@ ldap_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *sin)
 		case SASL_CB_USER:
 			log_debug(4, "got request for SASL_CB_USER");
 			CHECK(setting_get_str("sasl_user",
-					      ldap_inst->global_settings,
+					      ldap_inst->server_ldap_settings,
 					      (const char **)&in->result));
 			in->len = strlen(in->result);
 			ret = LDAP_SUCCESS;
 			break;
 		case SASL_CB_GETREALM:
 			log_debug(4, "got request for SASL_CB_GETREALM");
 			CHECK(setting_get_str("sasl_realm",
-					      ldap_inst->global_settings,
+					      ldap_inst->server_ldap_settings,
 					      (const char **)&in->result));
 			in->len = strlen(in->result);
 			ret = LDAP_SUCCESS;
 			break;
 		case SASL_CB_AUTHNAME:
 			log_debug(4, "got request for SASL_CB_AUTHNAME");
 			CHECK(setting_get_str("sasl_auth_name",
-					      ldap_inst->global_settings,
+					      ldap_inst->server_ldap_settings,
 					      (const char **)&in->result));
 			in->len = strlen(in->result);
 			ret = LDAP_SUCCESS;
 			break;
 		case SASL_CB_PASS:
 			log_debug(4, "got request for SASL_CB_PASS");
 			CHECK(setting_get_str("sasl_password",
-					      ldap_inst->global_settings,
+					      ldap_inst->server_ldap_settings,
 					      (const char **)&in->result));
 			in->len = strlen(in->result);
 			ret = LDAP_SUCCESS;
@@ -2466,7 +2496,7 @@ ldap_connect(ldap_instance_t *ldap_inst, ldap_connection_t *ldap_conn,
 	ret = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
 	LDAP_OPT_CHECK(ret, "failed to set LDAP version");
 
-	CHECK(setting_get_uint("timeout", ldap_inst->global_settings,
+	CHECK(setting_get_uint("timeout", ldap_inst->server_ldap_settings,
 			       &timeout_sec));
 	timeout.tv_sec = timeout_sec;
 	timeout.tv_usec = 0;
@@ -2540,7 +2570,7 @@ ldap_reconnect(ldap_instance_t *ldap_inst, ldap_connection_t *ldap_conn,
 
 		i = ISC_MIN(ntimes - 1, ldap_conn->tries);
 		CHECK(setting_get_uint("reconnect_interval",
-				       ldap_inst->global_settings,
+				       ldap_inst->server_ldap_settings,
 				       &reconnect_interval));
 		seconds = ISC_MIN(intervals[i], reconnect_interval);
 		isc_interval_set(&delay, seconds, 0);
@@ -2559,8 +2589,10 @@ force_reconnect:
 		ret = ldap_simple_bind_s(ldap_conn->handle, NULL, NULL);
 		break;
 	case AUTH_SIMPLE:
-		CHECK(setting_get_str("bind_dn", ldap_inst->global_settings, &bind_dn));
-		CHECK(setting_get_str("password", ldap_inst->global_settings, &password));
+		CHECK(setting_get_str("bind_dn", ldap_inst->server_ldap_settings,
+				      &bind_dn));
+		CHECK(setting_get_str("password", ldap_inst->server_ldap_settings,
+				      &password));
 		ret = ldap_simple_bind_s(ldap_conn->handle, bind_dn, password);
 		break;
 	case AUTH_SASL:
@@ -4288,7 +4320,7 @@ ldap_syncrepl_watcher(isc_threadarg_t arg)
 
 	while (!inst->exiting) {
 		ldap_sync_cleanup(&ldap_sync);
-		result = ldap_sync_prepare(inst, inst->global_settings,
+		result = ldap_sync_prepare(inst, inst->server_ldap_settings,
 					   conn, &ldap_sync);
 		if (result != ISC_R_SUCCESS) {
 			log_error_r("ldap_sync_prepare() failed, retrying "
diff --git a/src/settings.c b/src/settings.c
index 24004248ac706a5594ec803d79d99b2fa9335dc4..7dc5d4b6a40116e74e1e8f4bc2d0adba4d8c438d 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -61,6 +61,7 @@ static const setting_t settings_default[] = {
 	{ "serial_autoincrement",	default_string("")		},
 	{ "verbose_checks",		default_boolean(ISC_FALSE)	},
 	{ "directory",			default_string("")		},
+	{ "server_id",			default_string("")		},
 	end_of_settings
 };
 
diff --git a/src/settings.h b/src/settings.h
index e1d46f80392a2f7bcd42b01e3997ac4ff0c67a45..9bc41764238a8e1a878c8595211f06738fccd16d 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -13,6 +13,7 @@
 #define SETTING_LINE_MAXLENGTH 255
 #define SETTING_NAME_SEPARATORS " \t"
 #define SETTING_SET_NAME_LOCAL  "named.conf"
+#define SETTING_SET_NAME_SERVER "LDAP idnsServerConfig object"
 #define SETTING_SET_NAME_GLOBAL "LDAP idnsConfig object"
 #define SETTING_SET_NAME_ZONE   "LDAP idnsZone object"
 
-- 
2.5.5

From 19b4cad36bccfe9611c28b5023d5862260ab7bd5 Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Tue, 7 Jun 2016 12:41:50 +0200
Subject: [PATCH] Add LDAP schema for per-server config in LDAP.

Design: https://fedorahosted.org/bind-dyndb-ldap/wiki/Design/PerServerConfigInLDAP

https://fedorahosted.org/bind-dyndb-ldap/ticket/162
---
 doc/schema.ldif | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/doc/schema.ldif b/doc/schema.ldif
index a1fcac50d647cbed74e8688a6289beb6ae4bd048..d687b5ceb48b27aee36a8c74d4c5a67f00d667db 100644
--- a/doc/schema.ldif
+++ b/doc/schema.ldif
@@ -351,6 +351,13 @@ attributeTypes: ( 2.16.840.1.113730.3.8.5.18
  EQUALITY booleanMatch 
  SINGLE-VALUE )
 #
+attributeTypes: ( 2.16.840.1.113730.3.8.5.31
+ NAME 'idnsServerId'
+ DESC 'DNS server identifier'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ EQUALITY caseIgnoreMatch
+ SINGLE-VALUE )
+#
 objectClasses: ( 2.16.840.1.113730.3.8.6.0 
  NAME 'idnsRecord' 
  DESC 'dns Record, usually a host' 
@@ -392,3 +399,11 @@ objectClasses: ( 2.16.840.1.113730.3.8.6.3
  STRUCTURAL 
  MUST ( idnsName $ idnsZoneActive ) 
  MAY ( idnsForwarders $ idnsForwardPolicy ) )
+#
+objectClasses: ( 2.16.840.1.113730.3.8.6.6 
+ NAME 'idnsServerConfigObject' 
+ DESC 'DNS server configuration' 
+ SUP top 
+ STRUCTURAL 
+ MUST ( idnsServerId ) 
+ MAY ( idnsSOAmName $ idnsForwarders $ idnsForwardPolicy ) )
-- 
2.5.5

From 97c210a44f59fea7e3eb877ac1effc7c0ea9eb0b Mon Sep 17 00:00:00 2001
From: Petr Spacek <pspa...@redhat.com>
Date: Wed, 8 Jun 2016 14:00:12 +0200
Subject: [PATCH] Parse idnsServerConfigObject and use its values for forwarder
 configuration.

Values in idnsServerConfigObject override values in idnsConfigObject but
have lower priority than configuration in root zone.

https://fedorahosted.org/bind-dyndb-ldap/ticket/162
---
 src/ldap_entry.c  |  7 +++-
 src/ldap_entry.h  |  1 +
 src/ldap_helper.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 98 insertions(+), 9 deletions(-)

diff --git a/src/ldap_entry.c b/src/ldap_entry.c
index 361d2c1d98214de970376a8c524c18182b3d1d7d..a2d8a834cd4f3ca35bcb55cf90043d0aa0ef18e6 100644
--- a/src/ldap_entry.c
+++ b/src/ldap_entry.c
@@ -163,7 +163,8 @@ ldap_entry_reconstruct(isc_mem_t *mctx, mldapdb_t *mldap, struct berval *uuid,
 		CLEANUP_WITH(ISC_R_NOMEMORY);
 
 	CHECK(mldap_class_get(node, &entry->class));
-	if ((entry->class & LDAP_ENTRYCLASS_CONFIG) == 0)
+	if ((entry->class
+	    & (LDAP_ENTRYCLASS_CONFIG | LDAP_ENTRYCLASS_SERVERCONFIG)) == 0)
 		CHECK(mldap_dnsname_get(node, &entry->fqdn, &entry->zone_name));
 
 	*entryp = entry;
@@ -449,6 +450,8 @@ ldap_entry_parseclass(ldap_entry_t *entry, ldap_entryclass_t *class)
 			entryclass |= LDAP_ENTRYCLASS_FORWARD;
 		else if (!strcasecmp(val->value, "idnsconfigobject"))
 			entryclass |= LDAP_ENTRYCLASS_CONFIG;
+		else if (!strcasecmp(val->value, "idnsServerConfigObject"))
+			entryclass |= LDAP_ENTRYCLASS_SERVERCONFIG;
 	}
 
 	if (class == LDAP_ENTRYCLASS_NONE) {
@@ -544,6 +547,8 @@ ldap_entry_getclassname(const ldap_entryclass_t class) {
 		return "forward zone";
 	else if ((class & LDAP_ENTRYCLASS_CONFIG) != 0)
 		return "config object";
+	else if ((class & LDAP_ENTRYCLASS_SERVERCONFIG) != 0)
+		return "server config object";
 	else if ((class & LDAP_ENTRYCLASS_RR) != 0)
 		return "resource record";
 	else if (class != 0)
diff --git a/src/ldap_entry.h b/src/ldap_entry.h
index daac35d881901e79d73fff2284837aa111cd8c5a..50e725aa4f2f6bf8420b95c6ee451e238fad9f27 100644
--- a/src/ldap_entry.h
+++ b/src/ldap_entry.h
@@ -67,6 +67,7 @@ struct ldap_attribute {
 #define LDAP_ENTRYCLASS_MASTER	0x2
 #define LDAP_ENTRYCLASS_CONFIG	0x4
 #define LDAP_ENTRYCLASS_FORWARD	0x8
+#define LDAP_ENTRYCLASS_SERVERCONFIG	0x10
 
 #define DEFAULT_TTL 86400
 
diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index 471f8a3d5191b47bbde99d77774f55bc4462b8e3..ca789914a6c0ef06bb7e517464ed3b5cb496aa51 100644
--- a/src/ldap_helper.c
+++ b/src/ldap_helper.c
@@ -1445,6 +1445,32 @@ cleanup:
 	return ISC_R_SUCCESS;
 }
 
+/* Parse the idnsServerConfig object entry */
+static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
+ldap_parse_serverconfigentry(ldap_entry_t *entry, ldap_instance_t *inst)
+{
+	isc_result_t result;
+
+	/* BIND functions are thread safe, ldap instance 'inst' is locked
+	 * inside setting* functions. */
+
+	log_debug(3, "Parsing server configuration object");
+
+	result = fwd_parse_ldap(entry, inst->server_ldap_settings);
+	if (result == ISC_R_SUCCESS) {
+		result = fwd_configure_zone(inst->server_ldap_settings, inst,
+					    dns_rootname);
+		if (result != ISC_R_SUCCESS)
+			log_error_r("global forwarder could not be set up");
+	} else if (result != ISC_R_IGNORE)
+		goto cleanup;
+
+cleanup:
+	/* Configuration errors are not fatal. */
+	/* TODO: log something? */
+	return ISC_R_SUCCESS;
+}
+
 /* Parse the forward zone entry */
 static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
 ldap_parse_fwd_zoneentry(ldap_entry_t *entry, ldap_instance_t *inst)
@@ -3506,6 +3532,38 @@ cleanup:
 	isc_task_detach(&task);
 }
 
+static void ATTR_NONNULLS
+update_serverconfig(isc_task_t * task, isc_event_t *event)
+{
+	ldap_syncreplevent_t *pevent = (ldap_syncreplevent_t *)event;
+	isc_result_t result;
+	ldap_instance_t *inst = NULL;
+	ldap_entry_t *entry = pevent->entry;
+	isc_mem_t *mctx;
+
+	mctx = pevent->mctx;
+
+	CHECK(manager_get_ldap_instance(pevent->dbname, &inst));
+	INSIST(task == inst->task); /* For task-exclusive mode */
+	CHECK(ldap_parse_serverconfigentry(entry, inst));
+
+cleanup:
+	if (inst != NULL) {
+		sync_concurr_limit_signal(inst->sctx);
+		sync_event_signal(inst->sctx, event);
+	}
+	if (result != ISC_R_SUCCESS)
+		log_error_r("update_serverconfig (syncrepl) failed for %s. "
+			    "Configuration can be outdated, run `rndc reload`",
+			    ldap_entry_logname(entry));
+
+	ldap_entry_destroy(&entry);
+	isc_mem_free(mctx, pevent->dbname);
+	isc_mem_detach(&mctx);
+	isc_event_free(&event);
+	isc_task_detach(&task);
+}
+
 /**
  * @brief Update record in cache.
  *
@@ -3857,6 +3915,8 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype)
 
 	if ((entry->class & LDAP_ENTRYCLASS_CONFIG) != 0)
 		action = update_config;
+	else if ((entry->class & LDAP_ENTRYCLASS_SERVERCONFIG) != 0)
+		action = update_serverconfig;
 	else if ((entry->class & LDAP_ENTRYCLASS_MASTER) != 0)
 		action = update_zone;
 	else if ((entry->class & LDAP_ENTRYCLASS_FORWARD) != 0)
@@ -3871,7 +3931,8 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype)
 
 	/* All events for single zone are handled by one task, so we don't
 	 * need to spend time with normal records. */
-	if (action == update_zone || action == update_config) {
+	if (action == update_zone || action == update_config
+	    || action == update_serverconfig) {
 		INSIST(task == inst->task); /* For task-exclusive mode */
 		sync_state_get(inst->sctx, &sync_state);
 		if (sync_state == sync_init)
@@ -3899,7 +3960,8 @@ syncrepl_update(ldap_instance_t *inst, ldap_entry_t **entryp, int chgtype)
 
 	/* Lock syncrepl queue to prevent zone, config and resource records
 	 * from racing with each other. */
-	if (action == update_zone || action == update_config)
+	if (action == update_zone || action == update_config
+	    || action == update_serverconfig)
 		CHECK(sync_event_wait(inst->sctx, wait_event));
 
 cleanup:
@@ -4047,7 +4109,9 @@ int ldap_sync_search_entry (
 				  "object class in %s changed: "
 				  "rndc reload might be necessary",
 				  ldap_entry_logname(new_entry));
-		if ((old_entry->class & LDAP_ENTRYCLASS_CONFIG) == 0)
+		if ((old_entry->class
+		    & (LDAP_ENTRYCLASS_CONFIG | LDAP_ENTRYCLASS_SERVERCONFIG))
+		    == 0)
 			modrdn = !(dns_name_equal(&old_entry->zone_name,
 						  &new_entry->zone_name)
 				   && dns_name_equal(&old_entry->fqdn,
@@ -4071,7 +4135,9 @@ int ldap_sync_search_entry (
 	if (phase == LDAP_SYNC_CAPI_ADD || phase == LDAP_SYNC_CAPI_MODIFY) {
 		/* store new state into metaDB */
 		CHECK(mldap_entry_create(new_entry, inst->mldapdb, &node));
-		if ((new_entry->class & LDAP_ENTRYCLASS_CONFIG) == 0)
+		if ((new_entry->class
+		    & (LDAP_ENTRYCLASS_CONFIG | LDAP_ENTRYCLASS_SERVERCONFIG))
+		    == 0)
 			CHECK(mldap_dnsname_store(&new_entry->fqdn,
 						  &new_entry->zone_name, node));
 		/* commit new entry into metaLDAP DB before something breaks */
@@ -4222,6 +4288,15 @@ ldap_sync_prepare(ldap_instance_t *inst, settings_set_t *settings,
 	const char *base = NULL;
 	isc_uint32_t reconnect_interval;
 	ldap_sync_t *ldap_sync = NULL;
+	const char *server_id = NULL;
+	char filter[1024];
+	const char filter_template[] =
+		"(|(objectClass=idnsConfigObject)"
+		"  (objectClass=idnsZone)"
+		"  (objectClass=idnsForwardZone)"
+		"  (objectClass=idnsRecord)"
+		"  %s%s%s"
+		")";
 
 	REQUIRE(inst != NULL);
 	REQUIRE(ldap_syncp != NULL && *ldap_syncp == NULL);
@@ -4256,12 +4331,20 @@ ldap_sync_prepare(ldap_instance_t *inst, settings_set_t *settings,
 	if (ldap_sync->ls_base == NULL)
 		CLEANUP_WITH(ISC_R_NOMEMORY);
 	ldap_sync->ls_scope = LDAP_SCOPE_SUBTREE;
-	ldap_sync->ls_filter = ldap_strdup("(|(objectClass=idnsConfigObject)"
-					   "  (objectClass=idnsZone)"
-					   "  (objectClass=idnsForwardZone)"
-					   "  (objectClass=idnsRecord))");
+
+	/* request idnsServerConfig object only if server_id is specified */
+	CHECK(setting_get_str("server_id", settings, &server_id));
+	if (strlen(server_id) == 0)
+		CHECK(isc_string_printf(filter, sizeof(filter), filter_template,
+				        "", "", ""));
+	else
+		CHECK(isc_string_printf(filter, sizeof(filter), filter_template,
+				        "  (&(objectClass=idnsServerConfigObject)"
+				        "    (idnsServerId=", server_id, "))"));
+	ldap_sync->ls_filter = ldap_strdup(filter);
 	if (ldap_sync->ls_filter == NULL)
 		CLEANUP_WITH(ISC_R_NOMEMORY);
+	log_debug(1, "LDAP syncrepl filter = %s", ldap_sync->ls_filter);
 	ldap_sync->ls_timeout = -1; /* sync_poll is blocking */
 	ldap_sync->ls_ld = conn->handle;
 	/* This is a hack: ldap_sync_destroy() will call ldap_unbind().
-- 
2.5.5

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to