diff --git a/ChangeLog b/ChangeLog index f46694f45b..b835d41ea3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +569. [bug] tomek + b10-dhcp4: Fix bug whereby a DHCP packet without a client ID + could crash the MySQL lease database backend. + (Trac #2697, git b5e2be95d21ed750ad7cf5e15de2058aa8bc45f4) + 568. [func] muks Various message IDs have been renamed to remove the word 'ERROR' from them when they are not logged at ERROR severity level. diff --git a/src/lib/dhcpsrv/lease_mgr.cc b/src/lib/dhcpsrv/lease_mgr.cc index 6608b14ddd..2310dd4cd5 100644 --- a/src/lib/dhcpsrv/lease_mgr.cc +++ b/src/lib/dhcpsrv/lease_mgr.cc @@ -113,11 +113,22 @@ Lease4::toText() const { bool Lease4::operator==(const Lease4& other) const { + if ( (client_id_ && !other.client_id_) || + (!client_id_ && other.client_id_) ) { + // One lease has client-id, but the other doesn't + return false; + } + + if (client_id_ && other.client_id_ && + *client_id_ != *other.client_id_) { + // Different client-ids + return false; + } + return ( addr_ == other.addr_ && ext_ == other.ext_ && hwaddr_ == other.hwaddr_ && - *client_id_ == *other.client_id_ && t1_ == other.t1_ && t2_ == other.t2_ && valid_lft_ == other.valid_lft_ && diff --git a/src/lib/dhcpsrv/mysql_lease_mgr.cc b/src/lib/dhcpsrv/mysql_lease_mgr.cc index 292df616ad..6b6cde51d3 100644 --- a/src/lib/dhcpsrv/mysql_lease_mgr.cc +++ b/src/lib/dhcpsrv/mysql_lease_mgr.cc @@ -338,12 +338,25 @@ public: bind_[1].length = &hwaddr_length_; // client_id: varbinary(128) - client_id_ = lease_->client_id_->getClientId(); - client_id_length_ = client_id_.size(); - bind_[2].buffer_type = MYSQL_TYPE_BLOB; - bind_[2].buffer = reinterpret_cast(&client_id_[0]); - bind_[2].buffer_length = client_id_length_; - bind_[2].length = &client_id_length_; + if (lease_->client_id_) { + client_id_ = lease_->client_id_->getClientId(); + client_id_length_ = client_id_.size(); + bind_[2].buffer_type = MYSQL_TYPE_BLOB; + bind_[2].buffer = reinterpret_cast(&client_id_[0]); + bind_[2].buffer_length = client_id_length_; + bind_[2].length = &client_id_length_; + } else { + bind_[2].buffer_type = MYSQL_TYPE_NULL; + + // According to http://dev.mysql.com/doc/refman/5.5/en/ + // c-api-prepared-statement-data-structures.html, the other + // fields doesn't matter if type is set to MYSQL_TYPE_NULL, + // but let's set them to some sane values in case earlier versions + // didn't have that assumption. + static my_bool no_clientid = MLM_TRUE; + bind_[2].buffer = NULL; + bind_[2].is_null = &no_clientid; + } // valid lifetime: unsigned int bind_[3].buffer_type = MYSQL_TYPE_LONG;