]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsbackend.hh
add OpenSSL exception to PowerDNS, Netherlabs, van Dijk and Hubert copyrights
[thirdparty/pdns.git] / pdns / dnsbackend.hh
1 /*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002-2010 PowerDNS.COM BV
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
8
9 Additionally, the license of this program contains a special
10 exception which allows to distribute the program in binary form when
11 it is linked against OpenSSL.
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 St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22 #ifndef DNSBACKEND_HH
23 #define DNSBACKEND_HH
24
25 class DNSPacket;
26
27 #include "utility.hh"
28 #include <string>
29 #include <vector>
30 #include <map>
31 #include <sys/types.h>
32 #include "pdnsexception.hh"
33 #include <set>
34 #include <iostream>
35 #include <sys/socket.h>
36 #include <dirent.h>
37 #include "misc.hh"
38 #include "qtype.hh"
39 #include "dns.hh"
40 #include <vector>
41 #include "namespaces.hh"
42
43 class DNSBackend;
44 struct DomainInfo
45 {
46 DomainInfo() : backend(0) {}
47 uint32_t id;
48 string zone;
49 vector<string> masters;
50 uint32_t notified_serial;
51 uint32_t serial;
52 time_t last_check;
53 enum DomainKind { Master, Slave, Native } kind;
54 DNSBackend *backend;
55
56 bool operator<(const DomainInfo& rhs) const
57 {
58 return zone < rhs.zone;
59 }
60
61 const char *getKindString() const
62 {
63 return DomainInfo::getKindString(kind);
64 }
65
66 static const char *getKindString(enum DomainKind kind)
67 {
68 const char *kinds[]={"Master", "Slave", "Native"};
69 return kinds[kind];
70 }
71
72 static DomainKind stringToKind(const string& kind)
73 {
74 if(pdns_iequals(kind,"SLAVE"))
75 return DomainInfo::Slave;
76 else if(pdns_iequals(kind,"MASTER"))
77 return DomainInfo::Master;
78 else
79 return DomainInfo::Native;
80 }
81
82 };
83
84 struct TSIGKey {
85 std::string name;
86 std::string algorithm;
87 std::string key;
88 };
89
90 class DNSPacket;
91
92
93 //! This virtual base class defines the interface for backends for the ahudns.
94 /** To create a backend, inherit from this class and implement functions for all virtual methods.
95 Methods should not throw an exception if they are sure they did not find the requested data. However,
96 if an error occurred which prevented them temporarily from performing a lockup, they should throw a DBException,
97 which will cause the nameserver to send out a ServFail or take other evasive action. Probably only locking
98 issues should lead to DBExceptions.
99
100 More serious errors, which may indicate that the database connection is hosed, or a configuration error occurred, should
101 lead to the throwing of an PDNSException. This exception will fall straight through the UeberBackend and the PacketHandler
102 and be caught by the Distributor, which will delete your DNSBackend instance and spawn a new one.
103 */
104 class DNSBackend
105 {
106 public:
107 //! lookup() initiates a lookup. A lookup without results should not throw!
108 virtual void lookup(const QType &qtype, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0;
109 virtual bool get(DNSResourceRecord &)=0; //!< retrieves one DNSResource record, returns false if no more were available
110
111
112 //! Initiates a list of the specified domain
113 /** Once initiated, DNSResourceRecord objects can be retrieved using get(). Should return false
114 if the backend does not consider itself responsible for the id passed.
115 \param domain_id ID of which a list is requested
116 */
117 virtual bool list(const string &target, int domain_id)=0;
118
119 virtual ~DNSBackend(){};
120
121 //! fills the soadata struct with the SOA details. Returns false if there is no SOA.
122 virtual bool getSOA(const string &name, SOAData &soadata, DNSPacket *p=0);
123
124 //! Calculates a SOA serial for the zone and stores it in the third argument.
125 virtual bool calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial);
126
127 virtual bool replaceRRSet(uint32_t domain_id, const string& qname, const QType& qt, const vector<DNSResourceRecord>& rrset)
128 {
129 return false;
130 }
131
132 virtual bool listSubZone(const string &zone, int domain_id)
133 {
134 return false;
135 }
136
137 // the DNSSEC related (getDomainMetadata has broader uses too)
138 virtual bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta) { return false; }
139 virtual bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta) {return false;}
140
141 virtual void getAllDomains(vector<DomainInfo> *domains) { }
142
143 struct KeyData {
144 unsigned int id;
145 unsigned int flags;
146 bool active;
147 std::string content;
148 };
149
150 virtual bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys) { return false;}
151 virtual bool removeDomainKey(const string& name, unsigned int id) { return false; }
152 virtual int addDomainKey(const string& name, const KeyData& key){ return -1; }
153 virtual bool activateDomainKey(const string& name, unsigned int id) { return false; }
154 virtual bool deactivateDomainKey(const string& name, unsigned int id) { return false; }
155
156 virtual bool getTSIGKey(const string& name, string* algorithm, string* content) { return false; }
157 virtual bool setTSIGKey(const string& name, const string& algorithm, const string& content) { return false; }
158 virtual bool deleteTSIGKey(const string& name) { return false; }
159 virtual bool getTSIGKeys(std::vector< struct TSIGKey > &keys) { return false; }
160
161 virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after)
162 {
163 std::cerr<<"Default beforeAndAfterAbsolute called!"<<std::endl;
164 abort();
165 return false;
166 }
167
168 bool getBeforeAndAfterNames(uint32_t id, const std::string& zonename, const std::string& qname, std::string& before, std::string& after);
169
170 virtual bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth)
171 {
172 return false;
173 }
174
175 virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth)
176 {
177 return false;
178 }
179
180 virtual bool updateEmptyNonTerminals(uint32_t domain_id, const std::string& zonename, set<string>& insert, set<string>& erase, bool remove)
181 {
182 return false;
183 }
184
185 virtual bool nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const std::string& qname, bool auth)
186 {
187 return false;
188 }
189
190 virtual bool nullifyDNSSECOrderNameAndAuth(uint32_t domain_id, const std::string& qname, const std::string& type)
191 {
192 return false;
193 }
194
195 virtual bool setDNSSECAuthOnDsRecord(uint32_t domain_id, const std::string& qname)
196 {
197 return false;
198 }
199
200 virtual bool doesDNSSEC()
201 {
202 return false;
203 }
204
205 // end DNSSEC
206
207 //! returns true if master ip is master for domain name.
208 virtual bool isMaster(const string &name, const string &ip)
209 {
210 return false;
211 }
212
213 //! starts the transaction for updating domain qname (FIXME: what is id?)
214 virtual bool startTransaction(const string &qname, int id=-1)
215 {
216 return false;
217 }
218
219 //! commits the transaction started by startTransaction
220 virtual bool commitTransaction()
221 {
222 return false;
223 }
224
225 //! aborts the transaction started by strartTransaction, should leave state unaltered
226 virtual bool abortTransaction()
227 {
228 return false;
229 }
230
231 virtual void reload()
232 {
233 }
234
235 virtual void rediscover(string* status=0)
236 {
237 }
238
239 //! feeds a record to a zone, needs a call to startTransaction first
240 virtual bool feedRecord(const DNSResourceRecord &rr, string *ordername=0)
241 {
242 return false; // no problem!
243 }
244 virtual bool feedEnts(int domain_id, set<string> &nonterm)
245 {
246 return false;
247 }
248 virtual bool feedEnts3(int domain_id, const string &domain, set<string> &nonterm, unsigned int times, const string &salt, bool narrow)
249 {
250 return false;
251 }
252
253 //! if this returns true, DomainInfo di contains information about the domain
254 virtual bool getDomainInfo(const string &domain, DomainInfo &di)
255 {
256 return false;
257 }
258 //! slave capable backends should return a list of slaves that should be rechecked for staleness
259 virtual void getUnfreshSlaveInfos(vector<DomainInfo>* domains)
260 {
261 }
262
263 //! get a list of IP addresses that should also be notified for a domain
264 virtual void alsoNotifies(const string &domain, set<string> *ips)
265 {
266 }
267
268 //! get list of domains that have been changed since their last notification to slaves
269 virtual void getUpdatedMasters(vector<DomainInfo>* domains)
270 {
271 }
272
273 //! Called by PowerDNS to inform a backend that a domain has been checked for freshness
274 virtual void setFresh(uint32_t domain_id)
275 {
276
277 }
278 //! Called by PowerDNS to inform a backend that the changes in the domain have been reported to slaves
279 virtual void setNotified(uint32_t id, uint32_t serial)
280 {
281 }
282
283 //! Called when the Master of a domain should be changed
284 virtual bool setMaster(const string &domain, const string &ip)
285 {
286 return false;
287 }
288
289 //! Called when the Kind of a domain should be changed (master -> native and similar)
290 virtual bool setKind(const string &domain, const DomainInfo::DomainKind kind)
291 {
292 return false;
293 }
294
295 //! Can be called to seed the getArg() function with a prefix
296 void setArgPrefix(const string &prefix);
297
298 //! determine if ip is a supermaster or a domain
299 virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
300 {
301 return false;
302 }
303
304 //! called by PowerDNS to create a new domain
305 virtual bool createDomain(const string &domain)
306 {
307 return false;
308 }
309
310 //! called by PowerDNS to create a slave record for a superMaster
311 virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account)
312 {
313 return false;
314 }
315
316 //! called to delete a domain, incl. all metadata, zone contents, etc.
317 virtual bool deleteDomain(const string &domain)
318 {
319 return false;
320 }
321
322 protected:
323 bool mustDo(const string &key);
324 const string &getArg(const string &key);
325 int getArgAsNum(const string &key);
326 string getRemote(DNSPacket *p);
327 bool getRemote(DNSPacket *p, struct sockaddr *in, Utility::socklen_t *len);
328
329 private:
330 string d_prefix;
331 };
332
333 class BackendFactory
334 {
335 public:
336 BackendFactory(const string &name) : d_name(name) {}
337 virtual ~BackendFactory(){}
338 virtual DNSBackend *make(const string &suffix)=0;
339 virtual DNSBackend *makeMetadataOnly(const string &suffix)
340 {
341 return this->make(suffix);
342 }
343 virtual void declareArguments(const string &suffix=""){}
344 const string &getName() const;
345
346 protected:
347 void declare(const string &suffix, const string &param, const string &explanation, const string &value);
348
349 private:
350 const string d_name;
351 };
352
353 class BackendMakerClass
354 {
355 public:
356 void report(BackendFactory *bf);
357 void launch(const string &instr);
358 vector<DNSBackend *>all(bool skipBIND=false);
359 void load(const string &module);
360 int numLauncheable();
361 vector<string> getModules();
362
363 private:
364 void load_all();
365 typedef map<string,BackendFactory *>d_repository_t;
366 d_repository_t d_repository;
367 vector<pair<string,string> >d_instances;
368 };
369
370 extern BackendMakerClass &BackendMakers();
371
372 //! Exception that can be thrown by a DNSBackend to indicate a failure
373 class DBException : public PDNSException
374 {
375 public:
376 DBException(const string &reason) : PDNSException(reason){}
377 };
378
379
380 #endif