]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/serialtweaker.cc
Meson: Add systemd feature support for service files
[thirdparty/pdns.git] / pdns / serialtweaker.cc
CommitLineData
92c90b44
BH
1/*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002-2011 PowerDNS.COM BV
4
5 This program is free software; you can redistribute it and/or modify
6ca3fa73 6 it under the terms of the GNU General Public License version 2 as
92c90b44
BH
7 published by the Free Software Foundation
8
f782fe38
MH
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
92c90b44
BH
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
870a0fe4
AT
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
92c90b44
BH
26#include "dnsseckeeper.hh"
27#include "dnspacket.hh"
28#include "namespaces.hh"
fa8fd4d2 29
63347c6c 30uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq)
6ca3fa73
SB
31{
32 struct tm tm;
33 localtime_r(&t, &tm);
34 return
35 (uint32_t)(tm.tm_year+1900) * 1000000u
36 + (uint32_t)(tm.tm_mon + 1) * 10000u
37 + (uint32_t)tm.tm_mday * 100u
38 + seq;
39}
40
13f9e280 41uint32_t calculateEditSOA(uint32_t old_serial, const string& kind, const DNSName& zonename)
92c90b44 42{
f81291fd 43 if(pdns_iequals(kind,"INCEPTION-INCREMENT")) {
5ba9719b
RA
44 time_t inception = getStartOfWeek();
45 uint32_t inception_serial = localtime_format_YYYYMMDDSS(inception, 1);
46 uint32_t dont_increment_after = localtime_format_YYYYMMDDSS(inception + 2*86400, 99);
47
13f9e280 48 if(old_serial < inception_serial - 1) { /* less than <inceptionday>00 */
83609e21 49 return inception_serial; /* return <inceptionday>01 (skipping <inceptionday>00 as possible value) */
f613d242
CH
50 } else if (old_serial < inception_serial+1) {
51 /* "<inceptionday>00" and "<inceptionday>01" are reserved for inception increasing, so jump to "<inceptionday>02" */
52 return inception_serial+1;
13f9e280 53 } else if(old_serial <= dont_increment_after) { /* >= <inceptionday>00 but <= <inceptionday+2>99 */
f613d242 54 return old_serial + 1;
83609e21 55 }
5ba9719b 56 }
5ba9719b
RA
57 else if(pdns_iequals(kind,"INCREMENT-WEEKS")) {
58 time_t inception = getStartOfWeek();
13f9e280 59 return (old_serial + (inception / (7*86400)));
5ba9719b
RA
60 }
61 else if(pdns_iequals(kind,"EPOCH")) {
5a7a3b67 62 // coverity[store_truncates_time_t]
4646277d 63 return time(nullptr);
5ba9719b
RA
64 }
65 else if(pdns_iequals(kind,"INCEPTION-EPOCH")) {
eee11292 66 uint32_t inception = getStartOfWeek();
13f9e280 67 if (old_serial < inception)
5ba9719b 68 return inception;
d605927b
VV
69 }
70 else if(pdns_iequals(kind,"NONE")) {
71 // do nothing to serial. needed because a metadata of "" will use the default-soa-edit setting instead.
72 }
73 else if(!kind.empty()) {
e6a9dde5 74 g_log<<Logger::Warning<<"SOA-EDIT type '"<<kind<<"' for zone "<<zonename<<" is unknown."<<endl;
5ba9719b 75 }
0afb4e96
CH
76 // Seen strictly, this is a broken config: we can only come here if
77 // both SOA-EDIT and default-soa-edit are set to "", but the latter
78 // should be set to "NONE" instead.
13f9e280 79 return old_serial;
90ba52e0 80}
81
13f9e280
CH
82uint32_t calculateEditSOA(uint32_t old_serial, DNSSECKeeper& dk, const DNSName& zonename) {
83 string kind;
84 dk.getSoaEdit(zonename, kind);
13f9e280 85 return calculateEditSOA(old_serial, kind, zonename);
5ba9719b 86}
a6448d95 87
13f9e280
CH
88/** Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API. */
89static uint32_t calculateIncreaseSOA(uint32_t old_serial, const string& increaseKind, const string& editKind, const DNSName& zonename) {
636301b9
CH
90 if (pdns_iequals(increaseKind, "SOA-EDIT-INCREASE")) {
91 uint32_t new_serial = old_serial;
92 if (!editKind.empty()) {
865d5504
PD
93 if (pdns_iequals(editKind, "INCEPTION-EPOCH")) {
94 new_serial = calculateEditSOA(old_serial, "EPOCH", zonename);
95 } else {
96 new_serial = calculateEditSOA(old_serial, editKind, zonename);
97 }
a6448d95 98 }
636301b9
CH
99 if (new_serial <= old_serial) {
100 new_serial = old_serial + 1;
a6448d95 101 }
636301b9 102 return new_serial;
a6448d95 103 }
636301b9
CH
104 else if (pdns_iequals(increaseKind, "SOA-EDIT")) {
105 return calculateEditSOA(old_serial, editKind, zonename);
106 }
107 else if (pdns_iequals(increaseKind, "INCREASE")) {
13f9e280 108 return old_serial + 1;
a6448d95
CH
109 }
110 else if (pdns_iequals(increaseKind, "EPOCH")) {
5a7a3b67 111 // coverity[store_truncates_time_t]
4646277d 112 return time(nullptr);
a6448d95 113 }
636301b9 114 else if (pdns_iequals(increaseKind, "DEFAULT")) {
4646277d 115 time_t now = time(nullptr);
636301b9
CH
116 uint32_t new_serial = localtime_format_YYYYMMDDSS(now, 1);
117 if (new_serial <= old_serial) {
118 new_serial = old_serial + 1;
119 }
120 return new_serial;
121 } else if(!increaseKind.empty()) {
e6a9dde5 122 g_log<<Logger::Warning<<"SOA-EDIT-API/DNSUPDATE type '"<<increaseKind<<"' for zone "<<zonename<<" is unknown."<<endl;
a6448d95 123 }
636301b9 124 return old_serial;
a6448d95
CH
125}
126
13f9e280
CH
127/** Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
128 * Good if you already *have* a DNSResourceRecord.
129 * Content in rr is suitable for writing into a backend.
130 *
131 * @return true if changes may have been made
132 */
a6448d95
CH
133bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind) {
134 if (increaseKind.empty())
135 return false;
136
137 SOAData sd;
138 fillSOAData(rr.content, sd);
13f9e280
CH
139
140 sd.serial = calculateIncreaseSOA(sd.serial, increaseKind, editKind, rr.qname);
141 rr.content = makeSOAContent(sd)->getZoneRepresentation(true);
142 return true;
143}
144
145/** Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
146 * Makes a mostly reset DNSResourceRecord for you in @param rrout.
147 * Content in rrout is suitable for writing into a backend.
148 *
149 * @return true if rrout is now valid
150 */
151bool makeIncreasedSOARecord(SOAData& sd, const string& increaseKind, const string& editKind, DNSResourceRecord& rrout) {
152 if (increaseKind.empty())
153 return false;
154
155 sd.serial = calculateIncreaseSOA(sd.serial, increaseKind, editKind, sd.qname);
156 rrout.qname = sd.qname;
157 rrout.content = makeSOAContent(sd)->getZoneRepresentation(true);
158 rrout.qtype = QType::SOA;
159 rrout.domain_id = sd.domain_id;
d563b11a 160 rrout.auth = true;
13f9e280
CH
161 rrout.ttl = sd.ttl;
162
a6448d95
CH
163 return true;
164}
5fff7d51
KM
165
166DNSZoneRecord makeEditedDNSZRFromSOAData(DNSSECKeeper& dk, const SOAData& sd, DNSResourceRecord::Place place) {
167 SOAData edited = sd;
168 edited.serial = calculateEditSOA(sd.serial, dk, sd.qname);
169
170 DNSRecord soa;
171 soa.d_name = sd.qname;
172 soa.d_type = QType::SOA;
173 soa.d_ttl = sd.ttl;
174 soa.d_place = place;
d06dcda4 175 soa.setContent(makeSOAContent(edited));
5fff7d51
KM
176
177 DNSZoneRecord dzr;
178 dzr.domain_id = sd.domain_id;
179 dzr.signttl = sd.ttl;
180 dzr.auth = true;
9bbcf03a 181 dzr.dr = std::move(soa);
5fff7d51
KM
182
183 return dzr;
184}