• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 29938532552

22 Jul 2026 04:33PM UTC coverage: 65.622% (-5.5%) from 71.098%
29938532552

Pull #17766

github

web-flow
Merge ac2adfc18 into 0b57e5e81
Pull Request #17766: auth: finer TSIG key deletion

40164 of 74384 branches covered (54.0%)

Branch coverage included in aggregate %.

24 of 60 new or added lines in 12 files covered. (40.0%)

12221 existing lines in 121 files now uncovered.

109801 of 154144 relevant lines covered (71.23%)

7016519.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.82
/modules/bindbackend/binddnssec.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
#include "bindbackend2.hh"
27
#include "pdns/arguments.hh"
28
#include "pdns/dnsrecords.hh"
29

30
#ifndef HAVE_SQLITE3
31

32
void Bind2Backend::setupDNSSEC()
33
{
34
  if (!getArg("dnssec-db").empty()) {
35
    throw runtime_error("bind-dnssec-db requires building PowerDNS with SQLite3");
36
  }
37
}
38

39
unsigned int Bind2Backend::getCapabilities()
40
{
41
  unsigned int caps = CAP_LIST | CAP_SEARCH;
42
  if (d_hybrid) {
43
    caps |= CAP_DNSSEC;
44
  }
45
  return caps;
46
}
47

48
bool Bind2Backend::getNSEC3PARAM(const ZoneName& /* name */, NSEC3PARAMRecordContent* /* ns3p */)
49
{
50
  return false;
51
}
52

53
bool Bind2Backend::getNSEC3PARAMuncached(const ZoneName& /* name */, NSEC3PARAMRecordContent* /* ns3p */)
54
{
55
  return false;
56
}
57

58
bool Bind2Backend::getAllDomainMetadata(const ZoneName& /* name */, std::map<std::string, std::vector<std::string>>& /* meta */)
59
{
60
  return false;
61
}
62

63
bool Bind2Backend::getDomainMetadata(const ZoneName& /* name */, const std::string& /* kind */, std::vector<std::string>& /* meta */)
64
{
65
  return false;
66
}
67

68
bool Bind2Backend::setDomainMetadata(const ZoneName& /* name */, const std::string& /* kind */, const std::vector<std::string>& /* meta */)
69
{
70
  return false;
71
}
72

73
bool Bind2Backend::getDomainKeys(const ZoneName& /* name */, std::vector<KeyData>& /* keys */)
74
{
75
  return false;
76
}
77

78
bool Bind2Backend::removeDomainKey(const ZoneName& /* name */, unsigned int /* id */)
79
{
80
  return false;
81
}
82

83
bool Bind2Backend::addDomainKey(const ZoneName& /* name */, const KeyData& /* key */, int64_t& /* id */)
84
{
85
  return false;
86
}
87

88
bool Bind2Backend::activateDomainKey(const ZoneName& /* name */, unsigned int /* id */)
89
{
90
  return false;
91
}
92

93
bool Bind2Backend::deactivateDomainKey(const ZoneName& /* name */, unsigned int /* id */)
94
{
95
  return false;
96
}
97

98
bool Bind2Backend::publishDomainKey(const ZoneName& /* name */, unsigned int /* id */)
99
{
100
  return false;
101
}
102

103
bool Bind2Backend::unpublishDomainKey(const ZoneName& /* name */, unsigned int /* id */)
104
{
105
  return false;
106
}
107

108
bool Bind2Backend::getTSIGKey(const DNSName& /* name */, DNSName& /* algorithm */, string& /* content */)
109
{
110
  return false;
111
}
112

113
bool Bind2Backend::setTSIGKey(const DNSName& /* name */, const DNSName& /* algorithm */, const string& /* content */)
114
{
115
  return false;
116
}
117

118
bool Bind2Backend::deleteTSIGKey(const DNSName& /* name */, const DNSName& /* algorithm */)
119
{
120
  return false;
121
}
122

123
bool Bind2Backend::getTSIGKeys(std::vector<struct TSIGKey>& /* keys */)
124
{
125
  return false;
126
}
127

128
void Bind2Backend::setupStatements()
129
{
130
}
131

132
void Bind2Backend::freeStatements()
133
{
134
}
135

136
#else
137

138
#include "pdns/logger.hh"
139
#include "pdns/ssqlite3.hh"
140

141
#define ASSERT_ROW_COLUMNS(query, row, num)                                                                                                \
142
  {                                                                                                                                        \
136✔
143
    if (row.size() != num) {                                                                                                               \
136✔
144
      throw PDNSException(std::string(query) + " returned wrong number of columns, expected " #num ", got " + std::to_string(row.size())); \
×
145
    }                                                                                                                                      \
×
146
  }
136✔
147

148
void Bind2Backend::setupDNSSEC()
149
{
3,503✔
150
  if (getArg("dnssec-db").empty() || d_hybrid)
3,503!
151
    return;
2,174✔
152
  try {
1,329✔
153
    d_dnssecdb = std::make_shared<SSQLite3>(d_slog, getArg("dnssec-db"), getArg("dnssec-db-journal-mode"));
1,329✔
154
    setupStatements();
1,329✔
155
  }
1,329✔
156
  catch (SSqlException& se) {
1,329✔
157
    // this error is meant to kill the server dead - it makes no sense to continue..
158
    throw runtime_error("Error opening DNSSEC database in BIND backend: " + se.txtReason());
×
159
  }
×
160

161
  d_dnssecdb->setLog(::arg().mustDo("query-logging"));
1,329✔
162
}
1,329✔
163

164
void Bind2Backend::setupStatements()
165
{
1,329✔
166
  d_getAllDomainMetadataQuery_stmt = d_dnssecdb->prepare("select kind, content from domainmetadata where domain=:domain", 1);
1,329✔
167
  d_getDomainMetadataQuery_stmt = d_dnssecdb->prepare("select content from domainmetadata where domain=:domain and kind=:kind", 2);
1,329✔
168
  d_deleteDomainMetadataQuery_stmt = d_dnssecdb->prepare("delete from domainmetadata where domain=:domain and kind=:kind", 2);
1,329✔
169
  d_insertDomainMetadataQuery_stmt = d_dnssecdb->prepare("insert into domainmetadata (domain, kind, content) values (:domain,:kind,:content)", 3);
1,329✔
170
  d_getDomainKeysQuery_stmt = d_dnssecdb->prepare("select id,flags, active, published, content from cryptokeys where domain=:domain", 1);
1,329✔
171
  d_deleteDomainKeyQuery_stmt = d_dnssecdb->prepare("delete from cryptokeys where domain=:domain and id=:key_id", 2);
1,329✔
172
  d_insertDomainKeyQuery_stmt = d_dnssecdb->prepare("insert into cryptokeys (domain, flags, active, published, content) values (:domain, :flags, :active, :published, :content)", 5);
1,329✔
173
  d_GetLastInsertedKeyIdQuery_stmt = d_dnssecdb->prepare("select last_insert_rowid()", 0);
1,329✔
174
  d_activateDomainKeyQuery_stmt = d_dnssecdb->prepare("update cryptokeys set active=1 where domain=:domain and id=:key_id", 2);
1,329✔
175
  d_deactivateDomainKeyQuery_stmt = d_dnssecdb->prepare("update cryptokeys set active=0 where domain=:domain and id=:key_id", 2);
1,329✔
176
  d_publishDomainKeyQuery_stmt = d_dnssecdb->prepare("update cryptokeys set published=1 where domain=:domain and id=:key_id", 2);
1,329✔
177
  d_unpublishDomainKeyQuery_stmt = d_dnssecdb->prepare("update cryptokeys set published=0 where domain=:domain and id=:key_id", 2);
1,329✔
178
  d_getTSIGKeyQuery_stmt = d_dnssecdb->prepare("select algorithm, secret from tsigkeys where name=:key_name", 1);
1,329✔
179
  d_setTSIGKeyQuery_stmt = d_dnssecdb->prepare("replace into tsigkeys (name,algorithm,secret) values(:key_name, :algorithm, :content)", 3);
1,329✔
180
  d_deleteTSIGKeyQuery_stmt = d_dnssecdb->prepare("delete from tsigkeys where name=:key_name", 1);
1,329✔
181
  d_deleteTSIGKeyWithAlgorithmQuery_stmt = d_dnssecdb->prepare("delete from tsigkeys where name=:key_name and algorithm=:algorithm", 2);
1,329✔
182
  d_getTSIGKeysQuery_stmt = d_dnssecdb->prepare("select name,algorithm,secret from tsigkeys", 0);
1,329✔
183
}
1,329✔
184

185
void Bind2Backend::freeStatements()
186
{
3,370✔
187
  d_getAllDomainMetadataQuery_stmt.reset();
3,370✔
188
  d_getDomainMetadataQuery_stmt.reset();
3,370✔
189
  d_deleteDomainMetadataQuery_stmt.reset();
3,370✔
190
  d_insertDomainMetadataQuery_stmt.reset();
3,370✔
191
  d_getDomainKeysQuery_stmt.reset();
3,370✔
192
  d_deleteDomainKeyQuery_stmt.reset();
3,370✔
193
  d_insertDomainKeyQuery_stmt.reset();
3,370✔
194
  d_GetLastInsertedKeyIdQuery_stmt.reset();
3,370✔
195
  d_activateDomainKeyQuery_stmt.reset();
3,370✔
196
  d_deactivateDomainKeyQuery_stmt.reset();
3,370✔
197
  d_publishDomainKeyQuery_stmt.reset();
3,370✔
198
  d_unpublishDomainKeyQuery_stmt.reset();
3,370✔
199
  d_getTSIGKeyQuery_stmt.reset();
3,370✔
200
  d_setTSIGKeyQuery_stmt.reset();
3,370✔
201
  d_deleteTSIGKeyQuery_stmt.reset();
3,370✔
202
  d_deleteTSIGKeyWithAlgorithmQuery_stmt.reset();
3,370✔
203
  d_getTSIGKeysQuery_stmt.reset();
3,370✔
204
}
3,370✔
205

206
unsigned int Bind2Backend::getCapabilities()
207
{
7,342✔
208
  unsigned int caps = CAP_LIST | CAP_SEARCH;
7,342✔
209
  if (d_dnssecdb || d_hybrid) {
7,342!
210
    caps |= CAP_DNSSEC;
7,276✔
211
  }
7,276✔
212
  return caps;
7,342✔
213
}
7,342✔
214

215
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
216
bool Bind2Backend::getNSEC3PARAM(const ZoneName& name, NSEC3PARAMRecordContent* ns3p)
217
{
×
218
  BB2DomainInfo bbd;
×
219
  if (!safeGetBBDomainInfo(name, &bbd))
×
220
    return false;
×
221

222
  if (ns3p != nullptr) {
×
223
    *ns3p = bbd.d_nsec3param;
×
224
  }
×
225

226
  return bbd.d_nsec3zone;
×
227
}
×
228

229
bool Bind2Backend::getNSEC3PARAMuncached(const ZoneName& name, NSEC3PARAMRecordContent* ns3p)
230
{
2,749✔
231
  if (!d_dnssecdb || d_hybrid)
2,749!
232
    return false;
23✔
233

234
  string value;
2,726✔
235
  vector<string> meta;
2,726✔
236
  getDomainMetadata(name, "NSEC3PARAM", meta);
2,726✔
237
  if (!meta.empty())
2,726✔
238
    value = *meta.begin();
715✔
239
  else
2,011✔
240
    return false; // No NSEC3 zone
2,011✔
241

242
  static int maxNSEC3Iterations = ::arg().asNum("max-nsec3-iterations");
715✔
243
  if (ns3p) {
715!
244
    auto tmp = std::dynamic_pointer_cast<NSEC3PARAMRecordContent>(DNSRecordContent::make(QType::NSEC3PARAM, 1, value));
715✔
245
    *ns3p = *tmp;
715✔
246

247
    if (ns3p->d_iterations > maxNSEC3Iterations) {
715!
248
      ns3p->d_iterations = maxNSEC3Iterations;
×
249
      SLOG(g_log << Logger::Error << "Number of NSEC3 iterations for zone '" << name << "' is above 'max-nsec3-iterations'. Value adjusted to: " << maxNSEC3Iterations << endl,
×
250
           d_slog->info(Logr::Error, "Number of NSEC3 iterations for zone exceeds max-nsec3-iterations, clamping", "zone", Logging::Loggable(name), "max-nsec3-iterations", Logging::Loggable(maxNSEC3Iterations)));
×
251
    }
×
252

253
    if (ns3p->d_algorithm != 1) {
715!
254
      SLOG(g_log << Logger::Error << "Invalid hash algorithm for NSEC3: '" << std::to_string(ns3p->d_algorithm) << "', setting to 1 for zone '" << name << "'." << endl,
×
255
           d_slog->info(Logr::Error, "Invalid hash algorithm for NSEC3 on zone, setting to 1", "zone", Logging::Loggable(name), "algorithm", Logging::Loggable(ns3p->d_algorithm)));
×
256
      ns3p->d_algorithm = 1;
×
257
    }
×
258
  }
715✔
259

260
  return true;
715✔
261
}
2,726✔
262

263
bool Bind2Backend::getAllDomainMetadata(const ZoneName& name, std::map<std::string, std::vector<std::string>>& meta)
264
{
652✔
265
  if (!d_dnssecdb || d_hybrid)
652!
266
    return false;
47✔
267

268
  try {
605✔
269
    d_getAllDomainMetadataQuery_stmt->bind("domain", name)->execute();
605✔
270

271
    SSqlStatement::row_t row;
605✔
272
    while (d_getAllDomainMetadataQuery_stmt->hasNextRow()) {
1,197✔
273
      d_getAllDomainMetadataQuery_stmt->nextRow(row);
592✔
274
      meta[row[0]].push_back(row[1]);
592✔
275
    }
592✔
276

277
    d_getAllDomainMetadataQuery_stmt->reset();
605✔
278
  }
605✔
279
  catch (SSqlException& se) {
605✔
280
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getAllDomainMetadata(): " + se.txtReason());
×
281
  }
×
282
  return true;
605✔
283
}
605✔
284

285
bool Bind2Backend::getDomainMetadata(const ZoneName& name, const std::string& kind, std::vector<std::string>& meta)
286
{
3,262✔
287
  if (!d_dnssecdb || d_hybrid)
3,262!
288
    return false;
4✔
289

290
  try {
3,258✔
291
    d_getDomainMetadataQuery_stmt->bind("domain", name)->bind("kind", kind)->execute();
3,258✔
292

293
    SSqlStatement::row_t row;
3,258✔
294
    while (d_getDomainMetadataQuery_stmt->hasNextRow()) {
3,996✔
295
      d_getDomainMetadataQuery_stmt->nextRow(row);
738✔
296
      meta.push_back(row[0]);
738✔
297
    }
738✔
298

299
    d_getDomainMetadataQuery_stmt->reset();
3,258✔
300
  }
3,258✔
301
  catch (SSqlException& se) {
3,258✔
302
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getDomainMetadata(): " + se.txtReason());
×
303
  }
×
304
  return true;
3,258✔
305
}
3,258✔
306

307
bool Bind2Backend::setDomainMetadata(const ZoneName& name, const std::string& kind, const std::vector<std::string>& meta)
308
{
261✔
309
  if (!d_dnssecdb || d_hybrid)
261!
310
    return false;
×
311

312
  try {
261✔
313
    d_deleteDomainMetadataQuery_stmt->bind("domain", name)->bind("kind", kind)->execute()->reset();
261✔
314
    if (!meta.empty()) {
261✔
315
      for (const auto& value : meta) {
192✔
316
        d_insertDomainMetadataQuery_stmt->bind("domain", name)->bind("kind", kind)->bind("content", value)->execute()->reset();
192✔
317
      }
192✔
318
    }
192✔
319
  }
261✔
320
  catch (SSqlException& se) {
261✔
321
    throw PDNSException("Error accessing DNSSEC database in BIND backend, setDomainMetadata(): " + se.txtReason());
×
322
  }
×
323
  return true;
261✔
324
}
261✔
325

326
bool Bind2Backend::getDomainKeys(const ZoneName& name, std::vector<KeyData>& keys)
327
{
691✔
328
  if (!d_dnssecdb || d_hybrid)
691!
329
    return false;
43✔
330

331
  try {
648✔
332
    d_getDomainKeysQuery_stmt->bind("domain", name)->execute();
648✔
333

334
    KeyData kd;
648✔
335
    SSqlStatement::row_t row;
648✔
336
    while (d_getDomainKeysQuery_stmt->hasNextRow()) {
1,189✔
337
      d_getDomainKeysQuery_stmt->nextRow(row);
541✔
338
      pdns::checked_stoi_into(kd.id, row[0]);
541✔
339
      pdns::checked_stoi_into(kd.flags, row[1]);
541✔
340
      kd.active = (row[2] == "1");
541✔
341
      kd.published = (row[3] == "1");
541✔
342
      kd.content = row[4];
541✔
343
      keys.push_back(kd);
541✔
344
    }
541✔
345

346
    d_getDomainKeysQuery_stmt->reset();
648✔
347
  }
648✔
348
  catch (SSqlException& se) {
648✔
349
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getDomainKeys(): " + se.txtReason());
×
350
  }
×
351
  return true;
648✔
352
}
648✔
353

354
bool Bind2Backend::removeDomainKey(const ZoneName& name, unsigned int keyId)
355
{
×
356
  if (!d_dnssecdb || d_hybrid)
×
357
    return false;
×
358

359
  try {
×
360
    d_deleteDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", keyId)->execute()->reset();
×
361
  }
×
362
  catch (SSqlException& se) {
×
363
    throw PDNSException("Error accessing DNSSEC database in BIND backend, removeDomainKeys(): " + se.txtReason());
×
364
  }
×
365
  return true;
×
366
}
×
367

368
bool Bind2Backend::addDomainKey(const ZoneName& name, const KeyData& key, int64_t& keyId)
369
{
136✔
370
  if (!d_dnssecdb || d_hybrid)
136!
371
    return false;
×
372

373
  try {
136✔
374
    d_insertDomainKeyQuery_stmt->bind("domain", name)->bind("flags", key.flags)->bind("active", key.active)->bind("published", key.published)->bind("content", key.content)->execute()->reset();
136✔
375
  }
136✔
376
  catch (SSqlException& se) {
136✔
377
    throw PDNSException("Error accessing DNSSEC database in BIND backend, addDomainKey(): " + se.txtReason());
×
378
  }
×
379

380
  try {
136✔
381
    d_GetLastInsertedKeyIdQuery_stmt->execute();
136✔
382
    if (!d_GetLastInsertedKeyIdQuery_stmt->hasNextRow()) {
136!
383
      keyId = -2;
×
384
      return true;
×
385
    }
×
386
    SSqlStatement::row_t row;
136✔
387
    d_GetLastInsertedKeyIdQuery_stmt->nextRow(row);
136✔
388
    ASSERT_ROW_COLUMNS("get-last-inserted-key-id-query", row, 1);
136!
389
    pdns::checked_stoi_into(keyId, row[0]);
136✔
390
    d_GetLastInsertedKeyIdQuery_stmt->reset();
136✔
391
    if (keyId == 0) {
136!
392
      // No insert took place, report as error.
393
      keyId = -1;
×
394
    }
×
395
    return true;
136✔
396
  }
136✔
397
  catch (SSqlException& e) {
136✔
398
    keyId = -2;
×
399
    return true;
×
400
  }
×
401
}
136✔
402

403
bool Bind2Backend::activateDomainKey(const ZoneName& name, unsigned int keyId)
404
{
×
405
  if (!d_dnssecdb || d_hybrid)
×
406
    return false;
×
407

408
  try {
×
409
    d_activateDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", keyId)->execute()->reset();
×
410
  }
×
411
  catch (SSqlException& se) {
×
412
    throw PDNSException("Error accessing DNSSEC database in BIND backend, activateDomainKey(): " + se.txtReason());
×
413
  }
×
414
  return true;
×
415
}
×
416

417
bool Bind2Backend::deactivateDomainKey(const ZoneName& name, unsigned int keyId)
418
{
×
419
  if (!d_dnssecdb || d_hybrid)
×
420
    return false;
×
421

422
  try {
×
423
    d_deactivateDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", keyId)->execute()->reset();
×
424
  }
×
425
  catch (SSqlException& se) {
×
426
    throw PDNSException("Error accessing DNSSEC database in BIND backend, deactivateDomainKey(): " + se.txtReason());
×
427
  }
×
428
  return true;
×
429
}
×
430

431
bool Bind2Backend::publishDomainKey(const ZoneName& name, unsigned int keyId)
432
{
×
433
  if (!d_dnssecdb || d_hybrid)
×
434
    return false;
×
435

436
  try {
×
437
    d_publishDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", keyId)->execute()->reset();
×
438
  }
×
439
  catch (SSqlException& se) {
×
440
    throw PDNSException("Error accessing DNSSEC database in BIND backend, publishDomainKey(): " + se.txtReason());
×
441
  }
×
442
  return true;
×
443
}
×
444

445
bool Bind2Backend::unpublishDomainKey(const ZoneName& name, unsigned int keyId)
446
{
5✔
447
  if (!d_dnssecdb || d_hybrid)
5!
448
    return false;
×
449

450
  try {
5✔
451
    d_unpublishDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", keyId)->execute()->reset();
5✔
452
  }
5✔
453
  catch (SSqlException& se) {
5✔
454
    throw PDNSException("Error accessing DNSSEC database in BIND backend, unpublishDomainKey(): " + se.txtReason());
×
455
  }
×
456
  return true;
5✔
457
}
5✔
458

459
bool Bind2Backend::getTSIGKey(const DNSName& name, DNSName& algorithm, string& content)
460
{
47✔
461
  if (!d_dnssecdb || d_hybrid)
47!
462
    return false;
×
463

464
  try {
47✔
465
    d_getTSIGKeyQuery_stmt->bind("key_name", name)->execute();
47✔
466

467
    SSqlStatement::row_t row;
47✔
468
    while (d_getTSIGKeyQuery_stmt->hasNextRow()) {
94✔
469
      d_getTSIGKeyQuery_stmt->nextRow(row);
47✔
470
      // Note that this will return the last key found matching name and
471
      // optional algorithm.
472
      if (row.size() >= 2 && (algorithm.empty() || algorithm == DNSName(row[0]))) {
47!
473
        algorithm = DNSName(row[0]);
39✔
474
        content = row[1];
39✔
475
      }
39✔
476
    }
47✔
477

478
    d_getTSIGKeyQuery_stmt->reset();
47✔
479
  }
47✔
480
  catch (SSqlException& e) {
47✔
481
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getTSIGKey(): " + e.txtReason());
×
482
  }
×
483
  return true;
47✔
484
}
47✔
485

486
bool Bind2Backend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content)
487
{
5✔
488
  if (!d_dnssecdb || d_hybrid)
5!
489
    return false;
×
490

491
  try {
5✔
492
    d_setTSIGKeyQuery_stmt->bind("key_name", name)->bind("algorithm", algorithm)->bind("content", content)->execute()->reset();
5✔
493
  }
5✔
494
  catch (SSqlException& e) {
5✔
495
    throw PDNSException("Error accessing DNSSEC database in BIND backend, setTSIGKey(): " + e.txtReason());
×
496
  }
×
497
  return true;
5✔
498
}
5✔
499

500
bool Bind2Backend::deleteTSIGKey(const DNSName& name, const DNSName& algorithm)
501
{
×
502
  if (!d_dnssecdb || d_hybrid)
×
503
    return false;
×
504

505
  try {
×
NEW
506
    if (!algorithm.empty()) {
×
NEW
507
      d_deleteTSIGKeyWithAlgorithmQuery_stmt->bind("key_name", name)->bind("algorithm", algorithm)->execute()->reset();
×
NEW
508
    }
×
NEW
509
    else {
×
NEW
510
      d_deleteTSIGKeyQuery_stmt->bind("key_name", name)->execute()->reset();
×
NEW
511
    }
×
512
  }
×
513
  catch (SSqlException& e) {
×
514
    throw PDNSException("Error accessing DNSSEC database in BIND backend, deleteTSIGKey(): " + e.txtReason());
×
515
  }
×
516
  return true;
×
517
}
×
518

519
bool Bind2Backend::getTSIGKeys(std::vector<struct TSIGKey>& keys)
520
{
×
521
  if (!d_dnssecdb || d_hybrid)
×
522
    return false;
×
523

524
  try {
×
525
    d_getTSIGKeysQuery_stmt->execute();
×
526

527
    SSqlStatement::row_t row;
×
528
    while (d_getTSIGKeysQuery_stmt->hasNextRow()) {
×
529
      d_getTSIGKeysQuery_stmt->nextRow(row);
×
530
      struct TSIGKey key;
×
531
      key.name = DNSName(row[0]);
×
532
      key.algorithm = DNSName(row[1]);
×
533
      key.key = row[2];
×
534
      keys.push_back(std::move(key));
×
535
    }
×
536

537
    d_getTSIGKeysQuery_stmt->reset();
×
538
  }
×
539
  catch (SSqlException& e) {
×
540
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getTSIGKeys(): " + e.txtReason());
×
541
  }
×
542
  return true;
×
543
}
×
544

545
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc