source: trunk/dns-rpc.cgi@ 498

Last change on this file since 498 was 498, checked in by Kris Deugau, 11 years ago

/trunk

Add a line in dns-rpc.cgi's addRec() and updateRec() to allow RPC
callers to use the text labels for DNS types instead of having to
know the underlying integer value. Should work for all types
including the pseudotypes.

  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author Id
File size: 21.2 KB
Line 
1#!/usr/bin/perl -w -T
2# XMLRPC interface to manipulate most DNS DB entities
3##
4# $Id: dns-rpc.cgi 498 2013-05-06 02:41:31Z kdeugau $
5# Copyright 2012,2013 Kris Deugau <kdeugau@deepnet.cx>
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19##
20
21use strict;
22use warnings;
23
24# don't remove! required for GNU/FHS-ish install from tarball
25use lib '.'; ##uselib##
26use DNSDB;
27
28use FCGI;
29#use Frontier::RPC2;
30use Frontier::Responder;
31
32## We need to handle a couple of things globally, rather than pasting the same bit into *every* sub.
33## So, let's subclass Frontier::RPC2 + Frontier::Responder, so we can override the single sub in each
34## that needs kicking
35#### hmm. put this in a separate file?
36#package DNSDB::RPC;
37#our @ISA = ("Frontier::RPC2", "Frontier::Responder");
38#package main;
39
40my $dnsdb = DNSDB->new();
41
42my $methods = {
43 'dnsdb.addDomain' => \&addDomain,
44 'dnsdb.delZone' => \&delZone,
45 'dnsdb.addRDNS' => \&addRDNS,
46 'dnsdb.addGroup' => \&addGroup,
47 'dnsdb.delGroup' => \&delGroup,
48 'dnsdb.addUser' => \&addUser,
49 'dnsdb.updateUser' => \&updateUser,
50 'dnsdb.delUser' => \&delUser,
51 'dnsdb.getLocDropdown' => \&getLocDropdown,
52 'dnsdb.getSOA' => \&getSOA,
53 'dnsdb.getRecLine' => \&getRecLine,
54 'dnsdb.getRecList' => \&getRecList,
55 'dnsdb.getRecCount' => \&getRecCount,
56 'dnsdb.addRec' => \&addRec,
57 'dnsdb.updateRec' => \&updateRec,
58 'dnsdb.addOrUpdateRevRec' => \&addOrUpdateRevRec,
59 'dnsdb.delRec' => \&delRec,
60 'dnsdb.delByCIDR' => \&delByCIDR,
61#sub getLogCount {}
62#sub getLogEntries {}
63 'dnsdb.getRevPattern' => \&getRevPattern,
64 'dnsdb.zoneStatus' => \&zoneStatus,
65 'dnsdb.getZonesByCIDR' => \&getZonesByCIDR,
66
67 'dnsdb.getMethods' => \&get_method_list
68};
69
70my $reqcnt = 0;
71
72while (FCGI::accept >= 0) {
73 my $res = Frontier::Responder->new(
74 methods => $methods
75 );
76
77 # "Can't do that" errors
78 if (!$dnsdb) {
79 print "Content-type: text/xml\n\n".$res->{_decode}->encode_fault(5, $dnsdb->err);
80 } else {
81 print $res->answer;
82 }
83 last if $reqcnt++ > $dnsdb->{maxfcgi};
84} # while FCGI::accept
85
86
87exit;
88
89##
90## Subs below here
91##
92
93# Check RPC ACL
94sub _aclcheck {
95 my $subsys = shift;
96 return 1 if grep /$ENV{REMOTE_ADDR}/, @{$dnsdb->{rpcacl}{$subsys}};
97 return 0;
98}
99
100# Let's see if we can factor these out of the RPC method subs
101sub _commoncheck {
102 my $argref = shift;
103 my $needslog = shift;
104
105 die "Missing remote system name\n" if !$argref->{rpcsystem};
106 die "Access denied\n" if !_aclcheck($argref->{rpcsystem});
107 if ($needslog) {
108 die "Missing remote username\n" if !$argref->{rpcuser};
109 die "Couldn't set userdata for logging\n"
110 unless $dnsdb->initRPC(username => $argref->{rpcuser}, rpcsys => $argref->{rpcsystem},
111 fullname => ($argref->{fullname} ? $argref->{fullname} : $argref->{rpcuser}) );
112 }
113}
114
115# set location to the zone's default location if none is specified
116sub _loccheck {
117 my $argref = shift;
118 if (!$argref->{location} && $argref->{defrec} eq 'n') {
119 $argref->{location} = $dnsdb->getZoneLocation($argref->{revrec}, $argref->{parent_id});
120 }
121}
122
123# set ttl to zone defailt minttl if none is specified
124sub _ttlcheck {
125 my $argref = shift;
126 if (!$argref->{ttl}) {
127 my $tmp = $dnsdb->getSOA($argref->{defrec}, $argref->{revrec}, $argref->{parent_id});
128 $argref->{ttl} = $tmp->{minttl};
129 }
130}
131
132#sub connectDB {
133#sub finish {
134#sub initGlobals {
135#sub initPermissions {
136#sub getPermissions {
137#sub changePermissions {
138#sub comparePermissions {
139#sub changeGroup {
140#sub _log {
141
142sub addDomain {
143 my %args = @_;
144
145 _commoncheck(\%args, 'y');
146
147 my ($code, $msg) = $dnsdb->addDomain($args{domain}, $args{group}, $args{state});
148 die $msg if $code eq 'FAIL';
149 return $msg; # domain ID
150}
151
152sub delZone {
153 my %args = @_;
154
155 _commoncheck(\%args, 'y');
156 die "Need forward/reverse zone flag\n" if !$args{revrec};
157
158 my ($code,$msg);
159 # Let's be nice; delete based on zone id OR zone name. Saves an RPC call round-trip, maybe.
160 if ($args{zone} =~ /^\d+$/) {
161 ($code,$msg) = $dnsdb->delZone($args{zone}, $args{revrec});
162 } else {
163 my $zoneid;
164 $zoneid = $dnsdb->domainID($args{zone}) if $args{revrec} eq 'n';
165 $zoneid = $dnsdb->revID($args{zone}) if $args{revrec} eq 'y';
166 die "Can't find zone: $dnsdb->errstr\n" if !$zoneid;
167 ($code,$msg) = $dnsdb->delZone($zoneid, $args{revrec});
168 }
169 die $msg if $code eq 'FAIL';
170 return $msg;
171}
172
173#sub domainName {}
174#sub revName {}
175#sub domainID {}
176#sub revID {}
177
178sub addRDNS {
179 my %args = @_;
180
181 _commoncheck(\%args, 'y');
182
183 my ($code, $msg) = $dnsdb->addRDNS($args{revzone}, $args{revpatt}, $args{group}, $args{state}, $args{defloc});
184 die "$msg\n" if $code eq 'FAIL';
185 return $msg; # domain ID
186}
187
188#sub getZoneCount {}
189#sub getZoneList {}
190#sub getZoneLocation {}
191
192sub addGroup {
193 my %args = @_;
194
195 _commoncheck(\%args, 'y');
196 die "Missing new group name\n" if !$args{groupname};
197 die "Missing parent group ID\n" if !$args{parent_id};
198
199# not sure how to usefully represent permissions via RPC. :/
200# not to mention, permissions are checked at the UI layer, not the DB layer.
201 my $perms = {domain_edit => 1, domain_create => 1, domain_delete => 1,
202 record_edit => 1, record_create => 1, record_delete => 1
203 };
204## optional $inhert arg?
205 my ($code,$msg) = $dnsdb->addGroup($args{groupname}, $args{parent_id}, $perms);
206 die $msg if $code eq 'FAIL';
207 return $msg;
208}
209
210sub delGroup {
211 my %args = @_;
212
213 _commoncheck(\%args, 'y');
214 die "Missing group ID or name to remove\n" if !$args{group};
215
216 my ($code,$msg);
217 # Let's be nice; delete based on groupid OR group name. Saves an RPC call round-trip, maybe.
218 if ($args{group} =~ /^\d+$/) {
219 ($code,$msg) = $dnsdb->delGroup($args{group});
220 } else {
221 my $grpid = $dnsdb->groupID($args{group});
222 die "Can't find group\n" if !$grpid;
223 ($code,$msg) = $dnsdb->delGroup($grpid);
224 }
225 die $msg if $code eq 'FAIL';
226 return $msg;
227}
228
229#sub getChildren {}
230#sub groupName {}
231#sub getGroupCount {}
232#sub getGroupList {}
233#sub groupID {}
234
235sub addUser {
236 my %args = @_;
237
238 _commoncheck(\%args, 'y');
239
240# not sure how to usefully represent permissions via RPC. :/
241# not to mention, permissions are checked at the UI layer, not the DB layer.
242 # bend and twist; get those arguments in in the right order!
243 $args{type} = 'u' if !$args{type};
244 $args{permstring} = 'i' if !defined($args{permstring});
245 my @userargs = ($args{username}, $args{group}, $args{pass}, $args{state}, $args{type}, $args{permstring});
246 for my $argname ('fname','lname','phone') {
247 last if !$args{$argname};
248 push @userargs, $args{$argname};
249 }
250 my ($code,$msg) = $dnsdb->addUser(@userargs);
251 die $msg if $code eq 'FAIL';
252 return $msg;
253}
254
255#sub getUserCount {}
256#sub getUserList {}
257#sub getUserDropdown {}
258#sub checkUser {}
259
260sub updateUser {
261 my %args = @_;
262
263 _commoncheck(\%args, 'y');
264
265 die "Missing UID\n" if !$args{uid};
266
267 # bend and twist; get those arguments in in the right order!
268 $args{type} = 'u' if !$args{type};
269 my @userargs = ($args{uid}, $args{username}, $args{group}, $args{pass}, $args{state}, $args{type});
270 for my $argname ('fname','lname','phone') {
271 last if !$args{$argname};
272 push @userargs, $args{$argname};
273 }
274##fixme: also underlying in DNSDB::updateUser(): no way to just update this or that attribute;
275# have to pass them all in to be overwritten
276 my ($code,$msg) = $dnsdb->updateUser(@userargs);
277 die $msg if $code eq 'FAIL';
278 return $msg;
279}
280
281sub delUser {
282 my %args = @_;
283
284 _commoncheck(\%args, 'y');
285
286 die "Missing UID\n" if !$args{uid};
287 my ($code,$msg) = $dnsdb->delUser($args{uid});
288 die $msg if $code eq 'FAIL';
289 return $msg;
290}
291
292#sub userFullName {}
293#sub userStatus {}
294#sub getUserData {}
295
296#sub addLoc {}
297#sub updateLoc {}
298#sub delLoc {}
299#sub getLoc {}
300#sub getLocCount {}
301#sub getLocList {}
302
303sub getLocDropdown {
304 my %args = @_;
305
306 _commoncheck(\%args);
307 $args{defloc} = '' if !$args{defloc};
308
309 my $ret = $dnsdb->getLocDropdown($args{group}, $args{defloc});
310 return $ret;
311}
312
313sub getSOA {
314 my %args = @_;
315
316 _commoncheck(\%args);
317
318 my $ret = $dnsdb->getSOA($args{defrec}, $args{revrec}, $args{id});
319 if (!$ret) {
320 if ($args{defrec} eq 'y') {
321 die "No default SOA record in group\n";
322 } else {
323 die "No SOA record in zone\n";
324 }
325 }
326 return $ret;
327}
328
329#sub updateSOA {}
330
331sub getRecLine {
332 my %args = @_;
333
334 _commoncheck(\%args);
335
336 my $ret = $dnsdb->getRecLine($args{defrec}, $args{revrec}, $args{id});
337
338 die $dnsdb->errstr if !$ret;
339
340 return $ret;
341}
342
343sub getRecList {
344 my %args = @_;
345
346 _commoncheck(\%args);
347
348 # set some optional args
349 $args{nrecs} = 'all' if !$args{nrecs};
350 $args{nstart} = 0 if !$args{nstart};
351## for order, need to map input to column names
352 $args{order} = 'host' if !$args{order};
353 $args{direction} = 'ASC' if !$args{direction};
354
355 my $ret = $dnsdb->getRecList(defrec => $args{defrec}, revrec => $args{revrec}, id => $args{id},
356 offset => $args{offset}, sortby => $args{sortby}, sortorder => $args{sortorder},
357 filter => $args{filter});
358
359 die $dnsdb->errstr if !$ret;
360
361 return $ret;
362}
363
364sub getRecCount {
365 my %args = @_;
366
367 _commoncheck(\%args);
368
369 # set some optional args
370 $args{nrecs} = 'all' if !$args{nrecs};
371 $args{nstart} = 0 if !$args{nstart};
372## for order, need to map input to column names
373 $args{order} = 'host' if !$args{order};
374 $args{direction} = 'ASC' if !$args{direction};
375
376 my $ret = $dnsdb->getRecCount($args{defrec}, $args{revrec}, $args{id}, $args{filter});
377
378 die $dnsdb->errstr if !$ret;
379
380 return $ret;
381}
382
383sub addRec {
384 my %args = @_;
385
386 _commoncheck(\%args, 'y');
387
388 _loccheck(\%args);
389 _ttlcheck(\%args);
390
391 # allow passing text types rather than DNS integer IDs
392 $args{type} = $DNSDB::reverse_typemap{$args{type}} if $args{type} !~ /^d+$/;
393
394 my @recargs = ($args{defrec}, $args{revrec}, $args{parent_id},
395 \$args{name}, \$args{type}, \$args{address}, $args{ttl}, $args{location});
396 if ($args{type} == $DNSDB::reverse_typemap{MX} or $args{type} == $DNSDB::reverse_typemap{SRV}) {
397 push @recargs, $args{distance};
398 if ($args{type} == $DNSDB::reverse_typemap{SRV}) {
399 push @recargs, $args{weight};
400 push @recargs, $args{port};
401 }
402 }
403
404 my ($code, $msg) = $dnsdb->addRec(@recargs);
405
406 die $msg if $code eq 'FAIL';
407 return $msg;
408}
409
410sub updateRec {
411 my %args = @_;
412
413 _commoncheck(\%args, 'y');
414
415 # get old line, so we can update only the bits that the caller passed to change
416 # note we subbed address for val since it's a little more caller-friendly
417 my $oldrec = $dnsdb->getRecLine($args{defrec}, $args{revrec}, $args{id});
418 foreach my $field (qw(name type address ttl location distance weight port)) {
419 $args{$field} = $oldrec->{$field} if !$args{$field} && defined($oldrec->{$field});
420 }
421
422 # allow passing text types rather than DNS integer IDs
423 $args{type} = $DNSDB::reverse_typemap{$args{type}} if $args{type} !~ /^d+$/;
424
425 # note dist, weight, port are not required on all types; will be ignored if not needed.
426 # parent_id is the "primary" zone we're updating; necessary for forward/reverse voodoo
427 my ($code, $msg) = $dnsdb->updateRec($args{defrec}, $args{revrec}, $args{id}, $args{parent_id},
428 \$args{name}, \$args{type}, \$args{address}, $args{ttl}, $args{location},
429 $args{distance}, $args{weight}, $args{port});
430
431 die $msg if $code eq 'FAIL';
432 return $msg;
433}
434
435# Takes a passed CIDR block and DNS pattern; adds a new record or updates the record(s) affected
436sub addOrUpdateRevRec {
437 my %args = @_;
438
439 _commoncheck(\%args, 'y');
440 my $cidr = new NetAddr::IP $args{cidr};
441
442 my $zonelist = $dnsdb->getZonesByCIDR(%args);
443 if (scalar(@$zonelist) == 0) {
444 # enhh.... WTF?
445 } elsif (scalar(@$zonelist) == 1) {
446 # check if the single zone returned is bigger than the CIDR. if so, we can just add a record
447 my $zone = new NetAddr::IP $zonelist->[0]->{revnet};
448 if ($zone->contains($cidr)) {
449 # We need to strip the CIDR mask on IPv4 /32 assignments, or we just add a new record all the time.
450 my $filt = ($cidr->{isv6} || $cidr->masklen != 32 ? "$cidr" : $cidr->addr);
451 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y',
452 id => $zonelist->[0]->{rdns_id}, filter => $filt);
453 if (scalar(@$reclist) == 0) {
454 # Aren't Magic Numbers Fun? See pseudotype list in dnsadmin.
455 my $type = ($cidr->{isv6} ? 65284 : ($cidr->masklen == 32 ? 65280 : 65283) );
456 addRec(defrec =>'n', revrec => 'y', parent_id => $zonelist->[0]->{rdns_id}, type => $type,
457 address => "$cidr", %args);
458 } else {
459 my $flag = 0;
460 foreach my $rec (@$reclist) {
461 # pure PTR plus composite types
462 next unless $rec->{type} == 12 || $rec->{type} == 65280 || $rec->{type} == 65281
463 || $rec->{type} == 65282 || $rec->{type} == 65283 || $rec->{type} == 65284;
464 next unless $rec->{val} eq $filt; # make sure we really update the record we want to update.
465 $dnsdb->updateRec(defrec =>'n', revrec => 'y', id => $rec->{record_id},
466 parent_id => $zonelist->[0]->{rdns_id}, %args);
467 $flag = 1;
468 last; # only do one record.
469 }
470 unless ($flag) {
471 # Nothing was updated, so we didn't really have a match. Add as per @$reclist==0
472 # Aren't Magic Numbers Fun? See pseudotype list in dnsadmin.
473 my $type = ($cidr->{isv6} ? 65282 : ($cidr->masklen == 32 ? 65280 : 65283) );
474 $dnsdb->addRec(defrec =>'n', revrec => 'y', parent_id => $zonelist->[0]->{rdns_id}, type => $type,
475 address => "$cidr", %args);
476 }
477 }
478 } else {
479 # ebbeh? CIDR is only partly represented in DNS. This needs manual intervention.
480 } # done single-zone-contains-$cidr
481 } else {
482 # Overlapping reverse zones shouldn't be possible, so if we're here we've got a CIDR
483 # that spans multiple reverse zones (eg, /23 CIDR -> 2 /24 rzones)
484 foreach my $zdata (@$zonelist) {
485 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y',
486 id => $zdata->{rdns_id}, filter => $zdata->{revnet});
487 if (scalar(@$reclist) == 0) {
488 my $type = ($args{cidr}->{isv6} ? 65282 : ($args{cidr}->masklen == 32 ? 65280 : 65283) );
489 $dnsdb->addRec(defrec =>'n', revrec => 'y', parent_id => $zdata->{rdns_id}, type => $type,
490 address => "$args{cidr}", %args);
491 } else {
492 foreach my $rec (@$reclist) {
493 # only the composite and/or template types; pure PTR or nontemplate composite
494 # types are nominally impossible here.
495 next unless $rec->{type} == 65282 || $rec->{type} == 65283 || $rec->{type} == 65284;
496 $dnsdb->updateRec(defrec =>'n', revrec => 'y', id => $rec->{record_id},
497 parent_id => $zdata->{rdns_id}, %args);
498 last; # only do one record.
499 }
500 }
501 } # iterate zones within $cidr
502 } # done $cidr-contains-zones
503}
504
505sub delRec {
506 my %args = @_;
507
508 _commoncheck(\%args, 'y');
509
510 my ($code, $msg) = $dnsdb->delRec($args{defrec}, $args{recrev}, $args{id});
511
512 die $msg if $code eq 'FAIL';
513 return $msg;
514}
515
516sub delByCIDR {
517 my %args = @_;
518
519 _commoncheck(\%args, 'y');
520
521 # much like addOrUpdateRevRec()
522 my $zonelist = $dnsdb->getZonesByCIDR(%args);
523 my $cidr = new NetAddr::IP $args{cidr};
524
525 if (scalar(@$zonelist) == 0) {
526 # enhh.... WTF?
527 } elsif (scalar(@$zonelist) == 1) {
528
529 # check if the single zone returned is bigger than the CIDR
530 my $zone = new NetAddr::IP $zonelist->[0]->{revnet};
531 if ($zone->contains($cidr)) {
532
533 if ($args{delsubs}) {
534 # Delete ALL EVARYTHING!!one11!! in $args{cidr}
535 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y', id => $zonelist->[0]->{rdns_id});
536 foreach my $rec (@$reclist) {
537 my $reccidr = new NetAddr::IP $rec->{val};
538 next unless $cidr->contains($reccidr);
539 next unless $rec->{type} == 12 || $rec->{type} == 65280 || $rec->{type} == 65281 ||
540 $rec->{type} == 65282 || $rec->{type} == 65283 ||$rec->{type} == 65284;
541 ##fixme: multiple records, wanna wax'em all, how to report errors?
542 if ($args{delforward} ||
543 $rec->{type} == 12 || $rec->{type} == 65282 ||
544 $rec->{type} == 65283 || $rec->{type} == 65284) {
545 my ($code,$msg) = $dnsdb->delRec('n', 'y', $rec->{record_id});
546 } else {
547 my $ret = $dnsdb->downconvert($rec->{record_id}, $DNSDB::reverse_typemap{A});
548 }
549 }
550 if ($args{parpatt} && $zone == $cidr) {
551 # Edge case; we've just gone and axed all the records in the reverse zone.
552 # Re-add one to match the parent if we've been given a pattern to use.
553 $dnsdb->addRec(defrec =>'n', revrec => 'y', parent_id => $zonelist->[0]->{rdns_id},
554 type => ($zone->{isv6} ? 65284 : 65283), address => "$cidr", %args);
555 }
556
557 } else {
558 # Selectively delete only exact matches on $args{cidr}
559
560 # We need to strip the CIDR mask on IPv4 /32 assignments, or we can't find single-IP records
561 my $filt = ($cidr->{isv6} || $cidr->masklen != 32 ? "$cidr" : $cidr->addr);
562 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y',
563 id => $zonelist->[0]->{rdns_id}, filter => $filt, sortby => 'val', sortorder => 'DESC');
564 foreach my $rec (@$reclist) {
565 my $reccidr = new NetAddr::IP $rec->{val};
566 next unless $cidr == $reccidr;
567 next unless $rec->{type} == 12 || $rec->{type} == 65280 || $rec->{type} == 65281 ||
568 $rec->{type} == 65282 || $rec->{type} == 65283 ||$rec->{type} == 65284;
569 if ($args{delforward} || $rec->{type} == 12) {
570 my ($code,$msg) = $dnsdb->delRec('n', 'y', $rec->{record_id});
571 die $msg if $code eq 'FAIL';
572 return $msg;
573 } else {
574 my $ret = $dnsdb->downconvert($rec->{record_id}, $DNSDB::reverse_typemap{A});
575 die $dnsdb->errstr if !$ret;
576 return "A+PTR for $args{cidr} split and PTR removed";
577 }
578 } # foreach @$reclist
579 }
580
581 } else { # $cidr > $zone but we only have one zone
582 # ebbeh? CIDR is only partly represented in DNS. This needs manual intervention.
583 return "Warning: $args{cidr} is only partly represented in DNS. Check and remove DNS records manually.";
584 } # done single-zone-contains-$cidr
585
586 } else { # multiple zones nominally "contain" $cidr
587 # Overlapping reverse zones shouldn't be possible, so if we're here we've got a CIDR
588 # that spans multiple reverse zones (eg, /23 CIDR -> 2 /24 rzones)
589 foreach my $zdata (@$zonelist) {
590 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y', id => $zdata->{rdns_id});
591 if (scalar(@$reclist) == 0) {
592# nothing to do? or do we (re)add a record based on the parent?
593# yes, yes we do, past the close of the else
594# my $type = ($args{cidr}->{isv6} ? 65282 : ($args{cidr}->masklen == 32 ? 65280 : 65283) );
595# addRec(defrec =>'n', revrec => 'y', parent_id => $zdata->{rdns_id}, type => $type,
596# address => "$args{cidr}", %args);
597 } else {
598 foreach my $rec (@$reclist) {
599 next unless $rec->{type} == 12 || $rec->{type} == 65280 || $rec->{type} == 65281 ||
600 $rec->{type} == 65282 || $rec->{type} == 65283 || $rec->{type} == 65284;
601 # Template types are only useful when attached to a reverse zone.
602##fixme ..... or ARE THEY?
603 if ($args{delforward} ||
604 $rec->{type} == 12 || $rec->{type} == 65282 ||
605 $rec->{type} == 65283 || $rec->{type} == 65284) {
606 my ($code,$msg) = $dnsdb->delRec('n', 'y', $rec->{record_id});
607 } else {
608 my $ret = $dnsdb->downconvert($rec->{record_id}, $DNSDB::reverse_typemap{A});
609 }
610 } # foreach @$reclist
611 } # nrecs != 0
612 if ($args{parpatt}) {
613 # We've just gone and axed all the records in the reverse zone.
614 # Re-add one to match the parent if we've been given a pattern to use.
615 $dnsdb->addRec(defrec =>'n', revrec => 'y', parent_id => $zdata->{rdns_id},
616 type => ($cidr->{isv6} ? 65284 : 65283),
617 address => $zdata->{revnet}, name => $args{parpatt}, %args);
618 }
619 } # iterate zones within $cidr
620 } # done $cidr-contains-zones
621
622} # end delByCIDR()
623
624#sub getLogCount {}
625#sub getLogEntries {}
626
627sub getRevPattern {
628 my %args = @_;
629
630 _commoncheck(\%args, 'y');
631
632 return $dnsdb->getRevPattern($args{cidr}, $args{group});
633}
634
635#sub getTypelist {}
636#sub parentID {}
637#sub isParent {}
638
639sub zoneStatus {
640 my %args = @_;
641
642 _commoncheck(\%args, 'y');
643
644 my @arglist = ($args{zoneid});
645 push @arglist, $args{status} if defined($args{status});
646
647 my $status = $dnsdb->zoneStatus(@arglist);
648}
649
650# Get a list of hashes referencing the reverse zone(s) for a passed CIDR block
651sub getZonesByCIDR {
652 my %args = @_;
653
654 _commoncheck(\%args, 'y');
655
656 return $dnsdb->getZonesByCIDR(%args);
657}
658
659#sub importAXFR {}
660#sub importBIND {}
661#sub import_tinydns {}
662#sub export {}
663#sub __export_tiny {}
664#sub _printrec_tiny {}
665#sub mailNotify {}
666
667sub get_method_list {
668 my @methods = keys %{$methods};
669 return \@methods;
670}
Note: See TracBrowser for help on using the repository browser.