Hello, this patch set implements forwarder configuration in idnsServerConfigObject.
https://fedorahosted.org/bind-dyndb-ldap/ticket/162 -- 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 f106a6b0a60005d033d011ae5c943b7ce6a3a56a 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 | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 94 insertions(+), 7 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..7f8774079cc11f13b31d77fe3e6e262f97443603 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) @@ -4047,7 +4107,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 +4133,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 +4286,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 +4329,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