]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnsbackend.hh
rec docs: Update tools in the venv
[thirdparty/pdns.git] / pdns / dnsbackend.hh
CommitLineData
12c86877 1/*
12471842
PL
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 */
12c86877
BH
22#ifndef DNSBACKEND_HH
23#define DNSBACKEND_HH
24
973ad2b5
BH
25class DNSPacket;
26
12c86877
BH
27#include "utility.hh"
28#include <string>
29#include <vector>
30#include <map>
31#include <sys/types.h>
5c409fa2 32#include "pdnsexception.hh"
973ad2b5 33#include <set>
702b226d 34#include <iostream>
76473b92
KM
35#include <sys/socket.h>
36#include <dirent.h>
76979e74 37#include "misc.hh"
12c86877
BH
38#include "qtype.hh"
39#include "dns.hh"
e5b11b2f 40#include <vector>
10f4eea8 41#include "namespaces.hh"
6cc98ddf 42#include "comment.hh"
675fa24c 43#include "dnsname.hh"
28e2e78e 44#include "dnsrecords.hh"
76979e74 45
12c86877
BH
46class DNSBackend;
47struct DomainInfo
48{
f82ed9fc 49 DomainInfo() : last_check(0), backend(NULL), id(0), notified_serial(0), serial(0), kind(DomainInfo::Native) {}
52ff1db1 50
675fa24c 51 DNSName zone;
12c86877 52 time_t last_check;
8ffb7a9b 53 string account;
52ff1db1 54 vector<string> masters;
12c86877 55 DNSBackend *backend;
52ff1db1
PL
56
57 uint32_t id;
58 uint32_t notified_serial;
59
60 uint32_t serial;
61 enum DomainKind : uint8_t { Master, Slave, Native } kind;
7f3d870e
BH
62
63 bool operator<(const DomainInfo& rhs) const
64 {
65 return zone < rhs.zone;
66 }
ec10217f
CH
67
68 const char *getKindString() const
76979e74
CH
69 {
70 return DomainInfo::getKindString(kind);
71 }
72
73 static const char *getKindString(enum DomainKind kind)
ec10217f
CH
74 {
75 const char *kinds[]={"Master", "Slave", "Native"};
76 return kinds[kind];
77 }
76979e74
CH
78
79 static DomainKind stringToKind(const string& kind)
80 {
81 if(pdns_iequals(kind,"SLAVE"))
82 return DomainInfo::Slave;
83 else if(pdns_iequals(kind,"MASTER"))
84 return DomainInfo::Master;
85 else
86 return DomainInfo::Native;
87 }
88
12c86877
BH
89};
90
6f872b78 91struct TSIGKey {
675fa24c
PD
92 DNSName name;
93 DNSName algorithm;
6f872b78
AT
94 std::string key;
95};
96
12c86877 97class DNSPacket;
bdc9f8d2 98
3971cf53 99//! This virtual base class defines the interface for backends for the ahudns.
bdc9f8d2
BH
100/** To create a backend, inherit from this class and implement functions for all virtual methods.
101 Methods should not throw an exception if they are sure they did not find the requested data. However,
102 if an error occurred which prevented them temporarily from performing a lockup, they should throw a DBException,
103 which will cause the nameserver to send out a ServFail or take other evasive action. Probably only locking
104 issues should lead to DBExceptions.
105
106 More serious errors, which may indicate that the database connection is hosed, or a configuration error occurred, should
3f81d239 107 lead to the throwing of an PDNSException. This exception will fall straight through the UeberBackend and the PacketHandler
bdc9f8d2
BH
108 and be caught by the Distributor, which will delete your DNSBackend instance and spawn a new one.
109*/
12c86877
BH
110class DNSBackend
111{
112public:
bdc9f8d2 113 //! lookup() initiates a lookup. A lookup without results should not throw!
675fa24c 114 virtual void lookup(const QType &qtype, const DNSName &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0;
bdc9f8d2 115 virtual bool get(DNSResourceRecord &)=0; //!< retrieves one DNSResource record, returns false if no more were available
90ba52e0 116 virtual bool get(DNSZoneRecord &r);
702b226d 117
bdc9f8d2
BH
118 //! Initiates a list of the specified domain
119 /** Once initiated, DNSResourceRecord objects can be retrieved using get(). Should return false
120 if the backend does not consider itself responsible for the id passed.
121 \param domain_id ID of which a list is requested
122 */
675fa24c 123 virtual bool list(const DNSName &target, int domain_id, bool include_disabled=false)=0;
12c86877
BH
124
125 virtual ~DNSBackend(){};
126
bdc9f8d2 127 //! fills the soadata struct with the SOA details. Returns false if there is no SOA.
94bfa5b6 128 virtual bool getSOA(const DNSName &name, SOAData &soadata);
12c86877 129
d07fc616 130 //! Calculates a SOA serial for the zone and stores it in the third argument.
675fa24c 131 virtual bool calculateSOASerial(const DNSName& domain, const SOAData& sd, time_t& serial);
d07fc616 132
675fa24c 133 virtual bool replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<DNSResourceRecord>& rrset)
8bbb6f36
BH
134 {
135 return false;
136 }
137
675fa24c 138 virtual bool listSubZone(const DNSName &zone, int domain_id)
6a323f63
RA
139 {
140 return false;
141 }
142
4aafcb39 143 // the DNSSEC related (getDomainMetadata has broader uses too)
ad34750d
KM
144 bool isDnssecDomainMetadata (const string& name) {
145 return (name == "PRESIGNED" || name == "NSEC3PARAM" || name == "NSEC3NARROW");
146 }
675fa24c
PD
147 virtual bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) { return false; };
148 virtual bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) { return false; }
149 virtual bool getDomainMetadataOne(const DNSName& name, const std::string& kind, std::string& value)
d29d5db7
CH
150 {
151 std::vector<std::string> meta;
152 if (getDomainMetadata(name, kind, meta)) {
153 if(!meta.empty()) {
154 value = *meta.begin();
155 return true;
156 }
157 }
158 return false;
159 }
160
675fa24c
PD
161 virtual bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta) {return false;}
162 virtual bool setDomainMetadataOne(const DNSName& name, const std::string& kind, const std::string& value)
d29d5db7
CH
163 {
164 const std::vector<std::string> meta(1, value);
165 return setDomainMetadata(name, kind, meta);
166 }
167
4aafcb39 168
cea26350 169 virtual void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false) { }
1325e8a2 170
c14bc34a 171 /** Determines if we are authoritative for a zone, and at what level */
5b9ac871 172 virtual bool getAuth(DNSPacket *p, SOAData *sd, const DNSName &target);
c14bc34a 173
4aafcb39 174 struct KeyData {
eda140fa 175 std::string content;
4aafcb39
BH
176 unsigned int id;
177 unsigned int flags;
178 bool active;
4aafcb39
BH
179 };
180
9c1c5d49 181 virtual bool getDomainKeys(const DNSName& name, std::vector<KeyData>& keys) { return false;}
675fa24c 182 virtual bool removeDomainKey(const DNSName& name, unsigned int id) { return false; }
82cc0761 183 virtual bool addDomainKey(const DNSName& name, const KeyData& key, int64_t& id){ return false; }
675fa24c
PD
184 virtual bool activateDomainKey(const DNSName& name, unsigned int id) { return false; }
185 virtual bool deactivateDomainKey(const DNSName& name, unsigned int id) { return false; }
8ab63616 186
675fa24c
PD
187 virtual bool getTSIGKey(const DNSName& name, DNSName* algorithm, string* content) { return false; }
188 virtual bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content) { return false; }
189 virtual bool deleteTSIGKey(const DNSName& name) { return false; }
6f872b78 190 virtual bool getTSIGKeys(std::vector< struct TSIGKey > &keys) { return false; }
78bcb858 191
29e0008a 192 virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after)
4aafcb39
BH
193 {
194 std::cerr<<"Default beforeAndAfterAbsolute called!"<<std::endl;
195 abort();
196 return false;
197 }
198
675fa24c 199 virtual bool getBeforeAndAfterNames(uint32_t id, const DNSName& zonename, const DNSName& qname, DNSName& before, DNSName& after);
4aafcb39 200
96e63d77 201 virtual bool updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName& qname, const DNSName& ordername, bool auth, const uint16_t qtype=QType::ANY)
4aafcb39
BH
202 {
203 return false;
204 }
205
96e63d77 206 virtual bool updateEmptyNonTerminals(uint32_t domain_id, set<DNSName>& insert, set<DNSName>& erase, bool remove)
c2df797e
PD
207 {
208 return false;
209 }
210
ece45ffb
PD
211 virtual bool doesDNSSEC()
212 {
213 return false;
214 }
215
4aafcb39
BH
216 // end DNSSEC
217
6cc98ddf
CH
218 // comments support
219 virtual bool listComments(uint32_t domain_id)
220 {
221 return false; // unsupported by this backend
222 }
223
224 virtual bool getComment(Comment& comment)
225 {
226 return false;
227 }
228
229 virtual void feedComment(const Comment& comment)
230 {
231 }
232
675fa24c 233 virtual bool replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<Comment>& comments)
6cc98ddf
CH
234 {
235 return false;
236 }
237
bdc9f8d2 238 //! returns true if master ip is master for domain name.
675fa24c 239 virtual bool isMaster(const DNSName &name, const string &ip)
12c86877
BH
240 {
241 return false;
242 }
243
bdc9f8d2 244 //! starts the transaction for updating domain qname (FIXME: what is id?)
675fa24c 245 virtual bool startTransaction(const DNSName &qname, int id=-1)
12c86877
BH
246 {
247 return false;
248 }
249
bdc9f8d2 250 //! commits the transaction started by startTransaction
12c86877
BH
251 virtual bool commitTransaction()
252 {
253 return false;
254 }
255
bdc9f8d2 256 //! aborts the transaction started by strartTransaction, should leave state unaltered
12c86877
BH
257 virtual bool abortTransaction()
258 {
259 return false;
260 }
261
262 virtual void reload()
263 {
264 }
265
973ad2b5 266 virtual void rediscover(string* status=0)
12c86877
BH
267 {
268 }
269
bdc9f8d2 270 //! feeds a record to a zone, needs a call to startTransaction first
c9b43446 271 virtual bool feedRecord(const DNSResourceRecord &rr, const DNSName &ordername)
12c86877
BH
272 {
273 return false; // no problem!
274 }
675fa24c 275 virtual bool feedEnts(int domain_id, map<DNSName,bool> &nonterm)
f9cf6d92
KM
276 {
277 return false;
278 }
28e2e78e 279 virtual bool feedEnts3(int domain_id, const DNSName &domain, map<DNSName,bool> &nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow)
f9cf6d92
KM
280 {
281 return false;
282 }
283
bdc9f8d2 284 //! if this returns true, DomainInfo di contains information about the domain
675fa24c 285 virtual bool getDomainInfo(const DNSName &domain, DomainInfo &di)
12c86877
BH
286 {
287 return false;
288 }
bdc9f8d2 289 //! slave capable backends should return a list of slaves that should be rechecked for staleness
12c86877
BH
290 virtual void getUnfreshSlaveInfos(vector<DomainInfo>* domains)
291 {
292 }
293
bdc9f8d2 294 //! get a list of IP addresses that should also be notified for a domain
675fa24c 295 virtual void alsoNotifies(const DNSName &domain, set<string> *ips)
12c86877
BH
296 {
297 }
bdc9f8d2
BH
298
299 //! get list of domains that have been changed since their last notification to slaves
12c86877
BH
300 virtual void getUpdatedMasters(vector<DomainInfo>* domains)
301 {
302 }
bdc9f8d2
BH
303
304 //! Called by PowerDNS to inform a backend that a domain has been checked for freshness
092f210a 305 virtual void setFresh(uint32_t domain_id)
12c86877
BH
306 {
307
308 }
bdc9f8d2 309 //! Called by PowerDNS to inform a backend that the changes in the domain have been reported to slaves
092f210a 310 virtual void setNotified(uint32_t id, uint32_t serial)
12c86877
BH
311 {
312 }
313
6d58359c 314 //! Called when the Master of a domain should be changed
675fa24c 315 virtual bool setMaster(const DNSName &domain, const string &ip)
6d58359c
CH
316 {
317 return false;
318 }
319
320 //! Called when the Kind of a domain should be changed (master -> native and similar)
675fa24c 321 virtual bool setKind(const DNSName &domain, const DomainInfo::DomainKind kind)
6d58359c
CH
322 {
323 return false;
324 }
325
79532aa7 326 //! Called when the Account of a domain should be changed
675fa24c 327 virtual bool setAccount(const DNSName &domain, const string &account)
79532aa7
CH
328 {
329 return false;
330 }
331
bdc9f8d2 332 //! Can be called to seed the getArg() function with a prefix
12c86877 333 void setArgPrefix(const string &prefix);
bdc9f8d2
BH
334
335 //! determine if ip is a supermaster or a domain
675fa24c 336 virtual bool superMasterBackend(const string &ip, const DNSName &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db)
12c86877
BH
337 {
338 return false;
339 }
bdc9f8d2 340
487cf033 341 //! called by PowerDNS to create a new domain
675fa24c 342 virtual bool createDomain(const DNSName &domain)
487cf033
CH
343 {
344 return false;
345 }
346
bdc9f8d2 347 //! called by PowerDNS to create a slave record for a superMaster
675fa24c 348 virtual bool createSlaveDomain(const string &ip, const DNSName &domain, const string &nameserver, const string &account)
12c86877
BH
349 {
350 return false;
351 }
352
44e62984 353 //! called to delete a domain, incl. all metadata, zone contents, etc.
675fa24c 354 virtual bool deleteDomain(const DNSName &domain)
44e62984
CH
355 {
356 return false;
357 }
358
f641c3b7
PD
359 virtual string directBackendCmd(const string &query)
360 {
361 return "directBackendCmd not supported for this backend\n";
362 }
363
9f8e226e
AT
364 //! Search for records, returns true if search was done successfully.
365 virtual bool searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result)
366 {
367 return false;
368 }
369
370 //! Search for comments, returns true if search was done successfully.
371 virtual bool searchComments(const string &pattern, int maxResults, vector<Comment>& result)
372 {
373 return false;
374 }
375
ece1aa0b 376 const string& getPrefix() { return d_prefix; };
12c86877
BH
377protected:
378 bool mustDo(const string &key);
379 const string &getArg(const string &key);
380 int getArgAsNum(const string &key);
12c86877
BH
381
382private:
383 string d_prefix;
384};
385
386class BackendFactory
387{
388public:
389 BackendFactory(const string &name) : d_name(name) {}
390 virtual ~BackendFactory(){}
391 virtual DNSBackend *make(const string &suffix)=0;
2717b8b3
BH
392 virtual DNSBackend *makeMetadataOnly(const string &suffix)
393 {
394 return this->make(suffix);
395 }
12c86877
BH
396 virtual void declareArguments(const string &suffix=""){}
397 const string &getName() const;
398
399protected:
400 void declare(const string &suffix, const string &param, const string &explanation, const string &value);
401
402private:
403 const string d_name;
404};
405
406class BackendMakerClass
407{
408public:
409 void report(BackendFactory *bf);
410 void launch(const string &instr);
e0d84497 411 vector<DNSBackend *>all(bool skipBIND=false);
12c86877
BH
412 void load(const string &module);
413 int numLauncheable();
414 vector<string> getModules();
415
416private:
417 void load_all();
418 typedef map<string,BackendFactory *>d_repository_t;
419 d_repository_t d_repository;
420 vector<pair<string,string> >d_instances;
421};
422
423extern BackendMakerClass &BackendMakers();
424
bdc9f8d2 425//! Exception that can be thrown by a DNSBackend to indicate a failure
3f81d239 426class DBException : public PDNSException
cc3afe25
BH
427{
428public:
dd079764 429 DBException(const string &reason_) : PDNSException(reason_){}
cc3afe25
BH
430};
431
ceea1ba6 432/** helper function for both DNSPacket and addSOARecord() - converts a line into a struct, for easier parsing */
433void fillSOAData(const string &content, SOAData &data);
90ba52e0 434// same but more karmic
435void fillSOAData(const DNSZoneRecord& in, SOAData& data);
436// the reverse
437std::shared_ptr<DNSRecordContent> makeSOAContent(const SOAData& sd);
12c86877
BH
438
439#endif