Kea 3.3.4
rbac_acl.cc
Go to the documentation of this file.
1// Copyright (C) 2026 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
10
11#include <rbac/rbac.h>
12#include <rbac_log.h>
13
14using namespace isc;
15using namespace isc::data;
16using namespace isc::log;
17using namespace isc::rbac;
18using namespace std;
19
20namespace isc {
21namespace rbac {
22
24
25void
27 aclTable.clear();
28 aclTable["ALL"] = AclPtr(new AllAcl());
29 aclTable["NONE"] = AclPtr(new NoneAcl());
30 aclTable["READ"] = AclPtr(new AccessAcl("read"));
31 aclTable["WRITE"] = AclPtr(new AccessAcl("write"));
32}
33
36 if (!cfg) {
37 isc_throw(BadValue, "parse null access control list");
38 }
39 if (cfg->getType() == Element::string) {
40 const string& name = cfg->stringValue();
41 auto it = aclTable.find(name);
42 if (it == aclTable.end()) {
43 isc_throw(BadValue, "unknown access control list name '"
44 << name << "'");
45 }
46 return (it->second);
47 }
48 if (cfg->getType() != Element::map) {
49 isc_throw(BadValue, "access control list is not a string or a map");
50 }
51 AclPtr acl;
52 for (auto const& entry : cfg->mapValue()) {
53 if (entry.first == "comment") {
54 continue;
55 }
56 if (acl) {
57 isc_throw(BadValue, "spurious '" << entry.first << "' entry in "
58 << cfg->str());
59 }
60 if (entry.first == "not") {
61 acl.reset(new NotAcl(parse(entry.second)));
62 } else if (entry.first == "and") {
63 acl.reset(new AndAcl(parseList(entry.second)));
64 } else if (entry.first == "or") {
65 acl.reset(new OrAcl(parseList(entry.second)));
66 } else if (entry.first == "commands") {
67 if (entry.second->getType() != Element::list) {
68 isc_throw(BadValue, "commands access control list is not "
69 << "a list");
70 }
71 std::set<std::string> commands;
72 for (auto const& elem : entry.second->listValue()) {
73 if (elem->getType() != Element::string) {
74 isc_throw(BadValue, "commands access control list item is "
75 << "not a string");
76 }
77 const string& command = elem->stringValue();
78 if (!Api::getApiByName(command)) {
79 isc_throw(BadValue, "unknown command '" << command << "'");
80 }
81 static_cast<void>(commands.insert(command));
82 }
83 acl.reset(new CommandsAcl(commands));
84 } else if (entry.first == "access") {
85 if (entry.second->getType() != Element::string) {
86 isc_throw(BadValue, "access access control list is not a "
87 << "string");
88 }
89 const string& access = entry.second->stringValue();
90 if (access.empty()) {
91 isc_throw(BadValue, "access control list access is empty");
92 }
93 if (apiAccesses.count(access) == 0) {
94 isc_throw(BadValue, "unknown access '" << access << "'");
95 }
96 acl.reset(new AccessAcl(access));
97 } else if (entry.first == "hook") {
98 if (entry.second->getType() != Element::string) {
99 isc_throw(BadValue, "hook access control list is not a "
100 << "string");
101 }
102 const string& hook = entry.second->stringValue();
103 if (!hook.empty() && (apiHooks.count(hook) == 0)) {
104 isc_throw(BadValue, "unknown hook '" << hook << "'");
105 }
106 acl.reset(new HookAcl(hook));
107 } else {
108 isc_throw(BadValue, "unknown access control list keyword '"
109 << entry.first << "'");
110 }
111 }
112 if (!acl) {
113 isc_throw(BadValue, "bad access control list " << cfg->str());
114 }
115 return (acl);
116}
117
120 if (!cfg) {
121 isc_throw(BadValue, "parse null list of access control lists");
122 }
123 if (cfg->getType() != Element::list) {
124 isc_throw(BadValue, "list of access control lists is not a list");
125 }
126 AclList acls;
127 for (auto const& elem : cfg->listValue()) {
128 acls.push_back(Acl::parse(elem));
129 }
130 return (acls);
131}
132
133void
135 if (!def) {
136 isc_throw(BadValue, "null access control list definition");
137 }
138 if (def->getType() != Element::map) {
139 isc_throw(BadValue, "access control list definition is not a map");
140 }
141 if (def->size() != 1) {
142 isc_throw(BadValue, "access control list definition must have "
143 "one entry");
144 }
145 for (auto const& entry : def->mapValue()) {
146 const string& name = entry.first;
147 if (name.empty()) {
148 isc_throw(BadValue, "access control list definition name is empty");
149 }
150 if (aclTable.count(entry.first) != 0) {
151 isc_throw(BadValue, "access control list '" << name
152 << "' is already defined");
153 }
154 aclTable[name] = Acl::parse(entry.second);
155 }
156}
157
158} // end of namespace rbac
159} // end of namespace isc
@ map
Definition data.h:160
@ list
Definition data.h:159
@ string
Definition data.h:157
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Read or write access control list.
Definition rbac_acl.h:350
static AclPtr parse(data::ConstElementPtr cfg)
Parse an access control list.
Definition rbac_acl.cc:35
static void initTable()
Initialize the access control list table.
Definition rbac_acl.cc:26
static AclList parseList(data::ConstElementPtr cfg)
Parse a list of access control lists.
Definition rbac_acl.cc:119
static void parse(data::ConstElementPtr def)
Parse an access control list definition.
Definition rbac_acl.cc:134
All access control list.
Definition rbac_acl.h:280
Conjunction of access control lists.
Definition rbac_acl.h:176
static ApiPtr getApiByName(const std::string &name)
Lookup in the table.
Definition rbac_api.cc:35
Explicit access control list.
Definition rbac_acl.h:312
Hook access control list.
Definition rbac_acl.h:380
None access control list.
Definition rbac_acl.h:296
Boolean operators.
Definition rbac_acl.h:142
Disjunction of access control lists.
Definition rbac_acl.h:228
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
set< string > apiHooks
The API hook list.
Definition rbac_api.cc:32
boost::shared_ptr< Acl > AclPtr
Type of shared pointers to Acl.
Definition rbac_acl.h:29
std::map< std::string, AclPtr > AclTable
Type of the access control list table.
Definition rbac_acl.h:35
std::list< AclPtr > AclList
Type of list of shared pointers to Acl.
Definition rbac_acl.h:32
set< string > apiAccesses
The API access list (should be "read" and "write").
Definition rbac_api.cc:30
AclTable aclTable
The access control list table.
Definition rbac_acl.cc:23
Defines the logger used by the top-level component of kea-lfc.