]> git.ipfire.org Git - thirdparty/pdns.git/blame - modules/opendbxbackend/odbxbackend.cc
Logging: have a global g_log
[thirdparty/pdns.git] / modules / opendbxbackend / odbxbackend.cc
CommitLineData
a3814809 1/*
12471842
PL
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 * originally authored by Norbert Sendetzky
a3814809 5 *
12471842
PL
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
a3814809 9 *
12471842
PL
10 * In addition, for the avoidance of any doubt, permission is granted to
11 * link this program with OpenSSL and to (re)distribute the binaries
12 * produced as the result of such linking.
a3814809 13 *
12471842
PL
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
a3814809 18 *
12471842
PL
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
a3814809 22 */
870a0fe4
AT
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
790e7c1b
BH
26#include "odbxbackend.hh"
27
28
29
8e20e603
BH
30inline string& strbind( const string& search, const string& replace, string& subject )
31{
e0ec6e79 32 size_t pos = 0;
8e20e603 33
e0ec6e79
BH
34 while( ( pos = subject.find( search, pos ) ) != string::npos )
35 {
36 subject.replace( pos, search.size(), replace );
37 pos += replace.size();
38 }
8e20e603 39
e0ec6e79 40 return subject;
8e20e603
BH
41}
42
43
44
790e7c1b
BH
45OdbxBackend::OdbxBackend( const string& suffix )
46{
e0ec6e79
BH
47 vector<string> hosts;
48
49
50 try
51 {
52 m_result = NULL;
53 m_handle[READ] = NULL;
54 m_handle[WRITE] = NULL;
55 m_myname = "[OpendbxBackend]";
56 m_default_ttl = arg().asNum( "default-ttl" );
57 m_qlog = arg().mustDo( "query-logging" );
58
59 setArgPrefix( "opendbx" + suffix );
60
61 if( getArg( "host" ).size() > 0 )
62 {
e6a9dde5 63 g_log.log( m_myname + " WARNING: Using deprecated opendbx-host parameter", Logger::Warning );
e0ec6e79
BH
64 stringtok( m_hosts[READ], getArg( "host" ), ", " );
65 m_hosts[WRITE] = m_hosts[READ];
66 }
67 else
68 {
69 stringtok( m_hosts[READ], getArg( "host-read" ), ", " );
70 stringtok( m_hosts[WRITE], getArg( "host-write" ), ", " );
71 }
72
3f81d239 73 if( !connectTo( m_hosts[READ], READ ) ) { throw( PDNSException( "Fatal: Connecting to server for reading failed" ) ); }
74 if( !connectTo( m_hosts[WRITE], WRITE ) ) { throw( PDNSException( "Fatal: Connecting to server for writing failed" ) ); }
e0ec6e79 75 }
a2f4c096 76 catch( std::exception& e )
e0ec6e79 77 {
e6a9dde5 78 g_log.log( m_myname + " OdbxBackend(): Caught STL exception - " + e.what(), Logger::Error );
3f81d239 79 throw( PDNSException( "Fatal: STL exception" ) );
e0ec6e79 80 }
790e7c1b
BH
81}
82
83
84
85OdbxBackend::~OdbxBackend()
86{
e0ec6e79
BH
87 odbx_unbind( m_handle[WRITE] );
88 odbx_unbind( m_handle[READ] );
8e20e603 89
e0ec6e79
BH
90 odbx_finish( m_handle[WRITE] );
91 odbx_finish( m_handle[READ] );
790e7c1b
BH
92}
93
94
95
cf8c91f3 96bool OdbxBackend::getDomainInfo( const DNSName& domain, DomainInfo& di )
790e7c1b 97{
e0ec6e79
BH
98 const char* tmp;
99
100
101 try
102 {
e6a9dde5 103 DLOG( g_log.log( m_myname + " getDomainInfo()", Logger::Debug ) );
e0ec6e79
BH
104
105 string stmt = getArg( "sql-zoneinfo" );
cf8c91f3 106 string& stmtref = strbind( ":name", escape( domain.makeLowerCase().toStringRootDot(), READ ), stmt );
e0ec6e79
BH
107
108 if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
109 if( !getRecord( READ ) ) { return false; }
110
111 do
112 {
113 di.id = 0;
df26024e 114 di.zone.clear();
e0ec6e79
BH
115 di.masters.clear();
116 di.last_check = 0;
117 di.notified_serial = 0;
118 di.kind = DomainInfo::Native;
119 di.backend = this;
120 di.serial = 0;
121
122 if( ( tmp = odbx_field_value( m_result, 6 ) ) != NULL )
123 {
124 SOAData sd;
125
126 sd.serial = 0;
127 fillSOAData( string( tmp, odbx_field_length( m_result, 6 ) ), sd );
128
129 if( sd.serial == 0 && ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
130 {
131 sd.serial = strtol( tmp, NULL, 10 );
132 }
133
134 di.serial = sd.serial;
135 }
136
137 if( ( tmp = odbx_field_value( m_result, 4 ) ) != NULL )
138 {
139 di.last_check = strtol( tmp, NULL, 10 );
140 }
141
142 if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
143 {
144 stringtok(di.masters, string( tmp, odbx_field_length( m_result, 3 ) ), ", \t");
145 }
146
147 if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
148 {
149 if( !strncmp( tmp, "SLAVE", 5 ) )
150 {
151 di.kind = DomainInfo::Slave;
152 }
153 else if( !strncmp( tmp, "MASTER", 6 ) )
154 {
155 di.kind = DomainInfo::Master;
156 }
157 }
158
159 if( ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
160 {
cf8c91f3 161 di.zone = DNSName(string( tmp, odbx_field_length( m_result, 1 ) ));
e0ec6e79
BH
162 }
163
164 if( ( tmp = odbx_field_value( m_result, 0 ) ) != NULL )
165 {
166 di.id = strtol( tmp, NULL, 10 );
167 }
168 }
169 while( getRecord( READ ) );
170 }
a2f4c096 171 catch( std::exception& e )
e0ec6e79 172 {
e6a9dde5 173 g_log.log( m_myname + " getDomainInfo: Caught STL std::exception - " + e.what(), Logger::Error );
e0ec6e79
BH
174 return false;
175 }
176
177 return true;
e830c249
BH
178}
179
180
181
13f9e280 182bool OdbxBackend::getSOA( const DNSName& domain, SOAData& sd, bool unmodifiedSerial)
e830c249 183{
e0ec6e79
BH
184 const char* tmp;
185
186
187 try
188 {
e6a9dde5 189 DLOG( g_log.log( m_myname + " getSOA()", Logger::Debug ) );
e0ec6e79
BH
190
191 string stmt = getArg( "sql-lookupsoa" );
cf8c91f3 192 string& stmtref = strbind( ":name", escape( domain.makeLowerCase().toStringRootDot(), READ ), stmt );
e0ec6e79
BH
193
194 if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
195 if( !getRecord( READ ) ) { return false; }
196
197 do
198 {
01df0d92 199 sd.qname = domain;
e0ec6e79
BH
200 sd.serial = 0;
201 sd.ttl = m_default_ttl;
202
203 if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
204 {
205 fillSOAData( string( tmp, odbx_field_length( m_result, 3 ) ), sd );
206 }
207
208 if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
209 {
210 sd.ttl = strtoul( tmp, NULL, 10 );
ed56a9d7 211 }
e0ec6e79 212
13f9e280 213 if( !unmodifiedSerial && sd.serial == 0 && ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
e0ec6e79
BH
214 {
215 sd.serial = strtol( tmp, NULL, 10 );
216 }
217
218 if( ( tmp = odbx_field_value( m_result, 0 ) ) != NULL )
219 {
220 sd.domain_id = strtol( tmp, NULL, 10 );
221 }
222
223 if( sd.nameserver.empty() )
224 {
cf8c91f3 225 sd.nameserver = DNSName(arg()["default-soa-name"]);
e0ec6e79
BH
226 }
227
228 if( sd.hostmaster.empty() )
229 {
cf8c91f3 230 sd.hostmaster = DNSName("hostmaster") + DNSName(domain);
e0ec6e79
BH
231 }
232
233 sd.db = this;
234 }
235 while( getRecord( READ ) );
236 }
a2f4c096 237 catch( std::exception& e )
e0ec6e79 238 {
e6a9dde5 239 g_log.log( m_myname + " getSOA: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
240 return false;
241 }
242
243 return true;
790e7c1b
BH
244}
245
246
247
ed56a9d7 248bool OdbxBackend::list( const DNSName& target, int zoneid, bool include_disabled )
790e7c1b 249{
e0ec6e79
BH
250 try
251 {
e6a9dde5 252 DLOG( g_log.log( m_myname + " list()", Logger::Debug ) );
e0ec6e79 253
cf8c91f3 254 m_qname.clear();
e0ec6e79
BH
255 m_result = NULL;
256
90e286b7 257 int len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
e0ec6e79
BH
258
259 if( len < 0 )
260 {
e6a9dde5 261 g_log.log( m_myname + " list: Unable to convert zone id to string - format error", Logger::Error );
e0ec6e79
BH
262 return false;
263 }
264
579c61f5 265 if( len > static_cast<int>(sizeof( m_buffer )) - 1 )
e0ec6e79 266 {
e6a9dde5 267 g_log.log( m_myname + " list: Unable to convert zone id to string - insufficient buffer space", Logger::Error );
e0ec6e79
BH
268 return false;
269 }
270
271 string stmt = getArg( "sql-list" );
272 string& stmtref = strbind( ":id", string( m_buffer, len ), stmt );
273
274 if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
275 }
a2f4c096 276 catch( std::exception& e )
e0ec6e79 277 {
e6a9dde5 278 g_log.log( m_myname + " list: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
279 return false;
280 }
281
282 return true;
790e7c1b
BH
283}
284
285
286
ed56a9d7 287void OdbxBackend::lookup( const QType& qtype, const DNSName& qname, DNSPacket* dnspkt, int zoneid )
790e7c1b 288{
e0ec6e79
BH
289 try
290 {
e6a9dde5 291 DLOG( g_log.log( m_myname + " lookup()", Logger::Debug ) );
e0ec6e79
BH
292
293 string stmt;
294 string& stmtref = stmt;
295
296 m_result = NULL;
297 m_qname = qname;
298
299 if( zoneid < 0 )
300 {
301 if( qtype.getCode() == QType::ANY )
302 {
303 stmt = getArg( "sql-lookup" );
304 } else {
305 stmt = getArg( "sql-lookuptype" );
306 stmtref = strbind( ":type", qtype.getName(), stmt );
307 }
308 }
309 else
310 {
311 if( qtype.getCode() == QType::ANY )
312 {
cf8c91f3 313 stmt = getArg( "sql-lookupid" );
e0ec6e79
BH
314 } else {
315 stmt = getArg( "sql-lookuptypeid" );
316 stmtref = strbind( ":type", qtype.getName(), stmt );
317 }
318
90e286b7 319 int len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
e0ec6e79
BH
320
321 if( len < 0 )
322 {
e6a9dde5 323 g_log.log( m_myname + " lookup: Unable to convert zone id to string - format error", Logger::Error );
e0ec6e79
BH
324 throw( DBException( "Error: Libc error" ) );
325 }
326
579c61f5 327 if( len > static_cast<int>(sizeof( m_buffer )) - 1 )
e0ec6e79 328 {
e6a9dde5 329 g_log.log( m_myname + " lookup: Unable to convert zone id to string - insufficient buffer space", Logger::Error );
e0ec6e79
BH
330 throw( DBException( "Error: Libc error" ) );
331 }
332
333 stmtref = strbind( ":id", string( m_buffer, len ), stmtref );
334 }
335
cf8c91f3 336 stmtref = strbind( ":name", escape( qname.makeLowerCase().toStringRootDot(), READ ), stmtref );
e0ec6e79
BH
337
338 if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) )
339 {
340 throw( DBException( "Error: DB statement failed" ) );
341 }
342 }
a2f4c096 343 catch( std::exception& e )
e0ec6e79 344 {
e6a9dde5 345 g_log.log( m_myname + " lookup: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
346 throw( DBException( "Error: STL exception" ) );
347 }
790e7c1b
BH
348}
349
350
351
352bool OdbxBackend::get( DNSResourceRecord& rr )
353{
e0ec6e79 354 const char* tmp;
b9bafae0 355 string priority;
e0ec6e79
BH
356
357 try
358 {
e6a9dde5 359 DLOG( g_log.log( m_myname + " get()", Logger::Debug ) );
e0ec6e79
BH
360
361 if( getRecord( READ ) )
362 {
b9bafae0 363
e0ec6e79 364 rr.content = "";
e0ec6e79
BH
365 rr.domain_id = 0;
366 rr.last_modified = 0;
367 rr.ttl = m_default_ttl;
368 rr.qname = m_qname;
369
370 if( ( tmp = odbx_field_value( m_result, 0 ) ) != NULL )
371 {
372 rr.domain_id = strtol( tmp, NULL, 10 );
373 }
374
375 if( m_qname.empty() && ( tmp = odbx_field_value( m_result, 1 ) ) != NULL )
376 {
cf8c91f3 377 rr.qname = DNSName( string(tmp, odbx_field_length( m_result, 1 ) ));
e0ec6e79
BH
378 }
379
380 if( ( tmp = odbx_field_value( m_result, 2 ) ) != NULL )
381 {
864e676f 382 rr.qtype = tmp;
e0ec6e79
BH
383 }
384
385 if( ( tmp = odbx_field_value( m_result, 3 ) ) != NULL )
386 {
387 rr.ttl = strtoul( tmp, NULL, 10 );
388 }
389
390 if( ( tmp = odbx_field_value( m_result, 4 ) ) != NULL )
391 {
b9bafae0 392 priority = string( tmp, odbx_field_length( m_result, 4 ) );
e0ec6e79
BH
393 }
394
395 if( ( tmp = odbx_field_value( m_result, 5 ) ) != NULL )
396 {
397 rr.content = string( tmp, odbx_field_length( m_result, 5 ) );
398 }
399
b9bafae0
KM
400 if (rr.qtype==QType::MX || rr.qtype==QType::SRV)
401 rr.content = priority + " " + rr.content;
402
e0ec6e79
BH
403 return true;
404 }
405 }
a2f4c096 406 catch( std::exception& e )
e0ec6e79 407 {
e6a9dde5 408 g_log.log( m_myname + " get: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
409 return false;
410 }
411
412 return false;
790e7c1b
BH
413}
414
415
e830c249 416void OdbxBackend::setFresh( uint32_t domain_id )
790e7c1b 417{
90e286b7 418 int len;
e0ec6e79
BH
419
420
421 try
422 {
e6a9dde5 423 DLOG( g_log.log( m_myname + " setFresh()", Logger::Debug ) );
e0ec6e79
BH
424
425 if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
426 {
e6a9dde5 427 g_log.log( m_myname + " setFresh: Master server is unreachable", Logger::Error );
e0ec6e79
BH
428 throw( DBException( "Error: Server unreachable" ) );
429 }
430
431 len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-lastcheck" ).c_str(), time( 0 ), domain_id );
432
433 if( len < 0 )
434 {
e6a9dde5 435 g_log.log( m_myname + " setFresh: Unable to insert values into statement '" + getArg( "sql-update-lastcheck" ) + "' - format error", Logger::Error );
e0ec6e79
BH
436 throw( DBException( "Error: Libc error" ) );
437 }
438
579c61f5 439 if( len > static_cast<int>(sizeof( m_buffer )) - 1 )
e0ec6e79 440 {
e6a9dde5 441 g_log.log( m_myname + " setFresh: Unable to insert values into statement '" + getArg( "sql-update-lastcheck" ) + "' - insufficient buffer space", Logger::Error );
e0ec6e79
BH
442 throw( DBException( "Error: Libc error" ) );
443 }
444
445 if( !execStmt( m_buffer, len, WRITE ) )
446 {
447 throw( DBException( "Error: DB statement failed" ) );
448 }
449 }
a2f4c096 450 catch ( std::exception& e )
e0ec6e79 451 {
e6a9dde5 452 g_log.log( m_myname + " setFresh: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
453 throw( DBException( "Error: STL exception" ) );
454 }
790e7c1b
BH
455}
456
457
458
e830c249 459void OdbxBackend::setNotified( uint32_t domain_id, uint32_t serial )
790e7c1b 460{
e0ec6e79
BH
461 try
462 {
e6a9dde5 463 DLOG( g_log.log( m_myname + " setNotified()", Logger::Debug ) );
e0ec6e79
BH
464
465 if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
466 {
e6a9dde5 467 g_log.log( m_myname + " setFresh: Master server is unreachable", Logger::Error );
e0ec6e79
BH
468 throw( DBException( "Error: Server unreachable" ) );
469 }
470
90e286b7 471 int len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-update-serial" ).c_str(), serial, domain_id );
e0ec6e79
BH
472
473 if( len < 0 )
474 {
e6a9dde5 475 g_log.log( m_myname + " setNotified: Unable to insert values into statement '" + getArg( "sql-update-serial" ) + "' - format error", Logger::Error );
e0ec6e79
BH
476 throw( DBException( "Error: Libc error" ) );
477 }
478
579c61f5 479 if( len > static_cast<int>(sizeof( m_buffer )) - 1 )
e0ec6e79 480 {
e6a9dde5 481 g_log.log( m_myname + " setNotified: Unable to insert values into statement '" + getArg( "sql-update-serial" ) + "' - insufficient buffer space", Logger::Error );
e0ec6e79
BH
482 throw( DBException( "Error: Libc error" ) );
483 }
484
485 if( !execStmt( m_buffer, len, WRITE ) )
486 {
487 throw( DBException( "Error: DB statement failed" ) );
488 }
489 }
a2f4c096 490 catch ( std::exception& e )
e0ec6e79 491 {
e6a9dde5 492 g_log.log( m_myname + " setNotified: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
493 throw( DBException( "Error: STL exception" ) );
494 }
790e7c1b
BH
495}
496
497
498
cf8c91f3 499bool OdbxBackend::isMaster( const DNSName& domain, const string& ip )
790e7c1b 500{
e0ec6e79
BH
501 try
502 {
e6a9dde5 503 DLOG( g_log.log( m_myname + " isMaster()", Logger::Debug ) );
e0ec6e79
BH
504
505 string stmt = getArg( "sql-master" );
cf8c91f3 506 string& stmtref = strbind( ":name", escape( domain.makeLowerCase().toStringRootDot(), READ ), stmt );
e0ec6e79
BH
507
508 if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
509 if( !getRecord( READ ) ) { return false; }
510
511 do
512 {
513 if( odbx_field_value( m_result, 0 ) != NULL )
514 {
515 if( !strcmp( odbx_field_value( m_result, 0 ), ip.c_str() ) )
516 {
517 while( getRecord( READ ) );
518 return true;
519 }
520 }
521 }
522 while( getRecord( READ ) );
523 }
a2f4c096 524 catch ( std::exception& e )
e0ec6e79 525 {
e6a9dde5 526 g_log.log( m_myname + " isMaster: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
527 return false;
528 }
529
530 return false;
790e7c1b
BH
531}
532
533
534
535void OdbxBackend::getUnfreshSlaveInfos( vector<DomainInfo>* unfresh )
536{
e0ec6e79
BH
537 try
538 {
e6a9dde5 539 DLOG( g_log.log( m_myname + " getUnfreshSlaveInfos()", Logger::Debug ) );
e0ec6e79
BH
540
541 if( unfresh == NULL )
542 {
e6a9dde5 543 g_log.log( m_myname + " getUnfreshSlaveInfos: invalid parameter - NULL pointer", Logger::Error );
e0ec6e79
BH
544 return;
545 }
546
547 getDomainList( getArg( "sql-infoslaves" ), unfresh, &checkSlave );
548 }
a2f4c096 549 catch ( std::exception& e )
e0ec6e79 550 {
e6a9dde5 551 g_log.log( m_myname + " getUnfreshSlaveInfo: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79 552 }
790e7c1b
BH
553}
554
555
556
557void OdbxBackend::getUpdatedMasters( vector<DomainInfo>* updated )
558{
e0ec6e79
BH
559 try
560 {
e6a9dde5 561 DLOG( g_log.log( m_myname + " getUpdatedMasters()", Logger::Debug ) );
e0ec6e79
BH
562
563 if( updated == NULL )
564 {
e6a9dde5 565 g_log.log( m_myname + " getUpdatedMasters: invalid parameter - NULL pointer", Logger::Error );
e0ec6e79
BH
566 return;
567 }
568
569 getDomainList( getArg( "sql-infomasters" ), updated, &checkMaster );
570 }
a2f4c096 571 catch ( std::exception& e )
e0ec6e79 572 {
e6a9dde5 573 g_log.log( m_myname + " getUpdatedMasters: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79 574 }
790e7c1b
BH
575}
576
577
578
cf8c91f3 579bool OdbxBackend::superMasterBackend( const string& ip, const DNSName& domain, const vector<DNSResourceRecord>& set, string *nameserver, string* account, DNSBackend** ddb )
790e7c1b 580{
e0ec6e79
BH
581 try
582 {
e6a9dde5 583 DLOG( g_log.log( m_myname + " superMasterBackend()", Logger::Debug ) );
e0ec6e79
BH
584
585 if( account != NULL && ddb != NULL )
586 {
587 vector<DNSResourceRecord>::const_iterator i;
588
589 for( i = set.begin(); i != set.end(); i++ )
590 {
591 string stmt = getArg( "sql-supermaster" );
592 string& stmtref = strbind( ":ip", escape( ip, READ ), stmt );
593 stmtref = strbind( ":ns", escape( i->content, READ ), stmtref );
594
595 if( !execStmt( stmtref.c_str(), stmtref.size(), READ ) ) { return false; }
596
597 if( getRecord( READ ) )
598 {
599 if( odbx_field_value( m_result, 0 ) != NULL )
600 {
601 *account = string( odbx_field_value( m_result, 0 ), odbx_field_length( m_result, 0 ) );
602 }
603
604 while( getRecord( READ ) );
605
606 *ddb=this;
607 return true;
608 }
609 }
610 }
611 }
a2f4c096 612 catch ( std::exception& e )
e0ec6e79 613 {
e6a9dde5 614 g_log.log( m_myname + " superMasterBackend: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
615 return false;
616 }
617
618 return false;
790e7c1b
BH
619}
620
621
622
cf8c91f3 623bool OdbxBackend::createSlaveDomain( const string& ip, const DNSName& domain, const string &nameserver, const string& account )
790e7c1b 624{
e0ec6e79
BH
625 try
626 {
e6a9dde5 627 DLOG( g_log.log( m_myname + " createSlaveDomain()", Logger::Debug ) );
e0ec6e79
BH
628
629 if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
630 {
e6a9dde5 631 g_log.log( m_myname + " createSlaveDomain: Master server is unreachable", Logger::Error );
e0ec6e79
BH
632 return false;
633 }
634
cf8c91f3 635 int len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-slave" ).c_str(), escape( domain.makeLowerCase().toStringRootDot(), WRITE ).c_str(),
e0ec6e79
BH
636 escape( ip, WRITE ).c_str(), escape( account, WRITE ).c_str() );
637
638 if( len < 0 )
639 {
e6a9dde5 640 g_log.log( m_myname + " createSlaveDomain: Unable to insert values in statement '" + getArg( "sql-insert-slave" ) + "' - format error", Logger::Error );
e0ec6e79
BH
641 return false;
642 }
643
579c61f5 644 if( len > static_cast<int>(sizeof( m_buffer )) - 1 )
e0ec6e79 645 {
e6a9dde5 646 g_log.log( m_myname + " createSlaveDomain: Unable to insert values in statement '" + getArg( "sql-insert-slave" ) + "' - insufficient buffer space", Logger::Error );
e0ec6e79
BH
647 return false;
648 }
649
650 if( !execStmt( m_buffer, len, WRITE ) ) { return false; }
651 }
a2f4c096 652 catch ( std::exception& e )
e0ec6e79 653 {
e6a9dde5 654 g_log.log( m_myname + " createSlaveDomain: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
655 return false;
656 }
657
658 return true;
790e7c1b
BH
659}
660
661
662
d57d7155 663bool OdbxBackend::feedRecord( const DNSResourceRecord& rr, const DNSName& ordername )
790e7c1b 664{
e0ec6e79
BH
665 try
666 {
e6a9dde5 667 DLOG( g_log.log( m_myname + " feedRecord()", Logger::Debug ) );
e0ec6e79
BH
668
669 if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
670 {
e6a9dde5 671 g_log.log( m_myname + " feedRecord: Master server is unreachable", Logger::Error );
e0ec6e79
BH
672 return false;
673 }
674
21df0d27 675 unsigned int priority=0;
b9bafae0
KM
676 string content(rr.content);
677
678 if(rr.qtype == QType::MX || rr.qtype == QType::SRV) {
21df0d27 679 priority=pdns_stou(content);
b9bafae0
KM
680 string::size_type pos = content.find_first_not_of("0123456789");
681 if(pos != string::npos)
682 boost::erase_head(content, pos);
683 trim_left(content);
684 }
685
90e286b7 686 int len = snprintf( m_buffer, sizeof( m_buffer ) - 1, getArg( "sql-insert-record" ).c_str(), rr.domain_id,
cf8c91f3 687 escape( rr.qname.makeLowerCase().toStringRootDot(), WRITE ).c_str(), rr.qtype.getName().c_str(), rr.ttl, priority,
b9bafae0 688 escape( content, WRITE ).c_str() );
e0ec6e79
BH
689
690 if( len < 0 )
691 {
e6a9dde5 692 g_log.log( m_myname + " feedRecord: Unable to insert values in statement '" + getArg( "sql-insert-record" ) + "' - format error", Logger::Error );
e0ec6e79
BH
693 return false;
694 }
695
579c61f5 696 if( len > static_cast<int>(sizeof( m_buffer )) - 1 )
e0ec6e79 697 {
e6a9dde5 698 g_log.log( m_myname + " feedRecord: Unable to insert values in statement '" + getArg( "sql-insert-record" ) + "' - insufficient buffer space", Logger::Error );
e0ec6e79
BH
699 return false;
700 }
701
702 if( !execStmt( m_buffer, len, WRITE ) ) { return false; }
703 }
a2f4c096 704 catch ( std::exception& e )
e0ec6e79 705 {
e6a9dde5 706 g_log.log( m_myname + " feedRecord: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
707 return false;
708 }
709
710 return true;
790e7c1b
BH
711}
712
713
714
cf8c91f3 715bool OdbxBackend::startTransaction( const DNSName& domain, int zoneid )
790e7c1b 716{
e0ec6e79
BH
717 try
718 {
e6a9dde5 719 DLOG( g_log.log( m_myname + " startTransaction()", Logger::Debug ) );
790e7c1b 720
e0ec6e79
BH
721 if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
722 {
e6a9dde5 723 g_log.log( m_myname + " startTransaction: Master server is unreachable", Logger::Error );
e0ec6e79
BH
724 return false;
725 }
8e20e603 726
cf8c91f3
KM
727 string stmtref = getArg( "sql-transactbegin" );
728 if( !execStmt( stmtref.c_str(), stmtref.size(), WRITE ) ) { return false; }
90e286b7 729 int len = snprintf( m_buffer, sizeof( m_buffer ) - 1, "%d", zoneid );
e0ec6e79
BH
730
731 if( len < 0 )
732 {
e6a9dde5 733 g_log.log( m_myname + " startTransaction: Unable to convert zone id to string - format error", Logger::Error );
e0ec6e79
BH
734 return false;
735 }
736
579c61f5 737 if( len > static_cast<int>(sizeof( m_buffer )) - 1 )
e0ec6e79 738 {
e6a9dde5 739 g_log.log( m_myname + " startTransaction: Unable to convert zone id to string - insufficient buffer space", Logger::Error );
e0ec6e79
BH
740 return false;
741 }
742
340a213e 743 if(zoneid >= 0) {
cf8c91f3
KM
744 string stmt = getArg( "sql-zonedelete" );
745 stmtref = strbind( ":id", string( m_buffer, len ), stmt );
746 if( !execStmt( stmtref.c_str(), stmtref.size(), WRITE ) ) { return false; }
340a213e 747 }
e0ec6e79 748 }
a2f4c096 749 catch ( std::exception& e )
e0ec6e79 750 {
e6a9dde5 751 g_log.log( m_myname + " startTransaction: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
752 return false;
753 }
754
755 return true;
790e7c1b
BH
756}
757
758
759
760bool OdbxBackend::commitTransaction()
761{
e0ec6e79
BH
762 try
763 {
e6a9dde5 764 DLOG( g_log.log( m_myname + " commitTransaction()", Logger::Debug ) );
e0ec6e79
BH
765
766 if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
767 {
e6a9dde5 768 g_log.log( m_myname + " commitTransaction: Master server is unreachable", Logger::Error );
e0ec6e79
BH
769 return false;
770 }
771
772 const string& stmt = getArg( "sql-transactend" );
773 if( !execStmt( stmt.c_str(), stmt.size(), WRITE ) ) { return false; }
774 }
a2f4c096 775 catch ( std::exception& e )
e0ec6e79 776 {
e6a9dde5 777 g_log.log( m_myname + " commitTransaction: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
778 return false;
779 }
780
781 return true;
790e7c1b
BH
782}
783
784
785
786bool OdbxBackend::abortTransaction()
787{
e0ec6e79
BH
788 try
789 {
e6a9dde5 790 DLOG( g_log.log( m_myname + " abortTransaction()", Logger::Debug ) );
e0ec6e79
BH
791
792 if( !m_handle[WRITE] && !connectTo( m_hosts[WRITE], WRITE ) )
793 {
e6a9dde5 794 g_log.log( m_myname + " abortTransaction: Master server is unreachable", Logger::Error );
e0ec6e79
BH
795 return false;
796 }
797
798 const string& stmt = getArg( "sql-transactabort" );
799 if( !execStmt( stmt.c_str(), stmt.size(), WRITE ) ) { return false; }
800 }
a2f4c096 801 catch ( std::exception& e )
e0ec6e79 802 {
e6a9dde5 803 g_log.log( m_myname + " abortTransaction: Caught STL exception - " + e.what(), Logger::Error );
e0ec6e79
BH
804 return false;
805 }
806
807 return true;
790e7c1b 808}