Kea 3.0.0
unix_command_config.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2025 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
11#include <config/command_mgr.h>
13#include <util/filesystem.h>
14#include <limits>
15
16using namespace isc;
17using namespace isc::asiolink;
18using namespace isc::config;
19using namespace isc::data;
20using namespace isc::dhcp;
21using namespace isc::util::file;
22using namespace std;
23
24namespace isc {
25namespace config {
26
27namespace {
28 // Singleton PathChecker to set and hold valid unix socket path.
29 PathCheckerPtr socket_path_checker_;
30};
31
32const mode_t UnixCommandConfig::DEFAULT_SOCKET_PATH_PERMS = (S_IRWXU | S_IRGRP | S_IXGRP);
33
35
37 : socket_type_("unix"), socket_name_() {
38 if (config->getType() != Element::map) {
39 isc_throw(DhcpConfigError, "expected map type ("
40 << config->getPosition() << ")");
41 }
42 // Get socket type.
43 ConstElementPtr socket_type = config->get("socket-type");
44 if (socket_type) {
45 if (socket_type->getType() != Element::string) {
47 "invalid type specified for parameter 'socket-type' ("
48 << socket_type->getPosition() << ")");
49 }
50 socket_type_ = socket_type->stringValue();
51 if ((socket_type_ != "unix")) {
52 isc_throw(DhcpConfigError, "unsupported 'socket-type' '"
53 << socket_type_ << "' not 'unix'");
54 }
55 }
56 // Reject HTTP/HTTPS only socket-address.
57 if (config->contains("socket-address")) {
58 isc_throw(DhcpConfigError,
59 "parameter 'socket-address' is not supported by UNIX "
60 "control sockets");
61 }
62 // Get socket name.
63 ConstElementPtr socket_name = config->get("socket-name");
64 if (!socket_name) {
65 isc_throw(DhcpConfigError, "Mandatory 'socket-name' parameter missing");
66 }
67
68 if (socket_name->getType() != Element::string) {
69 isc_throw(DhcpConfigError,
70 "invalid type specified for parameter 'socket-name' ("
71 << socket_name->getPosition() << ")");
72 }
73
74 try {
75 socket_name_ = validatePath(socket_name->stringValue());
76 } catch (const std::exception& ex) {
77 isc_throw(DhcpConfigError, "'socket-name' is invalid: " << ex.what());
78 }
79
80 // Get user context.
81 ConstElementPtr user_context = config->get("user-context");
82 if (user_context) {
83 setContext(user_context);
84 }
85}
86
90 // Set user-context.
91 contextToElement(result);
92 // Set socket type.
93 result->set("socket-type", Element::create(socket_type_));
94 // Set socket name.
95 result->set("socket-name", Element::create(socket_name_));
96 return (result);
97}
98
99std::string
100UnixCommandConfig::getSocketPath(bool reset /* = false */,
101 const std::string explicit_path /* = "" */) {
102 if (!socket_path_checker_ || reset) {
103 socket_path_checker_.reset(new PathChecker(CONTROL_SOCKET_DIR,
104 "KEA_CONTROL_SOCKET_DIR"));
105 if (!explicit_path.empty()) {
106 socket_path_checker_->getPath(true, explicit_path);
107 }
108 }
109
110 return (socket_path_checker_->getPath());
111}
112
113std::string
114UnixCommandConfig::validatePath(const std::string socket_path) {
115 if (!socket_path_checker_) {
117 }
118
119 auto valid_path = socket_path_checker_->validatePath(socket_path);
120 if (!socket_path_checker_->pathHasPermissions(socket_path_perms_)) {
122 "socket path:" << socket_path_checker_->getPath()
123 << " does not exist or does not have permssions = "
124 << std::oct << socket_path_perms_);
125 }
126
127 return (valid_path);
128}
129
130mode_t
134
135void
137 /* = DEFAULT_SOCKET_PATH_PERMS */) {
138 socket_path_perms_ = perms;
139}
140
141} // end of isc::config
142} // end of isc
if(!(yy_init))
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition data.cc:249
@ map
Definition data.h:147
@ string
Definition data.h:144
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:304
static std::string getSocketPath(bool reset=false, const std::string explicit_path="")
Fetches the supported control socket path.
static mode_t getSocketPathPerms()
Fetches the required socket path permissions mask.
UnixCommandConfig(isc::data::ConstElementPtr config)
Constructor.
static const mode_t DEFAULT_SOCKET_PATH_PERMS
Defines the default permissions for unix socket parent directory.
static void setSocketPathPerms(mode_t perms=DEFAULT_SOCKET_PATH_PERMS)
Sets the required socket path permissions mask.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
static std::string validatePath(const std::string socket_path)
Validates a path against the supported path for unix control sockets.
static mode_t socket_path_perms_
Stores the default permissions for unix socket parent directory.
To be removed. Please use ConfigError instead.
Embodies a supported path against which file paths can be validated.
Definition filesystem.h:179
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
boost::shared_ptr< PathChecker > PathCheckerPtr
Defines a pointer to a PathChecker.
Definition filesystem.h:298
Defines the logger used by the top-level component of kea-lfc.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
void setContext(const data::ConstElementPtr &ctx)
Sets user context.