2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 * originally authored by Fredrik Danerklint
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.
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.
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.
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.
26 #include "luabackend.hh"
28 #include "pdns/logger.hh"
29 #include "pdns/arguments.hh"
32 bool LUABackend::updateDNSSECOrderAndAuth(uint32_t domain_id
, const DNSName
& zonename
, const DNSName
& qname
, bool auth
) {
34 if(f_lua_updatednssecorderandauth
== 0) {
37 L
<< Logger::Info
<< backend_name
<< "(updateDNSSECOrderAndAuth) domain_id: '" << domain_id
<< "' zonename: '" << zonename
<< "' qname: '" << qname
<< "' auth: '" << auth
<< "'" << endl
;
39 string ins
=qname
.makeRelative(zonename
).makeLowerCase().labelReverse().toString(" ", false);
40 return this->updateDNSSECOrderAndAuthAbsolute(domain_id
, qname
, ins
, auth
);
44 L
<< Logger::Info
<< backend_name
<< "(updateDNSSECOrderAndAuth) BEGIN domain_id: '" << domain_id
<< "' zonename: '" << zonename
<< "' qname: '" << qname
<< "' auth: '" << auth
<< "'" << endl
;
46 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_updatednssecorderandauth
);
48 lua_pushinteger(lua
, domain_id
);
49 lua_pushstring(lua
, zonename
.toString().c_str());
50 lua_pushstring(lua
, qname
.toString().c_str());
51 lua_pushboolean(lua
, auth
);
53 if(lua_pcall(lua
, 4, 1, f_lua_exec_error
) != 0) {
54 string e
= backend_name
+ lua_tostring(lua
, -1);
57 throw runtime_error(e
);
61 size_t returnedwhat
= lua_type(lua
, -1);
64 if (returnedwhat
== LUA_TBOOLEAN
)
65 ok
= lua_toboolean(lua
, -1);
70 L
<< Logger::Info
<< backend_name
<< "(updateDNSSECOrderAndAuth) END" << endl
;
75 bool LUABackend::updateDNSSECOrderNameAndAuth(unsigned int, DNSName
const&, DNSName
const&, DNSName
const&, bool, unsigned short)
80 bool LUABackend::updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id
, const DNSName
& qname
, const std::string
& ordername
, bool auth
) {
82 if(f_lua_updatednssecorderandauthabsolute
== 0)
86 L
<< Logger::Info
<< backend_name
<< "(updateDNSSECOrderAndAuthAbsolute) BEGIN domain_id: '" << domain_id
<< "' qname: '" << qname
<< "' ordername: '" << ordername
<< "' auth: '" << auth
<< "'" << endl
;
88 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_updatednssecorderandauthabsolute
);
90 lua_pushinteger(lua
, domain_id
);
91 lua_pushstring(lua
, qname
.toString().c_str());
92 lua_pushstring(lua
, ordername
.c_str());
93 lua_pushboolean(lua
, auth
);
95 if(lua_pcall(lua
, 4, 1, f_lua_exec_error
) != 0) {
96 string e
= backend_name
+ lua_tostring(lua
, -1);
99 throw runtime_error(e
);
103 size_t returnedwhat
= lua_type(lua
, -1);
106 if (returnedwhat
== LUA_TBOOLEAN
)
107 ok
= lua_toboolean(lua
, -1);
112 L
<< Logger::Info
<< backend_name
<< "(updateDNSSECOrderAndAuthAbsolute) END" << endl
;
117 bool LUABackend::getBeforeAndAfterNamesAbsolute(uint32_t id
, const DNSName
& qname
, DNSName
& unhashed
, DNSName
& before
, DNSName
& after
) {
119 if(f_lua_getbeforeandafternamesabsolute
== 0)
127 L
<< Logger::Info
<< backend_name
<< "(getBeforeAndAfterNamesAbsolute) BEGIN id: '" << id
<< "' qname: '" << qname
<< "'" << endl
;
129 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_updatednssecorderandauthabsolute
);
131 lua_pushinteger(lua
, id
);
132 lua_pushstring(lua
, qname
.toString().c_str());
134 if(lua_pcall(lua
, 2, 3, f_lua_exec_error
) != 0) {
135 string e
= backend_name
+ lua_tostring(lua
, -1);
138 throw runtime_error(e
);
142 size_t returnedwhat
= lua_type(lua
, -1);
143 bool ok
= returnedwhat
== LUA_TSTRING
;
147 L
<< Logger::Info
<< backend_name
<< "(getBeforeAndAfterNamesAbsolute) ERROR!" << endl
;
152 //will this be correct since we are poping one at the time?
153 unhashed
= DNSName(lua_tostring(lua
, -1));
156 returnedwhat
= lua_type(lua
, -1);
157 ok
= (returnedwhat
== LUA_TSTRING
) && ok
;
159 before
= DNSName(lua_tostring(lua
, -1));
162 returnedwhat
= lua_type(lua
, -1);
163 ok
= (returnedwhat
== LUA_TSTRING
) && ok
;
165 after
= DNSName(lua_tostring(lua
, -1));
169 L
<< Logger::Info
<< backend_name
<< "(getBeforeAndAfterNamesAbsolute) END unhashed: '" << unhashed
<< "' before: '" << before
<< "' after: '" << after
<< "' " << endl
;
174 bool LUABackend::updateDomainKey(const DNSName
& name
, unsigned int &id
, bool toowhat
) {
176 if(f_lua_updatedomainkey
== 0)
180 L
<< Logger::Info
<< backend_name
<< "(updateDomainKey) BEGIN name: '" << name
<< "' id: '" << id
<< "' toowhat: '" << toowhat
<< "'" << endl
;
182 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_updatedomainkey
);
184 lua_pushstring(lua
, name
.toString().c_str());
185 lua_pushinteger(lua
, id
);
186 lua_pushboolean(lua
, toowhat
);
188 if(lua_pcall(lua
, 3, 1, f_lua_exec_error
) != 0) {
189 string e
= backend_name
+ lua_tostring(lua
, -1);
192 throw runtime_error(e
);
196 size_t returnedwhat
= lua_type(lua
, -1);
199 if (returnedwhat
== LUA_TBOOLEAN
)
200 ok
= lua_toboolean(lua
, -1);
205 L
<< Logger::Info
<< backend_name
<< "(updateDomainKey) END" << endl
;
210 bool LUABackend::activateDomainKey(const DNSName
& name
, unsigned int id
) {
212 if(f_lua_activatedomainkey
== 0)
213 return updateDomainKey(name
, id
, true);
216 L
<< Logger::Info
<< backend_name
<< "(activateDomainKey) BEGIN name: '" << name
<< "' id: '" << id
<< endl
;
218 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_activatedomainkey
);
220 lua_pushstring(lua
, name
.toString().c_str());
221 lua_pushinteger(lua
, id
);
223 if(lua_pcall(lua
, 2, 1, f_lua_exec_error
) != 0) {
224 string e
= backend_name
+ lua_tostring(lua
, -1);
227 throw runtime_error(e
);
231 size_t returnedwhat
= lua_type(lua
, -1);
234 if (returnedwhat
== LUA_TBOOLEAN
)
235 ok
= lua_toboolean(lua
, -1);
240 L
<< Logger::Info
<< backend_name
<< "(activateDomainKey) END" << endl
;
245 bool LUABackend::deactivateDomainKey(const DNSName
& name
, unsigned int id
) {
247 if(f_lua_deactivatedomainkey
== 0)
248 return updateDomainKey(name
, id
, false);
251 L
<< Logger::Info
<< backend_name
<< "(deactivateDomainKey) BEGIN name: '" << name
<< "' id: '" << id
<< endl
;
253 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_deactivatedomainkey
);
255 lua_pushstring(lua
, name
.toString().c_str());
256 lua_pushinteger(lua
, id
);
258 if(lua_pcall(lua
, 2, 1, f_lua_exec_error
) != 0) {
259 string e
= backend_name
+ lua_tostring(lua
, -1);
262 throw runtime_error(e
);
266 size_t returnedwhat
= lua_type(lua
, -1);
269 if (returnedwhat
== LUA_TBOOLEAN
)
270 ok
= lua_toboolean(lua
, -1);
275 L
<< Logger::Info
<< backend_name
<< "(deactivateDomainKey) END" << endl
;
280 bool LUABackend::removeDomainKey(const DNSName
& name
, unsigned int id
) {
282 if(f_lua_removedomainkey
== 0)
286 L
<< Logger::Info
<< backend_name
<< "(removeDomainKey) BEGIN name: '" << name
<< "' id: '" << id
<< endl
;
288 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_removedomainkey
);
290 lua_pushstring(lua
, name
.toString().c_str());
291 lua_pushinteger(lua
, id
);
293 if(lua_pcall(lua
, 2, 1, f_lua_exec_error
) != 0) {
294 string e
= backend_name
+ lua_tostring(lua
, -1);
297 throw runtime_error(e
);
301 size_t returnedwhat
= lua_type(lua
, -1);
304 if (returnedwhat
== LUA_TBOOLEAN
)
305 ok
= lua_toboolean(lua
, -1);
310 L
<< Logger::Info
<< backend_name
<< "(removeDomainKey) END" << endl
;
315 bool LUABackend::addDomainKey(const DNSName
& name
, const KeyData
& key
, int64_t& id
) {
316 // there is no logging function in pdnsutil when running this routine?
318 //key = id, flags, active, content
320 if(f_lua_adddomainkey
== 0)
324 //L << Logger::Info << backend_name << "(addDomainKey) BEGIN name: '" << name << "' id: '" << id << endl;
325 cerr
<< backend_name
<< "(addDomainKey) BEGIN name: '" << name
<< endl
;
327 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_adddomainkey
);
329 lua_pushstring(lua
, name
.toString().c_str());
333 lua_pushliteral(lua
, "flags");
334 lua_pushinteger(lua
, key
.flags
);
335 lua_settable(lua
, -3);
337 lua_pushliteral(lua
, "active");
338 lua_pushboolean(lua
, key
.active
);
339 lua_settable(lua
, -3);
341 lua_pushliteral(lua
, "content");
342 lua_pushstring(lua
, key
.content
.c_str());
343 lua_settable(lua
, -3);
345 if(lua_pcall(lua
, 2, 1, f_lua_exec_error
) != 0) {
346 string e
= backend_name
+ lua_tostring(lua
, -1);
349 throw runtime_error(e
);
352 size_t returnedwhat
= lua_type(lua
, -1);
355 if (returnedwhat
== LUA_TNUMBER
)
356 ok
= lua_tonumber(lua
, -1);
361 cerr
<< backend_name
<< "(addDomainKey) END" << endl
;
366 bool LUABackend::getDomainKeys(const DNSName
& name
, unsigned int kind
, std::vector
<KeyData
>& keys
) {
367 //what is kind used for?
369 if(f_lua_getdomainkeys
== 0)
373 L
<< Logger::Info
<< backend_name
<< "(getDomainKeys) BEGIN name: '" << name
<< "' kind: '" << kind
<< endl
;
375 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_getdomainkeys
);
377 lua_pushstring(lua
, name
.toString().c_str());
378 lua_pushinteger(lua
, kind
);
380 if(lua_pcall(lua
, 2, 1, f_lua_exec_error
) != 0) {
381 string e
= backend_name
+ lua_tostring(lua
, -1);
384 throw runtime_error(e
);
388 size_t returnedwhat
= lua_type(lua
, -1);
390 if (returnedwhat
!= LUA_TTABLE
) {
393 L
<< Logger::Info
<< backend_name
<< "(getDomainKeys) ERROR!" << endl
;
402 while (lua_next(lua
, -2)) {
403 returnedwhat
= lua_type(lua
, -1);
404 if (returnedwhat
== LUA_TTABLE
) {
406 bool i
,f
,a
,c
= false;
408 i
= getValueFromTable(lua
, "id", kd
.id
);
409 f
= getValueFromTable(lua
, "flags", kd
.flags
);
410 a
= getValueFromTable(lua
, "active", kd
.active
);
411 c
= getValueFromTable(lua
, "content", kd
.content
);
413 if (i
&& f
&& a
&& c
) {
423 L
<< Logger::Info
<< backend_name
<< "(getDomainKeys) END" << endl
;
428 bool LUABackend::getTSIGKey(const DNSName
& name
, DNSName
* algorithm
, string
* content
) {
430 if(f_lua_gettsigkey
== 0)
434 L
<< Logger::Info
<< backend_name
<< "(getTSIGKey) BEGIN name: '" << name
<< "'" << endl
;
436 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_gettsigkey
);
438 lua_pushstring(lua
, name
.toString().c_str());
440 if(lua_pcall(lua
, 1, 2, f_lua_exec_error
) != 0) {
441 string e
= backend_name
+ lua_tostring(lua
, -1);
444 throw runtime_error(e
);
448 if ( (lua_type(lua
, -1) != LUA_TSTRING
) && (lua_type(lua
, -2) != LUA_TSTRING
) ) {
451 L
<< Logger::Info
<< backend_name
<< "(getTSIGKey) ERROR" << endl
;
457 a
= lua_tostring(lua
, -1);
460 c
= lua_tostring(lua
, -1);
463 *algorithm
= DNSName(a
);
467 L
<< Logger::Info
<< backend_name
<< "(getTSIGKey) END" << endl
;
472 bool LUABackend::setDomainMetadata(const DNSName
& name
, const std::string
& kind
, const std::vector
<std::string
>& meta
) {
474 if(f_lua_setdomainmetadata
== 0)
478 L
<< Logger::Info
<< backend_name
<< "(setDomainMetadata) BEGIN name: '" << name
<< "' kind: '" << kind
<< "'" << endl
;
480 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_setdomainmetadata
);
482 lua_pushstring(lua
, name
.toString().c_str());
483 lua_pushstring(lua
, kind
.c_str());
487 std::vector
<std::string
>::const_iterator i
;
491 for(i
= meta
.begin(); i
<meta
.end(); i
++ ) {
493 lua_pushinteger(lua
, c
);
494 lua_pushstring(lua
, i
->c_str());
495 lua_settable(lua
, -3);
498 if(lua_pcall(lua
, 3, 1, f_lua_exec_error
) != 0) {
499 string e
= backend_name
+ lua_tostring(lua
, -1);
502 throw runtime_error(e
);
506 size_t returnedwhat
= lua_type(lua
, -1);
509 if (returnedwhat
== LUA_TBOOLEAN
)
510 ok
= lua_toboolean(lua
, -1);
515 L
<< Logger::Info
<< backend_name
<< "(setDomainMetadata) END" << endl
;
521 bool LUABackend::getDomainMetadata(const DNSName
& name
, const std::string
& kind
, std::vector
<std::string
>& meta
) {
522 if(f_lua_getdomainmetadata
== 0)
526 L
<< Logger::Info
<< backend_name
<< "(getDomainMetadata) BEGIN name: '" << name
<< "' kind: '" << kind
<< "'" << endl
;
528 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_getdomainmetadata
);
530 lua_pushstring(lua
, name
.toString().c_str());
531 lua_pushstring(lua
, kind
.c_str());
533 if(lua_pcall(lua
, 2, 1, f_lua_exec_error
) != 0) {
534 string e
= backend_name
+ lua_tostring(lua
, -1);
537 throw runtime_error(e
);
541 if (lua_type(lua
, -1) != LUA_TTABLE
)
549 while (lua_next(lua
, -2)) {
550 returnedwhat
= lua_type(lua
, -1);
551 if (returnedwhat
== LUA_TSTRING
) {
553 meta
.push_back(lua_tostring(lua
, -1));
560 L
<< Logger::Info
<< backend_name
<< "(getDomainMetadata) END" << endl
;
566 void LUABackend::alsoNotifies(const DNSName
& domain
, set
<string
> *ips
) {
568 if(f_lua_alsonotifies
== 0)
572 L
<< Logger::Info
<< backend_name
<< "(alsonotifies) BEGIN domain: '" << domain
<< "'" << endl
;
574 lua_rawgeti(lua
, LUA_REGISTRYINDEX
, f_lua_alsonotifies
);
576 lua_pushstring(lua
, domain
.toString().c_str());
578 if(lua_pcall(lua
, 1, 1, f_lua_exec_error
) != 0) {
579 string e
= backend_name
+ lua_tostring(lua
, -1);
582 throw runtime_error(e
);
586 if (lua_type(lua
, -1) != LUA_TTABLE
)
593 while (lua_next(lua
, -2)) {
594 returnedwhat
= lua_type(lua
, -1);
595 if (returnedwhat
== LUA_TSTRING
) {
596 ips
->insert(lua_tostring(lua
, -1));
603 L
<< Logger::Info
<< backend_name
<< "(alsoNotifies) END" << endl
;