Changeset 548 for branches/stable
- Timestamp:
- 12/11/13 16:01:18 (11 years ago)
- Location:
- branches/stable
- Files:
-
- 5 deleted
- 48 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/stable
- Property svn:mergeinfo changed
/trunk merged: 493-534,536-543
- Property svn:mergeinfo changed
-
branches/stable/DNSDB.pm
r547 r548 3 3 ## 4 4 # $Id$ 5 # Copyright 2008-201 2Kris Deugau <kdeugau@deepnet.cx>5 # Copyright 2008-2013 Kris Deugau <kdeugau@deepnet.cx> 6 6 # 7 7 # This program is free software: you can redistribute it and/or modify … … 28 28 use Crypt::PasswdMD5; 29 29 use Net::SMTP; 30 use NetAddr::IP qw(:lower);30 use NetAddr::IP 4.027 qw(:lower); 31 31 use POSIX; 32 32 use Fcntl qw(:flock); 33 use Time::TAI64 qw(:tai64); 33 34 34 35 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); … … 40 41 &getPermissions &changePermissions &comparePermissions 41 42 &changeGroup 42 & loadConfig &connectDB &finish43 &connectDB &finish 43 44 &addDomain &delZone &domainName &revName &domainID &revID &addRDNS 44 45 &getZoneCount &getZoneList &getZoneLocation … … 49 50 &addLoc &updateLoc &delLoc &getLoc 50 51 &getLocCount &getLocList &getLocDropdown 51 &getSOA &updateSOA &getRecLine &get DomRecs&getRecCount52 &getSOA &updateSOA &getRecLine &getRecList &getRecCount 52 53 &addRec &updateRec &delRec 53 54 &getLogCount &getLogEntries … … 59 60 &export 60 61 &mailNotify 61 %typemap %reverse_typemap %config62 %typemap %reverse_typemap 62 63 @permtypes $permlist %permchains 63 64 ); … … 68 69 &getPermissions &changePermissions &comparePermissions 69 70 &changeGroup 70 & loadConfig &connectDB &finish71 &connectDB &finish 71 72 &addDomain &delZone &domainName &revName &domainID &revID &addRDNS 72 73 &getZoneCount &getZoneList &getZoneLocation … … 77 78 &addLoc &updateLoc &delLoc &getLoc 78 79 &getLocCount &getLocList &getLocDropdown 79 &getSOA &updateSOA &getRecLine &get DomRecs&getRecCount80 &getSOA &updateSOA &getRecLine &getRecList &getRecCount 80 81 &addRec &updateRec &delRec 81 82 &getLogCount &getLogEntries … … 87 88 &export 88 89 &mailNotify 89 %typemap %reverse_typemap %config90 %typemap %reverse_typemap 90 91 @permtypes $permlist %permchains 91 92 )] … … 94 95 our $errstr = ''; 95 96 our $resultstr = ''; 96 97 # Halfway sane defaults for SOA, TTL, etc.98 # serial defaults to 0 for convenience.99 # value will be either YYYYMMDDNN for BIND/etc, or auto-internal for tinydns100 our %def = qw (101 contact hostmaster.DOMAIN102 prins ns1.myserver.com103 serial 0104 soattl 86400105 refresh 10800106 retry 3600107 expire 604800108 minttl 10800109 ttl 10800110 );111 97 112 98 # Arguably defined wholly in the db, but little reason to change without supporting code changes … … 135 121 our %typemap; 136 122 our %reverse_typemap; 137 138 # Prepopulate a basic config. Note some of these *will* cause errors if left unset.139 # note: add appropriate stanzas in loadConfig to parse these140 our %config = (141 # Database connection info142 dbname => 'dnsdb',143 dbuser => 'dnsdb',144 dbpass => 'secret',145 dbhost => '',146 147 # Email notice settings148 mailhost => 'smtp.example.com',149 mailnotify => 'dnsdb@example.com', # to150 mailsender => 'dnsdb@example.com', # from151 mailname => 'DNS Administration',152 orgname => 'Example Corp',153 domain => 'example.com',154 155 # Template directory156 templatedir => 'templates/',157 # fmeh. this is a real web path, not a logical internal one. hm..158 # cssdir => 'templates/',159 sessiondir => 'session/',160 exportcache => 'cache/',161 162 # Session params163 timeout => '3600', # 1 hour default164 165 # Other miscellanea166 log_failures => 1, # log all evarthing by default167 perpage => 15,168 maxfcgi => 100, # reasonable default?169 );170 123 171 124 ## (Semi)private variables … … 221 174 my $class = ref($this) || $this; 222 175 my %args = @_; 223 ##fixme? to ponder: do we do some magic if the caller sets eg dbname to prevent parsing of the config file? 224 if (!loadConfig(basename => $args{configfile})) { 225 warn "Using default configuration; unable to load custom settings: $errstr\n"; 226 } 227 my $self = \%config; 228 $self->{configfile} = $args{configfile}; 176 177 # Prepopulate a basic config. Note some of these *will* cause errors if left unset. 178 # note: add appropriate stanzas in __cfgload() to parse these 179 my %defconfig = ( 180 # The only configuration options not loadable from a config file. 181 configfile => "/etc/dnsdb/dnsdb.conf", ##CFG_LEAF## 182 183 # Database connection info 184 dbname => 'dnsdb', 185 dbuser => 'dnsdb', 186 dbpass => 'secret', 187 dbhost => '', 188 189 # Email notice settings 190 mailhost => 'smtp.example.com', 191 mailnotify => 'dnsdb@example.com', # to 192 mailsender => 'dnsdb@example.com', # from 193 mailname => 'DNS Administration', 194 orgname => 'Example Corp', 195 domain => 'example.com', 196 197 # Template directory 198 templatedir => 'templates/', 199 # fmeh. this is a real web path, not a logical internal one. hm.. 200 # cssdir => 'templates/', 201 sessiondir => 'session/', 202 exportcache => 'cache/', 203 204 # Session params 205 timeout => '1h', # passed as-is to CGI::Session 206 207 # Other miscellanea 208 log_failures => 1, # log all evarthing by default 209 perpage => 15, 210 max_fcgi_requests => 100, # reasonable default? 211 force_refresh => 1, 212 lowercase => 0, # mangle as little as possible by default 213 ); 214 215 # Config file parse calls. 216 # If we are passed a blank argument for $args{configfile}, 217 # we should NOT parse the default config file - we will 218 # rely on hardcoded defaults OR caller-specified values. 219 # If we are passed a non-blank argument, parse that file. 220 # If no config file is specified, parse the default one. 221 my %siteconfig; 222 if (defined($args{configfile})) { 223 if ($args{configfile}) { 224 return if !__cfgload($args{configfile}, \%siteconfig); 225 } 226 } else { 227 return if !__cfgload($defconfig{configfile}, \%siteconfig); 228 } 229 230 # Assemble the object. Apply configuration hashes in order of precedence. 231 my $self = { 232 # Hardcoded defaults 233 %defconfig, 234 # Default config file OR caller-specified one, loaded above 235 %siteconfig, 236 # Caller-specified arguments 237 %args 238 }; 229 239 bless $self, $class; 240 241 # Several settings are booleans. Handle multiple possible ways of setting them. 242 for my $boolopt ('log_failures', 'force_refresh', 'lowercase') { 243 if ($self->{$boolopt} ne '1' && $self->{$boolopt} ne '0') { 244 # true/false, on/off, yes/no all valid. 245 if ($self->{$boolopt} =~ /^(?:true|false|t|f|on|off|yes|no)$/) { 246 if ($self->{$boolopt} =~ /(?:true|t|on|yes)/) { 247 $self->{$boolopt} = 1; 248 } else { 249 $self->{$boolopt} = 0; 250 } 251 } else { 252 warn "Bad $boolopt setting $self->{$boolopt}\n"; 253 $self->{$boolopt} = 1; 254 } 255 } 256 } 257 258 # Try to connect to the DB, and initialize a number of handy globals. 230 259 $self->{dbh} = connectDB($self->{dbname}, $self->{dbuser}, $self->{dbpass}, $self->{dbhost}) or return; 231 260 $self->initGlobals(); … … 236 265 sub DESTROY { 237 266 my $self = shift; 238 $self->{dbh}->disconnect ;267 $self->{dbh}->disconnect if $self->{dbh}; 239 268 } 269 270 sub errstr { $DNSDB::errstr; } 240 271 241 272 ## … … 370 401 371 402 ##fixme: farm out the actual logging to different subs for file, syslog, internal, etc based on config 372 # if ($ config{log_channel} eq 'sql') {403 # if ($self->{log_channel} eq 'sql') { 373 404 $dbh->do("INSERT INTO log (domain_id,rdns_id,group_id,entry,user_id,email,name) VALUES (?,?,?,?,?,?,?)", 374 405 undef, 375 406 ($args{domain_id}, $args{rdns_id}, $args{group_id}, $args{entry}, 376 407 $self->{loguserid}, $self->{logusername}, $self->{logfullname}) ); 377 # } elsif ($ config{log_channel} eq 'file') {378 # } elsif ($ config{log_channel} eq 'syslog') {408 # } elsif ($self->{log_channel} eq 'file') { 409 # } elsif ($self->{log_channel} eq 'syslog') { 379 410 # } 380 411 } # end _log … … 409 440 # or the intended parent domain for live records. 410 441 my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : $self->domainName($args{id})); 411 ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;442 ${$args{host}} =~ s/\.*$/\.$pname/ if (${$args{host}} ne '@' && ${$args{host}} !~ /$pname$/); 412 443 413 444 # Check IP is well-formed, and that it's a v4 address … … 526 557 ${$args{val}} = "ZONE,${$args{val}}" unless ${$args{val}} =~ /^ZONE/; 527 558 } 528 ${$args{host}} =~ s/\.*$/\.$ config{domain}/ if ${$args{host}} !~ /(?:$config{domain}|ADMINDOMAIN)$/;559 ${$args{host}} =~ s/\.*$/\.$self->{domain}/ if ${$args{host}} !~ /(?:$self->{domain}|ADMINDOMAIN)$/; 529 560 } 530 561 … … 1202 1233 #major patterns: 1203 1234 #dashed IP, forward and reverse 1235 #underscoreed IP, forward and reverse 1204 1236 #dotted IP, forward and reverse (even if forward is... dumb) 1205 # -> %r for reverse, %i for forward, leading - or . to indicate separator, defaults to -1237 # -> %r for reverse, %i for forward, leading -, _, or . to indicate separator, defaults to - 1206 1238 # %r or %-r => %4d-%3d-%2d-%1d 1239 # %_r => %4d_%3d_%2d_%1d 1207 1240 # %.r => %4d.%3d.%2d.%1d 1208 1241 # %i or %-i => %1d-%2d-%3d-%4d 1242 # %_i => %1d_%2d_%3d_%4d 1209 1243 # %.i => %1d.%2d.%3d.%4d 1210 1244 $$tmpl =~ s/\%r/\%4d-\%3d-\%2d-\%1d/g; 1211 $$tmpl =~ s/\%([-. ])r/\%4d$1\%3d$1\%2d$1\%1d/g;1245 $$tmpl =~ s/\%([-._])r/\%4d$1\%3d$1\%2d$1\%1d/g; 1212 1246 $$tmpl =~ s/\%i/\%1d-\%2d-\%3d-\%4d/g; 1213 $$tmpl =~ s/\%([-. ])i/\%1d$1\%2d$1\%3d$1\%4d/g;1247 $$tmpl =~ s/\%([-._])i/\%1d$1\%2d$1\%3d$1\%4d/g; 1214 1248 1215 1249 #hex-coded IP … … 1232 1266 } # _template4_expand() 1233 1267 1268 # Broad syntactic check on the hostname. Checks for valid characters, correctly-expandable template patterns. 1269 # Takes the hostname, type, and live/default and forward/reverse flags 1270 # Returns true/false, sets errstr on failures 1271 sub _check_hostname_form { 1272 my ($hname,$rectype,$defrec,$revrec) = @_; 1273 1274 if ($hname =~ /\%/ && ($rectype == 65282 || $rectype == 65283) ) { 1275 my $tmphost = $hname; 1276 # we don't actually need to test with the real IP passed; that saves a bit of fiddling. 1277 _template4_expand(\$tmphost, '10.10.10.10'); 1278 if ($tmphost =~ /\%/) { 1279 $errstr = "Invalid template $hname"; 1280 return; 1281 } 1282 } elsif ($revrec eq 'y') { 1283 # Reverse zones don't support @ in hostnames 1284 # Also skip failure on revzone TXT records; the hostname contains the TXT content in that case. 1285 if ($rectype != $reverse_typemap{TXT} && lc($hname) !~ /^[0-9a-z_.-]+$/) { 1286 $errstr = "Hostnames may not contain anything other than (0-9 a-z . _)"; 1287 return; 1288 } 1289 } else { 1290 if (lc($hname) !~ /^(?:[0-9a-z_.-]+|@)$/) { 1291 # Don't mention @, because it would be far too wordy to explain the nuance of @ 1292 $errstr = "Hostnames may not contain anything other than (0-9 a-z . _)"; 1293 return; 1294 } 1295 } 1296 return 1; 1297 } # _check_hostname_form() 1298 1234 1299 1235 1300 ## … … 1237 1302 ## 1238 1303 1239 ## DNSDB::loadConfig()1240 # Load the minimum required initial state (DB connect info) from a config file1241 # Load misc other bits while we're at it.1242 # Takes an optional hash that may contain:1243 # - basename and config path to look for1244 # Populates the %config and %def hashes1245 sub loadConfig {1246 my %args = @_;1247 $args{configfile} = '' if !$args{configfile};1248 1249 ##fixme this is *intended* to load a system-default config template, and allow1250 # overriding on a per-tool or per-web-UI-instance basis with a secondary config1251 # file. The "default" config file can't be deleted in the current form.1252 1253 my $deferr = ''; # place to put error from default config file in case we can't find either one1254 1255 my $configroot = "/etc/dnsdb"; ##CFG_LEAF##1256 $configroot = '' if $args{configfile} =~ m|^/|; # allow passed siteconfig to specify an arbitrary absolute path1257 $args{configfile} .= ".conf" if $args{configfile} !~ /\.conf$/;1258 my $defconfig = "$configroot/dnsdb.conf";1259 my $siteconfig = "$configroot/$args{configfile}";1260 1261 # System defaults1262 __cfgload("$defconfig") or $deferr = $errstr;1263 1264 # Per-site-ish settings.1265 if ($args{configfile} ne '.conf') {1266 unless (__cfgload("$siteconfig")) {1267 $errstr = ($deferr ? "Error opening default config file $defconfig: $deferr\n" : '').1268 "Error opening site config file $siteconfig";1269 return;1270 }1271 }1272 1273 # Munge log_failures.1274 if ($config{log_failures} ne '1' && $config{log_failures} ne '0') {1275 # true/false, on/off, yes/no all valid.1276 if ($config{log_failures} =~ /^(?:true|false|on|off|yes|no)$/) {1277 if ($config{log_failures} =~ /(?:true|on|yes)/) {1278 $config{log_failures} = 1;1279 } else {1280 $config{log_failures} = 0;1281 }1282 } else {1283 $errstr = "Bad log_failures setting $config{log_failures}";1284 $config{log_failures} = 1;1285 # Bad setting shouldn't be fatal.1286 # return 2;1287 }1288 }1289 1290 # All good, clear the error and go home.1291 $errstr = '';1292 return 1;1293 } # end loadConfig()1294 1295 1296 1304 ## DNSDB::__cfgload() 1297 1305 # Private sub to parse a config file and load it into %config 1298 # Takes a filename 1306 # Takes a filename and a hashref to put the parsed entries in 1299 1307 sub __cfgload { 1300 1308 $errstr = ''; 1301 1309 my $cfgfile = shift; 1310 my $cfg = shift; 1302 1311 1303 1312 if (open CFG, "<$cfgfile") { … … 1310 1319 # $mode = $1 if /^\[(a-z)+]/; 1311 1320 # DB connect info 1312 $config{dbname} = $1 if /^dbname\s*=\s*([a-z0-9_.-]+)/i; 1313 $config{dbuser} = $1 if /^dbuser\s*=\s*([a-z0-9_.-]+)/i; 1314 $config{dbpass} = $1 if /^dbpass\s*=\s*([a-z0-9_.-]+)/i; 1315 $config{dbhost} = $1 if /^dbhost\s*=\s*([a-z0-9_.-]+)/i; 1316 # SOA defaults 1317 $def{contact} = $1 if /^contact\s*=\s*([a-z0-9_.-]+)/i; 1318 $def{prins} = $1 if /^prins\s*=\s*([a-z0-9_.-]+)/i; 1319 $def{soattl} = $1 if /^soattl\s*=\s*(\d+)/i; 1320 $def{refresh} = $1 if /^refresh\s*=\s*(\d+)/i; 1321 $def{retry} = $1 if /^retry\s*=\s*(\d+)/i; 1322 $def{expire} = $1 if /^expire\s*=\s*(\d+)/i; 1323 $def{minttl} = $1 if /^minttl\s*=\s*(\d+)/i; 1324 $def{ttl} = $1 if /^ttl\s*=\s*(\d+)/i; 1321 $cfg->{dbname} = $1 if /^dbname\s*=\s*([a-z0-9_.-]+)/i; 1322 $cfg->{dbuser} = $1 if /^dbuser\s*=\s*([a-z0-9_.-]+)/i; 1323 $cfg->{dbpass} = $1 if /^dbpass\s*=\s*([a-z0-9_.-]+)/i; 1324 $cfg->{dbhost} = $1 if /^dbhost\s*=\s*([a-z0-9_.-]+)/i; 1325 1325 # Mail settings 1326 $c onfig{mailhost} = $1 if /^mailhost\s*=\s*([a-z0-9_.-]+)/i;1327 $c onfig{mailnotify} = $1 if /^mailnotify\s*=\s*([a-z0-9_.\@-]+)/i;1328 $c onfig{mailsender} = $1 if /^mailsender\s*=\s*([a-z0-9_.\@-]+)/i;1329 $c onfig{mailname} = $1 if /^mailname\s*=\s*([a-z0-9\s_.-]+)/i;1330 $c onfig{orgname} = $1 if /^orgname\s*=\s*([a-z0-9\s_.,'-]+)/i;1331 $c onfig{domain} = $1 if /^domain\s*=\s*([a-z0-9_.-]+)/i;1326 $cfg->{mailhost} = $1 if /^mailhost\s*=\s*([a-z0-9_.-]+)/i; 1327 $cfg->{mailnotify} = $1 if /^mailnotify\s*=\s*([a-z0-9_.\@-]+)/i; 1328 $cfg->{mailsender} = $1 if /^mailsender\s*=\s*([a-z0-9_.\@-]+)/i; 1329 $cfg->{mailname} = $1 if /^mailname\s*=\s*([a-z0-9\s_.-]+)/i; 1330 $cfg->{orgname} = $1 if /^orgname\s*=\s*([a-z0-9\s_.,'-]+)/i; 1331 $cfg->{domain} = $1 if /^domain\s*=\s*([a-z0-9_.-]+)/i; 1332 1332 # session - note this is fed directly to CGI::Session 1333 $c onfig{timeout} = $1 if /^[tT][iI][mM][eE][oO][uU][tT]\s*=\s*(\d+[smhdwMy]?)/;1334 $c onfig{sessiondir} = $1 if m{^sessiondir\s*=\s*([a-z0-9/_.-]+)}i;1333 $cfg->{timeout} = $1 if /^[tT][iI][mM][eE][oO][uU][tT]\s*=\s*(\d+[smhdwMy]?)/; 1334 $cfg->{sessiondir} = $1 if m{^sessiondir\s*=\s*([a-z0-9/_.-]+)}i; 1335 1335 # misc 1336 $config{log_failures} = $1 if /^log_failures\s*=\s*([a-z01]+)/i; 1337 $config{perpage} = $1 if /^perpage\s*=\s*(\d+)/i; 1338 $config{exportcache} = $1 if m{^exportcache\s*=\s*([a-z0-9/_.-]+)}i; 1336 $cfg->{log_failures} = $1 if /^log_failures\s*=\s*([a-z01]+)/i; 1337 $cfg->{perpage} = $1 if /^perpage\s*=\s*(\d+)/i; 1338 $cfg->{exportcache} = $1 if m{^exportcache\s*=\s*([a-z0-9/_.-]+)}i; 1339 $cfg->{lowercase} = $1 if /^lowercase\s*=\s*([a-z01]+)/i; 1340 # not supported in dns.cgi yet 1341 # $cfg->{templatedir} = $1 if m{^templatedir\s*=\s*([a-z0-9/_.-]+)}i; 1342 # $cfg->{templateoverride} = $1 if m{^templateoverride\s*=\s*([a-z0-9/_.-]+)}i; 1339 1343 # RPC options 1340 $config{rpcmode} = $1 if /^rpc_mode\s*=\s*(socket|HTTP|XMLRPC)\s*$/i; 1341 $config{maxfcgi} = $1 if /^max_fcgi_requests\s*=\s*(\d+)\s*$/i; 1344 $cfg->{rpcmode} = $1 if /^rpc_mode\s*=\s*(socket|HTTP|XMLRPC)\s*$/i; 1345 $cfg->{maxfcgi} = $1 if /^max_fcgi_requests\s*=\s*(\d+)\s*$/i; 1346 $cfg->{force_refresh} = $1 if /^force_refresh\s*=\s*([a-z01]+)/i; 1342 1347 if (my ($tmp) = /^rpc_iplist\s*=\s*(.+)/i) { 1343 1348 my @ips = split /[,\s]+/, $tmp; 1344 1349 my $rpcsys = shift @ips; 1345 push @{$c onfig{rpcacl}{$rpcsys}}, @ips;1350 push @{$cfg->{rpcacl}{$rpcsys}}, @ips; 1346 1351 } 1347 1352 } 1348 1353 close CFG; 1349 1354 } else { 1350 $errstr = $!;1355 $errstr = "Couldn't load configuration file $cfgfile: $!"; 1351 1356 return; 1352 1357 } … … 1531 1536 # about having to open a file or a syslog channel 1532 1537 ##fixme Need to call _initActionLog_blah() for various logging channels, configured 1533 # via dnsdb.conf, in $ config{log_channel} or something1538 # via dnsdb.conf, in $self->{log_channel} or something 1534 1539 # See https://secure.deepnet.cx/trac/dnsadmin/ticket/21 1535 1540 sub initActionLog { … … 1552 1557 1553 1558 # convert to real check once we have other logging channels 1554 # if ($ config{log_channel} eq 'sql') {1559 # if ($self->{log_channel} eq 'sql') { 1555 1560 # Open Log, Sez Me! 1556 1561 # } … … 1594 1599 my $sth = $dbh->prepare($sql); 1595 1600 1596 $sth->execute($id) or die "argh: ".$sth->errstr; 1601 ##fixme? we don't trap other plain SELECT errors 1602 $sth->execute($id); 1597 1603 1598 1604 # my $permref = $sth->fetchrow_hashref; … … 1778 1784 my $msg = $@; 1779 1785 eval { $dbh->rollback; }; 1780 if ($ config{log_failures}) {1786 if ($self->{log_failures}) { 1781 1787 $self->_log(group_id => $oldgid, entry => "Error moving $type $entname to $newgname: $msg"); 1782 1788 $dbh->commit; # since we enabled transactions earlier … … 1802 1808 my $self = shift; 1803 1809 my $dbh = $self->{dbh}; 1804 return ('FAIL',"Need database handle") if !$dbh;1805 1810 my $domain = shift; 1806 return ('FAIL',"Domain must not be blank ") if !$domain;1811 return ('FAIL',"Domain must not be blank\n") if !$domain; 1807 1812 my $group = shift; 1808 return ('FAIL'," Need group") if !defined($group);1813 return ('FAIL',"Group must be specified\n") if !defined($group); 1809 1814 my $state = shift; 1810 return ('FAIL',"Need domain status") if !defined($state); 1815 return ('FAIL',"Domain status must be specified\n") if !defined($state); 1816 my $defloc = shift || ''; 1811 1817 1812 1818 $state = 1 if $state =~ /^active$/; … … 1817 1823 return ('FAIL',"Invalid domain status") if $state !~ /^\d+$/; 1818 1824 1825 $domain = lc($domain) if $self->{lowercase}; 1826 1819 1827 return ('FAIL', "Invalid characters in domain") if $domain !~ /^[a-zA-Z0-9_.-]+$/; 1820 1828 … … 1836 1844 eval { 1837 1845 # insert the domain... 1838 $dbh->do("INSERT INTO domains (domain,group_id,status) VALUES (?,?,?)", undef, ($domain, $group, $state)); 1846 $dbh->do("INSERT INTO domains (domain,group_id,status,default_location) VALUES (?,?,?,?)", undef, 1847 ($domain, $group, $state, $defloc)); 1839 1848 1840 1849 # get the ID... … … 1847 1856 # ... and now we construct the standard records from the default set. NB: group should be variable. 1848 1857 my $sth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl FROM default_records WHERE group_id=?"); 1849 my $sth_in = $dbh->prepare("INSERT INTO records (domain_id,host,type,val,distance,weight,port,ttl )".1850 " VALUES ($dom_id,?,?,?,?,?,?,? )");1858 my $sth_in = $dbh->prepare("INSERT INTO records (domain_id,host,type,val,distance,weight,port,ttl,location)". 1859 " VALUES ($dom_id,?,?,?,?,?,?,?,?)"); 1851 1860 $sth->execute($group); 1852 while (my ($host, $type,$val,$dist,$weight,$port,$ttl) = $sth->fetchrow_array()) {1861 while (my ($host, $type, $val, $dist, $weight, $port, $ttl) = $sth->fetchrow_array()) { 1853 1862 $host =~ s/DOMAIN/$domain/g; 1854 1863 $val =~ s/DOMAIN/$domain/g; 1855 $sth_in->execute($host, $type,$val,$dist,$weight,$port,$ttl);1864 $sth_in->execute($host, $type, $val, $dist, $weight, $port, $ttl, $defloc); 1856 1865 if ($typemap{$type} eq 'SOA') { 1857 1866 my @tmp1 = split /:/, $host; … … 1877 1886 eval { $dbh->rollback; }; 1878 1887 $self->_log(group_id => $group, entry => "Failed adding domain $domain ($msg)") 1879 if $ config{log_failures};1888 if $self->{log_failures}; 1880 1889 $dbh->commit; # since we enabled transactions earlier 1881 1890 return ('FAIL',$msg); … … 1908 1917 return ('FAIL', ($revrec eq 'n' ? 'Domain' : 'Reverse zone')." ID $zoneid doesn't exist") if !$zone; 1909 1918 1910 # Set this up here since we may use if if $ config{log_failures} is enabled1919 # Set this up here since we may use if if $self->{log_failures} is enabled 1911 1920 my %loghash; 1912 1921 $loghash{domain_id} = $zoneid if $revrec eq 'n'; … … 1956 1965 eval { $dbh->rollback; }; 1957 1966 $loghash{entry} = "Error deleting $zone: $msg ($failmsg)"; 1958 if ($ config{log_failures}) {1967 if ($self->{log_failures}) { 1959 1968 $self->_log(%loghash); 1960 1969 $dbh->commit; # since we enabled transactions earlier … … 2008 2017 my ($domid) = $dbh->selectrow_array("SELECT domain_id FROM domains WHERE lower(domain) = lower(?)", 2009 2018 undef, ($domain) ); 2010 $errstr = $DBI::errstr if !$domid; 2019 if (!$domid) { 2020 if ($dbh->err) { 2021 $errstr = $DBI::errstr; 2022 } else { 2023 $errstr = "Domain $domain not present"; 2024 } 2025 } 2011 2026 return $domid if $domid; 2012 2027 } # end domainID() … … 2022 2037 my $revzone = shift; 2023 2038 my ($revid) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet=?", undef, ($revzone) ); 2024 $errstr = $DBI::errstr if !$revid; 2039 if (!$revid) { 2040 if ($dbh->err) { 2041 $errstr = $DBI::errstr; 2042 } else { 2043 $errstr = "Reverse zone $revzone not present"; 2044 } 2045 } 2025 2046 return $revid if $revid; 2026 2047 } # end revID() … … 2089 2110 } 2090 2111 2091 $host =~ s/ADMINDOMAIN/$ config{domain}/g;2112 $host =~ s/ADMINDOMAIN/$self->{domain}/g; 2092 2113 2093 2114 # Check to make sure the IP stubs will fit in the zone. Under most usage failures here should be rare. … … 2183 2204 eval { $dbh->rollback; }; 2184 2205 $self->_log(group_id => $group, entry => "Failed adding reverse zone $zone ($msg)") 2185 if $ config{log_failures};2206 if $self->{log_failures}; 2186 2207 $dbh->commit; # since we enabled transactions earlier 2187 2208 return ('FAIL',$msg); … … 2211 2232 2212 2233 my %args = @_; 2234 2235 # Fail on bad curgroup argument. There's no sane fallback on this one. 2236 if (!$args{curgroup} || $args{curgroup} !~ /^\d+$/) { 2237 $errstr = "Bad or missing curgroup argument"; 2238 return; 2239 } 2240 # Fail on bad childlist argument. This could be sanely ignored if bad, maybe. 2241 if ($args{childlist} && $args{childlist} !~ /^[\d,]+$/) { 2242 $errstr = "Bad childlist argument"; 2243 return; 2244 } 2213 2245 2214 2246 my @filterargs; … … 2250 2282 $args{sortorder} = 'ASC' if !$args{sortorder} || !grep /^$args{sortorder}$/, ('ASC','DESC'); 2251 2283 $args{offset} = 0 if !$args{offset} || $args{offset} !~ /^(?:all|\d+)$/; 2284 2285 # Fail on bad curgroup argument. There's no sane fallback on this one. 2286 if (!$args{curgroup} || $args{curgroup} !~ /^\d+$/) { 2287 $errstr = "Bad or missing curgroup argument"; 2288 return; 2289 } 2290 # Fail on bad childlist argument. This could be sanely ignored if bad, maybe. 2291 if ($args{childlist} && $args{childlist} !~ /^[\d,]+$/) { 2292 $errstr = "Bad childlist argument"; 2293 return; 2294 } 2252 2295 2253 2296 my @filterargs; … … 2277 2320 # A common tail. 2278 2321 $sql .= " ORDER BY ".($args{sortby} eq 'group' ? 'groups.group_name' : $args{sortby})." $args{sortorder} ". 2279 ($args{offset} eq 'all' ? '' : " LIMIT $ config{perpage}".2280 " OFFSET ".$args{offset}*$ config{perpage});2322 ($args{offset} eq 'all' ? '' : " LIMIT $self->{perpage}". 2323 " OFFSET ".$args{offset}*$self->{perpage}); 2281 2324 my $sth = $dbh->prepare($sql); 2282 2325 $sth->execute(@filterargs); … … 2404 2447 my $msg = $@; 2405 2448 eval { $dbh->rollback; }; 2406 if ($ config{log_failures}) {2449 if ($self->{log_failures}) { 2407 2450 $self->_log(group_id => $pargroup, entry => "Failed to add group $groupname: $msg"); 2408 2451 $dbh->commit; … … 2448 2491 my ($domcnt) = $dbh->selectrow_array("SELECT count(*) FROM domains WHERE group_id=?", undef, ($groupid)); 2449 2492 die "$domcnt domains still in group\n" if $domcnt; 2493 my ($revcnt) = $dbh->selectrow_array("SELECT count(*) FROM revzones WHERE group_id=?", undef, ($groupid)); 2494 die "$revcnt reverse zones still in group\n" if $revcnt; 2450 2495 my ($usercnt) = $dbh->selectrow_array("SELECT count(*) FROM users WHERE group_id=?", undef, ($groupid)); 2451 2496 die "$usercnt users still in group\n" if $usercnt; … … 2468 2513 my $msg = $@; 2469 2514 eval { $dbh->rollback; }; 2470 if ($ config{log_failures}) {2515 if ($self->{log_failures}) { 2471 2516 $self->_log(group_id => $parid, entry => "$failmsg: $msg"); 2472 2517 $dbh->commit; # since we enabled transactions earlier … … 2545 2590 my %args = @_; 2546 2591 2592 # Fail on bad curgroup argument. There's no sane fallback on this one. 2593 if (!$args{curgroup} || $args{curgroup} !~ /^\d+$/) { 2594 $errstr = "Bad or missing curgroup argument"; 2595 return; 2596 } 2597 # Fail on bad childlist argument. This could be sanely ignored if bad, maybe. 2598 if ($args{childlist} && $args{childlist} !~ /^[\d,]+$/) { 2599 $errstr = "Bad childlist argument"; 2600 return; 2601 } 2602 2547 2603 my @filterargs; 2548 2549 2604 $args{startwith} = undef if $args{startwith} && $args{startwith} !~ /^(?:[a-z]|0-9)$/; 2550 2605 push @filterargs, "^$args{startwith}" if $args{startwith}; … … 2571 2626 my %args = @_; 2572 2627 2628 # Fail on bad curgroup argument. There's no sane fallback on this one. 2629 if (!$args{curgroup} || $args{curgroup} !~ /^\d+$/) { 2630 $errstr = "Bad or missing curgroup argument"; 2631 return; 2632 } 2633 # Fail on bad childlist argument. This could be sanely ignored if bad, maybe. 2634 if ($args{childlist} && $args{childlist} !~ /^[\d,]+$/) { 2635 $errstr = "Bad childlist argument"; 2636 return; 2637 } 2638 2573 2639 my @filterargs; 2574 2575 2640 $args{startwith} = undef if $args{startwith} && $args{startwith} !~ /^(?:[a-z]|0-9)$/; 2576 2641 push @filterargs, "^$args{startwith}" if $args{startwith}; … … 2578 2643 2579 2644 # protection against bad or missing arguments 2580 $args{sortorder} = 'ASC' if !$args{sortorder}; 2645 $args{sortorder} = 'ASC' if !$args{sortorder} || !grep /^$args{sortorder}$/, ('ASC','DESC'); 2646 $args{sortby} = 'group' if !$args{sortby} || $args{sortby} !~ /^[\w_.]+$/; 2581 2647 $args{offset} = 0 if !$args{offset} || $args{offset} !~ /^(?:all|\d+)$/; 2582 2648 … … 2594 2660 " GROUP BY g.group_id, g.group_name, g2.group_name ". 2595 2661 " ORDER BY $args{sortby} $args{sortorder} ". 2596 ($args{offset} eq 'all' ? '' : " LIMIT $ config{perpage} OFFSET ".$args{offset}*$config{perpage});2662 ($args{offset} eq 'all' ? '' : " LIMIT $self->{perpage} OFFSET ".$args{offset}*$self->{perpage}); 2597 2663 my $glist = $dbh->selectall_arrayref($sql, { Slice => {} }, (@filterargs) ); 2598 2664 $errstr = $dbh->errstr if !$glist; … … 2749 2815 my $msg = $@; 2750 2816 eval { $dbh->rollback; }; 2751 if ($ config{log_failures}) {2817 if ($self->{log_failures}) { 2752 2818 $self->_log(group_id => $group, entry => "Error adding user $username: $msg"); 2753 2819 $dbh->commit; # since we enabled transactions earlier … … 2772 2838 my %args = @_; 2773 2839 2840 # Fail on bad curgroup argument. There's no sane fallback on this one. 2841 if (!$args{curgroup} || $args{curgroup} !~ /^\d+$/) { 2842 $errstr = "Bad or missing curgroup argument"; 2843 return; 2844 } 2845 # Fail on bad childlist argument. This could be sanely ignored if bad, maybe. 2846 if ($args{childlist} && $args{childlist} !~ /^[\d,]+$/) { 2847 $errstr = "Bad childlist argument"; 2848 return; 2849 } 2850 2774 2851 my @filterargs; 2775 2776 2852 $args{startwith} = undef if $args{startwith} && $args{startwith} !~ /^(?:[a-z]|0-9)$/; 2777 2853 push @filterargs, "^$args{startwith}" if $args{startwith}; 2778 2854 push @filterargs, $args{filter} if $args{filter}; 2779 2780 2855 2781 2856 my $sql = "SELECT count(*) FROM users ". … … 2801 2876 my %args = @_; 2802 2877 2878 # Fail on bad curgroup argument. There's no sane fallback on this one. 2879 if (!$args{curgroup} || $args{curgroup} !~ /^\d+$/) { 2880 $errstr = "Bad or missing curgroup argument"; 2881 return; 2882 } 2883 # Fail on bad childlist argument. This could be sanely ignored if bad, maybe. 2884 if ($args{childlist} && $args{childlist} !~ /^[\d,]+$/) { 2885 $errstr = "Bad childlist argument"; 2886 return; 2887 } 2888 2803 2889 my @filterargs; 2804 2805 2890 $args{startwith} = undef if $args{startwith} && $args{startwith} !~ /^(?:[a-z]|0-9)$/; 2806 2891 push @filterargs, "^$args{startwith}" if $args{startwith}; … … 2813 2898 2814 2899 # protection against bad or missing arguments 2815 $args{sortorder} = 'ASC' if !$args{sortorder} ;2816 $args{sortby} = 'u.username' if !$args{sortby} ;2900 $args{sortorder} = 'ASC' if !$args{sortorder} || !grep /^$args{sortorder}$/, ('ASC','DESC'); 2901 $args{sortby} = 'u.username' if !$args{sortby} || $args{sortby} !~ /^[\w_.]+$/; 2817 2902 $args{offset} = 0 if !$args{offset} || $args{offset} !~ /^(?:all|\d+)$/; 2818 2903 … … 2825 2910 " AND NOT u.type = 'R' ". 2826 2911 " ORDER BY $args{sortby} $args{sortorder} ". 2827 ($args{offset} eq 'all' ? '' : " LIMIT $ config{perpage} OFFSET ".$args{offset}*$config{perpage});2912 ($args{offset} eq 'all' ? '' : " LIMIT $self->{perpage} OFFSET ".$args{offset}*$self->{perpage}); 2828 2913 my $ulist = $dbh->selectall_arrayref($sql, { Slice => {} }, (@filterargs) ); 2829 2914 $errstr = $dbh->errstr if !$ulist; … … 2908 2993 my $msg = $@; 2909 2994 eval { $dbh->rollback; }; 2910 if ($ config{log_failures}) {2995 if ($self->{log_failures}) { 2911 2996 $self->_log(group_id => $group, entry => "Error updating user $username: $msg"); 2912 2997 $dbh->commit; # since we enabled transactions earlier … … 2947 3032 my $msg = $@; 2948 3033 eval { $dbh->rollback; }; 2949 if ($ config{log_failures}) {3034 if ($self->{log_failures}) { 2950 3035 $self->_log(group_id => $userdata->{group_id}, entry => "Error deleting user ID ". 2951 3036 "$userid/".$userdata->{username}.": $msg"); … … 3120 3205 my $msg = $@; 3121 3206 eval { $dbh->rollback; }; 3122 if ($ config{log_failures}) {3207 if ($self->{log_failures}) { 3123 3208 $shdesc = $loc if !$shdesc; 3124 3209 $self->_log(entry => "Failed adding location ($shdesc, '$iplist'): $msg"); … … 3167 3252 my $msg = $@; 3168 3253 eval { $dbh->rollback; }; 3169 if ($ config{log_failures}) {3254 if ($self->{log_failures}) { 3170 3255 $shdesc = $loc if !$shdesc; 3171 3256 $self->_log(entry => "Failed updating location ($shdesc, '$iplist'): $msg"); … … 3206 3291 my $msg = $@; 3207 3292 eval { $dbh->rollback; }; 3208 if ($ config{log_failures}) {3293 if ($self->{log_failures}) { 3209 3294 $self->_log(entry => "Failed to delete location ($olddesc, '$oldloc->{iplist}'): $msg"); 3210 3295 $dbh->commit; … … 3244 3329 my %args = @_; 3245 3330 3331 # Fail on bad curgroup argument. There's no sane fallback on this one. 3332 if (!$args{curgroup} || $args{curgroup} !~ /^\d+$/) { 3333 $errstr = "Bad or missing curgroup argument"; 3334 return; 3335 } 3336 # Fail on bad childlist argument. This could be sanely ignored if bad, maybe. 3337 if ($args{childlist} && $args{childlist} !~ /^[\d,]+$/) { 3338 $errstr = "Bad childlist argument"; 3339 return; 3340 } 3341 3246 3342 my @filterargs; 3247 3248 3343 $args{startwith} = undef if $args{startwith} && $args{startwith} !~ /^(?:[a-z]|0-9)$/; 3249 3344 push @filterargs, "^$args{startwith}" if $args{startwith}; 3250 3345 push @filterargs, $args{filter} if $args{filter}; 3251 3252 3346 3253 3347 my $sql = "SELECT count(*) FROM locations ". … … 3268 3362 my %args = @_; 3269 3363 3364 # Fail on bad curgroup argument. There's no sane fallback on this one. 3365 if (!$args{curgroup} || $args{curgroup} !~ /^\d+$/) { 3366 $errstr = "Bad or missing curgroup argument"; 3367 return; 3368 } 3369 # Fail on bad childlist argument. This could be sanely ignored if bad, maybe. 3370 if ($args{childlist} && $args{childlist} !~ /^[\d,]+$/) { 3371 $errstr = "Bad childlist argument"; 3372 return; 3373 } 3374 3270 3375 my @filterargs; 3271 3272 3376 $args{startwith} = undef if $args{startwith} && $args{startwith} !~ /^(?:[a-z]|0-9)$/; 3273 3377 push @filterargs, "^$args{startwith}" if $args{startwith}; … … 3280 3384 3281 3385 # protection against bad or missing arguments 3282 $args{sortorder} = 'ASC' if !$args{sortorder} ;3283 $args{sortby} = 'l.description' if !$args{sortby} ;3386 $args{sortorder} = 'ASC' if !$args{sortorder} || !grep /^$args{sortorder}$/, ('ASC','DESC'); 3387 $args{sortby} = 'l.description' if !$args{sortby} || $args{sortby} !~ /^[\w_.]+$/; 3284 3388 $args{offset} = 0 if !$args{offset} || $args{offset} !~ /^(?:all|\d+)$/; 3285 3389 … … 3291 3395 ($args{filter} ? " AND l.description ~* ?" : ''). 3292 3396 " ORDER BY $args{sortby} $args{sortorder} ". 3293 ($args{offset} eq 'all' ? '' : " LIMIT $ config{perpage} OFFSET ".$args{offset}*$config{perpage});3397 ($args{offset} eq 'all' ? '' : " LIMIT $self->{perpage} OFFSET ".$args{offset}*$self->{perpage}); 3294 3398 my $ulist = $dbh->selectall_arrayref($sql, { Slice => {} }, (@filterargs) ); 3295 3399 $errstr = $dbh->errstr if !$ulist; … … 3411 3515 $logdata{entry} = "Error updating ".($defrec eq 'y' ? ($revrec eq 'y' ? 'default reverse zone ' : 'default ') : ''). 3412 3516 "SOA record for $parname: $msg"; 3413 if ($ config{log_failures}) {3517 if ($self->{log_failures}) { 3414 3518 $self->_log(%logdata); 3415 3519 $dbh->commit; … … 3433 3537 my $id = shift; 3434 3538 3539 ##fixme: do we need a knob to twist to switch between unix epoch and postgres time string? 3435 3540 my $sql = "SELECT record_id,host,type,val,ttl". 3436 3541 ($defrec eq 'n' ? ',location' : ''). 3437 3542 ($revrec eq 'n' ? ',distance,weight,port' : ''). 3438 (($defrec eq 'y') ? ',group_id FROM ' : ',domain_id,rdns_id FROM ').3543 (($defrec eq 'y') ? ',group_id FROM ' : ',domain_id,rdns_id,stamp,stamp < now() AS ispast,expires,stampactive FROM '). 3439 3544 _rectable($defrec,$revrec)." WHERE record_id=?"; 3440 3545 my $ret = $dbh->selectrow_hashref($sql, undef, ($id) ); … … 3465 3570 3466 3571 ##fixme: should use above (getRecLine()) to get lines for below? 3467 ## DNSDB::get DomRecs()3468 # Return records for a domain3469 # Takes a d atabase handle, default/live flag, group/domainID, start,3572 ## DNSDB::getRecList() 3573 # Return records for a group or zone 3574 # Takes a default/live flag, group or zone ID, start, 3470 3575 # number of records, sort field, and sort order 3471 3576 # Returns a reference to an array of hashes 3472 sub get DomRecs{3577 sub getRecList { 3473 3578 $errstr = ''; 3474 3579 my $self = shift; … … 3482 3587 3483 3588 # protection against bad or missing arguments 3484 $args{sortorder} = 'ASC' if !$args{sortorder}; 3485 $args{sortby} = 'host' if !$args{sortby} && $args{revrec} eq 'n'; # default sort by host on domain record list 3486 $args{sortby} = 'val' if !$args{sortby} && $args{revrec} eq 'y'; # default sort by IP on revzone record list 3589 $args{sortorder} = 'ASC' if !$args{sortorder} || !grep /^$args{sortorder}$/, ('ASC','DESC'); 3590 my $defsort; 3591 $defsort = 'host' if $args{revrec} eq 'n'; # default sort by host on domain record list 3592 $defsort = 'val' if $args{revrec} eq 'y'; # default sort by IP on revzone record list 3593 $args{sortby} = '' if !$args{sortby}; 3594 $args{sortby} = $defsort if !$args{revrec}; 3595 $args{sortby} = $defsort if $args{sortby} !~ /^[\w_,.]+$/; 3487 3596 $args{offset} = 0 if !$args{offset} || $args{offset} !~ /^(?:all|\d+)$/; 3597 my $perpage = ($args{nrecs} ? $args{nrecs} : $self->{perpage}); 3488 3598 3489 3599 # sort reverse zones on IP, correctly … … 3508 3618 $newsort =~ s/^,//; 3509 3619 3620 ##fixme: do we need a knob to twist to switch from unix epoch to postgres time string? 3621 my $sql = "SELECT r.record_id,r.host,r.type,r.val,r.ttl"; 3622 $sql .= ",l.description AS locname,stamp,r.stamp < now() AS ispast,r.expires,r.stampactive" 3623 if $args{defrec} eq 'n'; 3624 $sql .= ",r.distance,r.weight,r.port" if $args{revrec} eq 'n'; 3625 $sql .= " FROM "._rectable($args{defrec},$args{revrec})." r "; 3510 3626 $sql .= "INNER JOIN rectypes t ON r.type=t.val "; # for sorting by type alphabetically 3511 3627 $sql .= "LEFT JOIN locations l ON r.location=l.location " if $args{defrec} eq 'n'; … … 3516 3632 # ensure consistent ordering by sorting on record_id too 3517 3633 $sql .= ", record_id $args{sortorder}"; 3518 $sql .= ($args{offset} eq 'all' ? '' : " LIMIT $ config{perpage} OFFSET ".$args{offset}*$config{perpage});3634 $sql .= ($args{offset} eq 'all' ? '' : " LIMIT $perpage OFFSET ".$args{offset}*$perpage); 3519 3635 3520 3636 my @bindvars = ($args{id}); … … 3522 3638 3523 3639 my $ret = $dbh->selectall_arrayref($sql, { Slice => {} }, (@bindvars) ); 3640 $errstr = "Error retrieving records: ".$dbh->errstr if !$ret; 3641 3524 3642 return $ret; 3525 } # end get DomRecs()3643 } # end getRecList() 3526 3644 3527 3645 … … 3581 3699 $location = '' if !$location; 3582 3700 3701 my $expires = shift; 3702 $expires = 1 if $expires eq 'until'; # Turn some special values into the appropriate booleans. 3703 $expires = 0 if $expires eq 'after'; 3704 my $stamp = shift; 3705 $stamp = '' if !$stamp; # Timestamp should be a string at this point. 3706 3583 3707 # Spaces are evil. 3584 3708 $host =~ s/^\s+//; … … 3590 3714 } 3591 3715 3592 # Validation 3593 my $addr = NetAddr::IP->new($val); 3594 if ($rectype == $reverse_typemap{A}) { 3595 return ('FAIL',$typemap{$rectype}." record must be a valid IPv4 address") 3596 unless $addr && !$addr->{isv6}; 3597 } 3598 if ($rectype == $reverse_typemap{AAAA}) { 3599 return ('FAIL',$typemap{$rectype}." record must be a valid IPv6 address") 3600 unless $addr && $addr->{isv6}; 3601 } 3716 if ($self->{lowercase}) { 3717 if ($typemap{$$rectype} ne 'TXT') { 3718 $$host = lc($$host); 3719 $$val = lc($$val); 3720 } else { 3721 # TXT records should preserve user entry in the string. 3722 if ($revrec eq 'n') { 3723 $$host = lc($$host); 3724 } else { 3725 $$val = lc($$val); 3726 } 3727 } 3728 } 3729 3730 # prep for validation 3731 my $addr = NetAddr::IP->new($$val); 3732 $$host =~ s/\.+$//; # FQDNs ending in . are an internal detail, and really shouldn't be exposed in the UI. 3602 3733 3603 3734 my $domid = 0; … … 3610 3741 return ('FAIL', "TTL must be numeric") unless $ttl =~ /^\d+$/; 3611 3742 3612 # Quick check on hostname parts. Note the regex is more forgiving than the error message; 3613 # domain names technically are case-insensitive, and we use printf-like % codes for a couple 3614 # of types. Other things may also be added to validate default records of several flavours. 3615 return ('FAIL', "Hostnames may not contain anything other than (0-9 a-z . _)") 3616 if $defrec eq 'n' && ($revrec eq 'y' ? $$rectype != $reverse_typemap{TXT} : 1) && 3617 $$host !~ /^[0-9a-z_%.-]+$/i; 3743 # Quick check on hostname parts. There are enough variations to justify a sub now. 3744 return ('FAIL', $errstr) if ! _check_hostname_form($$host, $$rectype, $defrec, $revrec); 3618 3745 3619 3746 # Collect these even if we're only doing a simple A record so we can call *any* validation sub … … 3637 3764 push @vallist, ($$host,$$rectype,$$val,$ttl,$id); 3638 3765 3639 # locations are not for default records, silly coder!3640 3766 if ($defrec eq 'n') { 3767 # locations are not for default records, silly coder! 3641 3768 $fields .= ",location"; 3642 3769 push @vallist, $location; 3643 } 3770 # timestamps are rare. 3771 if ($stamp) { 3772 $fields .= ",stamp,expires,stampactive"; 3773 push @vallist, $stamp, $expires, 'y'; 3774 } else { 3775 $fields .= ",stampactive"; 3776 push @vallist, 'n'; 3777 } 3778 } 3779 3780 # a little magic to get the right number of ? placeholders based on how many values we're providing 3644 3781 my $vallen = '?'.(',?'x$#vallist); 3645 3782 … … 3669 3806 $logdata{entry} .= "', TTL $ttl"; 3670 3807 $logdata{entry} .= ", location ".$self->getLoc($location)->{description} if $location; 3808 $logdata{entry} .= ($expires eq 'after' ? ', valid after ' : ', expires at ').$stamp if $stamp; 3671 3809 3672 3810 # Allow transactions, and raise an exception on errors so we can catch it later. … … 3684 3822 my $msg = $@; 3685 3823 eval { $dbh->rollback; }; 3686 if ($ config{log_failures}) {3824 if ($self->{log_failures}) { 3687 3825 $logdata{entry} = "Failed adding ".($defrec eq 'y' ? 'default ' : ''). 3688 3826 "record '$$host $typemap{$$rectype} $$val', TTL $ttl ($msg)"; … … 3722 3860 $location = '' if !$location; 3723 3861 3724 # prep for validation 3725 my $addr = NetAddr::IP->new($$val); 3726 $$host =~ s/\.+$//; # FQDNs ending in . are an internal detail, and really shouldn't be exposed in the UI. 3862 my $expires = shift; 3863 $expires = 1 if $expires eq 'until'; # Turn some special values into the appropriate booleans. 3864 $expires = 0 if $expires eq 'after'; 3865 my $stamp = shift; 3866 $stamp = '' if !$stamp; # Timestamp should be a string at this point. 3867 3868 # just set it to an empty string; failures will be caught later. 3869 $$host = '' if !$$host; 3727 3870 3728 3871 # Spaces are evil. … … 3735 3878 } 3736 3879 3880 if ($self->{lowercase}) { 3881 if ($typemap{$$rectype} ne 'TXT') { 3882 $$host = lc($$host); 3883 $$val = lc($$val); 3884 } else { 3885 # TXT records should preserve user entry in the string. 3886 if ($revrec eq 'n') { 3887 $$host = lc($$host); 3888 } else { 3889 $$val = lc($$val); 3890 } 3891 } 3892 } 3893 3894 # prep for validation 3895 my $addr = NetAddr::IP->new($$val); 3896 $$host =~ s/\.+$//; # FQDNs ending in . are an internal detail, and really shouldn't be exposed in the UI. 3897 3737 3898 my $domid = 0; 3738 3899 my $revid = 0; … … 3744 3905 return ('FAIL', "TTL must be numeric") unless $ttl =~ /^\d+$/; 3745 3906 3746 # Quick check on hostname parts. Note the regex is more forgiving than the error message; 3747 # domain names technically are case-insensitive, and we use printf-like % codes for a couple 3748 # of types. Other things may also be added to validate default records of several flavours. 3749 return ('FAIL', "Hostnames may not contain anything other than (0-9 a-z - . _)") 3750 if $defrec eq 'n' && ($revrec eq 'y' ? $$rectype != $reverse_typemap{TXT} : 1) && 3751 $$host !~ /^[0-9a-z_%.-]+$/i; 3907 # Quick check on hostname parts. There are enough variations to justify a sub now. 3908 return ('FAIL', $errstr) if ! _check_hostname_form($$host, $$rectype, $defrec, $revrec); 3752 3909 3753 3910 # only MX and SRV will use these … … 3780 3937 ($defrec eq 'y' ? $oldrec->{group_id} : ($revrec eq 'n' ? $oldrec->{domain_id} : $oldrec->{rdns_id})) ); 3781 3938 3782 # locations are not for default records, silly coder!3783 3939 if ($defrec eq 'n') { 3940 # locations are not for default records, silly coder! 3784 3941 $fields .= ",location"; 3785 3942 push @vallist, $location; 3943 # timestamps are rare. 3944 if ($stamp) { 3945 $fields .= ",stamp,expires,stampactive"; 3946 push @vallist, $stamp, $expires, 'y'; 3947 } else { 3948 $fields .= ",stampactive"; 3949 push @vallist, 'n'; 3950 } 3786 3951 } 3787 3952 … … 3837 4002 $logdata{entry} .= "', TTL $oldrec->{ttl}"; 3838 4003 $logdata{entry} .= ", location ".$self->getLoc($oldrec->{location})->{description} if $oldrec->{location}; 4004 $logdata{entry} .= ($oldrec->{expires} ? ', expires at ' : ', valid after ').$oldrec->{stamp} 4005 if $oldrec->{stampactive}; 3839 4006 $logdata{entry} .= "\nto\n"; 3840 4007 # More NS special … … 3848 4015 $logdata{entry} .= "', TTL $ttl"; 3849 4016 $logdata{entry} .= ", location ".$self->getLoc($location)->{description} if $location; 4017 $logdata{entry} .= ($expires eq 'after' ? ', valid after ' : ', expires at ').$stamp if $stamp; 3850 4018 3851 4019 local $dbh->{AutoCommit} = 0; … … 3864 4032 my $msg = $@; 3865 4033 eval { $dbh->rollback; }; 3866 if ($ config{log_failures}) {4034 if ($self->{log_failures}) { 3867 4035 $logdata{entry} = "Failed updating ".($defrec eq 'y' ? 'default ' : ''). 3868 4036 "record '$oldrec->{host} $typemap{$oldrec->{type}} $oldrec->{val}', TTL $oldrec->{ttl} ($msg)"; … … 3975 4143 my $msg = $@; 3976 4144 eval { $dbh->rollback; }; 3977 if ($ config{log_failures}) {4145 if ($self->{log_failures}) { 3978 4146 $logdata{entry} = "Error deleting ".($defrec eq 'y' ? 'default record' : 'record'). 3979 4147 " '$oldrec->{host} $typemap{$oldrec->{type}} $oldrec->{val}', TTL $oldrec->{ttl} ($msg)"; … … 4011 4179 $args{logtype} = 'domain' if $args{logtype} eq 'dom'; # hack pthui 4012 4180 return if !grep /^$args{logtype}$/, ('group', 'domain', 'revzone', 'user'); 4013 4014 $args{logtype} = 'revzone' if $args{logtype} eq 'rdns'; # hack pthui4015 4181 4016 4182 my $sql = "SELECT count(*) FROM log ". … … 4047 4213 4048 4214 # Sorting defaults 4049 $args{sort by} = 'stamp' if !$args{sortby};4050 $args{sort order} = 'DESC' if !$args{sortorder};4215 $args{sortorder} = 'DESC' if !$args{sortorder} || !grep /^$args{sortorder}$/, ('ASC','DESC'); 4216 $args{sortby} = 'stamp' if !$args{sortby} || $args{sortby} !~ /^[\w_.]+$/; 4051 4217 $args{offset} = 0 if !$args{offset} || $args{offset} !~ /^(?:all|\d+)$/; 4052 4218 … … 4060 4226 ($args{filter} ? " AND entry ~* ?" : ''). 4061 4227 " ORDER BY $args{sortby} $args{sortorder}, log_id $args{sortorder}". 4062 ($args{offset} eq 'all' ? '' : " LIMIT $ config{perpage} OFFSET ".$args{offset}*$config{perpage});4228 ($args{offset} eq 'all' ? '' : " LIMIT $self->{perpage} OFFSET ".$args{offset}*$self->{perpage}); 4063 4229 my $loglist = $dbh->selectall_arrayref($sql, { Slice => {} }, ($args{id}, @filterargs) ); 4064 4230 $errstr = $dbh->errstr if !$loglist; … … 4111 4277 # default; forward zone types. technically $type eq 'f' but not worth the error message. 4112 4278 $sql .= "stdflag=1 OR stdflag=2"; 4279 $sql .= " AND val < 65280" if $recgroup eq 'fo'; # An extra flag to trim off the pseudotypes as well. 4113 4280 } 4114 4281 $sql .= " ORDER BY listorder"; … … 4243 4410 $limiter++; 4244 4411 ##fixme: how often will this happen on a live site? fail at max limiter <n>? 4412 # 2013/10/22 only seems to happen when you request an entity that doesn't exist. 4245 4413 warn "no results looking for $sql with id $id (depth $limiter)\n"; 4246 4414 last; … … 4841 5009 my %recflags; 4842 5010 4843 my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1");4844 my $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ".4845 "FROM records WHERE domain_id=? AND type < 65280"); # Just exclude all types relating to rDNS4846 my $zonesth = $dbh->prepare("UPDATE domains SET changed='n' WHERE domain_id=?");4847 $domsth->execute();4848 while (my ($domid,$dom,$domstat,$changed) = $domsth->fetchrow_array) {4849 ##fixme: need to find a way to block opening symlinked files without introducing a race.4850 # O_NOFOLLOW4851 # If pathname is a symbolic link, then the open fails. This is a FreeBSD extension, which was4852 # added to Linux in version 2.1.126. Symbolic links in earlier components of the pathname will4853 # still be followed.4854 # but that doesn't help other platforms. :/4855 sysopen(ZONECACHE, "$config{exportcache}/$dom", O_RDWR|O_CREAT);4856 flock(ZONECACHE, LOCK_EX);4857 if ($changed || -s "$config{exportcache}/$dom" == 0) {4858 $recsth->execute($domid);4859 while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc) = $recsth->fetchrow_array) {4860 next if $recflags{$recid};4861 4862 $loc = '' if !$loc; # de-nullify - just in case4863 ##fixme: handle case of record-with-location-that-doesn't-exist better.4864 # note this currently fails safe (tested) - records with a location that4865 # doesn't exist will not be sent to any client4866 # $loc = '' if !$lochash->{$loc};4867 4868 ##fixme: record validity timestamp. tinydns supports fiddling with timestamps.4869 # note $ttl must be set to 0 if we want to use tinydns's auto-expiring timestamps.4870 # timestamps are TAI644871 # ~~ 2^62 + time()4872 my $stamp = '';4873 4874 # support tinydns' auto-TTL4875 $ttl = '' if $ttl == '0';4876 4877 # Spaces are evil.4878 $host =~ s/^\s+//;4879 $host =~ s/\s+$//;4880 if ($typemap{$type} ne 'TXT') {4881 # Leading or trailng spaces could be legit in TXT records.4882 $val =~ s/^\s+//;4883 $val =~ s/\s+$//;4884 }4885 4886 _printrec_tiny(*ZONECACHE, 'n', \%recflags,4887 $dom, $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp)4888 if *ZONECACHE;4889 4890 # in case the zone shrunk, get rid of garbage at the end of the file.4891 truncate(ZONECACHE, tell(ZONECACHE));4892 4893 $recflags{$recid} = 1;4894 } # while ($recsth)4895 }4896 # stream from cache, whether freshly created or existing4897 print $datafile $_ while <ZONECACHE>;4898 close ZONECACHE;4899 # mark domain as unmodified4900 $zonesth->execute($domid);4901 } # while ($domsth)4902 4903 my $revsth = $dbh->prepare("SELECT rdns_id,revnet,status,changed FROM revzones WHERE status=1 ".4904 "ORDER BY masklen(revnet) DESC");4905 4906 5011 # For reasons unknown, we can't sanely UNION these statements. Feh. 4907 5012 # Supposedly it should work though (note last 3 lines): … … 4918 5023 my $soasth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location ". 4919 5024 "FROM records WHERE rdns_id=? AND type=6"); 4920 $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location".5025 my $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location,extract(epoch from stamp),expires,stampactive ". 4921 5026 "FROM records WHERE rdns_id=? AND not type=6 ". 4922 5027 "ORDER BY masklen(CAST(val AS inet)) DESC, CAST(val AS inet)"); 4923 $zonesth = $dbh->prepare("UPDATE revzones SET changed='n' WHERE rdns_id=?"); 5028 my $revsth = $dbh->prepare("SELECT rdns_id,revnet,status,changed FROM revzones WHERE status=1 ". 5029 "ORDER BY masklen(revnet) DESC"); 5030 my $zonesth = $dbh->prepare("UPDATE revzones SET changed='n' WHERE rdns_id=?"); 4924 5031 $revsth->execute(); 4925 5032 while (my ($revid,$revzone,$revstat,$changed) = $revsth->fetchrow_array) { … … 4931 5038 # but that doesn't help other platforms. :/ 4932 5039 my $tmpzone = NetAddr::IP->new($revzone); 4933 sysopen(ZONECACHE, "$config{exportcache}/".$tmpzone->network->addr, O_RDWR|O_CREAT); 4934 flock(ZONECACHE, LOCK_EX); 4935 if ($changed || -s "$config{exportcache}/".$tmpzone->network->addr == 0) { 4936 # need to fetch this separately since the rest of the records all (should) have real IPs in val 4937 $soasth->execute($revid); 4938 my (@zsoa) = $soasth->fetchrow_array(); 4939 _printrec_tiny(*ZONECACHE,'y',\%recflags,$revzone, 4940 $zsoa[0],$zsoa[1],$zsoa[2],$zsoa[3],$zsoa[4],$zsoa[5],$zsoa[6],$zsoa[8],''); 4941 4942 $recsth->execute($revid); 4943 while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc) = $recsth->fetchrow_array) { 4944 next if $recflags{$recid}; 4945 4946 $loc = '' if !$loc; # de-nullify - just in case 5040 ##fixme: locations/views? subnet mask? need to avoid possible collisions with zone/superzone 5041 ## (eg /20 vs /24, starting on .0.0) 5042 my $cz = $tmpzone->network->addr."-".$tmpzone->masklen; 5043 my $cachefile = "$self->{exportcache}/$cz"; 5044 my $tmpcache = "$self->{exportcache}/tmp.$cz.$$"; 5045 eval { 5046 5047 # only update the cache file if the zone has changed, or if the cache file has nothing in it. 5048 if ($self->{force_refresh} || $changed || !-e $cachefile || -z $cachefile) { 5049 open ZONECACHE, ">$tmpcache" or die "Error creating temporary file $tmpcache: $!\n"; 5050 5051 # need to fetch this separately since the rest of the records all (should) have real IPs in val 5052 $soasth->execute($revid); 5053 my (@zsoa) = $soasth->fetchrow_array(); 5054 _printrec_tiny(*ZONECACHE,'y',\%recflags,$revzone, 5055 $zsoa[0],$zsoa[1],$zsoa[2],$zsoa[3],$zsoa[4],$zsoa[5],$zsoa[6],$zsoa[8],''); 5056 5057 $recsth->execute($revid); 5058 while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc,$stamp,$expires,$stampactive) = $recsth->fetchrow_array) { 5059 next if $recflags{$recid}; 5060 5061 # not sure this is necessary for revzones. 5062 # # Spaces are evil. 5063 # $val =~ s/^\s+//; 5064 # $val =~ s/\s+$//; 5065 # if ($typemap{$type} ne 'TXT') { 5066 # # Leading or trailng spaces could be legit in TXT records. 5067 # $host =~ s/^\s+//; 5068 # $host =~ s/\s+$//; 5069 # } 5070 5071 _printrec_tiny(*ZONECACHE, 'y', \%recflags, $revzone, 5072 $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp, $expires, $stampactive) 5073 if *ZONECACHE; 5074 5075 $recflags{$recid} = 1; 5076 5077 } # while ($recsth) 5078 5079 close ZONECACHE; # force the file to be written 5080 5081 # catch obvious write errors that leave an empty temp file 5082 if (-s $tmpcache) { 5083 rename $tmpcache, $cachefile 5084 or die "Error overwriting cache file $cachefile with temporary file: $!\n"; 5085 } 5086 5087 } # if $changed or cache filesize is 0 5088 5089 }; 5090 if ($@) { 5091 print "error writing new data for $revzone: $@\n"; 5092 # error! something borked, and we should be able to fall back on the old cache file 5093 # report the error, somehow. 5094 } else { 5095 # mark zone as unmodified. Only do this if no errors, that way 5096 # export failures should recover a little more automatically. 5097 $zonesth->execute($revid); 5098 } 5099 # Always stream the cache (even if stale or obsolete due to errors creating the new cache) 5100 open CACHE, "<$cachefile"; 5101 print $datafile $_ while <CACHE>; 5102 close CACHE; 5103 5104 } # while ($revsth) 5105 5106 my $domsth = $dbh->prepare("SELECT domain_id,domain,status,changed FROM domains WHERE status=1"); 5107 $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id,location,extract(epoch from stamp),expires,stampactive ". 5108 "FROM records WHERE domain_id=?"); # Just exclude all types relating to rDNS 5109 # "FROM records WHERE domain_id=? AND type < 65280"); # Just exclude all types relating to rDNS 5110 $zonesth = $dbh->prepare("UPDATE domains SET changed='n' WHERE domain_id=?"); 5111 $domsth->execute(); 5112 while (my ($domid,$dom,$domstat,$changed) = $domsth->fetchrow_array) { 5113 ##fixme: need to find a way to block opening symlinked files without introducing a race. 5114 # O_NOFOLLOW 5115 # If pathname is a symbolic link, then the open fails. This is a FreeBSD extension, which was 5116 # added to Linux in version 2.1.126. Symbolic links in earlier components of the pathname will 5117 # still be followed. 5118 # but that doesn't help other platforms. :/ 5119 my $cachefile = "$self->{exportcache}/$dom"; 5120 my $tmpcache = "$self->{exportcache}/tmp.$dom.$$"; 5121 eval { 5122 5123 # only update the cache file if the zone has changed, or if the cache file has nothing in it. 5124 if ($self->{force_refresh} || $changed || !-e $cachefile || -z $cachefile) { 5125 open ZONECACHE, ">$tmpcache" or die "Error creating temporary file $tmpcache: $!\n"; 5126 5127 $recsth->execute($domid); 5128 while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid,$loc,$stamp,$expires,$stampactive) = $recsth->fetchrow_array) { 5129 next if $recflags{$recid}; 5130 5131 # Spaces are evil. 5132 $host =~ s/^\s+//; 5133 $host =~ s/\s+$//; 5134 if ($typemap{$type} ne 'TXT') { 5135 # Leading or trailng spaces could be legit in TXT records. 5136 $val =~ s/^\s+//; 5137 $val =~ s/\s+$//; 5138 } 5139 5140 _printrec_tiny(*ZONECACHE, 'n', \%recflags, 5141 $dom, $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp, $expires, $stampactive) 5142 if *ZONECACHE; 5143 5144 $recflags{$recid} = 1; 5145 5146 } # while ($recsth) 5147 5148 close ZONECACHE; # force the file to be written 5149 5150 # catch obvious write errors that leave an empty temp file 5151 if (-s $tmpcache) { 5152 rename $tmpcache, $cachefile 5153 or die "Error overwriting cache file $cachefile with temporary file: $!\n"; 5154 } 5155 5156 } # if $changed or cache filesize is 0 5157 5158 }; 5159 if ($@) { 5160 print "error writing new data for $dom: $@\n"; 5161 # error! something borked, and we should be able to fall back on the old cache file 5162 # report the error, somehow. 5163 } else { 5164 # mark domain as unmodified. Only do this if no errors, that way 5165 # export failures should recover a little more automatically. 5166 $zonesth->execute($domid); 5167 } 5168 # Always stream the cache (even if stale or obsolete due to errors creating the new cache) 5169 open CACHE, "<$cachefile"; 5170 print $datafile $_ while <CACHE>; 5171 close CACHE; 5172 5173 } # while ($domsth) 5174 5175 } # end __export_tiny() 5176 5177 5178 # Utility sub for __export_tiny above 5179 sub _printrec_tiny { 5180 my ($datafile,$revrec,$recflags,$zone,$host,$type,$val,$dist,$weight,$port,$ttl,$loc,$stamp,$expires,$stampactive) = @_; 5181 5182 $loc = '' if !$loc; # de-nullify - just in case 4947 5183 ##fixme: handle case of record-with-location-that-doesn't-exist better. 4948 5184 # note this currently fails safe (tested) - records with a location that … … 4950 5186 # $loc = '' if !$lochash->{$loc}; 4951 5187 4952 ##fixme: record validity timestamp. tinydns supports fiddling with timestamps. 4953 # note $ttl must be set to 0 if we want to use tinydns's auto-expiring timestamps. 4954 # timestamps are TAI64 4955 # ~~ 2^62 + time() 4956 my $stamp = ''; 4957 4958 # support tinydns' auto-TTL 4959 $ttl = '' if $ttl == '0'; 4960 4961 _printrec_tiny(*ZONECACHE, 'y', \%recflags, $revzone, 4962 $host, $type, $val, $dist, $weight, $port, $ttl, $loc, $stamp) 4963 if *ZONECACHE; 4964 4965 # in case the zone shrunk, get rid of garbage at the end of the file. 4966 truncate(ZONECACHE, tell(ZONECACHE)); 4967 4968 $recflags{$recid} = 1; 4969 } # while ($recsth) 4970 } 4971 # stream from cache, whether freshly created or existing 4972 print $datafile $_ while <ZONECACHE>; 4973 close ZONECACHE; 4974 # mark zone as unmodified 4975 $zonesth->execute($revid); 4976 } # while ($domsth) 4977 4978 } # end __export_tiny() 4979 4980 4981 # Utility sub for __export_tiny above 4982 sub _printrec_tiny { 4983 my ($datafile,$revrec,$recflags,$zone,$host,$type,$val,$dist,$weight,$port,$ttl,$loc,$stamp) = @_; 5188 5189 ## Records that are valid only before or after a set time 5190 5191 # record due to expire sometime is the complex case. we don't want to just 5192 # rely on tinydns' auto-adjusting TTLs, because the default TTL in that case 5193 # is one day instead of the SOA minttl as BIND might do. 5194 5195 # consider the case where a record is set to expire a week ahead, but the next 5196 # day later you want to change it NOW (or as NOWish as you get with your DNS 5197 # management practice). but now you're stuck, because someone, somewhere, 5198 # has just done a lookup before your latest change was published, and they'll 5199 # be caching that old, broken record for 1 day instead of your zone default 5200 # TTL. 5201 5202 # $stamp-$ttl is the *latest* we can publish the record with the defined TTL 5203 # to still have the expiry happen as scheduled, but we need to find some 5204 # *earlier* point. We can maybe guess, and 2x TTL is probably reasonable, 5205 # but we need info on the export frequency. 5206 5207 # export the normal, non-expiring record up until $stamp-<guesstimate>, then 5208 # switch to exporting a record with the TAI64 stamp and a 0 TTL so tinydns 5209 # takes over TTL management. 5210 5211 if ($stampactive) { 5212 if ($expires) { 5213 # record expires at $stamp; decide if we need to keep the TTL and ignore 5214 # the stamp for a time or if we need to change the TTL to 0 and convert 5215 # $stamp to TAI64 so tinydns can use $stamp to autoadjust the TTL on the fly. 5216 # extra hack, optimally needs more knowledge of data export frequency 5217 # smack the idiot customer who insists on 0 TTLs; they can suck up and 5218 # deal with a 10-minute TTL. especially on scheduled changes. note this 5219 # should be (export freq * 2), but we don't know the actual export frequency. 5220 $ttl = 300 if $ttl == 0; #hack phtui 5221 my $ahead = (86400 < $ttl*2 ? 86400 : $ttl*2); 5222 if ((time() + $ahead) < $stamp) { 5223 # more than 2x TTL OR more than one day (whichever is less) from expiry time; publish normal record 5224 $stamp = ''; 5225 } else { 5226 # less than 2x TTL from expiry time, let tinydns take over TTL management and publish the TAI64 stamp. 5227 $ttl = 0; 5228 $stamp = unixtai64($stamp); 5229 $stamp =~ s/\@//; 5230 } 5231 } else { 5232 # record is "active after"; convert epoch from database to TAI64, publish, and collect $200. 5233 $stamp = unixtai64($stamp); 5234 $stamp =~ s/\@//; 5235 } 5236 } else { 5237 # flag for active timestamp is false; don't actually put a timestamp in the output 5238 $stamp = ''; 5239 } 5240 5241 # support tinydns' auto-TTL 5242 $ttl = '' if $ttl == -1; 5243 # these are WAY FREAKING HIGH - higher even than most TLD registry TTLs! 5244 # NS 259200 => 3d 5245 # all others 86400 => 1d 5246 5247 if ($revrec eq 'y') { 5248 $val = $zone if $val eq '@'; 5249 } else { 5250 $host = $zone if $host eq '@'; 5251 } 4984 5252 4985 5253 ## Convert a bare number into an octal-coded pair of octets. … … 5202 5470 } elsif ($type == 65281) { # AAAA+PTR 5203 5471 5204 #$$recflags{$val}++;5472 $$recflags{$val}++; 5205 5473 # treat these as two separate records. since tinydns doesn't have 5206 5474 # a native combined type, we have to create them separately anyway. 5207 if ($revrec eq 'n') { 5208 $type = 28; 5209 } else { 5210 $type = 12; 5211 } 5212 _printrec_tiny($datafile,$revrec,$recflags,$zone,$host,$type,$val,$dist,$weight,$port,$ttl,$loc,$stamp); 5475 # print both; a dangling record is harmless, and impossible via web 5476 # UI anyway 5477 _printrec_tiny($datafile,$revrec,$recflags,$zone,$host,28,$val,$dist,$weight,$port,$ttl,$loc,$stamp); 5478 _printrec_tiny($datafile,$revrec,$recflags,$zone,$host,12,$val,$dist,$weight,$port,$ttl,$loc,$stamp); 5213 5479 ##fixme: add a config flag to indicate use of the patch from http://www.fefe.de/dns/ 5214 5480 # type 6 is for AAAA+PTR, type 3 is for AAAA … … 5309 5575 my ($subj,$message) = @_; 5310 5576 5311 return if $ config{mailhost} eq 'smtp.example.com'; # do nothing if still using default SMTP host.5312 5313 my $mailer = Net::SMTP->new($ config{mailhost}, Hello => "dnsadmin.$config{domain}");5314 5315 my $mailsender = ($ config{mailsender} ? $config{mailsender} : $config{mailnotify});5577 return if $self->{mailhost} eq 'smtp.example.com'; # do nothing if still using default SMTP host. 5578 5579 my $mailer = Net::SMTP->new($self->{mailhost}, Hello => "dnsadmin.$self->{domain}"); 5580 5581 my $mailsender = ($self->{mailsender} ? $self->{mailsender} : $self->{mailnotify}); 5316 5582 5317 5583 $mailer->mail($mailsender); 5318 $mailer->to($ config{mailnotify});5319 $mailer->data("From: \"$ config{mailname}\" <$mailsender>\n",5320 "To: <$ config{mailnotify}>\n",5584 $mailer->to($self->{mailnotify}); 5585 $mailer->data("From: \"$self->{mailname}\" <$mailsender>\n", 5586 "To: <$self->{mailnotify}>\n", 5321 5587 "Date: ".strftime("%a, %d %b %Y %H:%M:%S %z",localtime)."\n", 5322 5588 "Subject: $subj\n", 5323 "X-Mailer: DNSAdmin Notify v".sprintf("%.1d",$DNSDB::VERSION)."\n",5324 "Organization: $ config{orgname}\n",5589 "X-Mailer: DNSAdmin v".$DNSDB::VERSION." Notify\n", 5590 "Organization: $self->{orgname}\n", 5325 5591 "\n$message\n"); 5326 5592 $mailer->quit; -
branches/stable/INSTALL
r263 r548 23 23 - Net::Whois::Raw 24 24 - Net::DNS 25 - Net::SMTP 25 26 - DBI 26 27 - DBD::Pg 27 - NetAddr::IP >= 4.x. 3.x may work, however 4.x has been out for 28 more than 4 years. 28 - NetAddr::IP >= 4.0.27 29 29 - Frontier::Responder (only required if using dns-rpc.cgi) 30 - FCGI (only required if you want to run the RPC script as FastCGI) 30 31 - tinydns - support for other DNS server software is planned 32 31 33 32 34 Installing DeepNet DNS Administrator … … 89 91 90 92 Basic installation should now be complete! Log in and start adding 91 your domains and domainrecords.93 your domains and reverse zones and their records. 92 94 93 95 A minimal export script is included (export.pl). This should be modified -
branches/stable/Makefile
r546 r548 46 46 INSTALL COPYING TODO Makefile dnsadmin.spec \ 47 47 \ 48 new-dns.sql dns.sql dns.cgi dns-rpc.cgi textrecs.cgi DNSDB.pm vega-import.pl export.pl \ 48 dns.sql dns-1.0-1.2.sql \ 49 \ 50 $(SCRIPTS) $(MODULES) \ 49 51 \ 50 52 index.shtml \ 51 53 \ 52 images/trash2.png images/fwd.png images/ffwd.png images/frev.png \ 53 images/rev.png images/DESC.png images/ASC.png images/tree_open.png images/tree_closed.png \ 54 $(IMAGES) \ 54 55 \ 55 templates/adddomain.tmpl templates/addgroup.tmpl templates/addrec.tmpl templates/adduser.tmpl \ 56 templates/axfr.tmpl templates/bulkchange.tmpl templates/bulkdomain.tmpl templates/dberr.tmpl \ 57 templates/deldom.tmpl templates/delgrp.tmpl templates/delloc.tmpl templates/delrec.tmpl \ 58 templates/delrevzone.tmpl templates/deluser.tmpl \ 59 templates/dns.css templates/dnsq.tmpl templates/domlist.tmpl templates/edgroup.tmpl \ 60 templates/editsoa.tmpl templates/footer.tmpl templates/fpnla.tmpl templates/grouptree.css \ 61 templates/grouptree-ie.css templates/grpman.tmpl templates/grptree.tmpl templates/header.tmpl \ 62 templates/lettsearch.tmpl templates/login.tmpl templates/log.tmpl templates/menu.tmpl \ 63 templates/newdomain.tmpl templates/newgrp.tmpl templates/permlist_enabled.tmpl templates/permlist.tmpl \ 64 templates/pgcount.tmpl templates/reclist.tmpl templates/record.tmpl templates/sbox.tmpl \ 65 templates/soadata.tmpl templates/template.tmpl templates/textrecs.tmpl templates/updatesoa.tmpl \ 66 templates/useradmin.tmpl templates/user.tmpl templates/whoisq.tmpl \ 56 $(TEMPLATES) \ 67 57 \ 68 58 dnsdb.conf … … 72 62 73 63 IMAGES = \ 74 images/trash2.png images/fwd.png images/ffwd.png images/frev.png \ 75 images/rev.png images/DESC.png images/ASC.png 64 images/ASC.png images/DESC.png \ 65 images/ffwd.png images/frev.png images/fwd.png images/rev.png \ 66 images/trash2.png \ 67 images/tree_closed.png images/tree_open.png 76 68 77 69 SCRIPTS = \ 78 dns.cgi dns-rpc.cgi textrecs.cgi vega-import.pl export.pl70 compact-recs.pl dns.cgi dns-rpc.cgi export.pl textrecs.cgi tiny-import.pl vega-import.pl 79 71 80 72 MODULES = DNSDB.pm 81 73 82 74 TEMPLATES = \ 83 templates/adddomain.tmpl templates/addgroup.tmpl templates/addrec.tmpl templates/add user.tmpl \84 templates/a xfr.tmpl templates/bulkchange.tmpl templates/bulkdomain.tmpl templates/dberr.tmpl \85 templates/ deldom.tmpl templates/delgrp.tmpl templates/delloc.tmpl templates/delrec.tmpl \86 templates/del revzone.tmpl templates/deluser.tmpl \75 templates/adddomain.tmpl templates/addgroup.tmpl templates/addrec.tmpl templates/addrevzone.tmpl \ 76 templates/adduser.tmpl templates/axfr.tmpl templates/badpage.tmpl templates/bulkchange.tmpl \ 77 templates/bulkdomain.tmpl templates/dberr.tmpl templates/deldom.tmpl templates/delgrp.tmpl \ 78 templates/delloc.tmpl templates/delrec.tmpl templates/delrevzone.tmpl templates/deluser.tmpl \ 87 79 templates/dns.css templates/dnsq.tmpl templates/domlist.tmpl templates/edgroup.tmpl \ 88 80 templates/editsoa.tmpl templates/footer.tmpl templates/fpnla.tmpl templates/grouptree.css \ 89 81 templates/grouptree-ie.css templates/grpman.tmpl templates/grptree.tmpl templates/header.tmpl \ 90 templates/lettsearch.tmpl templates/login.tmpl templates/log.tmpl templates/menu.tmpl \ 91 templates/newdomain.tmpl templates/newgrp.tmpl templates/permlist_enabled.tmpl templates/permlist.tmpl \ 92 templates/pgcount.tmpl templates/reclist.tmpl templates/record.tmpl templates/sbox.tmpl \ 93 templates/soadata.tmpl templates/template.tmpl templates/textrecs.tmpl templates/updatesoa.tmpl \ 94 templates/useradmin.tmpl templates/user.tmpl templates/whoisq.tmpl 82 templates/lettsearch.tmpl templates/location.tmpl templates/loclist.tmpl templates/login.tmpl \ 83 templates/log.tmpl templates/menu.tmpl templates/msgblock.tmpl templates/newdomain.tmpl \ 84 templates/newgrp.tmpl templates/newrevzone.tmpl templates/permlist.tmpl \ 85 templates/pgcount.tmpl templates/reclist.tmpl templates/record.tmpl templates/revzones.tmpl \ 86 templates/sbox.tmpl templates/soadata.tmpl templates/template.tmpl templates/textrecs.tmpl \ 87 templates/updatesoa.tmpl templates/useradmin.tmpl templates/user.tmpl templates/whoisq.tmpl 95 88 96 89 CONFIGFILES = dnsdb.conf … … 108 101 @for i in $(SCRIPTS) $(MODULES); do \ 109 102 $(INSTALL_SCRIPT) -D $$i $(DESTDIR)${datadir}/$(PKG_LEAF)/$$i ; \ 110 perl -pi -e 's|use lib '.'; ##uselib##|use lib "${datadir}/$(PKG_LEAF)/";|;' $(DESTDIR)${datadir}/$(PKG_LEAF)/$$i ; \ 111 perl -pi -e 's|use lib '.'; ##uselib##|use lib "${datadir}/$(PKG_LEAF)/";|;' $(DESTDIR)${datadir}/$(PKG_LEAF)/$$i ; \ 103 perl -pi -e "s|use lib '.';\s+##uselib##|use lib '${datadir}/$(PKG_LEAF)/';|;" $(DESTDIR)${datadir}/$(PKG_LEAF)/$$i ; \ 112 104 done 113 105 @$(INSTALL) -d $(DESTDIR)${sysconfdir}/$(CFG_LEAF)/ … … 120 112 $(INSTALL_DATA) $$i $(DESTDIR)${sysconfdir}/$(CFG_LEAF)/ ; \ 121 113 fi ; \ 122 perl -pi -e 's|"/etc/dnsdb "; ##CFG_LEAF##|"${sysconfdir}/$(CFG_LEAF)";|;' $(DESTDIR)${datadir}/$(PKG_LEAF)/DNSDB.pm ; \114 perl -pi -e 's|"/etc/dnsdb/dnsdb.conf",\s+##CFG_LEAF##|"${sysconfdir}/$(CFG_LEAF)/dnsdb.conf",|;' $(DESTDIR)${datadir}/$(PKG_LEAF)/DNSDB.pm ; \ 123 115 done 124 # # and now munge MyDNSDB.pm so it can find the core library125 # perl -pi -e 's|##uselib##|use lib "${libdir}/dnsdb";|;' $(DESTDIR)${sysconfdir}/dnsdb/MyDNSDB.pm126 116 127 117 #clean: -
branches/stable/UPGRADE
r530 r548 1 1 $Id$ 2 2 3 Upgrading from a previous release 4 ================================= 3 DeepNet DNS Administrator - Upgrade Notes 4 ========================================= 5 5 6 6 1.0 -> 1.2 7 - Make sure your NetAddr::IP version is 4.027 or greater. Older versions 8 have been found to be missing key methods. 9 7 10 - FastCGI is now supported for RPC. Install the FCGI module to support 8 11 this, and rename or symlink: -
branches/stable/compact-recs.pl
r547 r548 23 23 use warnings; 24 24 25 use lib '.'; 25 use lib '.'; ##uselib## 26 26 use DNSDB; 27 27 … … 120 120 $dbh->do("INSERT INTO records (domain_id, rdns_id, host, type, val, ttl, location) VALUES (?,?,?,?,?,?,?)", 121 121 undef, ($dparent, $zone, $patt, $newtype, $cidr, $soa->{minttl}, $ploc) ); 122 $dbh->do("UPDATE revzones SET changed='y' WHERE rdns_id = ?", undef, ($zone)); 123 $dbh->do("UPDATE domains SET changed='y' WHERE domain_id = ?", undef, ($dparent)) if $dparent; 122 124 $dnsdb->_log(rdns_id => $zone, domain_id => $dparent, group_id => 1, 123 125 entry => "A+PTR and/or PTR records in $cidr matching $patt replaced by $typemap{$newtype} record for $cidr"); -
branches/stable/dns-1.0-1.2.sql
r547 r548 40 40 \. 41 41 42 SELECT pg_catalog.setval('default_rev_records_record_id_seq', 5, false);42 SELECT pg_catalog.setval('default_rev_records_record_id_seq', 4, true); 43 43 44 44 ALTER TABLE domains ADD COLUMN changed boolean DEFAULT true NOT NULL; … … 72 72 ALTER TABLE records ADD COLUMN rdns_id INTEGER DEFAULT 0 NOT NULL; 73 73 ALTER TABLE records ADD COLUMN location character varying (4) DEFAULT '' NOT NULL; 74 -- Scheduled changes. 75 ALTER TABLE records ADD COLUMN stamp TIMESTAMP WITH TIME ZONE DEFAULT 'epoch' NOT NULL; 76 ALTER TABLE records ADD COLUMN expires boolean DEFAULT 'n' NOT NULL; 77 ALTER TABLE records ADD COLUMN stampactive boolean DEFAULT 'n' NOT NULL; 74 78 75 79 -- ~120s -> 75s performance boost on 100K records when always exporting all records … … 171 175 \. 172 176 177 -- and readd the primary key 178 ALTER TABLE ONLY rectypes 179 ADD CONSTRAINT rectypes_pkey PRIMARY KEY (val, name); 180 173 181 -- Update dbversion 174 182 UPDATE misc SET value='1.2' WHERE key='dbversion'; -
branches/stable/dns-rpc.cgi
r547 r548 3 3 ## 4 4 # $Id$ 5 # Copyright 2012 Kris Deugau <kdeugau@deepnet.cx>5 # Copyright 2012,2013 Kris Deugau <kdeugau@deepnet.cx> 6 6 # 7 7 # This program is free software: you can redistribute it and/or modify … … 41 41 42 42 my $methods = { 43 #sub getPermissions { 44 #sub changePermissions { 45 #sub comparePermissions { 46 #sub changeGroup { 43 47 'dnsdb.addDomain' => \&addDomain, 44 48 'dnsdb.delZone' => \&delZone, 49 #sub domainName { 50 #sub revName { 51 'dnsdb.domainID' => \&domainID, 52 #sub revID { 45 53 'dnsdb.addRDNS' => \&addRDNS, 54 #sub getZoneCount { 55 #sub getZoneList { 56 #sub getZoneLocation { 46 57 'dnsdb.addGroup' => \&addGroup, 47 58 'dnsdb.delGroup' => \&delGroup, 59 #sub getChildren { 60 #sub groupName { 61 #sub getGroupCount { 62 #sub getGroupList { 63 #sub groupID { 48 64 'dnsdb.addUser' => \&addUser, 65 #sub getUserCount { 66 #sub getUserList { 67 #sub getUserDropdown { 49 68 'dnsdb.updateUser' => \&updateUser, 50 69 'dnsdb.delUser' => \&delUser, 70 #sub userFullName { 71 #sub userStatus { 72 #sub getUserData { 73 #sub addLoc { 74 #sub updateLoc { 75 #sub delLoc { 76 #sub getLoc { 77 #sub getLocCount { 78 #sub getLocList { 51 79 'dnsdb.getLocDropdown' => \&getLocDropdown, 52 80 'dnsdb.getSOA' => \&getSOA, 81 #sub updateSOA { 53 82 'dnsdb.getRecLine' => \&getRecLine, 54 'dnsdb.get DomRecs' => \&getDomRecs,83 'dnsdb.getRecList' => \&getRecList, 55 84 'dnsdb.getRecCount' => \&getRecCount, 56 85 'dnsdb.addRec' => \&addRec, 57 86 'dnsdb.updateRec' => \&updateRec, 87 #sub downconvert { 58 88 'dnsdb.addOrUpdateRevRec' => \&addOrUpdateRevRec, 59 89 'dnsdb.delRec' => \&delRec, … … 62 92 #sub getLogEntries {} 63 93 'dnsdb.getRevPattern' => \&getRevPattern, 94 'dnsdb.getTypelist' => \&getTypelist, 95 'dnsdb.getTypemap' => \&getTypemap, 96 'dnsdb.getReverse_typemap' => \&getReverse_typemap, 97 #sub parentID { 98 #sub isParent { 64 99 'dnsdb.zoneStatus' => \&zoneStatus, 65 100 'dnsdb.getZonesByCIDR' => \&getZonesByCIDR, 101 #sub importAXFR { 102 #sub importBIND { 103 #sub import_tinydns { 104 #sub export { 105 #sub mailNotify { 66 106 67 107 'dnsdb.getMethods' => \&get_method_list … … 95 135 my $subsys = shift; 96 136 return 1 if grep /$ENV{REMOTE_ADDR}/, @{$dnsdb->{rpcacl}{$subsys}}; 137 warn "$subsys/$ENV{REMOTE_ADDR} not in ACL\n"; # a bit of logging 97 138 return 0; 98 139 } … … 111 152 fullname => ($argref->{fullname} ? $argref->{fullname} : $argref->{rpcuser}) ); 112 153 } 154 } 155 156 # check for defrec and revrec; only call on subs that deal with records 157 sub _reccheck { 158 my $argref = shift; 159 die "Missing defrec and/or revrec flags\n" if !($argref->{defrec} || $argref->{revrec}); 113 160 } 114 161 … … 145 192 _commoncheck(\%args, 'y'); 146 193 147 my ($code, $msg) = $dnsdb->addDomain($args{domain}, $args{group}, $args{state} );148 die $msgif $code eq 'FAIL';194 my ($code, $msg) = $dnsdb->addDomain($args{domain}, $args{group}, $args{state}, $args{location}); 195 die "$msg\n" if $code eq 'FAIL'; 149 196 return $msg; # domain ID 150 197 } … … 167 214 ($code,$msg) = $dnsdb->delZone($zoneid, $args{revrec}); 168 215 } 169 die $msgif $code eq 'FAIL';216 die "$msg\n" if $code eq 'FAIL'; 170 217 return $msg; 171 218 } … … 173 220 #sub domainName {} 174 221 #sub revName {} 175 #sub domainID {} 222 223 sub domainID { 224 my %args = @_; 225 226 _commoncheck(\%args, 'y'); 227 228 my $domid = $dnsdb->domainID($args{domain}); 229 die "$dnsdb->errstr\n" if !$domid; 230 return $domid; 231 } 232 176 233 #sub revID {} 177 234 … … 204 261 ## optional $inhert arg? 205 262 my ($code,$msg) = $dnsdb->addGroup($args{groupname}, $args{parent_id}, $perms); 206 die $msgif $code eq 'FAIL';263 die "$msg\n" if $code eq 'FAIL'; 207 264 return $msg; 208 265 } … … 223 280 ($code,$msg) = $dnsdb->delGroup($grpid); 224 281 } 225 die $msgif $code eq 'FAIL';282 die "$msg\n" if $code eq 'FAIL'; 226 283 return $msg; 227 284 } … … 249 306 } 250 307 my ($code,$msg) = $dnsdb->addUser(@userargs); 251 die $msgif $code eq 'FAIL';308 die "$msg\n" if $code eq 'FAIL'; 252 309 return $msg; 253 310 } … … 275 332 # have to pass them all in to be overwritten 276 333 my ($code,$msg) = $dnsdb->updateUser(@userargs); 277 die $msgif $code eq 'FAIL';334 die "$msg\n" if $code eq 'FAIL'; 278 335 return $msg; 279 336 } … … 286 343 die "Missing UID\n" if !$args{uid}; 287 344 my ($code,$msg) = $dnsdb->delUser($args{uid}); 288 die $msgif $code eq 'FAIL';345 die "$msg\n" if $code eq 'FAIL'; 289 346 return $msg; 290 347 } … … 315 372 316 373 _commoncheck(\%args); 374 375 _reccheck(\%args); 317 376 318 377 my $ret = $dnsdb->getSOA($args{defrec}, $args{revrec}, $args{id}); … … 334 393 _commoncheck(\%args); 335 394 395 _reccheck(\%args); 396 336 397 my $ret = $dnsdb->getRecLine($args{defrec}, $args{revrec}, $args{id}); 337 398 338 die $dnsdb->errstrif !$ret;399 die "$dnsdb->errstr\n" if !$ret; 339 400 340 401 return $ret; 341 402 } 342 403 343 sub get DomRecs{404 sub getRecList { 344 405 my %args = @_; 345 406 346 407 _commoncheck(\%args); 408 409 # deal gracefully with alternate calling convention for args{id} 410 $args{id} = $args{ID} if !$args{id} && $args{ID}; 411 # ... and fail if we don't have one 412 die "Missing zone ID\n" if !$args{id}; 413 414 # set some optional args 415 $args{offset} = 0 if !$args{offset}; 416 ## for order, need to map input to column names 417 $args{order} = 'host' if !$args{order}; 418 $args{direction} = 'ASC' if !$args{direction}; 419 $args{defrec} = 'n' if !$args{defrec}; 420 $args{revrec} = 'n' if !$args{revrec}; 421 422 # convert zone name to zone ID, if needed 423 if ($args{defrec} eq 'n') { 424 if ($args{revrec} eq 'n') { 425 $args{id} = $dnsdb->domainID($args{id}) if $args{id} !~ /^\d+$/; 426 } else { 427 $args{id} = $dnsdb->revID($args{id}) if $args{id} !~ /^\d+$/ 428 } 429 } 430 431 # fail if we *still* don't have a valid zone ID 432 die "$dnsdb->errstr\n" if !$args{id}; 433 434 # and finally retrieve the records. 435 my $ret = $dnsdb->getRecList(defrec => $args{defrec}, revrec => $args{revrec}, id => $args{id}, 436 offset => $args{offset}, nrecs => $args{nrecs}, sortby => $args{sortby}, 437 sortorder => $args{sortorder}, filter => $args{filter}); 438 die "$dnsdb->errstr\n" if !$ret; 439 440 return $ret; 441 } 442 443 sub getRecCount { 444 my %args = @_; 445 446 _commoncheck(\%args); 447 448 _reccheck(\%args); 347 449 348 450 # set some optional args … … 353 455 $args{direction} = 'ASC' if !$args{direction}; 354 456 355 my $ret = $dnsdb->getDomRecs(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; 457 my $ret = $dnsdb->getRecCount($args{defrec}, $args{revrec}, $args{id}, $args{filter}); 458 459 die "$dnsdb->errstr\n" if !$ret; 360 460 361 461 return $ret; 362 462 } 363 463 364 sub getRecCount {365 my %args = @_;366 367 _commoncheck(\%args);368 369 # set some optional args370 $args{nrecs} = 'all' if !$args{nrecs};371 $args{nstart} = 0 if !$args{nstart};372 ## for order, need to map input to column names373 $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 383 464 sub addRec { 384 465 my %args = @_; … … 386 467 _commoncheck(\%args, 'y'); 387 468 469 _reccheck(\%args); 388 470 _loccheck(\%args); 389 471 _ttlcheck(\%args); 390 472 473 # allow passing text types rather than DNS integer IDs 474 $args{type} = $DNSDB::reverse_typemap{$args{type}} if $args{type} !~ /^\d+$/; 475 391 476 my @recargs = ($args{defrec}, $args{revrec}, $args{parent_id}, 392 \$args{name}, \$args{type}, \$args{address}, $args{ttl}, $args{location}); 477 \$args{name}, \$args{type}, \$args{address}, $args{ttl}, $args{location}, 478 $args{expires}, $args{stamp}); 393 479 if ($args{type} == $DNSDB::reverse_typemap{MX} or $args{type} == $DNSDB::reverse_typemap{SRV}) { 394 480 push @recargs, $args{distance}; … … 401 487 my ($code, $msg) = $dnsdb->addRec(@recargs); 402 488 403 die $msgif $code eq 'FAIL';489 die "$msg\n" if $code eq 'FAIL'; 404 490 return $msg; 405 491 } … … 410 496 _commoncheck(\%args, 'y'); 411 497 498 _reccheck(\%args); 499 500 # put some caller-friendly names in their rightful DB column places 501 $args{val} = $args{address}; 502 $args{host} = $args{name}; 503 412 504 # get old line, so we can update only the bits that the caller passed to change 413 # note we subbed address for val since it's a little more caller-friendly414 505 my $oldrec = $dnsdb->getRecLine($args{defrec}, $args{revrec}, $args{id}); 415 foreach my $field (qw( name type address ttl locationdistance weight port)) {506 foreach my $field (qw(host type val ttl location expires distance weight port)) { 416 507 $args{$field} = $oldrec->{$field} if !$args{$field} && defined($oldrec->{$field}); 417 508 } 509 # stamp has special handling when blank or 0. "undefined" from the caller should mean "don't change" 510 $args{stamp} = $oldrec->{stamp} if !defined($args{stamp}) && defined($oldrec->{stamp}); 511 512 # allow passing text types rather than DNS integer IDs 513 $args{type} = $DNSDB::reverse_typemap{$args{type}} if $args{type} !~ /^\d+$/; 418 514 419 515 # note dist, weight, port are not required on all types; will be ignored if not needed. 420 516 # parent_id is the "primary" zone we're updating; necessary for forward/reverse voodoo 421 517 my ($code, $msg) = $dnsdb->updateRec($args{defrec}, $args{revrec}, $args{id}, $args{parent_id}, 422 \$args{name}, \$args{type}, \$args{address}, $args{ttl}, $args{location}, 518 \$args{host}, \$args{type}, \$args{val}, $args{ttl}, $args{location}, 519 $args{expires}, $args{stamp}, 423 520 $args{distance}, $args{weight}, $args{port}); 424 521 425 die $msgif $code eq 'FAIL';522 die "$msg\n" if $code eq 'FAIL'; 426 523 return $msg; 427 524 } … … 443 540 # We need to strip the CIDR mask on IPv4 /32 assignments, or we just add a new record all the time. 444 541 my $filt = ($cidr->{isv6} || $cidr->masklen != 32 ? "$cidr" : $cidr->addr); 445 my $reclist = $dnsdb->get DomRecs(defrec => 'n', revrec => 'y',542 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y', 446 543 id => $zonelist->[0]->{rdns_id}, filter => $filt); 447 544 if (scalar(@$reclist) == 0) { … … 477 574 # that spans multiple reverse zones (eg, /23 CIDR -> 2 /24 rzones) 478 575 foreach my $zdata (@$zonelist) { 479 my $reclist = $dnsdb->get DomRecs(defrec => 'n', revrec => 'y',576 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y', 480 577 id => $zdata->{rdns_id}, filter => $zdata->{revnet}); 481 578 if (scalar(@$reclist) == 0) { … … 502 599 _commoncheck(\%args, 'y'); 503 600 601 _reccheck(\%args); 602 504 603 my ($code, $msg) = $dnsdb->delRec($args{defrec}, $args{recrev}, $args{id}); 505 604 506 die $msgif $code eq 'FAIL';605 die "$msg\n" if $code eq 'FAIL'; 507 606 return $msg; 508 607 } … … 527 626 if ($args{delsubs}) { 528 627 # Delete ALL EVARYTHING!!one11!! in $args{cidr} 529 my $reclist = $dnsdb->get DomRecs(defrec => 'n', revrec => 'y', id => $zonelist->[0]->{rdns_id});628 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y', id => $zonelist->[0]->{rdns_id}); 530 629 foreach my $rec (@$reclist) { 531 630 my $reccidr = new NetAddr::IP $rec->{val}; … … 554 653 # We need to strip the CIDR mask on IPv4 /32 assignments, or we can't find single-IP records 555 654 my $filt = ($cidr->{isv6} || $cidr->masklen != 32 ? "$cidr" : $cidr->addr); 556 my $reclist = $dnsdb->get DomRecs(defrec => 'n', revrec => 'y',655 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y', 557 656 id => $zonelist->[0]->{rdns_id}, filter => $filt, sortby => 'val', sortorder => 'DESC'); 558 657 foreach my $rec (@$reclist) { … … 563 662 if ($args{delforward} || $rec->{type} == 12) { 564 663 my ($code,$msg) = $dnsdb->delRec('n', 'y', $rec->{record_id}); 565 die $msgif $code eq 'FAIL';664 die "$msg\n" if $code eq 'FAIL'; 566 665 return $msg; 567 666 } else { 568 667 my $ret = $dnsdb->downconvert($rec->{record_id}, $DNSDB::reverse_typemap{A}); 569 die $dnsdb->errstrif !$ret;668 die "$dnsdb->errstr\n" if !$ret; 570 669 return "A+PTR for $args{cidr} split and PTR removed"; 571 670 } … … 582 681 # that spans multiple reverse zones (eg, /23 CIDR -> 2 /24 rzones) 583 682 foreach my $zdata (@$zonelist) { 584 my $reclist = $dnsdb->get DomRecs(defrec => 'n', revrec => 'y', id => $zdata->{rdns_id});683 my $reclist = $dnsdb->getRecList(defrec => 'n', revrec => 'y', id => $zdata->{rdns_id}); 585 684 if (scalar(@$reclist) == 0) { 586 685 # nothing to do? or do we (re)add a record based on the parent? … … 627 726 } 628 727 629 #sub getTypelist {} 728 sub getTypelist { 729 my %args = @_; 730 _commoncheck(\%args, 'y'); 731 732 $args{selected} = $reverse_typemap{A} if !$args{selected}; 733 734 return $dnsdb->getTypelist($args{recgroup}, $args{selected}); 735 } 736 737 sub getTypemap { 738 my %args = @_; 739 _commoncheck(\%args, 'y'); 740 return \%typemap; 741 } 742 743 sub getReverse_typemap { 744 my %args = @_; 745 _commoncheck(\%args, 'y'); 746 return \%reverse_typemap; 747 } 748 630 749 #sub parentID {} 631 750 #sub isParent {} -
branches/stable/dns.cgi
r547 r548 3 3 ## 4 4 # $Id$ 5 # Copyright 2008-201 2Kris Deugau <kdeugau@deepnet.cx>5 # Copyright 2008-2013 Kris Deugau <kdeugau@deepnet.cx> 6 6 # 7 7 # This program is free software: you can redistribute it and/or modify … … 30 30 use Net::DNS; 31 31 use DBI; 32 32 33 use Data::Dumper; 33 34 … … 65 66 $webvar{revrec} = 'n' if !$webvar{revrec}; # non-reverse (domain) records 66 67 67 # load some local system defaults (mainly DB connect info) 68 # note this is not *absolutely* fatal, since there's a default dbname/user/pass in DNSDB.pm 69 # we'll catch a bad DB connect string once we get to trying that 70 ##fixme: pass params to loadConfig, and use them there, to allow one codebase to support multiple sites 68 # create a DNSDB object. this loads some local system defaults and connects to the DB 69 # with the credentials configured 70 ##fixme: pass params for loadConfig, and use them there, to allow one codebase to support multiple sites 71 71 my $dnsdb = new DNSDB; 72 72 … … 75 75 $footer->param(version => $DNSDB::VERSION); 76 76 77 ##fixme: slim chance this could be triggered on errors other than DB failure? 77 78 if (!$dnsdb) { 78 79 print "Content-type: text/html\n\n"; … … 87 88 $header->param(orgname => $dnsdb->{orgname}) if $dnsdb->{orgname} ne 'Example Corp'; 88 89 89 # persistent stuff needed on most/all pages 90 my $sid = ($webvar{sid} ? $webvar{sid} : undef); 91 my $session = new CGI::Session("driver:File", $sid, {Directory => $dnsdb->{sessiondir}}) 90 my $logingroup; 91 my $curgroup; 92 my @viewablegroups; 93 94 # retrieve the session ID from our cookie, if possible 95 my $sid = $q->cookie('dnsadmin_session'); 96 97 # see if the session loads 98 my $session = CGI::Session->load("driver:File", $sid, {Directory => $dnsdb->{sessiondir}}) 92 99 or die CGI::Session->errstr(); 93 #$sid = $session->id() if !$sid; 100 94 101 if (!$sid) { 95 # init stuff. can probably axe this down to just above if'n'when user manipulation happens 96 $sid = $session->id(); 97 $session->expire($dnsdb->{timeout}); 98 # need to know the "upper" group the user can deal with; may as well 99 # stick this in the session rather than calling out to the DB every time. 100 $session->param('logingroup',1); 101 $session->param('curgroup',1); # yes, we *do* need to track this too. er, probably. 102 $session->param('domlistsortby','domain'); 103 $session->param('domlistorder','ASC'); 104 $session->param('revzonessortby','revnet'); 105 $session->param('revzonesorder','ASC'); 106 $session->param('useradminsortby','user'); 107 $session->param('useradminorder','ASC'); 108 $session->param('grpmansortby','group'); 109 $session->param('grpmanorder','ASC'); 110 $session->param('reclistsortby','host'); 111 $session->param('reclistorder','ASC'); 112 $session->param('loclistsortby','description'); 113 $session->param('loclistorder','ASC'); 114 $session->param('logsortby','stamp'); 115 $session->param('logorder','DESC'); 102 $webvar{page} = 'login'; 103 } else { 104 # we have a session to load from, maybe 105 $logingroup = ($session->param('logingroup') ? $session->param('logingroup') : 1); 106 $curgroup = ($session->param('curgroup') ? $session->param('curgroup') : $logingroup); 107 # security check - does the user have permission to view this entity? 108 # this is a prep step used "many" places 109 $dnsdb->getChildren($logingroup, \@viewablegroups, 'all'); 110 push @viewablegroups, $logingroup; 111 ##fixme: make sessions persist through closing the site? 112 # this even bridges browser close too. hmm... 113 $webvar{page} = 'domlist' if !$webvar{page}; 116 114 } 117 115 118 # Just In Case. Stale sessions should not be resurrectable. 119 if ($sid ne $session->id()) { 120 $sid = ''; 121 changepage(page=> "login", sessexpired => 1); 122 } 123 124 # normal expiry, more or less 125 if ($session->is_expired) { 126 $sid = ''; 127 changepage(page=> "login", sessexpired => 1); 128 } 129 130 my $logingroup = ($session->param('logingroup') ? $session->param('logingroup') : 1); 131 my $curgroup = ($session->param('curgroup') ? $session->param('curgroup') : $logingroup); 132 133 # decide which page to spit out... 134 # also set $webvar{page} before we try to use it. 116 # set $webvar{page} before we try to use it. 135 117 $webvar{page} = 'login' if !$webvar{page}; 136 118 137 # per-page startwith, filter, searchsubs119 ## per-page startwith, filter, searchsubs 138 120 139 121 ##fixme: complain-munge-and-continue with non-"[a-z0-9-.]" filter and startwith … … 150 132 $webvar{searchsubs} =~ s/[^yn]//g if $webvar{searchsubs}; 151 133 152 $session->param($webvar{page}.'startwith', $webvar{startwith}) if defined($webvar{startwith}); 153 $session->param($webvar{page}.'filter', $webvar{filter}) if defined($webvar{filter}); 134 # pagination 135 my $perpage = 15; # Just In Case 136 $perpage = $dnsdb->{perpage} if $dnsdb->{perpage}; 137 my $offset = ($webvar{offset} ? $webvar{offset} : 0); 138 139 ## set up "URL to self" (whereami edition) 140 # @#$%@%@#% XHTML - & in a URL must be escaped. >:( 141 my $uri_self = $ENV{REQUEST_URI}; 142 $uri_self =~ s/\&([a-z])/\&\;$1/g; 143 144 # le sigh. and we need to strip any previous action 145 $uri_self =~ s/\&action=[^&]+//g; 146 147 # much magic happens. if startwith or a search string change (to, from, or 148 # across, in the request vs whatever's in the session) then the offset should 149 # be reset to 0 so that the first/prev/next/last widget populates correctly, 150 # and so that the list of whatever we're looking at actually shows things 151 # (since we may have started on page 42 of 300 with a LOOOOONG list, but we 152 # now only need 3 pages for the filtered list). 153 # while we're at it, plonk these into the session for safekeeping. 154 if (defined($webvar{startwith})) { 155 if ($webvar{startwith} ne $session->param($webvar{page}.'startwith')) { 156 $uri_self =~ s/\&offset=[^&]//; 157 $offset = 0; 158 } 159 $session->param($webvar{page}.'startwith', $webvar{startwith}); 160 } 161 if (defined($webvar{filter})) { 162 if ($webvar{filter} ne $session->param($webvar{page}.'filter')) { 163 $uri_self =~ s/\&offset=[^&]//; 164 $offset = 0; 165 } 166 $session->param($webvar{page}.'filter', $webvar{filter}) 167 } 154 168 $session->param($webvar{page}.'searchsubs', $webvar{searchsubs}) if defined($webvar{searchsubs}); 155 169 170 # and now that the search/filter criteria for this page are set, put them in some globals for actual use. 156 171 my $startwith = $session->param($webvar{page}.'startwith'); 157 172 my $filter = $session->param($webvar{page}.'filter'); … … 162 177 push @filterargs, "^[$startwith]" if $startwith; 163 178 push @filterargs, $filter if $filter; 164 165 ## set up "URL to self"166 # @#$%@%@#% XHTML - & in a URL must be escaped. >:(167 my $uri_self = $ENV{REQUEST_URI};168 $uri_self =~ s/\&([a-z])/\&\;$1/g;169 170 # le sigh. and we need to strip any previous action171 $uri_self =~ s/\&action=[^&]+//g;172 179 173 180 # and search filter options. these get stored in the session, but discarded … … 181 188 182 189 # Fix up $uri_self so we don't lose the session/page 183 $uri_self .= "?sid=$sid&page=$webvar{page}" if $uri_self =~ m{/dns.cgi$}; 184 $uri_self = "$ENV{SCRIPT_NAME}?sid=$sid&page=$webvar{page}$1" if $uri_self =~ m{/dns.cgi\&(.+)$}; 185 186 # pagination 187 my $perpage = 15; 188 $perpage = $dnsdb->{perpage} if $dnsdb->{perpage}; 189 my $offset = ($webvar{offset} ? $webvar{offset} : 0); 190 $uri_self .= "?page=$webvar{page}" if $uri_self =~ m{/dns.cgi$}; 191 $uri_self = "$ENV{SCRIPT_NAME}?page=$webvar{page}$1" if $uri_self =~ m{/dns.cgi\&(.+)$}; 192 193 ## end uri_self monkeying 190 194 191 195 # NB: these must match the field name and SQL ascend/descend syntax respectively 196 # sortby is reset to a suitable "default", then re-reset to whatever the user has 197 # clicked on last in the record=listing subs, but best to put a default here. 192 198 my $sortby = "domain"; 193 199 my $sortorder = "ASC"; 194 200 195 # security check - does the user have permission to view this entity? 196 # this is a prep step used "many" places 197 my @viewablegroups; 198 $dnsdb->getChildren($logingroup, \@viewablegroups, 'all'); 199 push @viewablegroups, $logingroup; 200 201 # Create the page template object. Display a reasonable error page and whine if the template doesn't exist. 201 202 my $page; 202 203 eval { … … 217 218 } 218 219 219 # handle login redirect 220 my $sesscookie; 221 222 # handle can-happen-on-(almost)-any-page actions 220 223 if ($webvar{action}) { 224 221 225 if ($webvar{action} eq 'login') { 222 226 # Snag ACL/permissions here too … … 226 230 if ($userdata) { 227 231 232 # (re)create the session 233 $session = new CGI::Session("driver:File", $sid, {Directory => $dnsdb->{sessiondir}}) 234 or die CGI::Session->errstr(); 235 $sid = $session->id(); 236 237 $sesscookie = $q->cookie( -name => 'dnsadmin_session', 238 -value => $sid, 239 -expires => "+".$dnsdb->{timeout}, 240 -secure => 0, 241 ## fixme: need to extract root path for cookie, so as to limit cookie to dnsadmin instance 242 # -path => $url 243 ); 244 228 245 # set session bits 246 $session->expire($dnsdb->{timeout}); 229 247 $session->param('logingroup',$userdata->{group_id}); 230 248 $session->param('curgroup',$userdata->{group_id}); … … 232 250 $session->param('username',$webvar{username}); 233 251 234 changepage(page => "domlist"); 252 # for reference. seems we don't need to set these on login any more. 253 # $session->param('domlistsortby','domain'); 254 # $session->param('domlistorder','ASC'); 255 # $session->param('revzonessortby','revnet'); 256 # $session->param('revzonesorder','ASC'); 257 # $session->param('useradminsortby','user'); 258 # $session->param('useradminorder','ASC'); 259 # $session->param('grpmansortby','group'); 260 # $session->param('grpmanorder','ASC'); 261 # $session->param('reclistsortby','host'); 262 # $session->param('reclistorder','ASC'); 263 # $session->param('loclistsortby','description'); 264 # $session->param('loclistorder','ASC'); 265 # $session->param('logsortby','stamp'); 266 # $session->param('logorder','DESC'); 267 268 ## "recover my link" - tack on request bits and use requested page instead of hardcoding domlist 269 # this could possibly be compacted by munging changepage a little so we don't have to deconstruct 270 # and reconstruct the URI argument list. 271 my %target = (page => "domlist"); 272 if ($webvar{target} && $webvar{target} =~ /\?/) { 273 my $tmp = (split /\?/, $webvar{target})[1]; 274 $tmp =~ s/^\&//; 275 my @targs = split /\&/, $tmp; 276 foreach (@targs) { 277 my ($k,$v) = split /=/; 278 $target{$k} = $v if $k; 279 # if we're going through a "session expired" login, we may have a different 280 # "current group" than the login group. 281 $session->param('curgroup', $v) if $k eq 'curgroup'; 282 ##fixme: page=record goes "FOOM", sometimes - cause/fix? 283 } 284 } 285 changepage(%target); 235 286 236 287 } else { … … 243 294 $session->flush(); 244 295 296 my $sesscookie = $q->cookie( -name => 'dnsadmin_session', 297 -value => $sid, 298 -expires => "-1", 299 -secure => 0, 300 ## fixme: need to extract root path for cookie, so as to limit cookie to dnsadmin instance 301 # -path => $url 302 ); 303 245 304 my $newurl = "http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}"; 246 305 $newurl =~ s|/[^/]+$|/|; 247 print "Status: 302\nLocation: $newurl\n\n";306 print $q->redirect( -uri => $newurl, -cookie => $sesscookie); 248 307 exit; 249 308 250 } elsif ($webvar{action} eq 'chgroup' ) {309 } elsif ($webvar{action} eq 'chgroup' && $webvar{page} ne 'login') { 251 310 # fiddle session-stored group data 252 311 # magic incantation to... uhhh... … … 276 335 changepage(%args); 277 336 } 278 279 } 337 # add offset back *into* $uri_self if we're also currently looking at a live record list. 338 if ($webvar{page} eq 'reclist' && $webvar{defrec} eq 'n') { 339 $uri_self .= "\&offset=$offset"; 340 } 341 } # done action=chgroup 280 342 } # handle global webvar{action}s 343 281 344 282 345 # finally check if the user was disabled. we could just leave this for logout/session expiry, … … 295 358 $dnsdb->initActionLog($session->param('uid')); 296 359 297 $page->param(sid => $sid) unless $webvar{page} eq 'login'; # no session ID on the login page 360 ## 361 ## Per-page processing 362 ## 298 363 299 364 if ($webvar{page} eq 'login') { 300 365 301 $page->param(loginfailed => 1) if $webvar{loginfailed}; 302 $page->param(sessexpired => 1) if $webvar{sessexpired}; 366 my $target = $ENV{REQUEST_URI}; 367 $target =~ s/\&/\&/g; 368 $page->param(target => $target); # needs to be trimmed a little, maybe? 369 370 $page->param(sessexpired => 1) if (!$sid && $target !~ m|/$|); 371 372 if ($webvar{loginfailed}) { 373 $page->param(loginfailed => 1); 374 $webvar{target} =~ s/\&/\&/g; # XHTML we do (not) love you so 375 $page->param(target => $webvar{target}) if $webvar{target}; 376 } 377 # if $webvar{sessexpired}; # or this with below? 378 if ($session->is_expired) { 379 $page->param(sessexpired => 1); 380 $session->delete(); # Just to make sure 381 $session->flush(); 382 } 303 383 $page->param(version => $DNSDB::VERSION); 384 $page->param(script_self => ($ENV{SCRIPT_NAME} =~ m|/([^/]+)$|)[0]); 304 385 305 386 } elsif ($webvar{page} eq 'domlist' or $webvar{page} eq 'index') { … … 337 418 $webvar{group} = $curgroup if !$webvar{group}; 338 419 fill_grouplist("grouplist", $webvar{group}); 339 fill_loclist( );420 fill_loclist($curgroup, $webvar{defloc} ? $webvar{defloc} : ''); 340 421 341 422 if ($session->param('add_failed')) { … … 363 444 $webvar{makeactive} = 0 if !defined($webvar{makeactive}); 364 445 365 my ($code,$msg) = $dnsdb->addDomain($webvar{domain}, $webvar{group}, ($webvar{makeactive} eq 'on' ? 1 : 0)); 446 my ($code,$msg) = $dnsdb->addDomain($webvar{domain}, $webvar{group}, ($webvar{makeactive} eq 'on' ? 1 : 0), 447 $webvar{defloc}); 366 448 367 449 if ($code eq 'OK') { … … 373 455 $session->param('add_failed', 1); 374 456 ##fixme: domain a security risk for XSS? 375 changepage(page => "newdomain", domain => $webvar{domain}, errmsg => $msg,376 makeactive => ($webvar{makeactive} ? 'y' : 'n'), group => $webvar{group});457 changepage(page => "newdomain", errmsg => $msg, domain => $webvar{domain}, 458 group => $webvar{group}, makeactive => ($webvar{makeactive} ? 'y' : 'n'), defloc => $webvar{defloc}); 377 459 } 378 460 … … 640 722 641 723 my @recargs = ($webvar{defrec}, $webvar{revrec}, $webvar{parentid}, 642 \$webvar{name}, \$webvar{type}, \$webvar{address}, $webvar{ttl}, $webvar{location}); 724 \$webvar{name}, \$webvar{type}, \$webvar{address}, $webvar{ttl}, $webvar{location}, 725 $webvar{expires}, $webvar{stamp}); 643 726 if ($webvar{type} == $reverse_typemap{MX} or $webvar{type} == $reverse_typemap{SRV}) { 644 727 push @recargs, $webvar{distance}; … … 688 771 $page->param(ttl => $recdata->{ttl}); 689 772 $page->param(typelist => $dnsdb->getTypelist($webvar{revrec}, $recdata->{type})); 690 773 if ($recdata->{stampactive}) { 774 $page->param(stamp => $recdata->{stamp}); 775 $page->param(stamp_until => $recdata->{expires}); 776 } 691 777 if ($webvar{defrec} eq 'n') { 692 778 fill_loclist($curgroup, $recdata->{location}); … … 704 790 my ($code,$msg) = $dnsdb->updateRec($webvar{defrec}, $webvar{revrec}, $webvar{id}, $webvar{parentid}, 705 791 \$webvar{name}, \$webvar{type}, \$webvar{address}, $webvar{ttl}, $webvar{location}, 792 $webvar{expires}, $webvar{stamp}, 706 793 $webvar{distance}, $webvar{weight}, $webvar{port}); 707 794 … … 1001 1088 $page->param(perpage => $perpage); 1002 1089 1003 my $domlist = $dnsdb->getZoneList(revrec => 'n', curgroup => $curgroup );1090 my $domlist = $dnsdb->getZoneList(revrec => 'n', curgroup => $curgroup, offset => $offset); 1004 1091 my $rownum = 0; 1005 1092 foreach my $dom (@{$domlist}) { … … 1693 1780 1694 1781 # start output here so we can redirect pages. 1695 print "Content-type: text/html\n\n", $header->output; 1782 print $q->header( -cookie => $sesscookie); 1783 print $header->output; 1696 1784 1697 1785 ##common bits … … 1722 1810 $page->param(inlogingrp => $curgroup == $logingroup); 1723 1811 1724 # fill in the URL-to-self 1812 # fill in the URL-to-self for the group tree and search-by-letter 1725 1813 $page->param(whereami => $uri_self); 1814 # fill in general URL-to-self 1815 $page->param(script_self => "$ENV{SCRIPT_NAME}?".($curgroup ? "curgroup=$curgroup" : '')); 1726 1816 } 1727 1817 … … 1766 1856 1767 1857 my @childlist; 1858 1859 # some magic to control bad offsets on group change 1860 my $grp_uri_self = $uri_self; 1861 $grp_uri_self =~ s/\&offset=[^&]+// unless ($webvar{page} eq 'reclist' && $webvar{defrec} eq 'n'); 1768 1862 1769 1863 my $grptree = HTML::Template->new(filename => 'templates/grptree.tmpl'); … … 1775 1869 $row{grpname} = $dnsdb->groupName($_); 1776 1870 $row{grpnum} = $_; 1777 $row{whereami} = $ uri_self;1871 $row{whereami} = $grp_uri_self; 1778 1872 $row{curgrp} = ($_ == $cur); 1779 1873 $row{expanded} = $dnsdb->isParent($_, 'group', $cur, 'group'); … … 1805 1899 1806 1900 # handle user check 1807 my $newurl = "http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}? sid=$sid";1901 my $newurl = "http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}?"; 1808 1902 foreach (sort keys %params) { 1809 1903 ## fixme: something is undefined here on add location … … 1814 1908 $session->flush(); 1815 1909 1816 print "Status: 302\nLocation: $newurl\n\n";1910 print $q->redirect ( -url => $newurl, -cookie => $sesscookie); 1817 1911 exit; 1818 1912 } # end changepage … … 1901 1995 $page->param(ttl => $soa->{ttl}); 1902 1996 1903 my $foo2 = $dnsdb->get DomRecs(defrec => $def, revrec => $rev, id => $id, offset => $webvar{offset},1997 my $foo2 = $dnsdb->getRecList(defrec => $def, revrec => $rev, id => $id, offset => $webvar{offset}, 1904 1998 sortby => $sortby, sortorder => $sortorder, filter => $filter); 1905 1999 1906 2000 foreach my $rec (@$foo2) { 1907 2001 $rec->{type} = $typemap{$rec->{type}}; 1908 $rec->{sid} = $webvar{sid};1909 2002 $rec->{fwdzone} = $rev eq 'n'; 1910 2003 $rec->{distance} = 'n/a' unless ($rec->{type} eq 'MX' || $rec->{type} eq 'SRV'); … … 1915 2008 $rec->{record_delete} = ($permissions{admin} || $permissions{record_delete}); 1916 2009 $rec->{locname} = '' unless ($permissions{admin} || $permissions{location_view}); 2010 # Timestamps 2011 if ($rec->{expires}) { 2012 $rec->{stamptype} = $rec->{ispast} ? 'expired at' : 'expires at'; 2013 } else { 2014 $rec->{stamptype} = 'valid after'; 2015 } 2016 # strip seconds and timezone? no, not yet. could probably offer a config knob on this display at some point. 2017 # $rec->{stamp} =~ s/:\d\d-\d+$//; 2018 delete $rec->{expires}; 2019 delete $rec->{ispast}; 1917 2020 } 1918 2021 $page->param(reclist => $foo2); … … 1945 2048 my $soa = $dnsdb->getSOA($webvar{defrec}, $webvar{revrec}, $webvar{parentid}); 1946 2049 $page->param(ttl => ($webvar{ttl} ? $webvar{ttl} : $soa->{minttl})); 2050 $page->param(stamp_until => ($webvar{expires} eq 'until')); 2051 $page->param(stamp => $webvar{stamp}); 1947 2052 } 1948 2053 … … 2006 2111 my $parent = shift; 2007 2112 2008 # Fix display/UI bug where if you are not on the first page of the list, and2009 # you add a search term or click one of the "starts with" links, you end up2010 # on a page showing nothing.2011 # For bonus points, this reverts to the original offset on clicking the "All" link (mostly)2012 if ($offset ne 'all') {2013 $offset-- while ($offset * $perpage) >= $pgcount;2014 }2015 2016 2113 $page->param(ntot => $pgcount); 2017 2114 $page->param(nfirst => (($offset eq 'all' ? 0 : $offset)*$perpage+1)); … … 2044 2141 fill_fpnla($count); 2045 2142 2143 $sortby = ($webvar{revrec} eq 'n' ? 'domain' : 'revnet'); 2046 2144 # sort/order 2047 2145 $session->param($webvar{page}.'sortby', $webvar{sortby}) if $webvar{sortby}; … … 2071 2169 my $zonelist = $dnsdb->getZoneList(childlist => $childlist, curgroup => $curgroup, revrec => $webvar{revrec}, 2072 2170 filter => ($filter ? $filter : undef), startwith => ($startwith ? $startwith : undef), 2073 offset => $ webvar{offset}, sortby => $sortby, sortorder => $sortorder2171 offset => $offset, sortby => $sortby, sortorder => $sortorder 2074 2172 ); 2075 2173 # probably don't need this, keeping for reference for now … … 2292 2390 foreach my $col (@$cols) { 2293 2391 my %coldata; 2294 $coldata{sid} = $sid;2295 2392 $coldata{page} = $webvar{page}; 2296 2393 $coldata{offset} = $webvar{offset} if $webvar{offset}; -
branches/stable/dns.sql
r547 r548 78 78 default_location character varying (4) DEFAULT '' NOT NULL 79 79 ); 80 -- ~2x performance boost iff most zones are fed to output from the cache 81 CREATE INDEX dom_status_index ON domains (status); 82 80 83 81 84 CREATE TABLE revzones ( … … 90 93 default_location character varying (4) DEFAULT '' NOT NULL 91 94 ); 95 CREATE INDEX rev_status_index ON revzones USING btree (status); 92 96 93 97 CREATE TABLE groups ( … … 109 113 log_id serial NOT NULL, 110 114 domain_id integer, 111 rdns_id integer,112 115 user_id integer, 113 116 group_id integer, … … 115 118 name character varying(60), 116 119 entry text, 117 stamp timestamp with time zone DEFAULT now() 120 stamp timestamp with time zone DEFAULT now(), 121 rdns_id integer 118 122 ); 119 123 … … 134 138 record_edit boolean DEFAULT false NOT NULL, 135 139 record_delete boolean DEFAULT false NOT NULL, 140 user_id integer UNIQUE, 141 group_id integer UNIQUE, 136 142 record_locchg boolean DEFAULT false NOT NULL, 137 143 location_create boolean DEFAULT false NOT NULL, 138 144 location_edit boolean DEFAULT false NOT NULL, 139 145 location_delete boolean DEFAULT false NOT NULL, 140 location_view boolean DEFAULT false NOT NULL, 141 user_id integer UNIQUE, 142 group_id integer UNIQUE 146 location_view boolean DEFAULT false NOT NULL 143 147 ); 144 148 145 149 -- Need *two* basic permissions; one for the initial group, one for the default admin user 146 COPY permissions (permission_id, "admin", self_edit, group_create, group_edit, group_delete, user_create, user_edit, user_delete, domain_create, domain_edit, domain_delete, record_create, record_edit, record_delete, record_locchg, location_create, location_edit, location_delete, location_view, user_id, group_id) FROM stdin;147 1 f f f f f f f f t t t t t t f f f f f \N 1148 2 t f f f f f f f f f f f f f f f f f f 1 \N150 COPY permissions (permission_id, "admin", self_edit, group_create, group_edit, group_delete, user_create, user_edit, user_delete, domain_create, domain_edit, domain_delete, record_create, record_edit, record_delete, user_id, group_id, record_locchg, location_create, location_edit, location_delete, location_view) FROM stdin; 151 1 f f f f f f f f t t t t t t \N 1 f f f f f 152 2 t f f f f f f f f f f f f f 1 \N f f f f f 149 153 \. 150 154 … … 152 156 CREATE TABLE records ( 153 157 domain_id integer NOT NULL DEFAULT 0, 154 rdns_id integer NOT NULL DEFAULT 0,155 158 record_id serial NOT NULL, 156 159 host text DEFAULT '' NOT NULL, … … 162 165 ttl integer DEFAULT 7200 NOT NULL, 163 166 description text, 164 location character varying (4) DEFAULT '' NOT NULL 165 ); 167 rdns_id integer NOT NULL DEFAULT 0, 168 location character varying (4) DEFAULT '' NOT NULL, 169 stamp TIMESTAMP WITH TIME ZONE DEFAULT 'epoch' NOT NULL, 170 expires boolean DEFAULT 'n' NOT NULL, 171 stampactive boolean DEFAULT 'n' NOT NULL 172 ); 173 CREATE INDEX rec_domain_index ON records USING btree (domain_id); 174 CREATE INDEX rec_revzone_index ON records USING btree (rdns_id); 175 CREATE INDEX rec_types_index ON records USING btree ("type"); 166 176 167 177 CREATE TABLE rectypes ( … … 309 319 ADD CONSTRAINT "$1" FOREIGN KEY (group_id) REFERENCES groups(group_id); 310 320 321 ALTER TABLE ONLY default_records 322 ADD CONSTRAINT "$1" FOREIGN KEY (group_id) REFERENCES groups(group_id); 323 324 ALTER TABLE ONLY users 325 ADD CONSTRAINT "$1" FOREIGN KEY (group_id) REFERENCES groups(group_id); 326 311 327 ALTER TABLE ONLY revzones 312 328 ADD CONSTRAINT "$1" FOREIGN KEY (group_id) REFERENCES groups(group_id); 313 329 314 ALTER TABLE ONLY default_records315 ADD CONSTRAINT "$1" FOREIGN KEY (group_id) REFERENCES groups(group_id);316 317 ALTER TABLE ONLY users318 ADD CONSTRAINT "$1" FOREIGN KEY (group_id) REFERENCES groups(group_id);319 320 330 ALTER TABLE ONLY groups 321 331 ADD CONSTRAINT group_parent FOREIGN KEY (parent_group_id) REFERENCES groups(group_id); 322 332 323 333 -- set starting sequence numbers, since we've inserted data before they're active 324 SELECT pg_catalog.setval('misc_misc_id_seq', 2, false); 325 SELECT pg_catalog.setval('default_records_record_id_seq', 8, false); 326 SELECT pg_catalog.setval(' default_rev_records_record_id_seq', 5, false);327 SELECT pg_catalog.setval('d omains_domain_id_seq', 1, false);328 SELECT pg_catalog.setval(' groups_group_id_seq', 2, false);329 SELECT pg_catalog.setval(' permissions_permission_id_seq', 3, false);330 SELECT pg_catalog.setval(' records_record_id_seq', 1, false);331 SELECT pg_catalog.setval('users_user_id_seq', 2, false);334 -- only set the ones that have data loaded with \copy, and obey the convention 335 -- that comes out of pg_dump 336 SELECT pg_catalog.setval('misc_misc_id_seq', 1, true); 337 SELECT pg_catalog.setval('default_records_record_id_seq', 8, true); 338 SELECT pg_catalog.setval('default_rev_records_record_id_seq', 4, true); 339 SELECT pg_catalog.setval('groups_group_id_seq', 1, true); 340 SELECT pg_catalog.setval('permissions_permission_id_seq', 2, true); 341 SELECT pg_catalog.setval('users_user_id_seq', 1, true); -
branches/stable/dnsdb.conf
r216 r548 2 2 3 3 # Database connection info 4 #dbname =dsndb5 #dbuser =dnsdb6 #dbpass =dnsdbpwd7 #dbhost =dnsdbhost4 #dbname = dsndb 5 #dbuser = dnsdb 6 #dbpass = dnsdbpwd 7 #dbhost = dnsdbhost 8 8 9 # SOA defaults. contact and prins may only contain a-z, 0-9, . and -,10 # the rest are expected to be numeric.11 #contact=hostmaster.example.com12 #prins=ns1.example.com13 #soattl=720014 #refresh=8640015 #retry=1440016 #expire=2880017 #minttl=90018 #ttl=90019 20 9 # Mail settings 21 #mailhost =smtp.example.com22 #mailnotify =dns@example.com23 #mailsender =hostmaster@example.com24 #mailname =Example Corp DNS Administrator25 #orgname =Example Corp26 #domain =example.com10 #mailhost = smtp.example.com 11 #mailnotify = dns@example.com 12 #mailsender = hostmaster@example.com 13 #mailname = Example Corp DNS Administrator 14 #orgname = Example Corp 15 #domain = example.com 27 16 28 17 # session - note this is fed directly to CGI::Session 29 18 # timeout supports (s)econds, (m)inutes, (h)ours, (d)ays, (w)eeks, (M)months, or (y)ears 30 #timeout =3h31 #sessiondir =/var/lib/dnsdb19 #timeout = 3h 20 #sessiondir = /var/lib/dnsdb 32 21 33 # misc 22 ## misc 23 34 24 # flag to indicate if failed changes should be logged 35 #log_failures =025 #log_failures = 1 36 26 # number of entries to display in lists 37 #perpage=25 27 #perpage = 25 28 # maximum number of FCGI requests to serve before reloading/restarting FCGI 29 #max_fcgi_requests = 10 30 # path for per-zone cache files for export 31 #exportcache = /var/cache/dnsdb 32 33 # always refresh the cache from the DB on export if 1/on 34 # if 0/off, use the "changed" flag on a zone to determine if we export from 35 # the DB or read from the existing cache file. 36 #force_refresh = 1 37 38 # RPC ACL 39 # A comma-separated list starting with an abstract "system name" 40 # (passed by an RPC caller), followed by a list of IP addresses 41 # allowed to make RPC calls with that name. 42 # Finer-grained access control must be handled by the caller. 43 #rpc_iplist = billing, 192.168.0.11 44 #rpc_iplist = billing, 172.12.12.12 45 #rpc_iplist = custportal, 192.168.1.12, 192.168.1.13 -
branches/stable/export.pl
r547 r548 3 3 ## 4 4 # $Id$ 5 # Copyright 2012 Kris Deugau <kdeugau@deepnet.cx>5 # Copyright 2012,2013 Kris Deugau <kdeugau@deepnet.cx> 6 6 # 7 7 # This program is free software: you can redistribute it and/or modify -
branches/stable/reverse-patterns.html
r532 r548 73 73 supported since DNS names may not contain most other 74 74 non-alphanumerics.</p> 75 <p>%blank% may be used to specifically prevent template expansion on 76 a segment of a block if desired; eg, if<br /> 77 192.168.23.0/24 has "unused-%i.example.com" set, adding an A+PTR 78 template for 192.168.23.48/30 of<br /> 79 "%blank%" will leave 192.168.23.48 through .51 without PTR records 80 unless specific entries exist for those IPs.<p> 75 81 </div> 76 82 </body> -
branches/stable/templates/axfr.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 5 4 <td align="center" valign="top"> 6 5 7 <form action=" dns.cgi" method="post">6 <form action="<TMPL_VAR NAME=script_self>" method="post"> 8 7 <fieldset> 9 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />10 8 <input type="hidden" name="page" value="axfr" /> 11 9 <input type="hidden" name="doit" value="y" /> -
branches/stable/templates/badpage.tmpl
r544 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <div id="badpage"> 3 2 <TMPL_IF badpage> -
branches/stable/templates/bulkchange.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> -
branches/stable/templates/bulkdomain.tmpl
r547 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 5 4 <td align="center" valign="top"> 6 5 7 <form action=" dns.cgi">6 <form action="<TMPL_VAR NAME=script_self>" method="post"> 8 7 <fieldset> 9 8 10 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />11 9 <input type="hidden" name="page" value="bulkchange" /> 12 10 <input type="hidden" name="offset" value="<TMPL_VAR NAME=offset>" /> -
branches/stable/templates/deldom.tmpl
r546 r548 5 5 <td align="center" valign="top"> 6 6 <h3>Are you really sure you want to delete domain <TMPL_VAR NAME=domain>?</h3> 7 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=deldom&del=cancel&id=<TMPL_VAR NAME=id>">cancel</a> | 8 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=deldom&del=ok&id=<TMPL_VAR NAME=id>">confirm</a>7 <a href="<TMPL_VAR NAME=script_self>&page=deldom&del=cancel&id=<TMPL_VAR NAME=id>">cancel</a> | 8 <a href="<TMPL_VAR NAME=script_self>&page=deldom&del=ok&id=<TMPL_VAR NAME=id>">confirm</a> 9 9 </td></tr></table> 10 10 -
branches/stable/templates/delgrp.tmpl
r546 r548 5 5 <td align="center" valign="top"> 6 6 <h3>Are you really sure you want to delete group <TMPL_VAR NAME=delgroupname>?</h3> 7 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delgrp&del=cancel&id=<TMPL_VAR NAME=id>">cancel</a> | 8 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delgrp&del=ok&id=<TMPL_VAR NAME=id>">confirm</a>7 <a href="<TMPL_VAR NAME=script_self>&page=delgrp&del=cancel&id=<TMPL_VAR NAME=id>">cancel</a> | 8 <a href="<TMPL_VAR NAME=script_self>&page=delgrp&del=ok&id=<TMPL_VAR NAME=id>">confirm</a> 9 9 </td></tr></table> 10 10 -
branches/stable/templates/delloc.tmpl
r546 r548 5 5 <td align="center" valign="top"> 6 6 <h3>Are you really sure you want to delete location <TMPL_VAR NAME=location>?</h3> 7 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delloc&del=cancel&locid=<TMPL_VAR NAME=locid>">cancel</a> | 8 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delloc&del=ok&locid=<TMPL_VAR NAME=locid>">confirm</a>7 <a href="<TMPL_VAR NAME=script_self>&page=delloc&del=cancel&locid=<TMPL_VAR NAME=locid>">cancel</a> | 8 <a href="<TMPL_VAR NAME=script_self>&page=delloc&del=ok&locid=<TMPL_VAR NAME=locid>">confirm</a> 9 9 </td></tr></table> 10 10 -
branches/stable/templates/delrec.tmpl
r544 r548 6 6 <h3>Are you really sure you want to delete record:<br /> 7 7 <TMPL_VAR NAME=host> <TMPL_VAR NAME=ftype> <TMPL_VAR NAME=recval></h3> 8 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delrec&del=cancel&id=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&parentid=<TMPL_VAR NAME=parentid>">cancel</a>8 <a href="<TMPL_VAR NAME=script_self>&page=delrec&del=cancel&id=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&parentid=<TMPL_VAR NAME=parentid>">cancel</a> 9 9 | 10 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delrec&del=ok&id=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&parentid=<TMPL_VAR NAME=parentid>">confirm</a>10 <a href="<TMPL_VAR NAME=script_self>&page=delrec&del=ok&id=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&parentid=<TMPL_VAR NAME=parentid>">confirm</a> 11 11 </td></tr></table> 12 12 -
branches/stable/templates/delrevzone.tmpl
r546 r548 5 5 <td align="center" valign="top"> 6 6 <h3>Are you really sure you want to delete reverse zone <TMPL_VAR NAME=revzone>?</h3> 7 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delrevzone&del=cancel&id=<TMPL_VAR NAME=id>">cancel</a> | 8 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delrevzone&del=ok&id=<TMPL_VAR NAME=id>">confirm</a>7 <a href="<TMPL_VAR NAME=script_self>&page=delrevzone&del=cancel&id=<TMPL_VAR NAME=id>">cancel</a> | 8 <a href="<TMPL_VAR NAME=script_self>&page=delrevzone&del=ok&id=<TMPL_VAR NAME=id>">confirm</a> 9 9 </td></tr></table> 10 10 -
branches/stable/templates/deluser.tmpl
r546 r548 5 5 <td align="center" valign="top"> 6 6 <h3>Are you really sure you want to delete user <TMPL_VAR NAME=user>?</h3> 7 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=deluser&del=cancel&id=<TMPL_VAR NAME=id>">cancel</a> | 8 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=deluser&del=ok&id=<TMPL_VAR NAME=id>">confirm</a>7 <a href="<TMPL_VAR NAME=script_self>&page=deluser&del=cancel&id=<TMPL_VAR NAME=id>">cancel</a> | 8 <a href="<TMPL_VAR NAME=script_self>&page=deluser&del=ok&id=<TMPL_VAR NAME=id>">confirm</a> 9 9 </td></tr></table> 10 10 -
branches/stable/templates/dns.css
r210 r548 36 36 background-color: #F0F0F0; 37 37 } 38 table.container {38 .container { 39 39 background-color: #FFFFFF; 40 40 border: none; … … 165 165 text-align: center; 166 166 padding: 5px; 167 width: 5 0%;167 width: 55%; 168 168 } 169 169 .warning { -
branches/stable/templates/dnsq.tmpl
r100 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 7 6 <TMPL_IF errmsg><div class="errmsg">Query error: <TMPL_VARNAME=errmsg></div></TMPL_IF> 8 7 9 <form action=" dns.cgi" method="post">8 <form action="<TMPL_VAR NAME=script_self>" method="post"> 10 9 <fieldset> 11 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />12 10 <input type="hidden" name="page" value="dnsq" /> 13 11 -
branches/stable/templates/domlist.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 18 17 <TMPL_IF domain_create> 19 18 <TMPL_IF domlist> 20 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=newdomain">New Domain</a>19 <a href="<TMPL_VAR NAME=script_self>&page=newdomain">New Domain</a> 21 20 <TMPL_ELSE> 22 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=newrevzone">New Reverse Zone</a>21 <a href="<TMPL_VAR NAME=script_self>&page=newrevzone">New Reverse Zone</a> 23 22 </TMPL_IF> 24 23 </TMPL_IF> … … 28 27 <table width="98%" border="0" cellspacing="4" cellpadding="3"> 29 28 <tr> 30 <TMPL_LOOP NAME=colheads> <td class="datahead_<TMPL_IF __first__>l<TMPL_ELSE>s</TMPL_IF>"><a href=" dns.cgi?sid=<TMPL_VAR31 NAME=s id>&page=<TMPL_VAR NAME=page><TMPL_IF NAME=offset>&offset=<TMPL_VAR29 <TMPL_LOOP NAME=colheads> <td class="datahead_<TMPL_IF __first__>l<TMPL_ELSE>s</TMPL_IF>"><a href="<TMPL_VAR 30 NAME=script_self>&page=<TMPL_VAR NAME=page><TMPL_IF NAME=offset>&offset=<TMPL_VAR 32 31 NAME=offset></TMPL_IF>&sortby=<TMPL_VAR NAME=sortby>&order=<TMPL_VAR NAME=order>"><TMPL_VAR 33 32 NAME=colname></a><TMPL_IF NAME=sortorder> <img alt="<TMPL_VAR NAME=sortorder>" src="images/<TMPL_VAR … … 40 39 <TMPL_LOOP name=domtable> 41 40 <tr class="row<TMPL_IF __odd__>0<TMPL_ELSE>1</TMPL_IF>"> 42 <td align="left"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=reclist&id=<TMPL_VAR NAME=domain_id>&defrec=n<TMPL_UNLESS domlist>&revrec=y</TMPL_UNLESS>"><TMPL_VAR NAME=domain></a></td>41 <td align="left"><a href="<TMPL_VAR NAME=script_self>&page=reclist&id=<TMPL_VAR NAME=domain_id>&defrec=n<TMPL_UNLESS domlist>&revrec=y</TMPL_UNLESS>"><TMPL_VAR NAME=domain></a></td> 43 42 <td><TMPL_IF status>Active<TMPL_ELSE>Inactive</TMPL_IF></td> 44 43 <td><TMPL_VAR name=group></td> 45 <TMPL_IF domain_edit> <td align="center"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_VAR NAME=curpage><TMPL_IF NAME=offset>&offset=<TMPL_VAR NAME=offset></TMPL_IF>&id=<TMPL_VAR NAME=domainid>&zonestatus=<TMPL_IF status>domoff<TMPL_ELSE>domon</TMPL_IF>"><TMPL_IF status>deactivate<TMPL_ELSE>activate</TMPL_IF></a></td></TMPL_IF>46 <TMPL_IF domain_delete> <td align="center"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_IF domlist>deldom<TMPL_ELSE>delrevzone</TMPL_IF>&id=<TMPL_VAR NAME=domain_id>"><img src="images/trash2.png" alt="[ Delete ]" /></a></td></TMPL_IF>44 <TMPL_IF domain_edit> <td align="center"><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_VAR NAME=curpage><TMPL_IF NAME=offset>&offset=<TMPL_VAR NAME=offset></TMPL_IF>&id=<TMPL_VAR NAME=domainid>&zonestatus=<TMPL_IF status>domoff<TMPL_ELSE>domon</TMPL_IF>"><TMPL_IF status>deactivate<TMPL_ELSE>activate</TMPL_IF></a></td></TMPL_IF> 45 <TMPL_IF domain_delete> <td align="center"><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_IF domlist>deldom<TMPL_ELSE>delrevzone</TMPL_IF>&id=<TMPL_VAR NAME=domain_id>"><img src="images/trash2.png" alt="[ Delete ]" /></a></td></TMPL_IF> 47 46 </tr> 48 47 </TMPL_LOOP> 48 <tr><td colspan="5" align="center"><TMPL_INCLUDE NAME="fpnla.tmpl"></td></tr> 49 49 <TMPL_ELSE> 50 50 <tr><td colspan="5" align="center">No <TMPL_IF domlist>domains<TMPL_ELSE>reverse zones</TMPL_IF> found</td></tr> -
branches/stable/templates/edgroup.tmpl
r207 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 5 4 <td align="center" valign="top"> 6 5 7 <form action=" dns.cgi" method="post">6 <form action="<TMPL_VAR NAME=script_self>" method="post"> 8 7 <fieldset> 9 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />10 8 <input type="hidden" name="page" value="edgroup" /> 11 9 <input type="hidden" name="grpaction" value="updperms" /> -
branches/stable/templates/editsoa.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 11 10 <div id="tableholder"> 12 11 13 <form action=" dns.cgi" method="post">12 <form action="<TMPL_VAR NAME=script_self>" method="post"> 14 13 <fieldset> 15 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />16 14 <input type="hidden" name="page" value="updatesoa" /> 17 15 <input type="hidden" name="id" value="<TMPL_VAR NAME=id>" /> -
branches/stable/templates/footer.tmpl
r433 r548 5 5 <div id="contact"> 6 6 <a href="https://secure.deepnet.cx/trac/dnsadmin">dnsadmin</a> <TMPL_VAR NAME=version> 7 © 2008-201 2<a href="mailto:kdeugau@deepnet.cx">Kris Deugau</a>/<a href="http://www.deepnet.cx">deepnet</a><br />7 © 2008-2013 <a href="mailto:kdeugau@deepnet.cx">Kris Deugau</a>/<a href="http://www.deepnet.cx">deepnet</a><br /> 8 8 Written for standards-based browsers (eg <a href="http://www.firefox.com">FireFox</a>/<a href="http://www.mozilla.org">Mozilla</a>) 9 9 </div> -
branches/stable/templates/fpnla.tmpl
r544 r548 1 <TMPL_IF navfirst><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_VAR NAME=curpage>&offset=0<TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>"><img src="images/frev.png" alt="[ First ]" />First</a><TMPL_ELSE><img src="images/frev.png" alt="[ First ]" />First</TMPL_IF> 2 <TMPL_IF navprev><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_VAR NAME=curpage>&offset=<TMPL_VAR NAME=prevoffs><TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>"><img src="images/rev.png" alt="[ Previous ]" />Previous</a><TMPL_ELSE><img src="images/rev.png" alt="[ Previous ]" />Previous</TMPL_IF> 3 <TMPL_IF navnext><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_VAR NAME=curpage>&offset=<TMPL_VAR NAME=nextoffs><TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>">Next<img src="images/fwd.png" alt="[ Next ]" /></a><TMPL_ELSE>Next<img src="images/fwd.png" alt="[ Next ]" /></TMPL_IF> 4 <TMPL_IF navlast><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_VAR NAME=curpage>&offset=<TMPL_VAR NAME=lastoffs><TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>">Last<img src="images/ffwd.png" alt="[ Last ]" /></a><TMPL_ELSE>Last<img src="images/ffwd.png" alt="[ Last ]" /></TMPL_IF> 5 <TMPL_IF navall><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_VAR NAME=curpage>&offset=all<TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>">All</a><TMPL_ELSE><TMPL_UNLESS onepage><a href="dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_VAR NAME=curpage>&offset=0<TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VARNAME=revrec></TMPL_IF>"><TMPL_VAR NAME=perpage> per page</a></TMPL_UNLESS></TMPL_IF>1 <TMPL_IF navfirst><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_VAR NAME=curpage>&offset=0<TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>"><img src="images/frev.png" alt="[ First ]" />First</a><TMPL_ELSE><img src="images/frev.png" alt="[ First ]" />First</TMPL_IF> 2 <TMPL_IF navprev><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_VAR NAME=curpage>&offset=<TMPL_VAR NAME=prevoffs><TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>"><img src="images/rev.png" alt="[ Previous ]" />Previous</a><TMPL_ELSE><img src="images/rev.png" alt="[ Previous ]" />Previous</TMPL_IF> 3 <TMPL_IF navnext><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_VAR NAME=curpage>&offset=<TMPL_VAR NAME=nextoffs><TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>">Next<img src="images/fwd.png" alt="[ Next ]" /></a><TMPL_ELSE>Next<img src="images/fwd.png" alt="[ Next ]" /></TMPL_IF> 4 <TMPL_IF navlast><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_VAR NAME=curpage>&offset=<TMPL_VAR NAME=lastoffs><TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>">Last<img src="images/ffwd.png" alt="[ Last ]" /></a><TMPL_ELSE>Last<img src="images/ffwd.png" alt="[ Last ]" /></TMPL_IF> 5 <TMPL_IF navall><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_VAR NAME=curpage>&offset=all<TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VAR NAME=revrec></TMPL_IF>">All</a><TMPL_ELSE><TMPL_UNLESS onepage><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_VAR NAME=curpage>&offset=0<TMPL_IF id>&id=<TMPL_VAR NAME=id></TMPL_IF><TMPL_IF defrec>&defrec=<TMPL_VAR NAME=defrec></TMPL_IF><TMPL_IF revrec>&revrec=<TMPL_VARNAME=revrec></TMPL_IF>"><TMPL_VAR NAME=perpage> per page</a></TMPL_UNLESS></TMPL_IF> -
branches/stable/templates/grpman.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 16 15 <tr><td colspan="3" align="center"><TMPL_INCLUDE NAME="lettsearch.tmpl"></td></tr> 17 16 <tr> 18 <td colspan="2"><TMPL_IF edgrp><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=edgroup&gid=<TMPL_VAR NAME=gid>">Edit Current Group</a></TMPL_IF></td>19 <td align="right"><TMPL_IF addgrp><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=newgrp">New Group</a></TMPL_IF>17 <td colspan="2"><TMPL_IF edgrp><a href="<TMPL_VAR NAME=script_self>&page=edgroup&gid=<TMPL_VAR NAME=gid>">Edit Current Group</a></TMPL_IF></td> 18 <td align="right"><TMPL_IF addgrp><a href="<TMPL_VAR NAME=script_self>&page=newgrp">New Group</a></TMPL_IF> 20 19 </td> 21 20 </tr> … … 24 23 <table width="98%" border="0" cellspacing="4" cellpadding="3"> 25 24 <tr> 26 <TMPL_LOOP NAME=colheads> <td class="datahead_<TMPL_IF __first__>l<TMPL_ELSE>s</TMPL_IF>"><a href=" dns.cgi?sid=<TMPL_VAR27 NAME=s id>&page=<TMPL_VAR NAME=page><TMPL_IF NAME=offset>&offset=<TMPL_VAR25 <TMPL_LOOP NAME=colheads> <td class="datahead_<TMPL_IF __first__>l<TMPL_ELSE>s</TMPL_IF>"><a href="<TMPL_VAR 26 NAME=script_self>&page=<TMPL_VAR NAME=page><TMPL_IF NAME=offset>&offset=<TMPL_VAR 28 27 NAME=offset></TMPL_IF>&sortby=<TMPL_VAR NAME=sortby>&order=<TMPL_VAR NAME=order>"><TMPL_VAR 29 28 NAME=colname></a><TMPL_IF NAME=sortorder> <img alt="<TMPL_VAR NAME=sortorder>" src="images/<TMPL_VAR … … 37 36 <TMPL_LOOP name=grouptable> 38 37 <tr class="row<TMPL_IF __odd__>0<TMPL_ELSE>1</TMPL_IF>"> 39 <td align="left"><TMPL_IF edgrp><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=edgroup&gid=<TMPL_VAR NAME=groupid>"><TMPL_VAR NAME=groupname></a><TMPL_ELSE><TMPL_VAR NAME=groupname></TMPL_IF></td>38 <td align="left"><TMPL_IF edgrp><a href="<TMPL_VAR NAME=script_self>&page=edgroup&gid=<TMPL_VAR NAME=groupid>"><TMPL_VAR NAME=groupname></a><TMPL_ELSE><TMPL_VAR NAME=groupname></TMPL_IF></td> 40 39 <td><TMPL_VAR name=pgroup></td> 41 40 <td><TMPL_VAR name=nusers></td> … … 43 42 <td><TMPL_VAR NAME=nrevzones></td> 44 43 <TMPL_IF delgrp> 45 <td align="center"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delgrp&id=<TMPL_VAR NAME=groupid>"><img src="images/trash2.png" alt="[ Delete ]" /></a></td>44 <td align="center"><a href="<TMPL_VAR NAME=script_self>&page=delgrp&id=<TMPL_VAR NAME=groupid>"><img src="images/trash2.png" alt="[ Delete ]" /></a></td> 46 45 </TMPL_IF> 47 46 </tr> 48 47 </TMPL_LOOP> 48 <tr><td colspan="6" align="center"><TMPL_INCLUDE NAME="fpnla.tmpl"></td></tr> 49 49 <TMPL_ELSE> 50 <tr><td colspan=" 5" align="center">No groups found</td></tr>50 <tr><td colspan="6" align="center">No groups found</td></tr> 51 51 </TMPL_IF> 52 52 </table> -
branches/stable/templates/header.tmpl
r210 r548 21 21 <link rel="stylesheet" type="text/css" href="templates/grouptree.css" /> 22 22 <!-- [endif] --> 23 24 <!-- Custom local stylesheet, if desired --> 25 <link rel="stylesheet" type="text/css" href="local.css" /> 23 26 </head> 24 27 <body> -
branches/stable/templates/location.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 9 8 <TMPL_ELSE> 10 9 11 <form action=" dns.cgi" method="post">10 <form action="<TMPL_VAR NAME=script_self>" method="post"> 12 11 <fieldset> 13 12 14 13 <input type="hidden" name="page" value="location" /> 15 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />16 14 <TMPL_IF id><input type="hidden" name="id" value="<TMPL_VAR NAME=id>" /></TMPL_IF> 17 15 <input type="hidden" name="locact" value="<TMPL_VAR NAME=locact>" /> -
branches/stable/templates/loclist.tmpl
r546 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 15 14 </tr> 16 15 <TMPL_IF addloc> 17 <tr><td colspan="3" align="right"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=location">New Location/View</a></td></tr>16 <tr><td colspan="3" align="right"><a href="<TMPL_VAR NAME=script_self>&page=location">New Location/View</a></td></tr> 18 17 </TMPL_IF> 19 18 </table> … … 21 20 <table width="98%" border="0" cellspacing="4" cellpadding="3" class="csubtable"> 22 21 <tr> 23 <TMPL_LOOP NAME=colheads> <td class="datahead_s"><a href=" dns.cgi?sid=<TMPL_VAR24 NAME=s id>&page=<TMPL_VAR NAME=page><TMPL_IF NAME=offset>&offset=<TMPL_VAR22 <TMPL_LOOP NAME=colheads> <td class="datahead_s"><a href="<TMPL_VAR 23 NAME=script_self>&page=<TMPL_VAR NAME=page><TMPL_IF NAME=offset>&offset=<TMPL_VAR 25 24 NAME=offset></TMPL_IF>&sortby=<TMPL_VAR NAME=sortby>&order=<TMPL_VAR NAME=order>"><TMPL_VAR 26 25 NAME=colname></a><TMPL_IF NAME=sortorder> <img alt="<TMPL_VAR NAME=sortorder>" src="images/<TMPL_VAR … … 32 31 <TMPL_LOOP name=loctable> 33 32 <tr class="row<TMPL_IF __odd__>0<TMPL_ELSE>1</TMPL_IF>"> 34 <td align="left"><TMPL_IF edloc><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=location&locact=edit&loc=<TMPL_VAR NAME=location>"><TMPL_VAR NAME=description></a><TMPL_ELSE><TMPL_VAR NAME=description></TMPL_IF></td>33 <td align="left"><TMPL_IF edloc><a href="<TMPL_VAR NAME=script_self>&page=location&locact=edit&loc=<TMPL_VAR NAME=location>"><TMPL_VAR NAME=description></a><TMPL_ELSE><TMPL_VAR NAME=description></TMPL_IF></td> 35 34 <td><TMPL_VAR name=iplist></td> 36 35 <td><TMPL_VAR name=group_name></td> 37 36 <TMPL_IF delloc> 38 <td align="center"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delloc&locid=<TMPL_VAR37 <td align="center"><a href="<TMPL_VAR NAME=script_self>&page=delloc&locid=<TMPL_VAR 39 38 NAME=location>"><img src="images/trash2.png" alt="[ Delete ]" /></a></td> 40 39 </TMPL_IF> -
branches/stable/templates/log.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 21 20 <!-- td>Customer ID</td --> 22 21 <tr class="darkrowheader"> 23 <TMPL_LOOP NAME=colheads> <td><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_VAR NAME=page><TMPL_IF22 <TMPL_LOOP NAME=colheads> <td><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_VAR NAME=page><TMPL_IF 24 23 NAME=offset>&offset=<TMPL_VAR NAME=offset></TMPL_IF>&sortby=<TMPL_VAR 25 24 NAME=sortby>&order=<TMPL_VAR NAME=order>&id=<TMPL_VAR NAME=id>&ltype=<TMPL_VAR … … 40 39 </tr> 41 40 </TMPL_LOOP> 41 <tr><td colspan="5" align="center"><TMPL_INCLUDE NAME="fpnla.tmpl"></td></tr> 42 42 <TMPL_ELSE> 43 43 <tr class="datalinelight"> -
branches/stable/templates/login.tmpl
r210 r548 1 <form method="post" action=" dns.cgi">1 <form method="post" action="<TMPL_VAR NAME=script_self>"> 2 2 <fieldset> 3 3 <input type="hidden" name="action" value="login" /> 4 4 <input type="hidden" name="page" value="login" /> 5 <input type="hidden" name="target" value="<TMPL_VAR NAME=target>" /> 5 6 6 7 <div id="login"> -
branches/stable/templates/menu.tmpl
r545 r548 1 1 <td class="menu"> 2 2 <TMPL_VAR NAME=username> logged in<br /> 3 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&action=logout">Log out</a>3 <a href="<TMPL_VAR NAME=script_self>&action=logout">Log out</a> 4 4 <hr /> 5 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=domlist">Domains</a><br />6 <TMPL_IF mayrdns><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=revzones">Reverse Zones</a><br /></TMPL_IF>7 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=useradmin">Users</a><br />8 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=log">Log</a><br />9 <TMPL_IF maydefrec><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=reclist&id=<TMPL_VAR NAME=group>&defrec=y">Default Records</a><br />10 <TMPL_IF mayrdns><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=reclist&id=<TMPL_VAR NAME=group>&defrec=y&revrec=y">Default Reverse Records</a><br /></TMPL_IF></TMPL_IF>11 <TMPL_IF mayloc><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=loclist&id=<TMPL_VAR NAME=group>">Locations/Views</a><br /></TMPL_IF>12 <TMPL_IF mayimport><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=axfr">AXFR Import</a><br /></TMPL_IF>13 <TMPL_IF maybulk><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=bulkdomain">Bulk Domain Operations</a><br /></TMPL_IF>5 <a href="<TMPL_VAR NAME=script_self>&page=domlist">Domains</a><br /> 6 <TMPL_IF mayrdns><a href="<TMPL_VAR NAME=script_self>&page=revzones">Reverse Zones</a><br /></TMPL_IF> 7 <a href="<TMPL_VAR NAME=script_self>&page=useradmin">Users</a><br /> 8 <a href="<TMPL_VAR NAME=script_self>&page=log">Log</a><br /> 9 <TMPL_IF maydefrec><a href="<TMPL_VAR NAME=script_self>&page=reclist&id=<TMPL_VAR NAME=group>&defrec=y">Default Records</a><br /> 10 <TMPL_IF mayrdns><a href="<TMPL_VAR NAME=script_self>&page=reclist&id=<TMPL_VAR NAME=group>&defrec=y&revrec=y">Default Reverse Records</a><br /></TMPL_IF></TMPL_IF> 11 <TMPL_IF mayloc><a href="<TMPL_VAR NAME=script_self>&page=loclist&id=<TMPL_VAR NAME=group>">Locations/Views</a><br /></TMPL_IF> 12 <TMPL_IF mayimport><a href="<TMPL_VAR NAME=script_self>&page=axfr">AXFR Import</a><br /></TMPL_IF> 13 <TMPL_IF maybulk><a href="<TMPL_VAR NAME=script_self>&page=bulkdomain">Bulk Domain Operations</a><br /></TMPL_IF> 14 14 <br /> 15 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=grpman"><TMPL_IF chggrps>Manage<TMPL_ELSE>View</TMPL_IF> groups</a><br />15 <a href="<TMPL_VAR NAME=script_self>&page=grpman"><TMPL_IF chggrps>Manage<TMPL_ELSE>View</TMPL_IF> groups</a><br /> 16 16 <hr /> 17 17 <div id="grptree"> … … 30 30 <!-- hmm: <TMPL_VAR NAME=groupname> --> 31 31 <hr /> 32 <a href="dns.cgi?sid=<TMPL_VAR NAME=sid>&page=dnsq">DNS Query</a><br /> 33 <a href="dns.cgi?sid=<TMPL_VAR NAME=sid>&page=whoisq">WHOIS Query</a><br /> 32 <a href="<TMPL_VAR NAME=script_self>&page=dnsq">DNS Query</a><br /> 33 <a href="<TMPL_VAR NAME=script_self>&page=whoisq">WHOIS Query</a><br /> 34 34 35 </td> -
branches/stable/templates/newdomain.tmpl
r546 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 5 4 <td align="center" valign="top"> 6 5 7 <form action=" dns.cgi">6 <form action="<TMPL_VAR NAME=script_self>"> 8 7 <fieldset> 9 8 10 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />11 9 <input type="hidden" name="page" value="adddomain" /> 12 10 <input type="hidden" name="newdomain" value="yes" /> … … 34 32 <TMPL_IF location_view><TMPL_IF record_locchg> 35 33 <tr class="datalinelight"> 36 <td> Default location/view:</td>34 <td>Location/view:</td> 37 35 <td><select name="defloc"> 38 36 <TMPL_LOOP name=loclist> <option value="<TMPL_VAR NAME=loc>"<TMPL_IF selected> selected="selected"</TMPL_IF>><TMPL_VAR NAME=locname></option> -
branches/stable/templates/newgrp.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 5 4 <td align="center" valign="top"> 6 5 7 <form action=" dns.cgi">6 <form action="<TMPL_VAR NAME=script_self>"> 8 7 <fieldset> 9 8 10 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />11 9 <input type="hidden" name="page" value="newgrp" /> 12 10 <input type="hidden" name="grpaction" value="add" /> -
branches/stable/templates/newrevzone.tmpl
r547 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 5 4 <td align="center" valign="top"> 6 5 7 <form action=" dns.cgi">6 <form action="<TMPL_VAR NAME=script_self>"> 8 7 <fieldset> 9 8 10 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />11 9 <input type="hidden" name="page" value="addrevzone" /> 12 10 <input type="hidden" name="newrevzone" value="yes" /> … … 28 26 </tr> 29 27 <tr class="datalinelight"> 30 <td>Default location/view:</td>31 <td align="left">32 <select name="location">33 <TMPL_LOOP loclist>34 <option value="<TMPL_VAR NAME=loc>"<TMPL_IF selected> selected</TMPL_IF>><TMPL_VAR NAME=locname></option>35 </TMPL_LOOP>36 </select>37 </td>38 </tr>39 <tr class="datalinelight">40 28 <td>Add reverse zone to group:</td> 41 29 <td><select name="group"> … … 47 35 <td>Make reverse zone active on next DNS propagation</td><td><input type="checkbox" name="makeactive" checked="checked" /></td> 48 36 </tr> 37 <TMPL_IF location_view><TMPL_IF record_locchg> 38 <tr class="datalinelight"> 39 <td>Location/view:</td> 40 <td align="left"> 41 <select name="location"> 42 <TMPL_LOOP loclist> 43 <option value="<TMPL_VAR NAME=loc>"<TMPL_IF selected> selected="selected"</TMPL_IF>><TMPL_VAR NAME=locname></option> 44 </TMPL_LOOP> 45 </select> 46 </td> 47 </tr> 48 </TMPL_IF></TMPL_IF> 49 49 <tr><td colspan="2" class="tblsubmit"><input type="submit" value="Add reverse zone" /></td></tr> 50 50 </table> -
branches/stable/templates/reclist.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 25 24 </td> 26 25 <td colspan="2" align="right"> 27 <form action=" dns.cgi">26 <form action="<TMPL_VAR NAME=script_self>"> 28 27 <fieldset> 29 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />30 28 <input type="hidden" name="page" value="reclist" /> 31 29 <input type="hidden" name="offset" value="0" /> … … 41 39 <tr class="darkrowheader"> 42 40 <td colspan="3">Records</td> 43 <td align="center"><a href="textrecs.cgi? sid=<TMPL_VAR NAME=sid>&id=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>">Plain text</a></td>44 <TMPL_IF record_create> <td align="right"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=record&parentid=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=new">Add record</a></td></TMPL_IF>45 <td align="right"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=log&id=<TMPL_VAR NAME=id><TMPL_IF logdom>&ltype=dom</TMPL_IF><TMPL_IF logrdns>&ltype=rdns</TMPL_IF>">View log</a></td>41 <td align="center"><a href="textrecs.cgi?id=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>">Plain text</a></td> 42 <TMPL_IF record_create> <td align="right"><a href="<TMPL_VAR NAME=script_self>&page=record&parentid=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=new">Add record</a></td></TMPL_IF> 43 <td align="right"><a href="<TMPL_VAR NAME=script_self>&page=log&id=<TMPL_VAR NAME=id><TMPL_IF logdom>&ltype=dom</TMPL_IF><TMPL_IF logrdns>&ltype=rdns</TMPL_IF>">View log</a></td> 46 44 </tr> 47 45 … … 51 49 <TMPL_IF reclist> 52 50 <tr class="darkrowheader"> 53 <TMPL_LOOP NAME=colheads> <td><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=<TMPL_VAR NAME=page><TMPL_IF51 <TMPL_LOOP NAME=colheads> <td><a href="<TMPL_VAR NAME=script_self>&page=<TMPL_VAR NAME=page><TMPL_IF 54 52 NAME=offset>&offset=<TMPL_VAR NAME=offset></TMPL_IF>&sortby=<TMPL_VAR 55 53 NAME=sortby>&order=<TMPL_VAR NAME=order>&id=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR … … 63 61 <tr class="row<TMPL_IF __odd__>0<TMPL_ELSE>1</TMPL_IF>"> 64 62 <TMPL_IF fwdzone> 65 <td><TMPL_IF record_edit><a href="dns.cgi?sid=<TMPL_VAR NAME=sid>&page=record&parentid=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=edit&id=<TMPL_VAR NAME=record_id>"><TMPL_VAR NAME=host></a><TMPL_IF locname> (<TMPL_VAR NAME=locname>)</TMPL_IF><TMPL_ELSE><TMPL_VAR NAME=host><TMPL_IF locname> (<TMPL_VAR NAME=locname>)</TMPL_IF></TMPL_IF></td> 63 <td><TMPL_IF record_edit><a href="<TMPL_VAR NAME=script_self>&page=record&parentid=<TMPL_VAR 64 NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=edit&id=<TMPL_VAR 65 NAME=record_id>"><TMPL_VAR NAME=host></a><TMPL_IF locname> (<TMPL_VAR 66 NAME=locname>)</TMPL_IF><TMPL_ELSE><TMPL_VAR NAME=host><TMPL_IF locname> (<TMPL_VAR 67 NAME=locname>)</TMPL_IF></TMPL_IF><TMPL_IF stampactive><br />(<TMPL_VAR NAME=stamptype> <TMPL_VAR 68 NAME=stamp>)</TMPL_IF></td> 66 69 <td><TMPL_VAR NAME=type></td> 67 70 <td><TMPL_VAR NAME=val></td> … … 70 73 <td><TMPL_VAR NAME=port></td> 71 74 <TMPL_ELSE> 72 <td><TMPL_IF record_edit><a href="dns.cgi?sid=<TMPL_VAR NAME=sid>&page=record&parentid=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=edit&id=<TMPL_VAR NAME=record_id>"><TMPL_VAR NAME=val></a><TMPL_IF locname> (<TMPL_VAR NAME=locname>)</TMPL_IF><TMPL_ELSE><TMPL_VAR NAME=val><TMPL_IF locname> (<TMPL_VAR NAME=locname>)</TMPL_IF></TMPL_IF></td> 75 <td><TMPL_IF record_edit><a href="<TMPL_VAR NAME=script_self>&page=record&parentid=<TMPL_VAR 76 NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&recact=edit&id=<TMPL_VAR 77 NAME=record_id>"><TMPL_VAR NAME=val></a><TMPL_IF locname> (<TMPL_VAR 78 NAME=locname>)</TMPL_IF><TMPL_ELSE><TMPL_VAR NAME=val><TMPL_IF locname> (<TMPL_VAR 79 NAME=locname>)</TMPL_IF></TMPL_IF><TMPL_IF stampactive><br />(<TMPL_VAR NAME=stamptype> <TMPL_VAR 80 NAME=stamp>)</TMPL_IF></td> 73 81 <td><TMPL_VAR NAME=type></td> 74 82 <td><TMPL_VAR NAME=host></td> 75 83 </TMPL_IF> 76 84 <td><TMPL_VAR NAME=ttl></td> 77 <TMPL_IF record_delete> <td align="center"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=delrec&id=<TMPL_VAR NAME=record_id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&parentid=<TMPL_VAR NAME=id>"><img src="images/trash2.png" alt="[ Delete ]" /></a></td></TMPL_IF>85 <TMPL_IF record_delete> <td align="center"><a href="<TMPL_VAR NAME=script_self>&page=delrec&id=<TMPL_VAR NAME=record_id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>&parentid=<TMPL_VAR NAME=id>"><img src="images/trash2.png" alt="[ Delete ]" /></a></td></TMPL_IF> 78 86 </tr> 79 87 </TMPL_LOOP> 88 <tr class="darkrowheader"><td colspan="8" align="center"><TMPL_INCLUDE NAME="fpnla.tmpl"></td></tr> 80 89 <TMPL_ELSE> 81 <tr><td colspan=" 5">No records found</td></tr>90 <tr><td colspan="8" align="center">No records found</td></tr> 82 91 </TMPL_IF> 83 92 </table> -
branches/stable/templates/record.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 9 8 <TMPL_ELSE> 10 9 11 <form action=" dns.cgi" method="post">10 <form action="<TMPL_VAR NAME=script_self>" method="post"> 12 11 <fieldset> 13 12 … … 15 14 <input type="hidden" name="defrec" value="<TMPL_VAR NAME=defrec>" /> 16 15 <input type="hidden" name="revrec" value="<TMPL_VAR NAME=revrec>" /> 17 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />18 16 <input type="hidden" name="parentid" value="<TMPL_VAR NAME=parentid>" /> 19 17 <input type="hidden" name="id" value="<TMPL_VAR NAME=id>" /> 20 18 <input type="hidden" name="recact" value="<TMPL_VAR NAME=recact>" /> 21 19 22 <table class="container" width=" 450">20 <table class="container" width="520"> 23 21 <tr><td> 24 22 … … 29 27 <TMPL_IF fwdzone> 30 28 <td>Hostname</td> 31 <td><input type="text" name="name" value="<TMPL_VAR NAME=name>" size="30" /> </td>29 <td><input type="text" name="name" value="<TMPL_VAR NAME=name>" size="30" /> <a href="reverse-patterns.html">?</a></td> 32 30 <TMPL_ELSE> 33 31 <td>IP Address</td> … … 49 47 <TMPL_ELSE> 50 48 <td>Hostname</td> 51 <td><input type="text" name="name" value="<TMPL_VAR NAME=name>" size="30" /> </td>49 <td><input type="text" name="name" value="<TMPL_VAR NAME=name>" size="30" /> <a href="reverse-patterns.html">?</a></td> 52 50 </TMPL_IF> 53 51 </tr> … … 83 81 </tr> 84 82 </TMPL_IF> 83 <TMPL_UNLESS is_default> 84 <tr class="datalinelight"> 85 <td>Timestamp<br />(blank or 0 disables timestamp)</td> 86 <td>Valid <input type="radio" name="expires" value="until"<TMPL_IF stamp_until> checked="checked"</TMPL_IF>>until 87 <input type="radio" name="expires" value="after"<TMPL_UNLESS stamp_until> checked="checked"</TMPL_UNLESS>>after: 88 <input type="text" name="stamp" value="<TMPL_VAR NAME=stamp>" /> 89 </td> 90 </tr> 91 </TMPL_UNLESS> 85 92 <tr class="datalinelight"> 86 93 <td colspan="2" align="center"><input type="submit" value=" <TMPL_VAR NAME=todo> " /></td> -
branches/stable/templates/soadata.tmpl
r545 r548 3 3 <td align="left">SOA:</td> 4 4 <TMPL_IF mayeditsoa> 5 <td align="right"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=editsoa&id=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>">edit</a></td></TMPL_IF>5 <td align="right"><a href="<TMPL_VAR NAME=script_self>&page=editsoa&id=<TMPL_VAR NAME=id>&defrec=<TMPL_VAR NAME=defrec>&revrec=<TMPL_VAR NAME=revrec>">edit</a></td></TMPL_IF> 6 6 </tr> 7 7 </table> -
branches/stable/templates/template.tmpl
r100 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> -
branches/stable/templates/user.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 5 4 <td align="center" valign="top"> 6 5 7 <form action=" dns.cgi" method="post">6 <form action="<TMPL_VAR NAME=script_self>" method="post"> 8 7 <fieldset> 9 8 10 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />11 9 <input type="hidden" name="page" value="user" /> 12 10 <input type="hidden" name="useraction" value="<TMPL_VAR NAME=action>" /> -
branches/stable/templates/useradmin.tmpl
r545 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 16 15 <tr><td colspan="3" align="center"><TMPL_INCLUDE NAME="lettsearch.tmpl"></td></tr> 17 16 <TMPL_IF adduser> 18 <tr><td colspan="3" align="right"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=user">New User</a></td></tr>17 <tr><td colspan="3" align="right"><a href="<TMPL_VAR NAME=script_self>&page=user">New User</a></td></tr> 19 18 </TMPL_IF> 20 19 </table> … … 22 21 <table width="98%" border="0" cellspacing="4" cellpadding="3" class="csubtable"> 23 22 <tr> 24 <TMPL_LOOP NAME=colheads> <td class="datahead_<TMPL_IF __first__>l<TMPL_ELSE>s</TMPL_IF>"><a href=" dns.cgi?sid=<TMPL_VAR25 NAME=s id>&page=<TMPL_VAR NAME=page><TMPL_IF NAME=offset>&offset=<TMPL_VAR23 <TMPL_LOOP NAME=colheads> <td class="datahead_<TMPL_IF __first__>l<TMPL_ELSE>s</TMPL_IF>"><a href="<TMPL_VAR 24 NAME=script_self>&page=<TMPL_VAR NAME=page><TMPL_IF NAME=offset>&offset=<TMPL_VAR 26 25 NAME=offset></TMPL_IF>&sortby=<TMPL_VAR NAME=sortby>&order=<TMPL_VAR NAME=order>"><TMPL_VAR 27 26 NAME=colname></a><TMPL_IF NAME=sortorder> <img alt="<TMPL_VAR NAME=sortorder>" src="images/<TMPL_VAR … … 33 32 <TMPL_LOOP name=usertable> 34 33 <tr class="row<TMPL_IF __odd__>0<TMPL_ELSE>1</TMPL_IF>"> 35 <td align="left"><TMPL_IF eduser><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=user&useraction=edit&user=<TMPL_VAR NAME=user_id>"><TMPL_VAR NAME=username></a><TMPL_ELSE><TMPL_VAR NAME=username></TMPL_IF></td>34 <td align="left"><TMPL_IF eduser><a href="<TMPL_VAR NAME=script_self>&page=user&useraction=edit&user=<TMPL_VAR NAME=user_id>"><TMPL_VAR NAME=username></a><TMPL_ELSE><TMPL_VAR NAME=username></TMPL_IF></td> 36 35 <td class="data_nowrap"><TMPL_VAR name=fname></td> 37 36 <td><TMPL_VAR name=type></td> … … 39 38 <td align="center"> 40 39 <TMPL_IF eduser> 41 <a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=useradmin<TMPL_IF NAME=offset>&offset=<TMPL_VAR NAME=offset></TMPL_IF>&id=<TMPL_VAR NAME=user_id>&userstatus=<TMPL_IF status>useroff<TMPL_ELSE>useron</TMPL_IF>"><TMPL_IF status>enabled<TMPL_ELSE>disabled</TMPL_IF></a>40 <a href="<TMPL_VAR NAME=script_self>&page=useradmin<TMPL_IF NAME=offset>&offset=<TMPL_VAR NAME=offset></TMPL_IF>&id=<TMPL_VAR NAME=user_id>&userstatus=<TMPL_IF status>useroff<TMPL_ELSE>useron</TMPL_IF>"><TMPL_IF status>enabled<TMPL_ELSE>disabled</TMPL_IF></a> 42 41 <TMPL_ELSE> 43 42 <TMPL_IF status>enabled<TMPL_ELSE>disabled</TMPL_IF> … … 45 44 </td> 46 45 <TMPL_IF deluser> 47 <td align="center"><a href=" dns.cgi?sid=<TMPL_VAR NAME=sid>&page=deluser&id=<TMPL_VAR NAME=user_id>"><img src="images/trash2.png" alt="[ Delete ]" /></a></td>46 <td align="center"><a href="<TMPL_VAR NAME=script_self>&page=deluser&id=<TMPL_VAR NAME=user_id>"><img src="images/trash2.png" alt="[ Delete ]" /></a></td> 48 47 </TMPL_IF> 49 48 </tr> 50 49 </TMPL_LOOP> 50 <tr><td colspan="6" align="center"><TMPL_INCLUDE NAME="fpnla.tmpl"></td></tr> 51 51 <TMPL_ELSE> 52 <tr><td colspan="6" >No users found</td></tr>52 <tr><td colspan="6" align="center">No users found</td></tr> 53 53 </TMPL_IF> 54 54 </table> -
branches/stable/templates/whoisq.tmpl
r100 r548 1 <!-- <TMPL_VAR NAME=sid> -->2 1 <table class="wholepage"><tr> 3 2 <TMPL_INCLUDE NAME="menu.tmpl"> … … 7 6 <TMPL_IF errmsg><div class="errmsg">Query error: <TMPL_VARNAME=errmsg></div></TMPL_IF> 8 7 9 <form action=" dns.cgi" method="post">8 <form action="<TMPL_VAR NAME=script_self>" method="post"> 10 9 <fieldset> 11 <input type="hidden" name="sid" value="<TMPL_VAR NAME=sid>" />12 10 <input type="hidden" name="page" value="whoisq" /> 13 11 <input type="hidden" name="askaway" value="y" /> -
branches/stable/textrecs.cgi
r547 r548 3 3 ## 4 4 # $Id$ 5 # Copyright 2012 Kris Deugau <kdeugau@deepnet.cx>5 # Copyright 2012,2013 Kris Deugau <kdeugau@deepnet.cx> 6 6 # 7 7 # This program is free software: you can redistribute it and/or modify … … 51 51 52 52 # Check the session and if we have a zone ID to retrieve. Call a failure sub if not. 53 my $sid = ($webvar{sid} ? $webvar{sid} : undef);53 my $sid = $q->cookie('dnsadmin_session'); 54 54 my $session = new CGI::Session("driver:File", $sid, {Directory => $dnsdb->{sessiondir}}) 55 55 or die CGI::Session->errstr(); … … 63 63 64 64 ##fixme: do we support both HTML-plain and true plaintext? could be done, with another $webvar{} 65 # Don't die on bad parameters. Saves munging the return from get DomRecs.65 # Don't die on bad parameters. Saves munging the return from getRecList. 66 66 #my $page = HTML::Template->new(filename => "$templatedir/textrecs.tmpl", 67 67 # loop_context_vars => 1, global_vars => 1, die_on_bad_params => 0); … … 73 73 print qq(Press the "Back" button to return to the standard record list.\n\n); 74 74 75 my $reclist = $dnsdb->get DomRecs(defrec => $webvar{defrec}, revrec => $webvar{revrec}, id => $webvar{id},75 my $reclist = $dnsdb->getRecList(defrec => $webvar{defrec}, revrec => $webvar{revrec}, id => $webvar{id}, 76 76 sortby => ($webvar{revrec} eq 'n' ? 'type,host' : 'type,val'), sortorder => 'ASC'); 77 77 foreach my $rec (@$reclist) { … … 81 81 $rec->{val} = "$rec->{distance} $rec->{val}" if $rec->{type} eq 'MX'; 82 82 $rec->{val} = "$rec->{distance} $rec->{weight} $rec->{port} $rec->{val}" if $rec->{type} eq 'SRV'; 83 printf "%-45s\t%d\t%s\t%s\n", $rec->{host}, $rec->{ttl}, $rec->{type}, $rec->{val}; 83 if ($webvar{revrec} eq 'y') { 84 printf "%-16s\t%d\t%s\t%s\n", $rec->{val}, $rec->{ttl}, $rec->{type}, $rec->{host}; 85 } else { 86 printf "%-45s\t%d\t%s\t%s\n", $rec->{host}, $rec->{ttl}, $rec->{type}, $rec->{val}; 87 } 84 88 } 85 89 #$page->param(defrec => ($webvar{defrec} eq 'y')); -
branches/stable/tiny-import.pl
r547 r548 3 3 ## 4 4 # $Id$ 5 # Copyright 2012 Kris Deugau <kdeugau@deepnet.cx>5 # Copyright 2012,2013 Kris Deugau <kdeugau@deepnet.cx> 6 6 # 7 7 # This program is free software: you can redistribute it and/or modify … … 25 25 use strict; 26 26 use warnings; 27 28 use lib '.'; 27 use POSIX; 28 use Time::TAI64 qw(:tai); 29 30 use lib '.'; ##uselib## 29 31 use DNSDB; 30 32 … … 37 39 conv => 0, 38 40 trial => 0, 41 legacy => 0, 39 42 ); 40 43 # Handle some command-line arguments 41 44 while ($ARGV[0] =~ /^-/) { 42 45 my $arg = shift @ARGV; 43 usage() if $arg !~ /^-[rc t]+$/;46 usage() if $arg !~ /^-[rclt]+$/; 44 47 # -r rewrite imported files to comment imported records 45 48 # -c coerce/downconvert A+PTR = records to PTR 49 # -l swallow A+PTR as-is 46 50 # -t trial mode; don't commit to DB or actually rewrite flatfile (disables -r) 47 51 $arg =~ s/^-//; … … 50 54 $importcfg{rw} = 1 if $_ eq 'r'; 51 55 $importcfg{conv} = 1 if $_ eq 'c'; 56 $importcfg{legacy} = 1 if $_ eq 'l'; 52 57 $importcfg{trial} = 1 if $_ eq 't'; 53 58 } … … 65 70 Multiple passes may be necessary if SOA and = records are heavily 66 71 intermixed and not clustered together. 72 -l (for "legacy") Force import of A+PTR records as-is. Mutually exclusive 73 with -c. -l takes precedence as -c is lossy. 67 74 -t Trial run mode; spits out records that would be left unimported. 68 75 Disables -r if set. … … 120 127 } 121 128 122 our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl,location ) ".123 " VALUES (?,?,?,?,?,?,?,?,?,? )");129 our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl,location,stamp,expires,stampactive) ". 130 " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"); 124 131 125 132 my %deleg; … … 243 250 } 244 251 252 sub calcstamp { 253 my $stampin = shift; 254 my $ttl = shift; 255 my $pzone = shift; 256 my $revrec = shift; 257 258 return ($ttl, 'n', 'n', '1970-01-01 00:00:00 -0') if !$stampin; 259 260 ##fixme Yes, this fails for records in 2038 sometime. No, I'm not going to care for a while. 261 $stampin = "\@$stampin"; # Time::TAI64 needs the leading @. Feh. 262 my $u = tai2unix($stampin); 263 $stampin = strftime("%Y-%m-%d %H:%M:%S %z", localtime($u)); 264 my $expires = 'n'; 265 if ($ttl) { 266 # TTL can stay put. 267 } else { 268 # TTL on import is 0, almost certainly wrong. Get the parent zone's SOA and use the minttl. 269 my $soa = $dnsdb->getSOA('n', $revrec, $pzone); 270 $ttl = $soa->{minttl}; 271 $expires = 'y'; 272 } 273 return ($ttl, 'y', $expires, $stampin); 274 } 245 275 246 276 sub recslurp { … … 263 293 $host =~ s/^=//; 264 294 $host =~ s/\.$//; 265 $ttl = 0 if !$ttl;295 $ttl = -1 if $ttl eq ''; 266 296 $stamp = '' if !$stamp; 267 297 $loc = '' if !$loc; … … 269 299 my $fparent = $dnsdb->_hostparent($host); 270 300 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($ip)); 301 302 my $stampactive = 'n'; 303 my $expires = 'n'; 304 305 # can't set a timestamp on an orphaned record. we'll actually fail import of this record a little later. 306 if ($fparent || $rparent) { 307 if ($fparent) { 308 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n'); 309 } else { 310 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 311 } 312 } 313 271 314 if ($fparent && $rparent) { 272 $recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc); 273 } else { 274 if ($importcfg{conv}) { 315 $recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 316 } else { 317 if ($importcfg{legacy}) { 318 # Just import it already! Record may still be subject to downconversion on editing. 319 $fparent = 0 if !$fparent; 320 $rparent = 0 if !$rparent; 321 if ($fparent || $rparent) { 322 $recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 323 } else { 324 # No parents found, cowardly refusing to add a dangling record 325 push @deferred, $rec unless $nodefer; 326 $impok = 0; 327 } 328 } elsif ($importcfg{conv}) { 275 329 # downconvert A+PTR if forward zone is not found 276 $recsth->execute(0, $rparent, $host, 12, $ip, 0, 0, 0, $ttl, $loc );330 $recsth->execute(0, $rparent, $host, 12, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 277 331 $converted++; 278 332 } else { … … 290 344 $host =~ s/\.$//; 291 345 $host =~ s/^\\052/*/; 292 $ttl = 0 if !$ttl; 293 $stamp = '' if !$stamp; 294 $loc = '' if !$loc; 295 $loc = '' if $loc =~ /^:+$/; 346 $ttl = -1 if $ttl eq ''; 347 $stamp = '' if !$stamp; 348 $loc = '' if !$loc; 349 $loc = '' if $loc =~ /^:+$/; 350 351 my $stampactive = 'n'; 352 my $expires = 'n'; 353 296 354 if ($host =~ /\.arpa$/) { 297 355 ($code,$msg) = DNSDB::_zone2cidr($host); 298 356 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 299 $recsth->execute(0, $rparent, $targ, 5, $msg->addr, 0, 0, 0, $ttl, $loc); 357 if ($rparent) { 358 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 359 $recsth->execute(0, $rparent, $targ, 5, $msg->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 360 } else { 361 push @deferred, $rec unless $nodefer; 362 $impok = 0; 363 # print "$tmporig deferred; can't find parent zone\n"; 364 } 300 365 301 366 ##fixme: automagically convert manually maintained sub-/24 delegations … … 308 373 my $fparent = $dnsdb->_hostparent($host); 309 374 if ($fparent) { 310 $recsth->execute($fparent, 0, $host, 5, $targ, 0, 0, 0, $ttl, $loc); 375 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n'); 376 $recsth->execute($fparent, 0, $host, 5, $targ, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 311 377 } else { 312 378 push @deferred, $rec unless $nodefer; … … 324 390 $ns =~ s/\.$//; 325 391 $ns = "$ns.ns.$zone" if $ns !~ /\./; 326 $ttl = 0 if !$ttl; 327 $stamp = '' if !$stamp; 328 $loc = '' if !$loc; 329 $loc = '' if $loc =~ /^:+$/; 392 $ttl = -1 if $ttl eq ''; 393 $stamp = '' if !$stamp; 394 $loc = '' if !$loc; 395 $loc = '' if $loc =~ /^:+$/; 396 397 my $stampactive = 'n'; 398 my $expires = 'n'; 399 330 400 if ($zone =~ /\.arpa$/) { 331 401 ($code,$msg) = DNSDB::_zone2cidr($zone); … … 336 406 # if !$rparent; 337 407 if ($rparent) { 338 $recsth->execute(0, $rparent, $ns, 2, $msg, 0, 0, 0, $ttl, $loc); 408 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 409 $recsth->execute(0, $rparent, $ns, 2, $msg, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 339 410 } else { 340 411 push @deferred, $rec unless $nodefer; … … 344 415 my $fparent = $dnsdb->_hostparent($zone); 345 416 if ($fparent) { 346 $recsth->execute($fparent, 0, $zone, 2, $ns, 0, 0, 0, $ttl, $loc); 347 $recsth->execute($fparent, 0, $ns, 2, $ip, 0, 0, 0, $ttl, $loc) if $ip; 417 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n'); 418 $recsth->execute($fparent, 0, $zone, 2, $ns, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 419 $recsth->execute($fparent, 0, $ns, 2, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive) if $ip; 348 420 } else { 349 421 push @deferred, $rec unless $nodefer; … … 358 430 $rip =~ s/^\^//; 359 431 $rip =~ s/\.$//; 360 $ttl = 0 if !$ttl; 361 $stamp = '' if !$stamp; 362 $loc = '' if !$loc; 363 $loc = '' if $loc =~ /^:+$/; 432 $ttl = -1 if $ttl eq ''; 433 $stamp = '' if !$stamp; 434 $loc = '' if !$loc; 435 $loc = '' if $loc =~ /^:+$/; 436 437 my $stampactive = 'n'; 438 my $expires = 'n'; 439 364 440 my $rparent; 365 441 if (my ($i, $z) = ($rip =~ /^(\d+)\.(\d+-(?:\d+\.){4}in-addr.arpa)$/) ) { … … 376 452 } 377 453 if ($rparent) { 378 $recsth->execute(0, $rparent, $host, 12, $msg->addr, 0, 0, 0, $ttl, $loc); 454 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 455 $recsth->execute(0, $rparent, $host, 12, $msg->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 379 456 } else { 380 457 push @deferred, $rec unless $nodefer; … … 389 466 $host =~ s/\.$//; 390 467 $host =~ s/^\\052/*/; 391 $ttl = 0 if !$ttl; 392 $stamp = '' if !$stamp; 393 $loc = '' if !$loc; 394 $loc = '' if $loc =~ /^:+$/; 468 $ttl = -1 if $ttl eq ''; 469 $stamp = '' if !$stamp; 470 $loc = '' if !$loc; 471 $loc = '' if $loc =~ /^:+$/; 472 473 my $stampactive = 'n'; 474 my $expires = 'n'; 395 475 396 476 my $domid = $dnsdb->_hostparent($host); 397 477 if ($domid) { 398 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc); 478 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 479 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 399 480 } else { 400 481 push @deferred, $rec unless $nodefer; … … 410 491 $master =~ s/\.$//; 411 492 $contact =~ s/\.$//; 412 $ttl = 0 if !$ttl; 413 $stamp = '' if !$stamp; 414 $loc = '' if !$loc; 415 $loc = '' if $loc =~ /^:+$/; 493 $ttl = -1 if $ttl eq ''; 494 $stamp = '' if !$stamp; 495 $loc = '' if !$loc; 496 $loc = '' if $loc =~ /^:+$/; 497 498 my $stampactive = 'n'; 499 my $expires = 'n'; 500 501 ##fixme er... what do we do with an SOA with a timestamp? O_o 502 # fail for now, since there's no clean way I can see to handle this (yet) 503 # maybe (ab)use the -l flag to import as-is? 504 if ($stamp) { 505 push @deferred, $rec unless $nodefer; 506 return 0; 507 } 508 509 ##fixme: need more magic on TTL, so we can decide whether to use the minttl or newttl 510 # my $newttl; 511 # ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'n'); 512 # $ttl = $newttl if !$ttl; 513 416 514 if ($zone =~ /\.arpa$/) { 417 515 ($code,$msg) = DNSDB::_zone2cidr($zone); … … 419 517 undef, ($msg, $loc)); 420 518 my ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')"); 421 $recsth->execute(0, $rdns, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, $loc); 519 my $newttl; 520 ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'y'); 521 $ttl = $newttl if !$ttl; 522 $recsth->execute(0, $rdns, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, 523 $loc, $stamp, $expires, $stampactive); 422 524 } else { 423 525 $dbh->do("INSERT INTO domains (domain,group_id,status,default_location) VALUES (?,1,1,?)", 424 526 undef, ($zone, $loc)); 425 527 my ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')"); 426 $recsth->execute($domid, 0, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, $loc); 528 my $newttl; 529 ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'n'); 530 $ttl = $newttl if !$ttl; 531 $recsth->execute($domid, 0, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, 532 $loc, $stamp, $expires, $stampactive); 427 533 } 428 534 … … 436 542 $host =~ s/\.$//; 437 543 $host = "$host.mx.$zone" if $host !~ /\./; 438 $ttl = 0 if !$ttl; 439 $stamp = '' if !$stamp; 440 $loc = '' if !$loc; 441 $loc = '' if $loc =~ /^:+$/; 544 $ttl = -1 if $ttl eq ''; 545 $stamp = '' if !$stamp; 546 $loc = '' if !$loc; 547 $loc = '' if $loc =~ /^:+$/; 548 549 my $stampactive = 'n'; 550 my $expires = 'n'; 442 551 443 552 # note we don't check for reverse domains here, because MX records don't make any sense in reverse zones. … … 447 556 my $domid = $dnsdb->_hostparent($zone); 448 557 if ($domid) { 449 $recsth->execute($domid, 0, $zone, 15, $host, $dist, 0, 0, $ttl, $loc); 450 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc) if $ip; 558 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 559 $recsth->execute($domid, 0, $zone, 15, $host, $dist, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 560 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive) if $ip; 451 561 } else { 452 562 push @deferred, $rec unless $nodefer; … … 461 571 $fqdn =~ s/^\\052/*/; 462 572 _deoctal(\$rdata); 463 $ttl = 0 if !$ttl; 464 $stamp = '' if !$stamp; 465 $loc = '' if !$loc; 466 $loc = '' if $loc =~ /^:+$/; 573 $ttl = -1 if $ttl eq ''; 574 $stamp = '' if !$stamp; 575 $loc = '' if !$loc; 576 $loc = '' if $loc =~ /^:+$/; 577 578 my $stampactive = 'n'; 579 my $expires = 'n'; 467 580 468 581 if ($fqdn =~ /\.arpa$/) { 469 582 ($code,$msg) = DNSDB::_zone2cidr($fqdn); 470 583 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 471 $recsth->execute(0, $rparent, $rdata, 16, "$msg", 0, 0, 0, $ttl, $loc); 584 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 585 $recsth->execute(0, $rparent, $rdata, 16, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 472 586 } else { 473 587 my $domid = $dnsdb->_hostparent($fqdn); 474 588 if ($domid) { 475 $recsth->execute($domid, 0, $fqdn, 16, $rdata, 0, 0, 0, $ttl, $loc); 589 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 590 $recsth->execute($domid, 0, $fqdn, 16, $rdata, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 476 591 } else { 477 592 push @deferred, $rec unless $nodefer; … … 488 603 $ns =~ s/\.$//; 489 604 $ns = "$ns.ns.$fqdn" if $ns !~ /\./; 490 $ttl = 0 if !$ttl; 491 $stamp = '' if !$stamp; 492 $loc = '' if !$loc; 493 $loc = '' if $loc =~ /^:+$/; 605 $ttl = -1 if $ttl eq ''; 606 $stamp = '' if !$stamp; 607 $loc = '' if !$loc; 608 $loc = '' if $loc =~ /^:+$/; 609 610 my $stampactive = 'n'; 611 my $expires = 'n'; 612 613 ##fixme er... what do we do with an SOA with a timestamp? O_o 614 # fail for now, since there's no clean way I can see to handle this (yet) 615 # maybe (ab)use the -l flag to import as-is? 616 if ($stamp) { 617 push @deferred, $rec unless $nodefer; 618 return 0; 619 } 620 621 ##fixme: need more magic on TTL, so we can decide whether to use the minttl or newttl 622 # my $newttl; 623 # ($newttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $minttl, 0, 'n'); 494 624 495 625 if ($fqdn =~ /\.arpa$/) { … … 501 631 undef, ($msg, $loc)); 502 632 ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')"); 633 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, 0, 'y'); 503 634 # this would probably make a lot more sense to do hostmaster.$config{admindomain} 504 $recsth->execute(0, $rdns, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", $loc); 505 } 506 $recsth->execute(0, $rdns, $ns, 2, "$msg", 0, 0, 0, $ttl, $loc); 635 # otherwise, it's as per the tinydns defaults that work tolerably well on a small scale 636 # serial -> modtime of data file, ref -> 16384, ret -> 2048, exp -> 1048576, min -> 2560 637 $recsth->execute(0, $rdns, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", 638 $loc, $stamp, $expires, $stampactive); 639 } 640 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, $rdns, 'y') if !$stamp; 641 $recsth->execute(0, $rdns, $ns, 2, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 507 642 ##fixme: (?) implement full conversion of tinydns . records? 508 643 # -> problem: A record for NS must be added to the appropriate *forward* zone, not the reverse 509 #$recsth->execute(0, $rdns, $ns, 1, $ip, 0, 0, 0, $ttl )644 #$recsth->execute(0, $rdns, $ns, 1, $ip, 0, 0, 0, $ttl, $stamp, $expires, $stampactive) 510 645 # ... auto-A-record simply does not make sense in reverse zones. Functionally 511 646 # I think it would work, sort of, but it's a nasty mess and anyone hosting reverse … … 521 656 undef, ($fqdn, $loc)); 522 657 ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')"); 523 $recsth->execute($domid, 0, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", $loc); 524 } 525 $recsth->execute($domid, 0, $fqdn, 2, $ns, 0, 0, 0, $ttl, $loc); 526 $recsth->execute($domid, 0, $ns, 1, $ip, 0, 0, 0, $ttl, $loc) if $ip; 658 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, 2560, 0, 'n'); 659 $recsth->execute($domid, 0, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", 660 $loc, $stamp, $expires, $stampactive); 661 } 662 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n') if !$stamp; 663 $recsth->execute($domid, 0, $fqdn, 2, $ns, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 664 $recsth->execute($domid, 0, $ns, 1, $ip, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive) if $ip; 527 665 } 528 666 … … 556 694 $fqdn =~ s/\.$//; 557 695 $fqdn =~ s/^\\052/*/; 558 $ttl = 0 if !$ttl; 559 $stamp = '' if !$stamp; 560 $loc = '' if !$loc; 561 $loc = '' if $loc =~ /^:+$/; 696 $ttl = -1 if $ttl eq ''; 697 $stamp = '' if !$stamp; 698 $loc = '' if !$loc; 699 $loc = '' if $loc =~ /^:+$/; 700 701 my $stampactive = 'n'; 702 my $expires = 'n'; 562 703 563 704 if ($type == 33) { … … 588 729 my $domid = $dnsdb->_hostparent($fqdn); 589 730 if ($domid) { 590 $recsth->execute($domid, 0, $fqdn, 33, $target, $prio, $weight, $port, $ttl, $loc) if $domid; 731 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 732 $recsth->execute($domid, 0, $fqdn, 33, $target, $prio, $weight, $port, $ttl, $loc, $stamp, $expires, $stampactive) if $domid; 591 733 } else { 592 734 push @deferred, $rec unless $nodefer; … … 605 747 606 748 my $fparent = $dnsdb->_hostparent($fqdn); 749 607 750 if ($fparent) { 608 $recsth->execute($fparent, 0, $fqdn, 28, $val->addr, 0, 0, 0, $ttl, $loc); 751 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $fparent, 'n'); 752 $recsth->execute($fparent, 0, $fqdn, 28, $val->addr, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 609 753 } else { 610 754 push @deferred, $rec unless $nodefer; … … 620 764 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 621 765 if ($rparent) { 622 $recsth->execute(0, $rparent, $txtstring, 16, "$msg", 0, 0, 0, $ttl, $loc); 766 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 767 $recsth->execute(0, $rparent, $txtstring, 16, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 623 768 } else { 624 769 push @deferred, $rec unless $nodefer; … … 628 773 my $domid = $dnsdb->_hostparent($fqdn); 629 774 if ($domid) { 630 $recsth->execute($domid, 0, $fqdn, 16, $txtstring, 0, 0, 0, $ttl, $loc); 775 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 776 $recsth->execute($domid, 0, $fqdn, 16, $txtstring, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 631 777 } else { 632 778 push @deferred, $rec unless $nodefer; … … 648 794 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 649 795 if ($rparent) { 650 $recsth->execute(0, $rparent, "$email $txtrec", 17, "$msg", 0, 0, 0, $ttl, $loc); 796 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $rparent, 'y'); 797 $recsth->execute(0, $rparent, "$email $txtrec", 17, "$msg", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive ); 651 798 } else { 652 799 push @deferred, $rec unless $nodefer; … … 656 803 my $domid = $dnsdb->_hostparent($fqdn); 657 804 if ($domid) { 658 $recsth->execute($domid, 0, $fqdn, 17, "$email $txtrec", 0, 0, 0, $ttl, $loc); 805 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 806 $recsth->execute($domid, 0, $fqdn, 17, "$email $txtrec", 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 659 807 } else { 660 808 push @deferred, $rec unless $nodefer; … … 672 820 my $domid = $dnsdb->_hostparent($fqdn); 673 821 if ($domid) { 674 $recsth->execute($domid, 0, $fqdn, 44, $sshfp, 0, 0, 0, $ttl, $loc); 822 ($ttl, $stampactive, $expires, $stamp) = calcstamp($stamp, $ttl, $domid, 'n'); 823 $recsth->execute($domid, 0, $fqdn, 44, $sshfp, 0, 0, 0, $ttl, $loc, $stamp, $expires, $stampactive); 675 824 } else { 676 825 push @deferred, $rec unless $nodefer; -
branches/stable/vega-import.pl
r547 r548 3 3 ## 4 4 # $Id$ 5 # Copyright 2011 ,2012Kris Deugau <kdeugau@deepnet.cx>5 # Copyright 2011-2013 Kris Deugau <kdeugau@deepnet.cx> 6 6 # 7 7 # This program is free software: you can redistribute it and/or modify
Note:
See TracChangeset
for help on using the changeset viewer.