From: Thomas Markwalder Date: Wed, 14 May 2025 12:44:26 +0000 (-0400) Subject: [#3831] leaseX-write restricted to supported path X-Git-Tag: Kea-2.7.9~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0a61f4a9ee07ca01098c59b4cc130559a175d6f6;p=thirdparty%2Fkea.git [#3831] leaseX-write restricted to supported path modified: hooks-lease-cmds.rst modified: ../../../src/hooks/dhcp/lease_cmds/lease_cmds.cc modified: ../../../src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds4_unittest.cc modified: ../../../src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds6_unittest.cc --- diff --git a/doc/sphinx/arm/hooks-lease-cmds.rst b/doc/sphinx/arm/hooks-lease-cmds.rst index a559d73f72..04c3c1d023 100644 --- a/doc/sphinx/arm/hooks-lease-cmds.rst +++ b/doc/sphinx/arm/hooks-lease-cmds.rst @@ -1093,6 +1093,17 @@ the file in an attempt to synchronize both the files and the in-memory images of the lease database. The extension ``.bak`` and the server PID number are added to the previous filename: for example, ``.bak14326``. +.. note:: + + As of Kea 2.7.9, the lease file may only be written to the data directory + determined during compilation: ``"[kea-install-dir]/var/lib/kea"``. This + path may be overridden at startup by setting the environment variable + ``KEA_DHCP_DATA_DIRECTORY`` to the desired path. If a path other than + this value is used in ``name``, Kea will emit an error and refuse to start + or, if already running, log an unrecoverable error. For ease of use in + specifying a custom file name simply omit the path portion from ``filename``. + + .. note:: These commands do not replace the LFC mechanism; they should be used diff --git a/src/hooks/dhcp/lease_cmds/lease_cmds.cc b/src/hooks/dhcp/lease_cmds/lease_cmds.cc index 9079f61c4d..bd82a10210 100644 --- a/src/hooks/dhcp/lease_cmds/lease_cmds.cc +++ b/src/hooks/dhcp/lease_cmds/lease_cmds.cc @@ -2757,9 +2757,12 @@ LeaseCmdsImpl::leaseWriteHandler(CalloutHandle& handle) { if (file->getType() != Element::string) { isc_throw(BadValue, "'filename' parameter must be a string"); } - string filename = file->stringValue(); - if (filename.empty()) { - isc_throw(BadValue, "'filename' parameter is empty"); + + std::string filename; + try { + filename = CfgMgr::instance().validatePath(file->stringValue()); + } catch (const std::exception& ex) { + isc_throw(BadValue, "'filename' parameter is invalid: " << ex.what()); } if (v4) { @@ -2767,6 +2770,7 @@ LeaseCmdsImpl::leaseWriteHandler(CalloutHandle& handle) { } else { LeaseMgrFactory::instance().writeLeases6(filename); } + ostringstream s; s << (v4 ? "IPv4" : "IPv6") << " lease database into '" diff --git a/src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds4_unittest.cc b/src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds4_unittest.cc index 91025b23ca..64492a3c60 100644 --- a/src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds4_unittest.cc +++ b/src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds4_unittest.cc @@ -3482,8 +3482,23 @@ void Lease4CmdsTest::testLease4Write() { " \"filename\": \"\"\n" " }\n" "}"; - exp_rsp = "'filename' parameter is empty"; + exp_rsp = "'filename' parameter is invalid: path: '' has no filename"; testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp); + + // Filename must use supported path. + txt = + "{\n" + " \"command\": \"lease4-write\",\n" + " \"arguments\": {" + " \"filename\": \"/tmp/myleases.txt\"\n" + " }\n" + "}"; + + std::ostringstream os; + os << "'filename' parameter is invalid: invalid path specified:" + << " '/tmp', supported path is '" << CfgMgr::instance().getDataDir() << "'"; + + testCommand(txt, CONTROL_RESULT_ERROR, os.str()); } TEST_F(Lease4CmdsTest, lease4AddMissingParams) { diff --git a/src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds6_unittest.cc b/src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds6_unittest.cc index 635b5e6e2f..f07514a334 100644 --- a/src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds6_unittest.cc +++ b/src/hooks/dhcp/lease_cmds/libloadtests/lease_cmds6_unittest.cc @@ -4409,7 +4409,7 @@ void Lease6CmdsTest::testLease6ConflictingBulkApplyAdd() { } void Lease6CmdsTest::testLease6Write() { - // lease4-write negative tests. Positive tests are in the + // lease6-write negative tests. Positive tests are in the // memfile_lease_mgr_unittest.cc file. // Initialize lease manager (true = v6, false = don't add leases) @@ -4444,8 +4444,22 @@ void Lease6CmdsTest::testLease6Write() { " \"filename\": \"\"\n" " }\n" "}"; - exp_rsp = "'filename' parameter is empty"; + exp_rsp = "'filename' parameter is invalid: path: '' has no filename"; testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp); + + // Filename must use supported path. + txt = + "{\n" + " \"command\": \"lease6-write\",\n" + " \"arguments\": {" + " \"filename\": \"/tmp/myleases.txt\"\n" + " }\n" + "}"; + + std::ostringstream os; + os << "'filename' parameter is invalid: invalid path specified:" + << " '/tmp', supported path is '" << CfgMgr::instance().getDataDir() << "'"; + } TEST_F(Lease6CmdsTest, lease6AddMissingParams) {