]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/auth-catalogzone.cc
rec: mention rust compiler in compiling docs
[thirdparty/pdns.git] / pdns / auth-catalogzone.cc
1 /*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "dnsbackend.hh"
28
29 void CatalogInfo::fromJson(const std::string& json, CatalogType type)
30 {
31 d_type = type;
32 if (d_type == CatalogType::None) {
33 throw std::runtime_error("CatalogType is set to None");
34 }
35 if (json.empty()) {
36 return;
37 }
38 std::string err;
39 d_doc = json11::Json::parse(json, err);
40 if (!d_doc.is_null()) {
41 if (!d_doc[getTypeString(d_type)].is_null()) {
42 auto items = d_doc[getTypeString(type)].object_items();
43 if (!items["coo"].is_null()) {
44 if (items["coo"].is_string()) {
45 if (!items["coo"].string_value().empty()) {
46 d_coo = DNSName(items["coo"].string_value());
47 }
48 }
49 else {
50 throw std::out_of_range("Key 'coo' is not a string");
51 }
52 }
53 if (!items["unique"].is_null()) {
54 if (items["unique"].is_string()) {
55 if (!items["unique"].string_value().empty()) {
56 d_unique = DNSName(items["unique"].string_value());
57 }
58 }
59 else {
60 throw std::out_of_range("Key 'unique' is not a string");
61 }
62 }
63 if (!items["group"].is_null()) {
64 if (items["group"].is_array()) {
65 for (const auto& value : items["group"].array_items()) {
66 d_group.insert(value.string_value());
67 }
68 }
69 else {
70 throw std::out_of_range("Key 'group' is not an array");
71 }
72 }
73 }
74 }
75 else {
76 throw std::runtime_error("Parsing of JSON options failed: " + err);
77 }
78 }
79
80 std::string CatalogInfo::toJson() const
81 {
82 if (d_type == CatalogType::None) {
83 throw std::runtime_error("CatalogType is set to None");
84 }
85 json11::Json::object object;
86 if (!d_coo.empty()) {
87 object["coo"] = d_coo.toString();
88 }
89 if (!d_unique.empty()) {
90 if (d_unique.countLabels() > 1) {
91 throw std::out_of_range("Multiple labels in a unique value are not allowed");
92 }
93 object["unique"] = d_unique.toString();
94 }
95 if (!d_group.empty()) {
96 json11::Json::array entries;
97 for (const auto& group : d_group) {
98 entries.push_back(group);
99 }
100 object["group"] = entries;
101 }
102 auto tmp = d_doc.object_items();
103 tmp[getTypeString(d_type)] = object;
104 const json11::Json ret = tmp;
105 return ret.dump();
106 }
107
108 void CatalogInfo::updateHash(CatalogHashMap& hashes, const DomainInfo& di) const
109 {
110 hashes[di.catalog].process(std::to_string(di.id) + di.zone.toLogString() + string("\0", 1) + d_coo.toLogString() + string("\0", 1) + d_unique.toLogString());
111 for (const auto& group : d_group) {
112 hashes[di.catalog].process(std::to_string(group.length()) + group);
113 }
114 }
115
116 DNSZoneRecord CatalogInfo::getCatalogVersionRecord(const DNSName& zone)
117 {
118 DNSZoneRecord dzr;
119 dzr.dr.d_name = DNSName("version") + zone;
120 dzr.dr.d_ttl = 0;
121 dzr.dr.d_type = QType::TXT;
122 dzr.dr.setContent(std::make_shared<TXTRecordContent>("2"));
123 return dzr;
124 }
125
126 void CatalogInfo::toDNSZoneRecords(const DNSName& zone, vector<DNSZoneRecord>& dzrs) const
127 {
128 DNSName prefix;
129 if (d_unique.empty()) {
130 prefix = getUnique();
131 }
132 else {
133 prefix = d_unique;
134 }
135 prefix += DNSName("zones") + zone;
136
137 DNSZoneRecord dzr;
138 dzr.dr.d_name = prefix;
139 dzr.dr.d_ttl = 0;
140 dzr.dr.d_type = QType::PTR;
141 dzr.dr.setContent(std::make_shared<PTRRecordContent>(d_zone.toString()));
142 dzrs.emplace_back(dzr);
143
144 if (!d_coo.empty()) {
145 dzr.dr.d_name = DNSName("coo") + prefix;
146 dzr.dr.d_ttl = 0;
147 dzr.dr.d_type = QType::PTR;
148 dzr.dr.setContent(std::make_shared<PTRRecordContent>(d_coo));
149 dzrs.emplace_back(dzr);
150 }
151
152 for (const auto& group : d_group) {
153 dzr.dr.d_name = DNSName("group") + prefix;
154 dzr.dr.d_ttl = 0;
155 dzr.dr.d_type = QType::TXT;
156 dzr.dr.setContent(std::make_shared<TXTRecordContent>("\"" + group + "\""));
157 dzrs.emplace_back(dzr);
158 }
159 }