diff options
Diffstat (limited to 'src/lib/dhcpsrv/parsers/dbaccess_parser.cc')
-rw-r--r-- | src/lib/dhcpsrv/parsers/dbaccess_parser.cc | 79 |
1 files changed, 52 insertions, 27 deletions
diff --git a/src/lib/dhcpsrv/parsers/dbaccess_parser.cc b/src/lib/dhcpsrv/parsers/dbaccess_parser.cc index 6b7fa51eec..e4231dc1e2 100644 --- a/src/lib/dhcpsrv/parsers/dbaccess_parser.cc +++ b/src/lib/dhcpsrv/parsers/dbaccess_parser.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -13,6 +13,7 @@ #include <dhcpsrv/lease_mgr_factory.h> #include <dhcpsrv/host_mgr.h> #include <dhcpsrv/parsers/dbaccess_parser.h> +#include <dhcpsrv/parsers/dhcp_parsers.h> #include <boost/foreach.hpp> #include <boost/lexical_cast.hpp> @@ -29,13 +30,14 @@ namespace dhcp { // Factory function to build the parser -DbAccessParser::DbAccessParser(const std::string&, DBType db_type) +DbAccessParser::DbAccessParser(DBType db_type) : values_(), type_(db_type) { } // Parse the configuration and check that the various keywords are consistent. void -DbAccessParser::build(isc::data::ConstElementPtr config_value) { +DbAccessParser::parse(CfgDbAccessPtr& cfg_db, + ConstElementPtr database_config) { // To cope with incremental updates, the strategy is: // 1. Take a copy of the stored keyword/value pairs. @@ -45,13 +47,17 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) { // 5. Save resulting database access string in the Configuration // Manager. + // Note only range checks can fail with a database_config from + // a flex/bison parser. + // 1. Take a copy of the stored keyword/value pairs. std::map<string, string> values_copy = values_; int64_t lfc_interval = 0; int64_t timeout = 0; + int64_t port = 0; // 2. Update the copy with the passed keywords. - BOOST_FOREACH(ConfigPair param, config_value->mapValue()) { + BOOST_FOREACH(ConfigPair param, database_config->mapValue()) { try { if ((param.first == "persist") || (param.first == "readonly")) { values_copy[param.first] = (param.second->boolValue() ? @@ -67,12 +73,17 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) { values_copy[param.first] = boost::lexical_cast<std::string>(timeout); + } else if (param.first == "port") { + port = param.second->intValue(); + values_copy[param.first] = + boost::lexical_cast<std::string>(port); + } else { values_copy[param.first] = param.second->stringValue(); } } catch (const isc::data::TypeError& ex) { // Append position of the element. - isc_throw(BadValue, "invalid value type specified for " + isc_throw(DhcpConfigError, "invalid value type specified for " "parameter '" << param.first << "' (" << param.second->getPosition() << ")"); } @@ -83,33 +94,54 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) { // a. Check if the "type" keyword exists and thrown an exception if not. StringPairMap::const_iterator type_ptr = values_copy.find("type"); if (type_ptr == values_copy.end()) { - isc_throw(TypeKeywordMissing, (type_ == LEASE_DB ? "lease" : "host") + isc_throw(DhcpConfigError, (type_ == LEASE_DB ? "lease" : "host") << " database access parameters must " "include the keyword 'type' to determine type of database " - "to be accessed (" << config_value->getPosition() << ")"); + "to be accessed (" << database_config->getPosition() << ")"); } // b. Check if the 'type' keyword known and throw an exception if not. + // + // Please note when you add a new database backend you have to add + // the new type here and in server grammars. string dbtype = type_ptr->second; - if ((dbtype != "memfile") && (dbtype != "mysql") && (dbtype != "postgresql") && (dbtype != "cql")) { - isc_throw(BadValue, "unknown backend database type: " << dbtype - << " (" << config_value->getPosition() << ")"); + if ((dbtype != "memfile") && + (dbtype != "mysql") && + (dbtype != "postgresql") && + (dbtype != "cql")) { + ConstElementPtr value = database_config->get("type"); + isc_throw(DhcpConfigError, "unknown backend database type: " << dbtype + << " (" << value->getPosition() << ")"); } - // c. Check that the lfc-interval is a number and it is within a resonable - // range. - if ((lfc_interval < 0) || (lfc_interval > std::numeric_limits<uint32_t>::max())) { - isc_throw(BadValue, "lfc-interval value: " << lfc_interval + // c. Check that the lfc-interval is within a reasonable range. + if ((lfc_interval < 0) || + (lfc_interval > std::numeric_limits<uint32_t>::max())) { + ConstElementPtr value = database_config->get("lfc-interval"); + isc_throw(DhcpConfigError, "lfc-interval value: " << lfc_interval << " is out of range, expected value: 0.." - << std::numeric_limits<uint32_t>::max()); + << std::numeric_limits<uint32_t>::max() + << " (" << value->getPosition() << ")"); } - // d. Check that the timeout is a number and it is within a resonable - // range. - if ((timeout < 0) || (timeout > std::numeric_limits<uint32_t>::max())) { - isc_throw(BadValue, "timeout value: " << timeout + // d. Check that the timeout is within a reasonable range. + if ((timeout < 0) || + (timeout > std::numeric_limits<uint32_t>::max())) { + ConstElementPtr value = database_config->get("connect-timeout"); + isc_throw(DhcpConfigError, "connect-timeout value: " << timeout << " is out of range, expected value: 0.." - << std::numeric_limits<uint32_t>::max()); + << std::numeric_limits<uint32_t>::max() + << " (" << value->getPosition() << ")"); + } + + // e. Check that the port is within a reasonable range. + if ((port < 0) || + (port > std::numeric_limits<uint16_t>::max())) { + ConstElementPtr value = database_config->get("port"); + isc_throw(DhcpConfigError, "port value: " << port + << " is out of range, expected value: 0.." + << std::numeric_limits<uint16_t>::max() + << " (" << value->getPosition() << ")"); } // 4. If all is OK, update the stored keyword/value pairs. We do this by @@ -119,7 +151,6 @@ DbAccessParser::build(isc::data::ConstElementPtr config_value) { values_.swap(values_copy); // 5. Save the database access string in the Configuration Manager. - CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess(); if (type_ == LEASE_DB) { cfg_db->setLeaseDbAccessString(getDbAccessString()); @@ -152,11 +183,5 @@ DbAccessParser::getDbAccessString() const { return (dbaccess); } -// Commit the changes - reopen the database with the new parameters -void -DbAccessParser::commit() { -} - }; // namespace dhcp }; // namespace isc - |