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

PowerDNS / pdns / 14306456626

07 Apr 2025 10:06AM UTC coverage: 63.439% (-0.02%) from 63.458%
14306456626

Pull #15382

github

web-flow
Merge 2b94b920c into 02c5a6340
Pull Request #15382: [auth] Backend capabilities

41595 of 100248 branches covered (41.49%)

Branch coverage included in aggregate %.

26 of 41 new or added lines in 12 files covered. (63.41%)

262 existing lines in 17 files now uncovered.

128466 of 167822 relevant lines covered (76.55%)

3845483.37 hits per line

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

57.31
/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
  if (d_hybrid) {
42
    return CAP_DNSSEC | CAP_LIST;
43
  }
44
  else {
45
    return CAP_LIST;
46
  }
47
}
48

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

137
#else
138

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

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

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

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

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

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

205
unsigned int Bind2Backend::getCapabilities()
206
{
1,706✔
207
  if (d_dnssecdb || d_hybrid) {
1,706!
208
    return CAP_DNSSEC | CAP_LIST;
1,667✔
209
  }
1,667✔
210
  return CAP_LIST;
39✔
211
}
1,706✔
212

213
bool Bind2Backend::getNSEC3PARAM(const DNSName& name, NSEC3PARAMRecordContent* ns3p)
214
{
×
215
  BB2DomainInfo bbd;
×
216
  if (!safeGetBBDomainInfo(name, &bbd))
×
217
    return false;
×
218

219
  if (ns3p != nullptr) {
×
220
    *ns3p = bbd.d_nsec3param;
×
221
  }
×
222

223
  return bbd.d_nsec3zone;
×
224
}
×
225

226
bool Bind2Backend::getNSEC3PARAMuncached(const DNSName& name, NSEC3PARAMRecordContent* ns3p)
227
{
2,739✔
228
  if (!d_dnssecdb || d_hybrid)
2,739!
229
    return false;
23✔
230

231
  string value;
2,716✔
232
  vector<string> meta;
2,716✔
233
  getDomainMetadata(name, "NSEC3PARAM", meta);
2,716✔
234
  if (!meta.empty())
2,716✔
235
    value = *meta.begin();
715✔
236
  else
2,001✔
237
    return false; // No NSEC3 zone
2,001✔
238

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

244
    if (ns3p->d_iterations > maxNSEC3Iterations) {
715!
245
      ns3p->d_iterations = maxNSEC3Iterations;
×
246
      g_log << Logger::Error << "Number of NSEC3 iterations for zone '" << name << "' is above 'max-nsec3-iterations'. Value adjusted to: " << maxNSEC3Iterations << endl;
×
247
    }
×
248

249
    if (ns3p->d_algorithm != 1) {
715!
250
      g_log << Logger::Error << "Invalid hash algorithm for NSEC3: '" << std::to_string(ns3p->d_algorithm) << "', setting to 1 for zone '" << name << "'." << endl;
×
251
      ns3p->d_algorithm = 1;
×
252
    }
×
253
  }
715✔
254

255
  return true;
715✔
256
}
2,716✔
257

258
bool Bind2Backend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta)
259
{
641✔
260
  if (!d_dnssecdb || d_hybrid)
641!
261
    return false;
47✔
262

263
  try {
594✔
264
    d_getAllDomainMetadataQuery_stmt->bind("domain", name)->execute();
594✔
265

266
    SSqlStatement::row_t row;
594✔
267
    while (d_getAllDomainMetadataQuery_stmt->hasNextRow()) {
1,184✔
268
      d_getAllDomainMetadataQuery_stmt->nextRow(row);
590✔
269
      meta[row[0]].push_back(row[1]);
590✔
270
    }
590✔
271

272
    d_getAllDomainMetadataQuery_stmt->reset();
594✔
273
  }
594✔
274
  catch (SSqlException& se) {
594✔
275
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getAllDomainMetadata(): " + se.txtReason());
×
276
  }
×
277
  return true;
594✔
278
}
594✔
279

280
bool Bind2Backend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta)
281
{
3,240✔
282
  if (!d_dnssecdb || d_hybrid)
3,240!
283
    return false;
4✔
284

285
  try {
3,236✔
286
    d_getDomainMetadataQuery_stmt->bind("domain", name)->bind("kind", kind)->execute();
3,236✔
287

288
    SSqlStatement::row_t row;
3,236✔
289
    while (d_getDomainMetadataQuery_stmt->hasNextRow()) {
3,968✔
290
      d_getDomainMetadataQuery_stmt->nextRow(row);
732✔
291
      meta.push_back(row[0]);
732✔
292
    }
732✔
293

294
    d_getDomainMetadataQuery_stmt->reset();
3,236✔
295
  }
3,236✔
296
  catch (SSqlException& se) {
3,236✔
297
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getDomainMetadata(): " + se.txtReason());
×
298
  }
×
299
  return true;
3,236✔
300
}
3,236✔
301

302
bool Bind2Backend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta)
303
{
261✔
304
  if (!d_dnssecdb || d_hybrid)
261!
305
    return false;
×
306

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

321
bool Bind2Backend::getDomainKeys(const DNSName& name, std::vector<KeyData>& keys)
322
{
672✔
323
  if (!d_dnssecdb || d_hybrid)
672!
324
    return false;
43✔
325

326
  try {
629✔
327
    d_getDomainKeysQuery_stmt->bind("domain", name)->execute();
629✔
328

329
    KeyData kd;
629✔
330
    SSqlStatement::row_t row;
629✔
331
    while (d_getDomainKeysQuery_stmt->hasNextRow()) {
1,151✔
332
      d_getDomainKeysQuery_stmt->nextRow(row);
522✔
333
      pdns::checked_stoi_into(kd.id, row[0]);
522✔
334
      pdns::checked_stoi_into(kd.flags, row[1]);
522✔
335
      kd.active = (row[2] == "1");
522✔
336
      kd.published = (row[3] == "1");
522✔
337
      kd.content = row[4];
522✔
338
      keys.push_back(kd);
522✔
339
    }
522✔
340

341
    d_getDomainKeysQuery_stmt->reset();
629✔
342
  }
629✔
343
  catch (SSqlException& se) {
629✔
344
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getDomainKeys(): " + se.txtReason());
×
345
  }
×
346
  return true;
629✔
347
}
629✔
348

349
bool Bind2Backend::removeDomainKey(const DNSName& name, unsigned int id)
350
{
×
351
  if (!d_dnssecdb || d_hybrid)
×
352
    return false;
×
353

354
  try {
×
355
    d_deleteDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
×
356
  }
×
357
  catch (SSqlException& se) {
×
358
    throw PDNSException("Error accessing DNSSEC database in BIND backend, removeDomainKeys(): " + se.txtReason());
×
359
  }
×
360
  return true;
×
361
}
×
362

363
bool Bind2Backend::addDomainKey(const DNSName& name, const KeyData& key, int64_t& id)
364
{
123✔
365
  if (!d_dnssecdb || d_hybrid)
123!
366
    return false;
×
367

368
  try {
123✔
369
    d_insertDomainKeyQuery_stmt->bind("domain", name)->bind("flags", key.flags)->bind("active", key.active)->bind("published", key.published)->bind("content", key.content)->execute()->reset();
123✔
370
  }
123✔
371
  catch (SSqlException& se) {
123✔
372
    throw PDNSException("Error accessing DNSSEC database in BIND backend, addDomainKey(): " + se.txtReason());
×
373
  }
×
374

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

398
bool Bind2Backend::activateDomainKey(const DNSName& name, unsigned int id)
399
{
×
400
  if (!d_dnssecdb || d_hybrid)
×
401
    return false;
×
402

403
  try {
×
404
    d_activateDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
×
405
  }
×
406
  catch (SSqlException& se) {
×
407
    throw PDNSException("Error accessing DNSSEC database in BIND backend, activateDomainKey(): " + se.txtReason());
×
408
  }
×
409
  return true;
×
410
}
×
411

412
bool Bind2Backend::deactivateDomainKey(const DNSName& name, unsigned int id)
413
{
×
414
  if (!d_dnssecdb || d_hybrid)
×
415
    return false;
×
416

417
  try {
×
418
    d_deactivateDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
×
419
  }
×
420
  catch (SSqlException& se) {
×
421
    throw PDNSException("Error accessing DNSSEC database in BIND backend, deactivateDomainKey(): " + se.txtReason());
×
422
  }
×
423
  return true;
×
424
}
×
425

426
bool Bind2Backend::publishDomainKey(const DNSName& name, unsigned int id)
427
{
×
428
  if (!d_dnssecdb || d_hybrid)
×
429
    return false;
×
430

431
  try {
×
432
    d_publishDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
×
433
  }
×
434
  catch (SSqlException& se) {
×
435
    throw PDNSException("Error accessing DNSSEC database in BIND backend, publishDomainKey(): " + se.txtReason());
×
436
  }
×
437
  return true;
×
438
}
×
439

440
bool Bind2Backend::unpublishDomainKey(const DNSName& name, unsigned int id)
441
{
5✔
442
  if (!d_dnssecdb || d_hybrid)
5!
443
    return false;
×
444

445
  try {
5✔
446
    d_unpublishDomainKeyQuery_stmt->bind("domain", name)->bind("key_id", id)->execute()->reset();
5✔
447
  }
5✔
448
  catch (SSqlException& se) {
5✔
449
    throw PDNSException("Error accessing DNSSEC database in BIND backend, unpublishDomainKey(): " + se.txtReason());
×
450
  }
×
451
  return true;
5✔
452
}
5✔
453

454
bool Bind2Backend::getTSIGKey(const DNSName& name, DNSName& algorithm, string& content)
455
{
47✔
456
  if (!d_dnssecdb || d_hybrid)
47!
457
    return false;
×
458

459
  try {
47✔
460
    d_getTSIGKeyQuery_stmt->bind("key_name", name)->execute();
47✔
461

462
    SSqlStatement::row_t row;
47✔
463
    while (d_getTSIGKeyQuery_stmt->hasNextRow()) {
94✔
464
      d_getTSIGKeyQuery_stmt->nextRow(row);
47✔
465
      if (row.size() >= 2 && (algorithm.empty() || algorithm == DNSName(row[0]))) {
47!
466
        algorithm = DNSName(row[0]);
47✔
467
        content = row[1];
47✔
468
      }
47✔
469
    }
47✔
470

471
    d_getTSIGKeyQuery_stmt->reset();
47✔
472
  }
47✔
473
  catch (SSqlException& e) {
47✔
474
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getTSIGKey(): " + e.txtReason());
×
475
  }
×
476
  return true;
47✔
477
}
47✔
478

479
bool Bind2Backend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content)
480
{
5✔
481
  if (!d_dnssecdb || d_hybrid)
5!
482
    return false;
×
483

484
  try {
5✔
485
    d_setTSIGKeyQuery_stmt->bind("key_name", name)->bind("algorithm", algorithm)->bind("content", content)->execute()->reset();
5✔
486
  }
5✔
487
  catch (SSqlException& e) {
5✔
488
    throw PDNSException("Error accessing DNSSEC database in BIND backend, setTSIGKey(): " + e.txtReason());
×
489
  }
×
490
  return true;
5✔
491
}
5✔
492

493
bool Bind2Backend::deleteTSIGKey(const DNSName& name)
494
{
×
495
  if (!d_dnssecdb || d_hybrid)
×
496
    return false;
×
497

498
  try {
×
499
    d_deleteTSIGKeyQuery_stmt->bind("key_name", name)->execute()->reset();
×
500
  }
×
501
  catch (SSqlException& e) {
×
502
    throw PDNSException("Error accessing DNSSEC database in BIND backend, deleteTSIGKey(): " + e.txtReason());
×
503
  }
×
504
  return true;
×
505
}
×
506

507
bool Bind2Backend::getTSIGKeys(std::vector<struct TSIGKey>& keys)
508
{
×
509
  if (!d_dnssecdb || d_hybrid)
×
510
    return false;
×
511

512
  try {
×
513
    d_getTSIGKeysQuery_stmt->execute();
×
514

515
    SSqlStatement::row_t row;
×
516
    while (d_getTSIGKeysQuery_stmt->hasNextRow()) {
×
517
      d_getTSIGKeysQuery_stmt->nextRow(row);
×
518
      struct TSIGKey key;
×
519
      key.name = DNSName(row[0]);
×
520
      key.algorithm = DNSName(row[1]);
×
521
      key.key = row[2];
×
522
      keys.push_back(key);
×
523
    }
×
524

525
    d_getTSIGKeysQuery_stmt->reset();
×
526
  }
×
527
  catch (SSqlException& e) {
×
528
    throw PDNSException("Error accessing DNSSEC database in BIND backend, getTSIGKeys(): " + e.txtReason());
×
529
  }
×
530
  return true;
×
531
}
×
532

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

© 2026 Coveralls, Inc