181 lines
8.1 KiB
Diff
181 lines
8.1 KiB
Diff
diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes
|
|
index 1deb2e6074..b359d09616 100644
|
|
--- a/src/bin/dhcp4/dhcp4_messages.mes
|
|
+++ b/src/bin/dhcp4/dhcp4_messages.mes
|
|
@@ -164,6 +164,20 @@ This debug message is issued when the server starts processing the Hostname
|
|
option sent in the client's query. The argument includes the client and
|
|
transaction identification information.
|
|
|
|
+% DHCP4_CLIENT_HOSTNAME_SCRUBBED_EMPTY %1: sanitizing client's Hostname option '%2' yielded an empty string
|
|
+Logged at debug log level 50.
|
|
+This debug message is issued when the result of sanitizing the
|
|
+hostname option(12) sent by the client is an empty string. When this occurs
|
|
+the server will ignore the hostname option. The arguments include the
|
|
+client and the hostname option it sent.
|
|
+
|
|
+% DHCP4_CLIENT_FQDN_SCRUBBED_EMPTY %1: sanitizing client's FQDN option '%2' yielded an empty string
|
|
+Logged at debug log level 50.
|
|
+This debug message is issued when the result of sanitizing the
|
|
+FQDN option(81) sent by the client is an empty string. When this occurs
|
|
+the server will ignore the FQDN option. The arguments include the
|
|
+client and the FQDN option it sent.
|
|
+
|
|
% DHCP4_CLIENT_NAME_PROC_FAIL %1: failed to process the fqdn or hostname sent by a client: %2
|
|
Logged at debug log level 55.
|
|
This debug message is issued when the DHCP server was unable to process the
|
|
diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc
|
|
index 0701ed41e9..a6be662889 100644
|
|
--- a/src/bin/dhcp4/dhcp4_srv.cc
|
|
+++ b/src/bin/dhcp4/dhcp4_srv.cc
|
|
@@ -2714,8 +2714,15 @@ Dhcpv4Srv::processClientFqdnOption(Dhcpv4Exchange& ex) {
|
|
} else {
|
|
// Adjust the domain name based on domain name value and type sent by the
|
|
// client and current configuration.
|
|
- d2_mgr.adjustDomainName<Option4ClientFqdn>(*fqdn, *fqdn_resp,
|
|
- *(ex.getContext()->getDdnsParams()));
|
|
+ try {
|
|
+ d2_mgr.adjustDomainName<Option4ClientFqdn>(*fqdn, *fqdn_resp,
|
|
+ *(ex.getContext()->getDdnsParams()));
|
|
+ } catch (const FQDNScrubbedEmpty& scrubbed) {
|
|
+ LOG_DEBUG(ddns4_logger, DBG_DHCP4_DETAIL, DHCP4_CLIENT_FQDN_SCRUBBED_EMPTY)
|
|
+ .arg(ex.getQuery()->getLabel())
|
|
+ .arg(scrubbed.what());
|
|
+ return;
|
|
+ }
|
|
}
|
|
|
|
// Add FQDN option to the response message. Note that, there may be some
|
|
@@ -2857,7 +2864,15 @@ Dhcpv4Srv::processHostnameOption(Dhcpv4Exchange& ex) {
|
|
ex.getContext()->getDdnsParams()->getHostnameSanitizer();
|
|
|
|
if (sanitizer) {
|
|
- hostname = sanitizer->scrub(hostname);
|
|
+ auto tmp = sanitizer->scrub(hostname);
|
|
+ if (tmp.empty()) {
|
|
+ LOG_DEBUG(ddns4_logger, DBG_DHCP4_DETAIL, DHCP4_CLIENT_HOSTNAME_SCRUBBED_EMPTY)
|
|
+ .arg(ex.getQuery()->getLabel())
|
|
+ .arg(hostname);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ hostname = tmp;
|
|
}
|
|
|
|
// Convert hostname to lower case.
|
|
diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes
|
|
index fff50ed367..79fc984ff5 100644
|
|
--- a/src/bin/dhcp6/dhcp6_messages.mes
|
|
+++ b/src/bin/dhcp6/dhcp6_messages.mes
|
|
@@ -1167,3 +1167,10 @@ such modification. The clients will remember previous server-id, and will
|
|
use it to extend their leases. As a result, they will have to go through
|
|
a rebinding phase to re-acquire their leases and associate them with a
|
|
new server id.
|
|
+
|
|
+% DHCP6_CLIENT_FQDN_SCRUBBED_EMPTY %1: sanitizing client's FQDN option '%2' yielded an empty string
|
|
+Logged at debug log level 50.
|
|
+This debug message is issued when the result of sanitizing the
|
|
+FQDN option(39) sent by the client is an empty string. When this occurs
|
|
+the server will ignore the FQDN option. The arguments include the
|
|
+client and the FQDN option it sent.
|
|
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
|
|
index 417960b126..f999c3178f 100644
|
|
--- a/src/bin/dhcp6/dhcp6_srv.cc
|
|
+++ b/src/bin/dhcp6/dhcp6_srv.cc
|
|
@@ -2332,7 +2332,14 @@ Dhcpv6Srv::processClientFqdn(const Pkt6Ptr& question, const Pkt6Ptr& answer,
|
|
} else {
|
|
// Adjust the domain name based on domain name value and type sent by
|
|
// the client and current configuration.
|
|
- d2_mgr.adjustDomainName<Option6ClientFqdn>(*fqdn, *fqdn_resp, *ddns_params);
|
|
+ try {
|
|
+ d2_mgr.adjustDomainName<Option6ClientFqdn>(*fqdn, *fqdn_resp, *ddns_params);
|
|
+ } catch(const FQDNScrubbedEmpty& scrubbed) {
|
|
+ LOG_DEBUG(ddns6_logger, DBG_DHCP6_DETAIL, DHCP6_CLIENT_FQDN_SCRUBBED_EMPTY)
|
|
+ .arg(question->getLabel())
|
|
+ .arg(scrubbed.what());
|
|
+ return;
|
|
+ }
|
|
}
|
|
|
|
// Once we have the FQDN setup to use it for the lease hostname. This
|
|
diff --git a/src/lib/dhcpsrv/d2_client_mgr.cc b/src/lib/dhcpsrv/d2_client_mgr.cc
|
|
index 84ee11d9fb..54c815176e 100644
|
|
--- a/src/lib/dhcpsrv/d2_client_mgr.cc
|
|
+++ b/src/lib/dhcpsrv/d2_client_mgr.cc
|
|
@@ -186,10 +186,15 @@ std::string
|
|
D2ClientMgr::qualifyName(const std::string& partial_name,
|
|
const DdnsParams& ddns_params,
|
|
const bool trailing_dot) const {
|
|
+ if (partial_name.empty()) {
|
|
+ isc_throw(BadValue, "D2ClientMgr::qualifyName"
|
|
+ " - partial_name cannot be an empty string");
|
|
+ }
|
|
+
|
|
std::ostringstream gen_name;
|
|
gen_name << partial_name;
|
|
std::string suffix = ddns_params.getQualifyingSuffix();
|
|
- if (!suffix.empty() && partial_name.back() != '.') {
|
|
+ if (!suffix.empty() && (partial_name.back() != '.')) {
|
|
bool suffix_present = true;
|
|
std::string str = gen_name.str();
|
|
auto suffix_rit = suffix.rbegin();
|
|
@@ -241,7 +246,7 @@ D2ClientMgr::qualifyName(const std::string& partial_name,
|
|
// If the trailing dot should not be appended but it is present,
|
|
// remove it.
|
|
if ((len > 0) && (str[len - 1] == '.')) {
|
|
- gen_name.str(str.substr(0,len-1));
|
|
+ gen_name.str(str.substr(0, len-1));
|
|
}
|
|
|
|
}
|
|
diff --git a/src/lib/dhcpsrv/d2_client_mgr.h b/src/lib/dhcpsrv/d2_client_mgr.h
|
|
index 7344f19a40..238fd0a415 100644
|
|
--- a/src/lib/dhcpsrv/d2_client_mgr.h
|
|
+++ b/src/lib/dhcpsrv/d2_client_mgr.h
|
|
@@ -30,6 +30,14 @@
|
|
namespace isc {
|
|
namespace dhcp {
|
|
|
|
+/// @brief Exception thrown when host name sanitizing reduces
|
|
+/// the domain name to an empty string.
|
|
+class FQDNScrubbedEmpty : public Exception {
|
|
+public:
|
|
+ FQDNScrubbedEmpty(const char* file, size_t line, const char* what) :
|
|
+ isc::Exception(file, line, what) { }
|
|
+};
|
|
+
|
|
/// @brief Defines the type for D2 IO error handler.
|
|
/// This callback is invoked when a send to kea-dhcp-ddns completes with a
|
|
/// failed status. This provides the application layer (Kea) with a means to
|
|
@@ -197,6 +205,7 @@ public:
|
|
/// suffix itself is empty (i.e. "").
|
|
///
|
|
/// @return std::string containing the qualified name.
|
|
+ /// @throw BadValue if partial_name is empty.
|
|
std::string qualifyName(const std::string& partial_name,
|
|
const DdnsParams& ddns_params,
|
|
const bool trailing_dot) const;
|
|
@@ -264,6 +273,9 @@ public:
|
|
/// @param ddns_params DDNS behavioral configuration parameters
|
|
/// @tparam T FQDN Option class containing the FQDN data such as
|
|
/// dhcp::Option4ClientFqdn or dhcp::Option6ClientFqdn
|
|
+ ///
|
|
+ /// @throw FQDNScrubbedEmpty if hostname sanitizing reduces the input domain
|
|
+ /// name to an empty string.
|
|
template <class T>
|
|
void adjustDomainName(const T& fqdn, T& fqdn_resp,
|
|
const DdnsParams& ddns_params);
|
|
@@ -515,7 +527,12 @@ D2ClientMgr::adjustDomainName(const T& fqdn, T& fqdn_resp, const DdnsParams& ddn
|
|
ss << sanitizer->scrub(label);
|
|
}
|
|
|
|
- client_name = ss.str();
|
|
+ std::string clean_name = ss.str();
|
|
+ if (clean_name.empty() || clean_name == ".") {
|
|
+ isc_throw(FQDNScrubbedEmpty, client_name);
|
|
+ }
|
|
+
|
|
+ client_name = clean_name;
|
|
}
|
|
|
|
// If the supplied name is partial, qualify it by adding the suffix.
|