Commit 9852a98c2a7918edbdc8a7860f035de556a1fa9c
1 parent
b075427b
add code
Showing
79 changed files
with
7359 additions
and
0 deletions
config/config.php
0 → 100644
| 1 | +<?php | |
| 2 | +// Include paths. | |
| 3 | +$_CONF['smbind_ng'] = "/usr/share/smbind-ng/php-ng/"; | |
| 4 | +$_CONF['smarty_path'] = "/usr/share/smbind-ng/smarty/libs"; | |
| 5 | +$_CONF['peardb_path'] = "/usr/share/php"; | |
| 6 | +$_CONF['title'] = ""; | |
| 7 | +$_CONF['footer'] = ""; | |
| 8 | +$_CONF['marker'] = ""; | |
| 9 | +$_CONF['template'] = "default"; | |
| 10 | +$_CONF['recaptcha'] = "yes"; | |
| 11 | +$_CONF['tmp_path'] = $_CONF['smbind_ng'] . "tmp"; | |
| 12 | +$_CONF['rc_pubkey'] = ""; | |
| 13 | +$_CONF['rc_privkey'] = ""; | |
| 14 | +$_CONF['nocaptcha'] = array(); | |
| 15 | +$_CONF['staticdomain'] = 'static.myonline.hu'; | |
| 16 | + | |
| 17 | +// Database DSN. | |
| 18 | +$_CONF['db_type'] = 'mysql'; // mysql for MySQL, pgsql for PostgreSQL | |
| 19 | +$_CONF['db_user'] = ''; | |
| 20 | +$_CONF['db_pass'] = ''; | |
| 21 | +$_CONF['db_host'] = ''; | |
| 22 | +$_CONF['db_db'] = ''; | |
| 23 | + | |
| 24 | +// Zone data paths (normal). | |
| 25 | +$_CONF['path'] = "/etc/smbind-ng/zones/"; | |
| 26 | +$_CONF['conf'] = "/etc/smbind-ng/smbind.conf"; # Include this file in named.conf. | |
| 27 | +$_CONF['rollerconf'] = "/etc/smbind-ng/rollrec/zones.rollrec"; | |
| 28 | + | |
| 29 | +// BIND utilities. | |
| 30 | +$_CONF['namedcheckconf'] = "/usr/sbin/named-checkconf"; | |
| 31 | +$_CONF['namedcheckzone'] = "/usr/sbin/named-checkzone"; | |
| 32 | +$_CONF['rndc'] = "/usr/sbin/rndc"; | |
| 33 | +$_CONF['zonesigner'] = "/usr/sbin/zonesigner"; | |
| 34 | +$_CONF['rollinit'] = "/usr/sbin/rollinit"; | |
| 35 | +$_CONF['dig'] = "/usr/bin/dig"; | |
| 36 | +?> | ... | ... |
index.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "src/include.php"; | |
| 3 | + | |
| 4 | +$smarty->assign("pagetitle", "Main"); | |
| 5 | +$smarty->assign("user", $user->getFullName()); | |
| 6 | +$smarty->assign("zones", sizeof($user->getMasters('live'))); | |
| 7 | +$smarty->assign("slave_zones", sizeof($user->getSlaves('live'))); | |
| 8 | +$smarty->assign("status", rndc_status()); | |
| 9 | +$smarty->assign("bad", $user->getUnvalidatedZones('master')); | |
| 10 | +$smarty->assign("bad_slaves", $user->getUnvalidatedZones('slave')); | |
| 11 | +$smarty->assign("comm", $user->getCommitableZones('master')); | |
| 12 | +$smarty->assign("comm_slaves", $user->getCommitableZones('slave')); | |
| 13 | +$smarty->assign("del", $user->getDeletedZones('master')); | |
| 14 | +$smarty->assign("del_slaves", $user->getDeletedZones('slave')); | |
| 15 | +$smarty->assign("template", "mainpage.tpl"); | |
| 16 | +$smarty->assign("help", help("mainpage")); | |
| 17 | +$smarty->assign("menu_button", menu_buttons()); | |
| 18 | +$smarty->display("main.tpl"); | |
| 19 | +?> | ... | ... |
lib/punycode.class.php
0 → 100644
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * The MIT License (MIT) | |
| 4 | + * | |
| 5 | + * Copyright (c) 2013 mk-j, zedwood.com | |
| 6 | + * | |
| 7 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 8 | + * of this software and associated documentation files (the "Software"), to deal | |
| 9 | + * in the Software without restriction, including without limitation the rights | |
| 10 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 11 | + * copies of the Software, and to permit persons to whom the Software is | |
| 12 | + * furnished to do so, subject to the following conditions: | |
| 13 | + * | |
| 14 | + * The above copyright notice and this permission notice shall be included in all | |
| 15 | + * copies or substantial portions of the Software. | |
| 16 | + * | |
| 17 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 18 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 19 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 20 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 21 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 22 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| 23 | + * SOFTWARE. | |
| 24 | + */ | |
| 25 | +function_exists('mb_internal_encoding') or die('unsupported dependency, mbstring'); | |
| 26 | +class Punycode | |
| 27 | +{ | |
| 28 | + const TMIN = 1; | |
| 29 | + const TMAX = 26; | |
| 30 | + const BASE = 36; | |
| 31 | + const INITIAL_N = 128; | |
| 32 | + const INITIAL_BIAS = 72; | |
| 33 | + const DAMP = 700; | |
| 34 | + const SKEW = 38; | |
| 35 | + const DELIMITER = '-'; | |
| 36 | + //Punycode::::encodeHostName() corresponds to idna_toASCII('xärg.örg'); | |
| 37 | + public static function encodeHostName($hostname) | |
| 38 | + { | |
| 39 | + if (!self::is_valid_utf8($hostname)) | |
| 40 | + { | |
| 41 | + return $hostname;//invalid | |
| 42 | + } | |
| 43 | + if (function_exists('idn_to_ascii') && 0) | |
| 44 | + { | |
| 45 | + return idn_to_ascii($hostname);//php 5.3+ | |
| 46 | + } | |
| 47 | + $old_encoding = mb_internal_encoding(); | |
| 48 | + mb_internal_encoding("UTF-8"); | |
| 49 | + $pieces = explode(".", self::mb_strtolower($hostname) ); | |
| 50 | + $punycode_pieces = array(); | |
| 51 | + foreach($pieces as $piece) | |
| 52 | + { | |
| 53 | + if (preg_match("/[\x{80}-\x{FFFF}]/u", $piece))//is multi byte utf8 | |
| 54 | + { | |
| 55 | + $punycode_pieces[] = "xn--".self::encode($piece); | |
| 56 | + } | |
| 57 | + else if (preg_match('/^[a-z\d][a-z\d-]{0,62}$/i', $piece) && !preg_match('/-$/', $piece) )//is valid ascii hostname | |
| 58 | + { | |
| 59 | + $punycode_pieces[] = $piece; | |
| 60 | + } | |
| 61 | + else | |
| 62 | + { | |
| 63 | + mb_internal_encoding($old_encoding); | |
| 64 | + return $hostname;//invalid domain | |
| 65 | + } | |
| 66 | + } | |
| 67 | + mb_internal_encoding($old_encoding); | |
| 68 | + return implode(".", $punycode_pieces); | |
| 69 | + } | |
| 70 | + //Punycode::::decodeHostName() corresponds to idna_toUnicode('xn--xrg-9ka.xn--rg-eka'); | |
| 71 | + public static function decodeHostName($encoded_hostname) | |
| 72 | + { | |
| 73 | + if (!preg_match('/[a-z\d.-]{1,255}/', $encoded_hostname)) | |
| 74 | + { | |
| 75 | + return false; | |
| 76 | + } | |
| 77 | + if (function_exists('idn_to_utf8') && 0) | |
| 78 | + { | |
| 79 | + return idn_to_utf8($encoded_hostname); | |
| 80 | + } | |
| 81 | + $old_encoding = mb_internal_encoding(); | |
| 82 | + mb_internal_encoding("UTF-8"); | |
| 83 | + $pieces = explode(".", strtolower($encoded_hostname)); | |
| 84 | + foreach($pieces as $piece) | |
| 85 | + { | |
| 86 | + if (!preg_match('/^[a-z\d][a-z\d-]{0,62}$/i', $piece) || preg_match('/-$/', $piece) ) | |
| 87 | + { | |
| 88 | + mb_internal_encoding($old_encoding); | |
| 89 | + return $encoded_hostname;//invalid | |
| 90 | + } | |
| 91 | + $punycode_pieces[] = strpos($piece, "xn--")===0 ? self::decode(substr($piece,4)) : $piece; | |
| 92 | + } | |
| 93 | + mb_internal_encoding($old_encoding); | |
| 94 | + return implode(".", $punycode_pieces); | |
| 95 | + } | |
| 96 | + protected static function encode($input) | |
| 97 | + { | |
| 98 | + try | |
| 99 | + { | |
| 100 | + $n = self::INITIAL_N; | |
| 101 | + $delta = 0; | |
| 102 | + $bias = self::INITIAL_BIAS; | |
| 103 | + $output=''; | |
| 104 | + $input_length = self::mb_strlen($input); | |
| 105 | + $b=0; | |
| 106 | + for($i=0; $i<$input_length; $i++) | |
| 107 | + { | |
| 108 | + $chr = self::mb_substr($input,$i,1); | |
| 109 | + $c = self::uniord( $chr );//autoloaded class | |
| 110 | + if ($c < self::INITIAL_N) | |
| 111 | + { | |
| 112 | + $output.= $chr; | |
| 113 | + $b++; | |
| 114 | + } | |
| 115 | + } | |
| 116 | + | |
| 117 | + if ($b==$input_length)//no international chars to convert to punycode here | |
| 118 | + { | |
| 119 | + throw new Exception("PunycodeException.BAD_INPUT"); | |
| 120 | + } | |
| 121 | + else if ($b>0) | |
| 122 | + { | |
| 123 | + $output.= self::DELIMITER; | |
| 124 | + } | |
| 125 | + $h = $b; | |
| 126 | + while($h < $input_length) | |
| 127 | + { | |
| 128 | + $m = PHP_INT_MAX; | |
| 129 | + // Find the minimum code point >= n | |
| 130 | + for($i=0; $i<$input_length; $i++) | |
| 131 | + { | |
| 132 | + $chr = self::mb_substr($input,$i,1); | |
| 133 | + $c = self::uniord( $chr ); | |
| 134 | + if ($c >= $n && $c < $m) | |
| 135 | + { | |
| 136 | + $m = $c; | |
| 137 | + } | |
| 138 | + } | |
| 139 | + | |
| 140 | + | |
| 141 | + if (($m - $n) > (PHP_INT_MAX - $delta) / ($h+1)) | |
| 142 | + { | |
| 143 | + throw new Exception("PunycodeException.OVERFLOW"); | |
| 144 | + } | |
| 145 | + $delta = $delta + ($m - $n) * ($h + 1); | |
| 146 | + $n = $m; | |
| 147 | + | |
| 148 | + for($j=0; $j<$input_length; $j++) | |
| 149 | + { | |
| 150 | + $chr = self::mb_substr($input,$j,1); | |
| 151 | + $c = self::uniord( $chr ); | |
| 152 | + if ($c < $n) | |
| 153 | + { | |
| 154 | + $delta++; | |
| 155 | + if (0==$delta) | |
| 156 | + { | |
| 157 | + throw new Exception("PunycodeException.OVERFLOW"); | |
| 158 | + } | |
| 159 | + } | |
| 160 | + | |
| 161 | + if ($c == $n) | |
| 162 | + { | |
| 163 | + $q = $delta; | |
| 164 | + for($k= self::BASE;; $k+=self::BASE) | |
| 165 | + { | |
| 166 | + $t=0; | |
| 167 | + if ($k <= $bias) | |
| 168 | + { | |
| 169 | + $t= self::TMIN; | |
| 170 | + } else if ($k >= $bias + self::TMAX) { | |
| 171 | + $t= self::TMAX; | |
| 172 | + } else { | |
| 173 | + $t = $k - $bias; | |
| 174 | + } | |
| 175 | + if ($q < $t) | |
| 176 | + { | |
| 177 | + break; | |
| 178 | + } | |
| 179 | + $output.= chr( self::digit2codepoint($t + ($q - $t) % (self::BASE - $t)) ); | |
| 180 | + $q = floor( ($q-$t) / (self::BASE - $t) );//integer division | |
| 181 | + } | |
| 182 | + $output.= chr( self::digit2codepoint($q) ); | |
| 183 | + $bias = self::adapt($delta, $h+1, $h==$b); | |
| 184 | + $delta=0; | |
| 185 | + $h++; | |
| 186 | + } | |
| 187 | + } | |
| 188 | + $delta++; | |
| 189 | + $n++; | |
| 190 | + } | |
| 191 | + } | |
| 192 | + catch (Exception $e) | |
| 193 | + { | |
| 194 | + error_log("[PUNYCODE] error ".$e->getMessage()); | |
| 195 | + return $input; | |
| 196 | + } | |
| 197 | + return $output; | |
| 198 | + } | |
| 199 | + protected static function decode($input) | |
| 200 | + { | |
| 201 | + try | |
| 202 | + { | |
| 203 | + $n = self::INITIAL_N; | |
| 204 | + $i = 0; | |
| 205 | + $bias = self::INITIAL_BIAS; | |
| 206 | + $output = ''; | |
| 207 | + $d = self::rstrpos($input, self::DELIMITER); | |
| 208 | + if ($d>0) { | |
| 209 | + for($j=0; $j<$d; $j++) { | |
| 210 | + $chr = self::mb_substr($input,$j,1); | |
| 211 | + $c = self::uniord( $chr ); | |
| 212 | + if ($c>=self::INITIAL_N) { | |
| 213 | + throw new Exception("PunycodeException.BAD_INPUT"); | |
| 214 | + } | |
| 215 | + $output.=$chr; | |
| 216 | + } | |
| 217 | + $d++; | |
| 218 | + } else { | |
| 219 | + $d = 0; | |
| 220 | + } | |
| 221 | + $input_length = self::mb_strlen($input); | |
| 222 | + while ($d < $input_length) { | |
| 223 | + $oldi = $i; | |
| 224 | + $w = 1; | |
| 225 | + for($k= self::BASE;; $k += self::BASE) { | |
| 226 | + if ($d == $input_length) { | |
| 227 | + throw new Exception("PunycodeException.BAD_INPUT"); | |
| 228 | + } | |
| 229 | + $chr = self::mb_substr($input,$d++,1); | |
| 230 | + $c = self::uniord( $chr ); | |
| 231 | + $digit = self::codepoint2digit($c); | |
| 232 | + if ($digit > (PHP_INT_MAX - $i) / $w) { | |
| 233 | + throw new Exception("PunycodeException.OVERFLOW"); | |
| 234 | + } | |
| 235 | + $i = $i + $digit * $w; | |
| 236 | + $t=0; | |
| 237 | + if ($k <= $bias) { | |
| 238 | + $t = self::TMIN; | |
| 239 | + } else if ($k >= $bias + self::TMAX) { | |
| 240 | + $t = self::TMAX; | |
| 241 | + } else { | |
| 242 | + $t = $k - $bias; | |
| 243 | + } | |
| 244 | + if ($digit < $t) { | |
| 245 | + break; | |
| 246 | + } | |
| 247 | + $w = $w * (self::BASE - $t); | |
| 248 | + } | |
| 249 | + $output_length = self::mb_strlen($output); | |
| 250 | + $bias = self::adapt($i - $oldi, $output_length + 1, $oldi == 0); | |
| 251 | + if ($i / ($output_length + 1) > PHP_INT_MAX - $n) { | |
| 252 | + throw new Exception("PunycodeException.OVERFLOW"); | |
| 253 | + } | |
| 254 | + $n = floor($n + $i / ($output_length + 1)); | |
| 255 | + $i = $i % ($output_length + 1); | |
| 256 | + $output = self::mb_strinsert($output, self::utf8($n), $i); | |
| 257 | + $i++; | |
| 258 | + } | |
| 259 | + } | |
| 260 | + catch(Exception $e) | |
| 261 | + { | |
| 262 | + error_log("[PUNYCODE] error ".$e->getMessage()); | |
| 263 | + return $input; | |
| 264 | + } | |
| 265 | + return $output; | |
| 266 | + } | |
| 267 | +//adapt patched from: | |
| 268 | +//https://github.com/takezoh/php-PunycodeEncoder/blob/master/punycode.php | |
| 269 | + protected static function adapt($delta, $numpoints, $firsttime) | |
| 270 | + { | |
| 271 | + $delta = (int)($firsttime ? $delta / self::DAMP : $delta / 2); | |
| 272 | + $delta += (int)($delta / $numpoints); | |
| 273 | + $k = 0; | |
| 274 | + while ($delta > (((self::BASE - self::TMIN) * self::TMAX) / 2)) { | |
| 275 | + $delta = (int)($delta / (self::BASE - self::TMIN)); | |
| 276 | + $k += self::BASE; | |
| 277 | + } | |
| 278 | + return $k + (int)((self::BASE - self::TMIN + 1) * $delta / ($delta + self::SKEW)); | |
| 279 | + } | |
| 280 | + protected static function digit2codepoint($d) | |
| 281 | + { | |
| 282 | + if ($d < 26) { | |
| 283 | + // 0..25 : 'a'..'z' | |
| 284 | + return $d + ord('a'); | |
| 285 | + } else if ($d < 36) { | |
| 286 | + // 26..35 : '0'..'9'; | |
| 287 | + return $d - 26 + ord('0'); | |
| 288 | + } else { | |
| 289 | + throw new Exception("PunycodeException.BAD_INPUT"); | |
| 290 | + } | |
| 291 | + } | |
| 292 | + protected static function codepoint2digit($c) | |
| 293 | + { | |
| 294 | + if ($c - ord('0') < 10) { | |
| 295 | + // '0'..'9' : 26..35 | |
| 296 | + return $c - ord('0') + 26; | |
| 297 | + } else if ($c - ord('a') < 26) { | |
| 298 | + // 'a'..'z' : 0..25 | |
| 299 | + return $c - ord('a'); | |
| 300 | + } else { | |
| 301 | + throw new Exception("PunycodeException.BAD_INPUT"); | |
| 302 | + } | |
| 303 | + } | |
| 304 | + protected static function rstrpos($haystack, $needle) | |
| 305 | + { | |
| 306 | + $pos = strpos (strrev($haystack), $needle); | |
| 307 | + if ($pos === false) | |
| 308 | + return false; | |
| 309 | + return strlen ($haystack)-1 - $pos; | |
| 310 | + } | |
| 311 | + protected static function mb_strinsert($haystack, $needle, $position) | |
| 312 | + { | |
| 313 | + $old_encoding = mb_internal_encoding(); | |
| 314 | + mb_internal_encoding("UTF-8"); | |
| 315 | + $r = mb_substr($haystack,0,$position).$needle.mb_substr($haystack,$position); | |
| 316 | + mb_internal_encoding($old_encoding); | |
| 317 | + return $r; | |
| 318 | + } | |
| 319 | + | |
| 320 | + protected static function mb_substr($str,$start,$length) | |
| 321 | + { | |
| 322 | + $old_encoding = mb_internal_encoding(); | |
| 323 | + mb_internal_encoding("UTF-8"); | |
| 324 | + $r = mb_substr($str,$start,$length); | |
| 325 | + mb_internal_encoding($old_encoding); | |
| 326 | + return $r; | |
| 327 | + } | |
| 328 | + protected static function mb_strlen($str) | |
| 329 | + { | |
| 330 | + $old_encoding = mb_internal_encoding(); | |
| 331 | + mb_internal_encoding("UTF-8"); | |
| 332 | + $r = mb_strlen($str); | |
| 333 | + mb_internal_encoding($old_encoding); | |
| 334 | + return $r; | |
| 335 | + } | |
| 336 | + protected static function mb_strtolower($str) | |
| 337 | + { | |
| 338 | + $old_encoding = mb_internal_encoding(); | |
| 339 | + mb_internal_encoding("UTF-8"); | |
| 340 | + $r = mb_strtolower($str); | |
| 341 | + mb_internal_encoding($old_encoding); | |
| 342 | + return $r; | |
| 343 | + } | |
| 344 | + | |
| 345 | + public static function uniord($c)//cousin of ord() but for unicode | |
| 346 | + { | |
| 347 | + $ord0 = ord($c{0}); if ($ord0>=0 && $ord0<=127) return $ord0; | |
| 348 | + $ord1 = ord($c{1}); if ($ord0>=192 && $ord0<=223) return ($ord0-192)*64 + ($ord1-128); | |
| 349 | + if ($ord0==0xed && ($ord1 & 0xa0) == 0xa0) return false; //code points, 0xd800 to 0xdfff | |
| 350 | + $ord2 = ord($c{2}); if ($ord0>=224 && $ord0<=239) return ($ord0-224)*4096 + ($ord1-128)*64 + ($ord2-128); | |
| 351 | + $ord3 = ord($c{3}); if ($ord0>=240 && $ord0<=247) return ($ord0-240)*262144 + ($ord1-128)*4096 + ($ord2-128)*64 + ($ord3-128); | |
| 352 | + return false; | |
| 353 | + } | |
| 354 | + public static function utf8($num)//cousin of ascii() but for utf8 | |
| 355 | + { | |
| 356 | + if($num<=0x7F) return chr($num); | |
| 357 | + if($num<=0x7FF) return chr(($num>>6)+192).chr(($num&63)+128); | |
| 358 | + if(0xd800<=$num && $num<=0xdfff) return '';//invalid block of utf8 | |
| 359 | + if($num<=0xFFFF) return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128); | |
| 360 | + if($num<=0x10FFFF) return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128).chr(($num&63)+128); | |
| 361 | + return ''; | |
| 362 | + } | |
| 363 | + | |
| 364 | + public static function is_valid_utf8($string) | |
| 365 | + { | |
| 366 | + for ($i=0, $ix=strlen($string); $i < $ix; $i++) | |
| 367 | + { | |
| 368 | + $c = ord($string{$i}); | |
| 369 | + if ($c==0x09 || $c==0x0a || $c==0x0d || (0x20 <= $c && $c < 0x7e) ) $n = 0; # 0bbbbbbb | |
| 370 | + else if (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb | |
| 371 | + else if ($c==0xed && (ord($string{$i+1}) & 0xa0)==0xa0) return false; //code points, 0xd800 to 0xdfff | |
| 372 | + else if (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb | |
| 373 | + else if (($c & 0xF8) == 0xF0) $n=3; # 11110bbb | |
| 374 | + //else if (($c & 0xFC) == 0xF8) $n=4; # 111110bb //byte 5, unnecessary in 4 byte UTF-8 | |
| 375 | + //else if (($c & 0xFE) == 0xFC) $n=5; # 1111110b //byte 6, unnecessary in 4 byte UTF-8 | |
| 376 | + else return false; | |
| 377 | + for ($j=0; $j<$n; $j++) { // n bytes matching 10bbbbbb follow ? | |
| 378 | + if ((++$i == $ix) || ((ord($string{$i}) & 0xC0) != 0x80)) | |
| 379 | + return false; | |
| 380 | + } | |
| 381 | + } | |
| 382 | + return true; | |
| 383 | + } | |
| 384 | +} | |
| 385 | + | ... | ... |
lib/recaptchalib.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * This is a PHP library that handles calling reCAPTCHA. | |
| 4 | + * - Documentation and latest version | |
| 5 | + * http://recaptcha.net/plugins/php/ | |
| 6 | + * - Get a reCAPTCHA API Key | |
| 7 | + * https://www.google.com/recaptcha/admin/create | |
| 8 | + * - Discussion group | |
| 9 | + * http://groups.google.com/group/recaptcha | |
| 10 | + * | |
| 11 | + * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net | |
| 12 | + * AUTHORS: | |
| 13 | + * Mike Crawford | |
| 14 | + * Ben Maurer | |
| 15 | + * | |
| 16 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 17 | + * of this software and associated documentation files (the "Software"), to deal | |
| 18 | + * in the Software without restriction, including without limitation the rights | |
| 19 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 20 | + * copies of the Software, and to permit persons to whom the Software is | |
| 21 | + * furnished to do so, subject to the following conditions: | |
| 22 | + * | |
| 23 | + * The above copyright notice and this permission notice shall be included in | |
| 24 | + * all copies or substantial portions of the Software. | |
| 25 | + * | |
| 26 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 27 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 28 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 29 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 30 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 31 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 32 | + * THE SOFTWARE. | |
| 33 | + */ | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * The reCAPTCHA server URL's | |
| 37 | + */ | |
| 38 | +define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api"); | |
| 39 | +define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api"); | |
| 40 | +define("RECAPTCHA_VERIFY_SERVER", "www.google.com"); | |
| 41 | + | |
| 42 | +/** | |
| 43 | + * Encodes the given data into a query string format | |
| 44 | + * @param $data - array of string elements to be encoded | |
| 45 | + * @return string - encoded request | |
| 46 | + */ | |
| 47 | +function _recaptcha_qsencode ($data) { | |
| 48 | + $req = ""; | |
| 49 | + foreach ( $data as $key => $value ) | |
| 50 | + $req .= $key . '=' . urlencode( stripslashes($value) ) . '&'; | |
| 51 | + | |
| 52 | + // Cut the last '&' | |
| 53 | + $req=substr($req,0,strlen($req)-1); | |
| 54 | + return $req; | |
| 55 | +} | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | +/** | |
| 60 | + * Submits an HTTP POST to a reCAPTCHA server | |
| 61 | + * @param string $host | |
| 62 | + * @param string $path | |
| 63 | + * @param array $data | |
| 64 | + * @param int port | |
| 65 | + * @return array response | |
| 66 | + */ | |
| 67 | +function _recaptcha_http_post($host, $path, $data, $port = 80) { | |
| 68 | + | |
| 69 | + $req = _recaptcha_qsencode ($data); | |
| 70 | + | |
| 71 | + $http_request = "POST $path HTTP/1.0\r\n"; | |
| 72 | + $http_request .= "Host: $host\r\n"; | |
| 73 | + $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; | |
| 74 | + $http_request .= "Content-Length: " . strlen($req) . "\r\n"; | |
| 75 | + $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; | |
| 76 | + $http_request .= "\r\n"; | |
| 77 | + $http_request .= $req; | |
| 78 | + | |
| 79 | + $response = ''; | |
| 80 | + if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { | |
| 81 | + die ('Could not open socket'); | |
| 82 | + } | |
| 83 | + | |
| 84 | + fwrite($fs, $http_request); | |
| 85 | + | |
| 86 | + while ( !feof($fs) ) | |
| 87 | + $response .= fgets($fs, 1160); // One TCP-IP packet | |
| 88 | + fclose($fs); | |
| 89 | + $response = explode("\r\n\r\n", $response, 2); | |
| 90 | + | |
| 91 | + return $response; | |
| 92 | +} | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | +/** | |
| 97 | + * Gets the challenge HTML (javascript and non-javascript version). | |
| 98 | + * This is called from the browser, and the resulting reCAPTCHA HTML widget | |
| 99 | + * is embedded within the HTML form it was called from. | |
| 100 | + * @param string $pubkey A public key for reCAPTCHA | |
| 101 | + * @param string $error The error given by reCAPTCHA (optional, default is null) | |
| 102 | + * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) | |
| 103 | + | |
| 104 | + * @return string - The HTML to be embedded in the user's form. | |
| 105 | + */ | |
| 106 | +function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) | |
| 107 | +{ | |
| 108 | + if ($pubkey == null || $pubkey == '') { | |
| 109 | + die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"); | |
| 110 | + } | |
| 111 | + | |
| 112 | + if ($use_ssl) { | |
| 113 | + $server = RECAPTCHA_API_SECURE_SERVER; | |
| 114 | + } else { | |
| 115 | + $server = RECAPTCHA_API_SERVER; | |
| 116 | + } | |
| 117 | + | |
| 118 | + $errorpart = ""; | |
| 119 | + if ($error) { | |
| 120 | + $errorpart = "&error=" . $error; | |
| 121 | + } | |
| 122 | + return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script> | |
| 123 | + | |
| 124 | + <noscript> | |
| 125 | + <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/> | |
| 126 | + <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea> | |
| 127 | + <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/> | |
| 128 | + </noscript>'; | |
| 129 | +} | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | +/** | |
| 135 | + * A ReCaptchaResponse is returned from recaptcha_check_answer() | |
| 136 | + */ | |
| 137 | +class ReCaptchaResponse { | |
| 138 | + var $is_valid; | |
| 139 | + var $error; | |
| 140 | +} | |
| 141 | + | |
| 142 | + | |
| 143 | +/** | |
| 144 | + * Calls an HTTP POST function to verify if the user's guess was correct | |
| 145 | + * @param string $privkey | |
| 146 | + * @param string $remoteip | |
| 147 | + * @param string $challenge | |
| 148 | + * @param string $response | |
| 149 | + * @param array $extra_params an array of extra variables to post to the server | |
| 150 | + * @return ReCaptchaResponse | |
| 151 | + */ | |
| 152 | +function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) | |
| 153 | +{ | |
| 154 | + if ($privkey == null || $privkey == '') { | |
| 155 | + die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"); | |
| 156 | + } | |
| 157 | + | |
| 158 | + if ($remoteip == null || $remoteip == '') { | |
| 159 | + die ("For security reasons, you must pass the remote ip to reCAPTCHA"); | |
| 160 | + } | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + //discard spam submissions | |
| 165 | + if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { | |
| 166 | + $recaptcha_response = new ReCaptchaResponse(); | |
| 167 | + $recaptcha_response->is_valid = false; | |
| 168 | + $recaptcha_response->error = 'incorrect-captcha-sol'; | |
| 169 | + return $recaptcha_response; | |
| 170 | + } | |
| 171 | + | |
| 172 | + $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", | |
| 173 | + array ( | |
| 174 | + 'privatekey' => $privkey, | |
| 175 | + 'remoteip' => $remoteip, | |
| 176 | + 'challenge' => $challenge, | |
| 177 | + 'response' => $response | |
| 178 | + ) + $extra_params | |
| 179 | + ); | |
| 180 | + | |
| 181 | + $answers = explode ("\n", $response [1]); | |
| 182 | + $recaptcha_response = new ReCaptchaResponse(); | |
| 183 | + | |
| 184 | + if (trim ($answers [0]) == 'true') { | |
| 185 | + $recaptcha_response->is_valid = true; | |
| 186 | + } | |
| 187 | + else { | |
| 188 | + $recaptcha_response->is_valid = false; | |
| 189 | + $recaptcha_response->error = $answers [1]; | |
| 190 | + } | |
| 191 | + return $recaptcha_response; | |
| 192 | + | |
| 193 | +} | |
| 194 | + | |
| 195 | +/** | |
| 196 | + * gets a URL where the user can sign up for reCAPTCHA. If your application | |
| 197 | + * has a configuration page where you enter a key, you should provide a link | |
| 198 | + * using this function. | |
| 199 | + * @param string $domain The domain where the page is hosted | |
| 200 | + * @param string $appname The name of your application | |
| 201 | + */ | |
| 202 | +function recaptcha_get_signup_url ($domain = null, $appname = null) { | |
| 203 | + return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname)); | |
| 204 | +} | |
| 205 | + | |
| 206 | +function _recaptcha_aes_pad($val) { | |
| 207 | + $block_size = 16; | |
| 208 | + $numpad = $block_size - (strlen ($val) % $block_size); | |
| 209 | + return str_pad($val, strlen ($val) + $numpad, chr($numpad)); | |
| 210 | +} | |
| 211 | + | |
| 212 | +/* Mailhide related code */ | |
| 213 | + | |
| 214 | +function _recaptcha_aes_encrypt($val,$ky) { | |
| 215 | + if (! function_exists ("mcrypt_encrypt")) { | |
| 216 | + die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); | |
| 217 | + } | |
| 218 | + $mode=MCRYPT_MODE_CBC; | |
| 219 | + $enc=MCRYPT_RIJNDAEL_128; | |
| 220 | + $val=_recaptcha_aes_pad($val); | |
| 221 | + return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); | |
| 222 | +} | |
| 223 | + | |
| 224 | + | |
| 225 | +function _recaptcha_mailhide_urlbase64 ($x) { | |
| 226 | + return strtr(base64_encode ($x), '+/', '-_'); | |
| 227 | +} | |
| 228 | + | |
| 229 | +/* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ | |
| 230 | +function recaptcha_mailhide_url($pubkey, $privkey, $email) { | |
| 231 | + if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { | |
| 232 | + die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . | |
| 233 | + "you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>"); | |
| 234 | + } | |
| 235 | + | |
| 236 | + | |
| 237 | + $ky = pack('H*', $privkey); | |
| 238 | + $cryptmail = _recaptcha_aes_encrypt ($email, $ky); | |
| 239 | + | |
| 240 | + return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); | |
| 241 | +} | |
| 242 | + | |
| 243 | +/** | |
| 244 | + * gets the parts of the email to expose to the user. | |
| 245 | + * eg, given johndoe@example,com return ["john", "example.com"]. | |
| 246 | + * the email is then displayed as john...@example.com | |
| 247 | + */ | |
| 248 | +function _recaptcha_mailhide_email_parts ($email) { | |
| 249 | + $arr = preg_split("/@/", $email ); | |
| 250 | + | |
| 251 | + if (strlen ($arr[0]) <= 4) { | |
| 252 | + $arr[0] = substr ($arr[0], 0, 1); | |
| 253 | + } else if (strlen ($arr[0]) <= 6) { | |
| 254 | + $arr[0] = substr ($arr[0], 0, 3); | |
| 255 | + } else { | |
| 256 | + $arr[0] = substr ($arr[0], 0, 4); | |
| 257 | + } | |
| 258 | + return $arr; | |
| 259 | +} | |
| 260 | + | |
| 261 | +/** | |
| 262 | + * Gets html to display an email address given a public an private key. | |
| 263 | + * to get a key, go to: | |
| 264 | + * | |
| 265 | + * http://www.google.com/recaptcha/mailhide/apikey | |
| 266 | + */ | |
| 267 | +function recaptcha_mailhide_html($pubkey, $privkey, $email) { | |
| 268 | + $emailparts = _recaptcha_mailhide_email_parts ($email); | |
| 269 | + $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); | |
| 270 | + | |
| 271 | + return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) . | |
| 272 | + "' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]); | |
| 273 | + | |
| 274 | +} | |
| 275 | + | |
| 276 | + | |
| 277 | +?> | ... | ... |
lib/smbind.class.php
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | + require_once 'MDB2.php'; | |
| 4 | + require_once 'punycode.class.php'; | |
| 5 | + | |
| 6 | + $db = array(); | |
| 7 | + | |
| 8 | + define('COMMENT_PATTERN', '/(\s+;|^;)[^\n]*/i'); | |
| 9 | + define('ORIGIN_PATTERN', '/^\$ORIGIN\s+(.+)\.\s*/msi'); | |
| 10 | + define('SOA_BEGINS_PATTERN', '/^([^\s]+)?(\s+[\d\w]+)?\s+IN\s+SOA\s+/msi'); | |
| 11 | + define('FULL_SOA_PATTERN', '/^([^\s]+)?(\s+[\d\w]+)?\s+IN\s+SOA\s+([-\w\d.]*)\.\s+([-\w\d.]*)\s+\((.*)\)/msi'); | |
| 12 | + define('TIMES_PATTERN', '/\s*(\d+\w?)\s+(\d+\w?)\s+(\d+\w?)\s+(\d+\w?)\s+(\d+\w?)/msi'); | |
| 13 | + define('TXT_PATTERN', '/^\"(.*)\"/msi'); | |
| 14 | + define('MX_PATTERN', '/^(\d+)\s+([^\s]*)/msi'); | |
| 15 | + define('TYPE_PATTERN', '(A|A6|AAAA|AFSDB|APL|ATMA|AXFR|CERT|CNAME|DNAME|DNSKEY|DS|EID|GPOS|HINFO|ISDN|IXFR|KEY|KX|LOC|MAILB|MINFO|MX|NAPTR|NIMLOC|NS|NSAP|NSAP-PTR|NSEC|NXT|OPT|PTR|PX|RP|RRSIG|RT|SIG|SINK|SRV|SSHFP|TKEY|TSIG|TXT|WKS|X25)'); | |
| 16 | + define('RECORD_PATTERN', '/^([^\s]+)?(\s+[\d][\d\w]*)?(\s+IN)?\s+'.TYPE_PATTERN.'\s+([^\s].*$)/msi'); | |
| 17 | + define('BIND_TIME_PATTERN', '/^(\d+)([smhdw])/'); | |
| 18 | + define('IDN_PUNY_PATTERN', '/[^a-z0-9-]/i'); | |
| 19 | + define('IDN_UTF_PATTERN', '/[^a-z0-9\x80-\xFF-]/i'); | |
| 20 | + define('BIND_ZONENAME_PATTERN', '/zone\s+"([^"]+)".*$/msi'); | |
| 21 | + define('BIND_ZONEDATA_PATTERN', '/^([^\s]+)\s+"?([^"]+)"?$/'); | |
| 22 | + define('BIND_SLAVEMASTER_PATTERN', '/^\{([^\};]+);}$/'); | |
| 23 | + | |
| 24 | + function idnToHost($idn) { | |
| 25 | + preg_match(IDN_UTF_PATTERN, $idn, $match); | |
| 26 | + if (count($match) == 0) { | |
| 27 | + $out = ($idn > '') ? Punycode::encodeHostName($idn) : ''; | |
| 28 | + return ((strlen($out) > 4) && (substr($out, 0, 4) == 'xn--')) ? $out : $idn; | |
| 29 | + } | |
| 30 | + $tags = explode($match[0], $idn); | |
| 31 | + $ret = array(); | |
| 32 | + foreach ($tags as $tag) { | |
| 33 | + $ret[] = ($tag == '') ? '' : idnToHost($tag); | |
| 34 | + } | |
| 35 | + return implode($match[0], $ret); | |
| 36 | + } | |
| 37 | + | |
| 38 | + function hostToIdn($host) { | |
| 39 | + preg_match(IDN_PUNY_PATTERN, $host, $match); | |
| 40 | + if (count($match) == 0) { | |
| 41 | + return ((strlen($host) > 4) && (substr($host, 0, 4) == 'xn--')) ? Punycode::decodeHostName($host) : $host; | |
| 42 | + } | |
| 43 | + $tags = explode($match[0], $host); | |
| 44 | + $ret = array(); | |
| 45 | + foreach ($tags as $tag) { | |
| 46 | + $ret[] = ($tag == '') ? '' : hostToIdn($tag, $match[0]); | |
| 47 | + } | |
| 48 | + return implode($match[0], $ret); | |
| 49 | + } | |
| 50 | + | |
| 51 | + class bindConfig { | |
| 52 | + | |
| 53 | + private $zonedef = array(); | |
| 54 | + private $err = ''; | |
| 55 | + | |
| 56 | + public function __debugInfo() { | |
| 57 | + return array( | |
| 58 | + 'zonedef' => $this->zonedef, | |
| 59 | + 'err' => $this->err, | |
| 60 | + ); | |
| 61 | + } | |
| 62 | + | |
| 63 | + public function __construct($file = NULL) { | |
| 64 | + if (!is_null($file)) { | |
| 65 | + return $this->loadConfig($file); | |
| 66 | + } else { | |
| 67 | + $this->zonedef = array(); | |
| 68 | + return true; | |
| 69 | + } | |
| 70 | + } | |
| 71 | + | |
| 72 | + public function getErr() { | |
| 73 | + return $this->err; | |
| 74 | + } | |
| 75 | + | |
| 76 | + public function loadConfig($fpath) { | |
| 77 | + if (!is_string($fpath)) { | |
| 78 | + $this->err .= "Only string parameter accepted\n"; | |
| 79 | + error_log($this->err); | |
| 80 | + return false; | |
| 81 | + } | |
| 82 | + if ($fpath == '') { | |
| 83 | + $this->err .= "Given string is empty\n"; | |
| 84 | + error_log($this->err); | |
| 85 | + return false; | |
| 86 | + } | |
| 87 | + if (!file_exists($fpath)) { | |
| 88 | + $this->err .= "File doesn't exist: '" . $fpath . "'\n"; | |
| 89 | + error_log($this->err); | |
| 90 | + return false; | |
| 91 | + } | |
| 92 | + $conf = file($fpath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); | |
| 93 | + $one = array(); | |
| 94 | + $name = ''; | |
| 95 | + foreach ($conf as $line) { | |
| 96 | + $line = preg_replace('/(\/\/.*|;)$/', '', trim($line)); | |
| 97 | + if ($line == '') { | |
| 98 | + continue; | |
| 99 | + } | |
| 100 | + if ($name == '') { | |
| 101 | + preg_match(BIND_ZONENAME_PATTERN, $line, $match); | |
| 102 | + if (!isset($match[1])) { | |
| 103 | + $this->err .= "Read config error\n"; | |
| 104 | + error_log($this->err); | |
| 105 | + return false; | |
| 106 | + } | |
| 107 | + $name = $match[1]; | |
| 108 | + } else { | |
| 109 | + if ($line == '}') { | |
| 110 | + $this->zonedef[$name] = $one; | |
| 111 | + $one = array(); | |
| 112 | + $name = ''; | |
| 113 | + } else { | |
| 114 | + preg_match(BIND_ZONEDATA_PATTERN, $line, $match); | |
| 115 | + if ((!isset($match[1])) || | |
| 116 | + (!isset($match[2]))) { | |
| 117 | + $this->err .= "Read config error\n"; | |
| 118 | + error_log($this->err); | |
| 119 | + return false; | |
| 120 | + } | |
| 121 | + $key = $match[1]; | |
| 122 | + $data = $match[2]; | |
| 123 | + if ($key == 'masters') { | |
| 124 | + preg_match(BIND_SLAVEMASTER_PATTERN, $data, $match); | |
| 125 | + if (!isset($match[1])) { | |
| 126 | + $this->err .= "Read config error\n"; | |
| 127 | + error_log($this->err); | |
| 128 | + return false; | |
| 129 | + } | |
| 130 | + $data = $match[1]; | |
| 131 | + } | |
| 132 | + $one[$key] = $data; | |
| 133 | + } | |
| 134 | + } | |
| 135 | + } | |
| 136 | + return true; | |
| 137 | + } | |
| 138 | + | |
| 139 | + public function addConfig($name, $data) { | |
| 140 | + $name = strval($name); | |
| 141 | + if (($name == '') || | |
| 142 | + (!is_array($data))) { | |
| 143 | + $this->err .= "Cannot set configset\n"; | |
| 144 | + error_log($this->err); | |
| 145 | + return false; | |
| 146 | + } | |
| 147 | + $this->zonedef[$name] = $data; | |
| 148 | + return true; | |
| 149 | + } | |
| 150 | + | |
| 151 | + public function eraseConfig($name) { | |
| 152 | + $name = strval($name); | |
| 153 | + if ($name == '') { | |
| 154 | + $this->err .= "Cannot set configset\n"; | |
| 155 | + error_log($this->err); | |
| 156 | + return false; | |
| 157 | + } | |
| 158 | + $this->zonedef[$name] = array(); | |
| 159 | + return true; | |
| 160 | + } | |
| 161 | + | |
| 162 | + public function saveConfig($fname) { | |
| 163 | + if (!is_string($fname)) { | |
| 164 | + $this->err .= "Only string parameter accepted\n"; | |
| 165 | + error_log($this->err); | |
| 166 | + return false; | |
| 167 | + } | |
| 168 | + if ($fname == '') { | |
| 169 | + $this->err .= "Given string is empty\n"; | |
| 170 | + error_log($this->err); | |
| 171 | + return false; | |
| 172 | + } | |
| 173 | + $fh = fopen($fname,'w'); | |
| 174 | + fwrite($fh, "// SMbind-ng configuration\n\n"); | |
| 175 | + foreach($this->zonedef as $zone => $def) { | |
| 176 | + if (count($def) == 0) { | |
| 177 | + continue; | |
| 178 | + } | |
| 179 | + fwrite($fh, "// Zone " . hostToIdn($zone) . " (" . $def['type'] . ")\n"); | |
| 180 | + fwrite($fh, "zone \"" . $zone . "\" {\n"); | |
| 181 | + foreach ($def as $key => $param) { | |
| 182 | + switch ($key) { | |
| 183 | + case 'file': | |
| 184 | + $data = "\"" . $param . "\""; | |
| 185 | + break; | |
| 186 | + case 'masters': | |
| 187 | + $data = "{" . $param . ";}"; | |
| 188 | + break; | |
| 189 | + default: | |
| 190 | + $data = $param; | |
| 191 | + } | |
| 192 | + fwrite($fh, str_pad($key, 10, " ", STR_PAD_LEFT) . " " . $data . ";\n"); | |
| 193 | + } | |
| 194 | + fwrite($fh,"};\n\n"); | |
| 195 | + } | |
| 196 | + fclose($fh); | |
| 197 | + return true; | |
| 198 | + } | |
| 199 | + } | |
| 200 | + | |
| 201 | + class Configuration { | |
| 202 | + | |
| 203 | + private $info = array(); | |
| 204 | + | |
| 205 | + public function __debugInfo() { | |
| 206 | + return $this->info; | |
| 207 | + } | |
| 208 | + | |
| 209 | + public function __construct($conffile) { | |
| 210 | + global $db; | |
| 211 | + if (is_string($conffile)) { | |
| 212 | + include $conffile; | |
| 213 | + $dsn = $_CONF['db_type'] . "://" . | |
| 214 | + $_CONF['db_user'] . ":" . | |
| 215 | + $_CONF['db_pass'] . "@" . | |
| 216 | + $_CONF['db_host'] . "/" . | |
| 217 | + $_CONF['db_db'] . | |
| 218 | + '?charset=UTF8'; | |
| 219 | + $db = MDB2::connect($dsn); | |
| 220 | + if (MDB2::isError($db)) { | |
| 221 | + die("Database error: " . MDB2::errorMessage($dbconnect)); | |
| 222 | + } else { | |
| 223 | + $db->setFetchMode(MDB2_FETCHMODE_ASSOC); | |
| 224 | + } | |
| 225 | + $query = $db->query("SELECT prefkey, prefval FROM options WHERE preftype = 'normal'"); | |
| 226 | + if (MDB2::isError($query)) { | |
| 227 | + $err = $query->getMessage() . "\n" . $query->getDebugInfo(); | |
| 228 | + error_log($err); | |
| 229 | + die($err); | |
| 230 | + } | |
| 231 | + while ($res = $query->fetchRow()) { | |
| 232 | + $key = $res['prefkey']; | |
| 233 | + switch ($key) { | |
| 234 | + case 'prins': | |
| 235 | + case 'secns': | |
| 236 | + $keyparam = substr($key, 0, 3) . '_d' . substr($key, -2); | |
| 237 | + break; | |
| 238 | + default: | |
| 239 | + $keyparam = $key; | |
| 240 | + } | |
| 241 | + $_CONF[$keyparam] = $res['prefval']; | |
| 242 | + } | |
| 243 | + $query = $db->query("SELECT prefkey FROM options WHERE prefval = 'on' AND preftype = 'record' ORDER BY prefkey"); | |
| 244 | + $_CONF['parameters'] = array(); | |
| 245 | + while ($res = $query->fetchRow()) { | |
| 246 | + $_CONF['parameters'][] = $res['prefkey']; | |
| 247 | + } | |
| 248 | + $query = $db->query("SELECT DISTINCT type FROM records"); | |
| 249 | + while ($res = $query->fetchRow()) { | |
| 250 | + $_CONF['parameters'][] = $res['type']; | |
| 251 | + } | |
| 252 | + $_CONF['parameters'] = array_unique($_CONF['parameters']); | |
| 253 | + $_CONF['dsn'] = $dsn; | |
| 254 | + $this->info = $_CONF; | |
| 255 | + } | |
| 256 | + } | |
| 257 | + | |
| 258 | + public function __call($method, $args) { | |
| 259 | + if (is_string($method)) { | |
| 260 | + $m = $this->from_CC(substr($method, 3, strlen($method) - 3)); | |
| 261 | + return array_key_exists($m, $this->info) ? $this->info[$m] : false; | |
| 262 | + } | |
| 263 | + } | |
| 264 | + | |
| 265 | + public function __set($param, $arg) { | |
| 266 | + return true; | |
| 267 | + } | |
| 268 | + | |
| 269 | + public function __get($param) { | |
| 270 | + $name = strtolower($param); | |
| 271 | + $return = (array_key_exists($name, $this->info)) ? $this->info[$name] : NULL; | |
| 272 | + if (is_null($return)) { | |
| 273 | + switch ($name) { | |
| 274 | + case 'recaptcha': | |
| 275 | + $return = 'no'; | |
| 276 | + break; | |
| 277 | + case 'nocaptcha': | |
| 278 | + $return = array(); | |
| 279 | + break; | |
| 280 | + case 'namedcheckzone': | |
| 281 | + $return = '/usr/sbin/named-checkzone'; | |
| 282 | + break; | |
| 283 | + case 'namedcheckconf': | |
| 284 | + $return = '/usr/sbin/named-checkconf'; | |
| 285 | + break; | |
| 286 | + case 'rndc': | |
| 287 | + $return = '/usr/sbin/rndc'; | |
| 288 | + break; | |
| 289 | + case 'range': | |
| 290 | + $return = 10; | |
| 291 | + break; | |
| 292 | + case 'title': | |
| 293 | + $return = 'SMbind-ng'; | |
| 294 | + break; | |
| 295 | + case 'template': | |
| 296 | + $return = 'default'; | |
| 297 | + break; | |
| 298 | + default: | |
| 299 | + $return = ''; | |
| 300 | + } | |
| 301 | + } | |
| 302 | + return $return; | |
| 303 | + } | |
| 304 | + | |
| 305 | + private function from_CC($str) { | |
| 306 | + $str = strtolower($str); | |
| 307 | + $func = create_function('$c', 'return "_" . strtolower($c[1]);'); | |
| 308 | + return preg_replace_callback('/([A-Z])/', $func, $str); | |
| 309 | + } | |
| 310 | + | |
| 311 | + public function isExists($id) { | |
| 312 | + return isset($this->info[strtolower($id)]); | |
| 313 | + } | |
| 314 | + | |
| 315 | + } | |
| 316 | + | |
| 317 | + class Session { | |
| 318 | + | |
| 319 | + private $usr = ''; | |
| 320 | + private $psw = ''; | |
| 321 | + private $inc = NULL; | |
| 322 | + | |
| 323 | + public function __debugInfo() { | |
| 324 | + return array( | |
| 325 | + 'usr' => $this->usr, | |
| 326 | + 'psw' => $this->psw, | |
| 327 | + 'inc' => $this->inc, | |
| 328 | + ); | |
| 329 | + } | |
| 330 | + | |
| 331 | + public function __construct() { | |
| 332 | + session_start(); | |
| 333 | + if ((isset($_SESSION['i'])) && (is_numeric($_SESSION['i'])) && ($_SESSION['i'] > 0)) { | |
| 334 | + $this->inc = $_SESSION['i']; | |
| 335 | + $this->inc++; | |
| 336 | + if ((isset($_SESSION['p'])) && (is_string($_SESSION['p']))) { | |
| 337 | + $this->psw = $_SESSION['p']; | |
| 338 | + if ((isset($_SESSION['u'])) && (is_string($_SESSION['u']))) { | |
| 339 | + $this->usr = $_SESSION['u']; | |
| 340 | + } else { | |
| 341 | + $this->psw = ''; | |
| 342 | + } | |
| 343 | + } | |
| 344 | + } else { | |
| 345 | + $this->inc = 1; | |
| 346 | + } | |
| 347 | + $_SESSION['i'] = $this->inc; | |
| 348 | + } | |
| 349 | + | |
| 350 | + public function login($user, $pass) { | |
| 351 | + $_SESSION['u'] = $user; | |
| 352 | + $_SESSION['p'] = $pass; | |
| 353 | + $usr = $user; | |
| 354 | + $psw = $pass; | |
| 355 | + } | |
| 356 | + | |
| 357 | + public function destroy() { | |
| 358 | + $this->usr = ''; | |
| 359 | + $this->psw = ''; | |
| 360 | + $this->inc = 0; | |
| 361 | + $_SESSION = array(); | |
| 362 | + session_destroy(); | |
| 363 | + } | |
| 364 | + | |
| 365 | + public function isEnoughOld() { | |
| 366 | + return $this->inc > 3; | |
| 367 | + } | |
| 368 | + } | |
| 369 | + | |
| 370 | + class User { | |
| 371 | + private $data = array( | |
| 372 | + 'id' => 0, | |
| 373 | + 'username' => '', | |
| 374 | + 'realname' => '', | |
| 375 | + 'password' => '', | |
| 376 | + 'admin' => false, | |
| 377 | + ); | |
| 378 | + private $mzones = array(); | |
| 379 | + private $szones = array(); | |
| 380 | + private $err = ''; | |
| 381 | + private $db = array(); | |
| 382 | + | |
| 383 | + public function __debugInfo() { | |
| 384 | + return array( | |
| 385 | + 'data' => $this->data, | |
| 386 | + 'mzones' => $this->mzones, | |
| 387 | + 'szones' => $this->szones, | |
| 388 | + 'err' => $this->err, | |
| 389 | + 'db' => NULL, | |
| 390 | + ); | |
| 391 | + } | |
| 392 | + | |
| 393 | + public function __construct($uid = NULL) { | |
| 394 | + global $db; | |
| 395 | + $this->db = &$db; | |
| 396 | + if ((is_null($uid)) && | |
| 397 | + (isset($_SESSION['i'])) && | |
| 398 | + ($_SESSION['i'] > 1) && | |
| 399 | + (isset($_SESSION['u'])) && | |
| 400 | + ($_SESSION['p'])) { | |
| 401 | + $user = $_SESSION['u']; | |
| 402 | + $pass = $_SESSION['p']; | |
| 403 | + if (is_object($db)) { | |
| 404 | + if ((is_string($user)) && (is_string($pass))) { | |
| 405 | + $res = $this->db->query("SELECT * FROM users WHERE username ='" . $user . "' AND password = '" . $pass . "'"); | |
| 406 | + if (MDB2::isError($res)) { | |
| 407 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 408 | + error_log($this->err); | |
| 409 | + return false; | |
| 410 | + } elseif ($res->numRows() == 0) { | |
| 411 | + $this->err .= "Username or password does not match"; | |
| 412 | + error_log($this->err); | |
| 413 | + return false; | |
| 414 | + } else { | |
| 415 | + $row = $res->fetchRow(); | |
| 416 | + foreach ($row as $key => $value) { | |
| 417 | + switch ($key) { | |
| 418 | + case 'id': | |
| 419 | + $this->data[$key] = intval($value); | |
| 420 | + break; | |
| 421 | + case 'admin': | |
| 422 | + $this->data[$key] = ($value == 'yes'); | |
| 423 | + break; | |
| 424 | + default: | |
| 425 | + $this->data[$key] = strval($value); | |
| 426 | + } | |
| 427 | + } | |
| 428 | + $this->loadUserZones(); | |
| 429 | + return true; | |
| 430 | + } | |
| 431 | + } | |
| 432 | + } | |
| 433 | + } elseif (((is_array($uid)) && | |
| 434 | + (is_numeric($uid['id']))) || | |
| 435 | + (is_numeric($uid))) { | |
| 436 | + $aid = (is_array($uid)) ? $uid : array('id' => $uid); | |
| 437 | + if ($aid['id'] == 0) { | |
| 438 | + foreach ($aid as $key => $value) { | |
| 439 | + $this->data[$key] = $value; | |
| 440 | + } | |
| 441 | + $this->data['username'] = ((isset($aid['username'])) && ($aid['username'] > '')) ? $aid['username'] : 'NONE'; | |
| 442 | + $this->data['realname'] = ((isset($aid['realname'])) && ($aid['realname'] > '')) ? $aid['realname'] : $this->data['username']; | |
| 443 | + $this->data['password'] = ((isset($aid['password'])) && ($aid['password'] > '')) ? $aid['password'] : 'NONE'; | |
| 444 | + $this->data['admin'] = ((isset($aid['admin'])) && ($aid['admin'] > '') && (($aid['admin'] == 'yes') || ($aid['admin'] == 'no'))) ? $aid['admin'] : 'no'; | |
| 445 | + $res = $this->db->query("SELECT * FROM users WHERE username='" . $this->data['username'] . "'"); | |
| 446 | + if (MDB2::isError($res)) { | |
| 447 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 448 | + error_log($this->err); | |
| 449 | + return false; | |
| 450 | + } | |
| 451 | + if ($res->numRows() > 0) { | |
| 452 | + $this->err .= ($this->data['username'] == 'NONE') ? "Previous error cause a problem\n" : "User already exists\n"; | |
| 453 | + error_log($this->err); | |
| 454 | + return false; | |
| 455 | + } | |
| 456 | + $res = $this->db->query("INSERT INTO users (username, realname, admin, password) VALUES ('" . | |
| 457 | + $this->data['username'] . "', '" . | |
| 458 | + $this->data['realname'] . "', '" . | |
| 459 | + $this->data['admin'] . "', '" . | |
| 460 | + $this->data['password'] . "')"); | |
| 461 | + if (MDB2::isError($res)) { | |
| 462 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 463 | + error_log($this->err); | |
| 464 | + return false; | |
| 465 | + } | |
| 466 | + $res = $this->db->query("SELECT id FROM users WHERE username='" . | |
| 467 | + $this->data['username'] . "' AND realname='" . | |
| 468 | + $this->data['realname'] . "' AND password='" . | |
| 469 | + $this->data['password'] . "'"); | |
| 470 | + if (MDB2::isError($res)) { | |
| 471 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 472 | + error_log($this->err); | |
| 473 | + return false; | |
| 474 | + } | |
| 475 | + $ret = $res->fetchRow(); | |
| 476 | + $this->data['id'] = $ret['id']; | |
| 477 | + return true; | |
| 478 | + } else { | |
| 479 | + $self->data['id'] = $aid['id']; | |
| 480 | + $res = $this->db->query("SELECT * FROM users WHERE id = '" . $self->data['id'] . "'"); | |
| 481 | + if (MDB2::isError($res)) { | |
| 482 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 483 | + error_log($this->err); | |
| 484 | + return false; | |
| 485 | + } elseif ($res->numRows() == 0) { | |
| 486 | + $this->err .= "User not found with this id = " . $self->data['id']; | |
| 487 | + error_log($this->err); | |
| 488 | + return false; | |
| 489 | + } else { | |
| 490 | + $row = $res->fetchRow(); | |
| 491 | + foreach ($row as $key => $value) { | |
| 492 | + switch ($key) { | |
| 493 | + case 'id': | |
| 494 | + $this->data[$key] = intval($value); | |
| 495 | + break; | |
| 496 | + case 'admin': | |
| 497 | + $this->data[$key] = ($value == 'yes'); | |
| 498 | + break; | |
| 499 | + default: | |
| 500 | + $this->data[$key] = strval($value); | |
| 501 | + } | |
| 502 | + } | |
| 503 | + } | |
| 504 | + } | |
| 505 | + } | |
| 506 | + } | |
| 507 | + | |
| 508 | + public function loadUserZones() { | |
| 509 | + $WHERE = ''; | |
| 510 | + if (!$this->isAdmin()) { | |
| 511 | + $WHERE .= "WHERE owner = '" . $this->getId() . "' "; | |
| 512 | + } | |
| 513 | + $res = $this->db->query("SELECT id FROM zones " . $WHERE . "ORDER BY name"); | |
| 514 | + if (MDB2::isError($res)) { | |
| 515 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 516 | + error_log($this->err); | |
| 517 | + return false; | |
| 518 | + } else { | |
| 519 | + $this->mzones = array(); | |
| 520 | + while ($rec = $res->fetchRow()) { | |
| 521 | + $this->mzones[] = $rec['id']; | |
| 522 | + } | |
| 523 | + $res = $this->db->query("SELECT id FROM slave_zones " . $WHERE . "ORDER BY name"); | |
| 524 | + if (MDB2::isError($res)) { | |
| 525 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 526 | + error_log($this->err); | |
| 527 | + return false; | |
| 528 | + } else { | |
| 529 | + $this->szones = array(); | |
| 530 | + while ($rec = $res->fetchRow()) { | |
| 531 | + $this->szones[] = $rec['id']; | |
| 532 | + } | |
| 533 | + } | |
| 534 | + } | |
| 535 | + return true; | |
| 536 | + } | |
| 537 | + | |
| 538 | + public function getUnvalidatedZones($zonetype = NULL) { | |
| 539 | + $ret = array(); | |
| 540 | + if (is_string($zonetype)) { | |
| 541 | + $tag = ''; | |
| 542 | + $db = NULL; | |
| 543 | + switch ($zonetype) { | |
| 544 | + case 'slave': | |
| 545 | + $tag = 'slave_'; | |
| 546 | + $cnt = sizeof($this->szones); | |
| 547 | + $lst = implode(',', $this->szones); | |
| 548 | + break; | |
| 549 | + case 'master': | |
| 550 | + $cnt = sizeof($this->mzones); | |
| 551 | + $lst = implode(',', $this->mzones); | |
| 552 | + break; | |
| 553 | + } | |
| 554 | + if ($cnt > 0) { | |
| 555 | + $res = $this->db->query("SELECT id, name FROM " . $tag . "zones WHERE id IN (" . $lst . ") AND valid <> 'yes' and updated <> 'del'"); | |
| 556 | + if (MDB2::isError($res)) { | |
| 557 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 558 | + error_log($this->err); | |
| 559 | + return false; | |
| 560 | + } else { | |
| 561 | + while ($recd = $res->fetchRow()) { | |
| 562 | + $recd['name'] = hostToIdn($recd['name']); | |
| 563 | + $ret[] = $recd; | |
| 564 | + } | |
| 565 | + } | |
| 566 | + } | |
| 567 | + } | |
| 568 | + return $ret; | |
| 569 | + } | |
| 570 | + public function getDeletedZones($zonetype = NULL) { | |
| 571 | + $ret = array(); | |
| 572 | + if (is_string($zonetype)) { | |
| 573 | + $tag = ''; | |
| 574 | + $db = NULL; | |
| 575 | + switch ($zonetype) { | |
| 576 | + case 'slave': | |
| 577 | + $tag = 'slave_'; | |
| 578 | + $cnt = sizeof($this->szones); | |
| 579 | + $lst = implode(',', $this->szones); | |
| 580 | + break; | |
| 581 | + case 'master': | |
| 582 | + $cnt = sizeof($this->mzones); | |
| 583 | + $lst = implode(',', $this->mzones); | |
| 584 | + break; | |
| 585 | + } | |
| 586 | + if ($cnt > 0) { | |
| 587 | + $res = $this->db->query("SELECT id, name FROM " . $tag . "zones WHERE owner = " . $this->data['id'] . " AND updated = 'del'"); | |
| 588 | + if (MDB2::isError($res)) { | |
| 589 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 590 | + error_log($this->err); | |
| 591 | + return false; | |
| 592 | + } else { | |
| 593 | + while ($recd = $res->fetchRow()) { | |
| 594 | + $recd['name'] = hostToIdn($recd['name']); | |
| 595 | + $ret[] = $recd; | |
| 596 | + } | |
| 597 | + } | |
| 598 | + } | |
| 599 | + } | |
| 600 | + return $ret; | |
| 601 | + } | |
| 602 | + | |
| 603 | + public function getCommitableZones($zonetype = NULL) { | |
| 604 | + $ret = array(); | |
| 605 | + if (is_string($zonetype)) { | |
| 606 | + $tag = ''; | |
| 607 | + $db = NULL; | |
| 608 | + switch ($zonetype) { | |
| 609 | + case 'slave': | |
| 610 | + $tag = 'slave_'; | |
| 611 | + $cnt = sizeof($this->szones); | |
| 612 | + $lst = implode(',', $this->szones); | |
| 613 | + break; | |
| 614 | + case 'master': | |
| 615 | + $cnt = sizeof($this->mzones); | |
| 616 | + $lst = implode(',', $this->mzones); | |
| 617 | + break; | |
| 618 | + } | |
| 619 | + if ($cnt > 0) { | |
| 620 | + $res = $this->db->query("SELECT id, name FROM " . $tag . "zones WHERE id IN (" . $lst . ") AND valid = 'yes' AND updated = 'yes'"); | |
| 621 | + if (MDB2::isError($res)) { | |
| 622 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 623 | + error_log($this->err); | |
| 624 | + return false; | |
| 625 | + } else { | |
| 626 | + while ($recd = $res->fetchRow()) { | |
| 627 | + $recd['name'] = hostToIdn($recd['name']); | |
| 628 | + $ret[] = $recd; | |
| 629 | + } | |
| 630 | + } | |
| 631 | + } | |
| 632 | + } | |
| 633 | + return $ret; | |
| 634 | + } | |
| 635 | + | |
| 636 | + public function eraseUser() { | |
| 637 | + $this->loadUserZones(); | |
| 638 | + $mz =array(); | |
| 639 | + foreach ($this->mzones as $master) { | |
| 640 | + $mz = new masterRecord($master); | |
| 641 | + $mz->loadZoneHead(); | |
| 642 | + $mzh = $mz->getZoneHead(); | |
| 643 | + $mzh['owner'] = 1; | |
| 644 | + $mz->setZoneHead($mzh); | |
| 645 | + $mz->saveZoneHead(); | |
| 646 | + } | |
| 647 | + $mz =array(); | |
| 648 | + $sz =array(); | |
| 649 | + foreach ($this->szones as $slave) { | |
| 650 | + $sz = new slaveRecord($slave); | |
| 651 | + $sz->loadZoneHead(); | |
| 652 | + $szh = $sz->getZoneHead(); | |
| 653 | + $szh['owner'] = 1; | |
| 654 | + $sz->setZoneHead($szh); | |
| 655 | + $sz->saveZoneHead(); | |
| 656 | + } | |
| 657 | + $sz =array(); | |
| 658 | + $res = $this->db->query("DELETE FROM users WHERE id = " . $this->data['id']); | |
| 659 | + if (MDB2::isError($res)) { | |
| 660 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 661 | + error_log($this->err); | |
| 662 | + return false; | |
| 663 | + } | |
| 664 | + return true; | |
| 665 | + } | |
| 666 | + | |
| 667 | + public function getMasters($type = 'all') { | |
| 668 | + $out = array(); | |
| 669 | + if ($type == 'live') { | |
| 670 | + foreach ($this->mzones as $zoneid) { | |
| 671 | + $zone = new masterZone(array('id' => intval($zoneid))); | |
| 672 | + $zone->loadZoneHead(); | |
| 673 | + $head = $zone->getZoneHeadRaw(); | |
| 674 | + if ($head['updated'] != 'del') { | |
| 675 | + $out[] = intval($zoneid); | |
| 676 | + } | |
| 677 | + } | |
| 678 | + } else { | |
| 679 | + $out = $this->mzones; | |
| 680 | + } | |
| 681 | + return $out; | |
| 682 | + } | |
| 683 | + | |
| 684 | + public function getSlaves($type = 'all') { | |
| 685 | + $out = array(); | |
| 686 | + if ($type == 'live') { | |
| 687 | + foreach ($this->szones as $zoneid) { | |
| 688 | + $zone = new slaveZone(array('id' => intval($zoneid))); | |
| 689 | + $zone->loadZoneHead(); | |
| 690 | + $head = $zone->getZoneHeadRaw(); | |
| 691 | + if ($head['updated'] != 'del') { | |
| 692 | + $out[] = intval($zoneid); | |
| 693 | + } | |
| 694 | + } | |
| 695 | + } else { | |
| 696 | + $out = $this->szones; | |
| 697 | + } | |
| 698 | + return $out; | |
| 699 | + } | |
| 700 | + | |
| 701 | + public function isOwned($id, $type, $state = 'all') { | |
| 702 | + $zarr = array(); | |
| 703 | + switch ($type) { | |
| 704 | + case 'master': | |
| 705 | + $zarr = $this->getMasters($state); | |
| 706 | + break; | |
| 707 | + case 'slave': | |
| 708 | + $zarr = $this->getSlaves($state); | |
| 709 | + break; | |
| 710 | + } | |
| 711 | + foreach ($zarr as $zid) { | |
| 712 | + if ($zid == $id) { | |
| 713 | + return true; | |
| 714 | + } | |
| 715 | + } | |
| 716 | + return false; | |
| 717 | + } | |
| 718 | + | |
| 719 | + public function getName() { | |
| 720 | + return $this->data['username']; | |
| 721 | + } | |
| 722 | + | |
| 723 | + public function getErr() { | |
| 724 | + return $this->err; | |
| 725 | + } | |
| 726 | + | |
| 727 | + public function getFullName() { | |
| 728 | + return $this->data['realname']; | |
| 729 | + } | |
| 730 | + | |
| 731 | + public function isAdmin() { | |
| 732 | + return $this->data['admin']; | |
| 733 | + } | |
| 734 | + | |
| 735 | + public function getId() { | |
| 736 | + return $this->data['id']; | |
| 737 | + } | |
| 738 | + | |
| 739 | + public function getPasswordHash() { | |
| 740 | + return $this->data['password']; | |
| 741 | + } | |
| 742 | + | |
| 743 | + public function getUser() { | |
| 744 | + $arr = array(); | |
| 745 | + foreach (array('id', 'username', 'realname', 'admin') as $key) { | |
| 746 | + $arr[$key] = $this->data[$key]; | |
| 747 | + } | |
| 748 | + return $arr; | |
| 749 | + } | |
| 750 | + | |
| 751 | + public function getAllusers() { | |
| 752 | + $out = array(); | |
| 753 | + $res = $this->db->query("SELECT id, username, realname, admin FROM users ORDER BY realname"); | |
| 754 | + if (MDB2::isError($res)) { | |
| 755 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 756 | + error_log($this->err); | |
| 757 | + } else { | |
| 758 | + while ($row = $res->fetchRow()) { | |
| 759 | + $out[] = $row; | |
| 760 | + } | |
| 761 | + } | |
| 762 | + return $out; | |
| 763 | + } | |
| 764 | + | |
| 765 | + public function loadUserById() { | |
| 766 | + $res = $this->db->query("SELECT * FROM users WHERE id = " . $this->data['id']); | |
| 767 | + if (MDB2::isError($res)) { | |
| 768 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 769 | + error_log($this->err); | |
| 770 | + return false; | |
| 771 | + } elseif ($res->numRows() == 0) { | |
| 772 | + $this->err .= "User not found"; | |
| 773 | + error_log($this->err); | |
| 774 | + return false; | |
| 775 | + } else { | |
| 776 | + $row = $res->fetchRow(); | |
| 777 | + foreach ($row as $key => $value) { | |
| 778 | + switch ($key) { | |
| 779 | + case 'id': | |
| 780 | + $this->data[$key] = intval($value); | |
| 781 | + break; | |
| 782 | + case 'admin': | |
| 783 | + $this->data[$key] = ($value == 'yes'); | |
| 784 | + break; | |
| 785 | + default: | |
| 786 | + $this->data[$key] = strval($value); | |
| 787 | + } | |
| 788 | + } | |
| 789 | + return true; | |
| 790 | + } | |
| 791 | + } | |
| 792 | + | |
| 793 | + public function set($rname = NULL, $pass = NULL, $adm = NULL) { | |
| 794 | + if ((isset($pass)) || (isset($adm)) || (isset($rname))) { | |
| 795 | + $pstr = ((is_null($pass)) || (strlen($pass) != 32)) ? "" : "password = '" . $pass . "'"; | |
| 796 | + $astr = ((is_null($adm)) || (($adm != 'yes') && ($adm != 'no'))) ? "" : "admin = '" . $adm . "'"; | |
| 797 | + $rnstr = ((is_null($rname)) || ($rname == '')) ? "" : "realname = '" . $rname . "'"; | |
| 798 | + $setstr = $pstr; | |
| 799 | + if ($astr > '') { | |
| 800 | + $setstr .= ($setstr != "") ? ", " . $astr : $astr; | |
| 801 | + } | |
| 802 | + if ($rnstr > '') { | |
| 803 | + $setstr .= ($setstr != "") ? ", " . $rnstr : $rnstr; | |
| 804 | + } | |
| 805 | + if ($setstr > "") { | |
| 806 | + $res = $this->db->query("UPDATE users SET " . $setstr . " WHERE id = " . $this->data['id']); | |
| 807 | + if (MDB2::isError($res)) { | |
| 808 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 809 | + error_log($this->err); | |
| 810 | + return false; | |
| 811 | + } | |
| 812 | + return $this->loadUserById(); | |
| 813 | + } else { | |
| 814 | + return true; | |
| 815 | + } | |
| 816 | + } else { | |
| 817 | + return false; | |
| 818 | + } | |
| 819 | + } | |
| 820 | + } | |
| 821 | + | |
| 822 | + class masterRecord { | |
| 823 | + | |
| 824 | + private $record = array( | |
| 825 | + 'id' => NULL, | |
| 826 | + 'zone' => NULL, | |
| 827 | + 'host' => '', | |
| 828 | + 'type' => '', | |
| 829 | + 'pri' => 0, | |
| 830 | + 'destination' => '', | |
| 831 | + 'ttl' => 0, | |
| 832 | + ); | |
| 833 | + private $db = NULL; | |
| 834 | + private $err = ''; | |
| 835 | + | |
| 836 | + public function __debugInfo() { | |
| 837 | + return array( | |
| 838 | + 'record' => $this->record, | |
| 839 | + 'err' => $this->err, | |
| 840 | + 'db' => NULL, | |
| 841 | + ); | |
| 842 | + } | |
| 843 | + | |
| 844 | + public function __construct($param = NULL) { | |
| 845 | + global $db; | |
| 846 | + if (is_object($db)) { | |
| 847 | + $this->db = &$db; | |
| 848 | + } | |
| 849 | + if (!is_null($param)) { | |
| 850 | + return $this->setRecord($param); | |
| 851 | + } | |
| 852 | + return true; | |
| 853 | + } | |
| 854 | + | |
| 855 | + public function getId() { | |
| 856 | + return $this->record['id']; | |
| 857 | + } | |
| 858 | + | |
| 859 | + private function fill_record($param) { | |
| 860 | + foreach ($param as $key => $value) { | |
| 861 | + switch ($key) { | |
| 862 | + case 'id': | |
| 863 | + case 'pri': | |
| 864 | + case 'ttl': | |
| 865 | + case 'zone': | |
| 866 | + $this->record[$key] = intval($value); | |
| 867 | + break; | |
| 868 | + case 'host': | |
| 869 | + $this->record[$key] = idnToHost($value); | |
| 870 | + break; | |
| 871 | + case 'type': | |
| 872 | + $this->record[$key] = strtoupper($value); | |
| 873 | + break; | |
| 874 | + case 'destination': | |
| 875 | + switch ($this->record['type']) { | |
| 876 | + case 'MX': | |
| 877 | + case 'CNAME': | |
| 878 | + case 'SRV': | |
| 879 | + case 'PTR': | |
| 880 | + case 'NS': | |
| 881 | + $this->record[$key] = idnToHost($value); | |
| 882 | + break; | |
| 883 | + default: | |
| 884 | + $this->record[$key] = strval($value); | |
| 885 | + } | |
| 886 | + break; | |
| 887 | + default: | |
| 888 | + $this->record[$key] = $value; | |
| 889 | + } | |
| 890 | + } | |
| 891 | + } | |
| 892 | + | |
| 893 | + public function setRecord($param) { | |
| 894 | + if (is_string($param)) { | |
| 895 | + if (!$this->parseRecord($param)) { | |
| 896 | + return false; | |
| 897 | + } | |
| 898 | + } elseif (is_numeric($param)) { | |
| 899 | + $this->record['id'] = $param; | |
| 900 | + } elseif (is_array($param)) { | |
| 901 | + $this->fill_record($param); | |
| 902 | + } else { | |
| 903 | + ob_start(); | |
| 904 | + var_dump($param); | |
| 905 | + $this->err .= "Unidentified parameter" . "\n" . ob_get_clean(); | |
| 906 | + error_log($this->err); | |
| 907 | + return false; | |
| 908 | + } | |
| 909 | + return true; | |
| 910 | + } | |
| 911 | + | |
| 912 | + private function bind_time_format($value) { | |
| 913 | + if (preg_match(BIND_TIME_PATTERN, strtolower($value), $match)) { | |
| 914 | + $value = $match[1]; | |
| 915 | + switch ($match[2]) { | |
| 916 | + case "s": | |
| 917 | + $multiplier = 1; | |
| 918 | + break; | |
| 919 | + case "m": | |
| 920 | + $multiplier = 60; | |
| 921 | + break; | |
| 922 | + case "h": | |
| 923 | + $multiplier = 3600; | |
| 924 | + break; | |
| 925 | + case "d": | |
| 926 | + $multiplier = 86400; | |
| 927 | + break; | |
| 928 | + case "w": | |
| 929 | + $multiplier = 604800; | |
| 930 | + break; | |
| 931 | + } | |
| 932 | + $value = $value*$multiplier; | |
| 933 | + } | |
| 934 | + return $value; | |
| 935 | + } | |
| 936 | + | |
| 937 | + private function parseRecord($buffer) { | |
| 938 | + if (preg_match(RECORD_PATTERN, $buffer, $match)) { | |
| 939 | + $this->record['host'] = $match[1]; | |
| 940 | + if ($this->record['host'] == '') { | |
| 941 | + $this->record['host'] = '@'; | |
| 942 | + } | |
| 943 | + $this->record['type'] = strtoupper($match[4]); | |
| 944 | + if (isset($match[2])) { | |
| 945 | + $this->record['ttl'] = intval($this->bind_time_format($match[2])); | |
| 946 | + } else { | |
| 947 | + $this->record['ttl'] = 0; | |
| 948 | + } | |
| 949 | + switch ($this->record['type']) { | |
| 950 | + case 'MX': | |
| 951 | + if (preg_match(MX_PATTERN, $match[5], $match)) { | |
| 952 | + $this->record['pri'] = intval($match[1]); | |
| 953 | + $this->record['destination'] = idnToHost($match[2]); | |
| 954 | + } else { | |
| 955 | + ob_start(); | |
| 956 | + var_dump($buffer); | |
| 957 | + $this->err .= "MX cannot be parsed" . "\n" . ob_get_clean(); | |
| 958 | + error_log($this->err); | |
| 959 | + return NULL; | |
| 960 | + } | |
| 961 | + break; | |
| 962 | + case 'SRV': | |
| 963 | + case 'CNAME': | |
| 964 | + case 'NS': | |
| 965 | + case 'PTR': | |
| 966 | + $this->record['destination'] = idnToHost($match[5]); | |
| 967 | + break; | |
| 968 | + case 'TXT': | |
| 969 | + $this->record['destination'] = idnToHost(preg_replace('/(^"+|"+$|"+\s*"+)/msi', '', trim($match[5]))); | |
| 970 | + break; | |
| 971 | + default: | |
| 972 | + $this->record['destination'] = $match[5]; | |
| 973 | + } | |
| 974 | + return true; | |
| 975 | + } else { | |
| 976 | + ob_start(); | |
| 977 | + var_dump($buffer); | |
| 978 | + $this->err .= "Record cannot be parsed" . "\n" . ob_get_clean(); | |
| 979 | + error_log($this->err); | |
| 980 | + return false; | |
| 981 | + } | |
| 982 | + } | |
| 983 | + | |
| 984 | + public function getRecordRaw() { | |
| 985 | + return $this->record; | |
| 986 | + } | |
| 987 | + | |
| 988 | + public function getRecord() { | |
| 989 | + $out = $this->record; | |
| 990 | + $out['host'] = hostToIdn($out['host']); | |
| 991 | + switch ($out['type']) { | |
| 992 | + case 'MX': | |
| 993 | + case 'SRV': | |
| 994 | + case 'NS': | |
| 995 | + case 'CNAME': | |
| 996 | + case 'PTR': | |
| 997 | + $out['destination'] = hostToIdn($out['destination']); | |
| 998 | + } | |
| 999 | + return $out; | |
| 1000 | + } | |
| 1001 | + | |
| 1002 | + private function is_identified() { | |
| 1003 | + return (is_numeric($this->record['id']) && ($this->record['id'] > 0)); | |
| 1004 | + } | |
| 1005 | + | |
| 1006 | + public function loadRecord() { | |
| 1007 | + if ($this->is_identified()) { | |
| 1008 | + $res = $this->db->query('SELECT * FROM records WHERE id =' . $this->record['id']); | |
| 1009 | + if (MDB2::isError($res)) { | |
| 1010 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1011 | + error_log($this->err); | |
| 1012 | + return false; | |
| 1013 | + } else { | |
| 1014 | + $row = $res->fetchRow(); | |
| 1015 | + if (is_array($row)) { | |
| 1016 | + $this->fill_record($row); | |
| 1017 | + return true; | |
| 1018 | + } else { | |
| 1019 | + return NULL; | |
| 1020 | + } | |
| 1021 | + } | |
| 1022 | + } else { | |
| 1023 | + ob_start(); | |
| 1024 | + var_dump($this-record); | |
| 1025 | + $this->err .= "Record is not identified" . "\n" . ob_get_clean(); | |
| 1026 | + error_log($this->err); | |
| 1027 | + return false; | |
| 1028 | + } | |
| 1029 | + } | |
| 1030 | + | |
| 1031 | + public function getErr() { | |
| 1032 | + return $this->err; | |
| 1033 | + } | |
| 1034 | + | |
| 1035 | + private function is_complete() { | |
| 1036 | + return (($this->record['zone'] > 0) && | |
| 1037 | + ($this->record['type'] > '') && | |
| 1038 | + ( | |
| 1039 | + ($this->record['host'] > '') || | |
| 1040 | + ($this->record['destination'] > '') | |
| 1041 | + )); | |
| 1042 | + } | |
| 1043 | + | |
| 1044 | + private function find_record() { | |
| 1045 | + $res = $this->db->query("SELECT id FROM records WHERE " . | |
| 1046 | + "zone = " . $this->record['zone'] . " AND " . | |
| 1047 | + "host = '" . $this->record['host'] . "' AND " . | |
| 1048 | + "ttl = " . $this->record['ttl'] . " AND " . | |
| 1049 | + "type = '" . $this->record['type'] . "' AND " . | |
| 1050 | + "pri = " . $this->record['pri'] . " AND " . | |
| 1051 | + "destination = '" . $this->record['destination'] . "'" | |
| 1052 | + ); | |
| 1053 | + if (MDB2::isError($res)) { | |
| 1054 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1055 | + error_log($this->err); | |
| 1056 | + return 0; | |
| 1057 | + } else { | |
| 1058 | + $value = $res->fetchRow(); | |
| 1059 | + return $value['id']; | |
| 1060 | + } | |
| 1061 | + } | |
| 1062 | + | |
| 1063 | + public function saveRecord() { | |
| 1064 | + if ($this->is_complete()) { | |
| 1065 | + if ($this->record['host'] == '') { | |
| 1066 | + $this->record['host'] = '@'; | |
| 1067 | + } elseif ($this->record['destination'] == '') { | |
| 1068 | + $this->record['destination'] = '@'; | |
| 1069 | + } | |
| 1070 | + if ($this->record['type'] == 'MX') { | |
| 1071 | + $this->record['pri'] = ($this->record['pri'] == 0) ? 10 : $this->record['pri']; | |
| 1072 | + } else { | |
| 1073 | + $this->record['pri'] = 0; | |
| 1074 | + } | |
| 1075 | + if ((is_numeric($this->record['id'])) && ($this->record['id'] > 0)) { | |
| 1076 | + $res = $this->db->query("UPDATE records SET " . | |
| 1077 | + "zone = " . $this->record['zone'] . ", " . | |
| 1078 | + "host = '" . $this->record['host'] . "', " . | |
| 1079 | + "ttl = " . $this->record['ttl'] . ", " . | |
| 1080 | + "type = '" . $this->record['type'] . "', " . | |
| 1081 | + "pri = " . $this->record['pri'] . ", " . | |
| 1082 | + "destination = '" . $this->record['destination'] . | |
| 1083 | + "' WHERE id = " . $this->record['id'] | |
| 1084 | + ); | |
| 1085 | + if (MDB2::isError($res)) { | |
| 1086 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1087 | + error_log($this->err); | |
| 1088 | + return false; | |
| 1089 | + } else { | |
| 1090 | + return $this->loadRecord(); | |
| 1091 | + } | |
| 1092 | + } else { | |
| 1093 | + $id = $this->find_record(); | |
| 1094 | + if ($id > 0) { | |
| 1095 | + $this->record['id'] = $id; | |
| 1096 | + return true; | |
| 1097 | + } else { | |
| 1098 | + $res = $this->db->query("INSERT INTO records (zone, host, ttl, type, pri, destination) VALUES (" . | |
| 1099 | + $this->record['zone'] . ", '" . | |
| 1100 | + $this->record['host'] . "', " . | |
| 1101 | + $this->record['ttl'] . ", '" . | |
| 1102 | + $this->record['type'] . "', " . | |
| 1103 | + $this->record['pri'] . ", '" . | |
| 1104 | + $this->record['destination'] . "')" | |
| 1105 | + ); | |
| 1106 | + if (MDB2::isError($res)) { | |
| 1107 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1108 | + error_log($this->err); | |
| 1109 | + return false; | |
| 1110 | + } else { | |
| 1111 | + $id = $this->find_record(); | |
| 1112 | + if ($id > 0) { | |
| 1113 | + $this->record['id'] = $id; | |
| 1114 | + return true; | |
| 1115 | + } else { | |
| 1116 | + if ($this->err == '') { | |
| 1117 | + ob_start(); | |
| 1118 | + var_dump($this->record); | |
| 1119 | + $this->err .= "Unknown write error" . "\n" . ob_get_clean(); | |
| 1120 | + error_log($this->err); | |
| 1121 | + } | |
| 1122 | + return false; | |
| 1123 | + } | |
| 1124 | + } | |
| 1125 | + } | |
| 1126 | + } | |
| 1127 | + } else { | |
| 1128 | + ob_start(); | |
| 1129 | + var_dump($this->record); | |
| 1130 | + $this->err .= "Record is not complete" . "\n" . ob_get_clean(); | |
| 1131 | + error_log($this->err); | |
| 1132 | + return false; | |
| 1133 | + } | |
| 1134 | + } | |
| 1135 | + | |
| 1136 | + public function eraseRecord() { | |
| 1137 | + if ($this->is_identified()) { | |
| 1138 | + $res = $this->db->query("DELETE FROM records WHERE id = " . $this->record['id']); | |
| 1139 | + if (MDB2::isError($res)) { | |
| 1140 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1141 | + error_log($this->err); | |
| 1142 | + return false; | |
| 1143 | + } else { | |
| 1144 | + return true; | |
| 1145 | + } | |
| 1146 | + } else { | |
| 1147 | + ob_start(); | |
| 1148 | + var_dump($this->record); | |
| 1149 | + $this->err .= "Record is not set" . "\n" . ob_get_clean(); | |
| 1150 | + error_log($this->err); | |
| 1151 | + return false; | |
| 1152 | + } | |
| 1153 | + } | |
| 1154 | + } | |
| 1155 | + | |
| 1156 | + class slaveZone { | |
| 1157 | + private $head = array( | |
| 1158 | + 'id' => NULL, | |
| 1159 | + 'name' => '', | |
| 1160 | + 'master' => '', | |
| 1161 | + 'owner' => 0, | |
| 1162 | + 'updated' => 'no', | |
| 1163 | + 'valid' => 'may', | |
| 1164 | + ); | |
| 1165 | + private $db = NULL; | |
| 1166 | + private $err = ''; | |
| 1167 | + | |
| 1168 | + public function __debugInfo() { | |
| 1169 | + return array( | |
| 1170 | + 'head' => $this->head, | |
| 1171 | + 'err' => $this->err, | |
| 1172 | + 'db' => NULL, | |
| 1173 | + ); | |
| 1174 | + } | |
| 1175 | + | |
| 1176 | + public function __construct($param = NULL) { | |
| 1177 | + global $db; | |
| 1178 | + if (is_object($db)) { | |
| 1179 | + $this->db = &$db; | |
| 1180 | + } | |
| 1181 | + if (!is_null($param)) { | |
| 1182 | + return $this->setZoneHead($param); | |
| 1183 | + } | |
| 1184 | + return true; | |
| 1185 | + } | |
| 1186 | + | |
| 1187 | + public function setZoneHead($param) { | |
| 1188 | + if (is_string($param)) { | |
| 1189 | + $this->head['name'] = idnToHost($param); | |
| 1190 | + } elseif (is_numeric($param)) { | |
| 1191 | + $this->head['id'] = $param; | |
| 1192 | + } elseif (is_array($param)) { | |
| 1193 | + $this->fill_head($param); | |
| 1194 | + } else { | |
| 1195 | + ob_start(); | |
| 1196 | + var_dump($param); | |
| 1197 | + $this->err .= "Unidentified parameter" . "\n" . ob_get_clean(); | |
| 1198 | + error_log($this->err); | |
| 1199 | + return false; | |
| 1200 | + } | |
| 1201 | + return true; | |
| 1202 | + } | |
| 1203 | + | |
| 1204 | + private function fill_head($param) { | |
| 1205 | + foreach ($param as $key => $value) { | |
| 1206 | + switch ($key) { | |
| 1207 | + case 'id': | |
| 1208 | + case 'owner': | |
| 1209 | + $this->head[$key] = intval($value); | |
| 1210 | + break; | |
| 1211 | + case 'master': | |
| 1212 | + case 'name': | |
| 1213 | + $this->head[$key] = idnToHost($value); | |
| 1214 | + break; | |
| 1215 | + default: | |
| 1216 | + $this->head[$key] = $value; | |
| 1217 | + } | |
| 1218 | + } | |
| 1219 | + } | |
| 1220 | + | |
| 1221 | + private function is_identified() { | |
| 1222 | + return ((isset($this->head['id'])) || ($this->head['name'] > '')); | |
| 1223 | + } | |
| 1224 | + | |
| 1225 | + private function notIdent($complete = false) { | |
| 1226 | + ob_start(); | |
| 1227 | + var_dump($this->head); | |
| 1228 | + $head = ob_get_clean(); | |
| 1229 | + if ($complete) { | |
| 1230 | + $this->err .= "Zone is not complete" . "\n" . $head; | |
| 1231 | + error_log($this->err); | |
| 1232 | + } else { | |
| 1233 | + $this->err .= "Unidentified zone" . "\n" . $head; | |
| 1234 | + error_log($this->err); | |
| 1235 | + } | |
| 1236 | + } | |
| 1237 | + | |
| 1238 | + public function loadZoneHead() { | |
| 1239 | + if ($this->is_identified()) { | |
| 1240 | + $where = ' WHERE '; | |
| 1241 | + if (isset($this->head['id'])) { | |
| 1242 | + $where .= "id = " . $this->head['id']; | |
| 1243 | + } else { | |
| 1244 | + $where .= "name = '" . $this->head['name'] . "'"; | |
| 1245 | + } | |
| 1246 | + $res = $this->db->query("SELECT * FROM slave_zones" . $where); | |
| 1247 | + if (MDB2::isError($res)) { | |
| 1248 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1249 | + error_log($this->err); | |
| 1250 | + return false; | |
| 1251 | + } else { | |
| 1252 | + $row = $res->fetchRow(); | |
| 1253 | + if (is_array($row)) { | |
| 1254 | + $this->fill_head($row); | |
| 1255 | + return true; | |
| 1256 | + } else { | |
| 1257 | + return NULL; | |
| 1258 | + } | |
| 1259 | + } | |
| 1260 | + } else { | |
| 1261 | + notIdent(); | |
| 1262 | + return false; | |
| 1263 | + } | |
| 1264 | + } | |
| 1265 | + | |
| 1266 | + public function eraseZone() { | |
| 1267 | + if (!$this->is_identified()) { | |
| 1268 | + ob_start(); | |
| 1269 | + var_dump($this->head); | |
| 1270 | + $this->err .= "Zone head is not complete" . "\n" . ob_get_clean(); | |
| 1271 | + error_log($this->err); | |
| 1272 | + return false; | |
| 1273 | + } else { | |
| 1274 | + $where = ' WHERE '; | |
| 1275 | + if ($this->head['id'] >>= 0) { | |
| 1276 | + $where .= "id = " . $this->head['id']; | |
| 1277 | + } else { | |
| 1278 | + $where .= "name = '" . $this->head['name'] . "'"; | |
| 1279 | + } | |
| 1280 | + $res = $this->db->query("DELETE FROM slave_zones " . $where); | |
| 1281 | + if (MDB2::isError($res)) { | |
| 1282 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1283 | + error_log($this->err); | |
| 1284 | + return false; | |
| 1285 | + } | |
| 1286 | + $this->clearZone(); | |
| 1287 | + return true; | |
| 1288 | + } | |
| 1289 | + } | |
| 1290 | + | |
| 1291 | + public function clearZone() { | |
| 1292 | + | |
| 1293 | + $hd = array( | |
| 1294 | + 'id' => NULL, | |
| 1295 | + 'name' => '', | |
| 1296 | + 'master' => '', | |
| 1297 | + 'owner' => 0, | |
| 1298 | + 'updated' => 'no', | |
| 1299 | + 'valid' => 'may', | |
| 1300 | + ); | |
| 1301 | + } | |
| 1302 | + | |
| 1303 | + public function dumpZone($dig) { | |
| 1304 | + if ($this->is_identified()) { | |
| 1305 | + if (!$this->is_complete()) { | |
| 1306 | + $this->loadZoneHead(); | |
| 1307 | + } | |
| 1308 | + $cmd = $dig . " axfr @" . $this->head['master'] . " " . $this->head['name'] . ". +time=2 +tries=2 +retry=1 2>/dev/null"; | |
| 1309 | + unset($coutput); | |
| 1310 | + exec($cmd, $coutput, $exit); | |
| 1311 | + $out = ''; | |
| 1312 | + foreach ($coutput as $line) { | |
| 1313 | + $val = preg_replace('/(^;.*$|\r|\n)/', '', $line); | |
| 1314 | + $out .= ($val > '') ? $val . "\n" : ''; | |
| 1315 | + } | |
| 1316 | + return $out; | |
| 1317 | + } else { | |
| 1318 | + $this->err .= "Zone identification failed\n"; | |
| 1319 | + error_log($this->err); | |
| 1320 | + return false; | |
| 1321 | + } | |
| 1322 | + } | |
| 1323 | + | |
| 1324 | + public function validateZone($dig) { | |
| 1325 | + $out = $this->dumpZone($dig); | |
| 1326 | + if ((isset($out)) && ($out > '')) { | |
| 1327 | + return true; | |
| 1328 | + } elseif (isset($out)) { | |
| 1329 | + $err = "Zone transfer failed\n"; | |
| 1330 | + error_log($err); | |
| 1331 | + $this->err .= $err; | |
| 1332 | + } | |
| 1333 | + return false; | |
| 1334 | + } | |
| 1335 | + | |
| 1336 | + public function getZoneHeadRaw() { | |
| 1337 | + return $this->head; | |
| 1338 | + } | |
| 1339 | + | |
| 1340 | + public function getZoneHead() { | |
| 1341 | + $out = array(); | |
| 1342 | + foreach ($this->head as $key => $value) { | |
| 1343 | + switch ($key) { | |
| 1344 | + case 'master': | |
| 1345 | + case 'name': | |
| 1346 | + $out[$key] = hostToIdn($value); | |
| 1347 | + break; | |
| 1348 | + default: | |
| 1349 | + $out[$key] = $value; | |
| 1350 | + } | |
| 1351 | + } | |
| 1352 | + return $out; | |
| 1353 | + } | |
| 1354 | + | |
| 1355 | + public function getErr() { | |
| 1356 | + return $this->err; | |
| 1357 | + } | |
| 1358 | + | |
| 1359 | + private function is_complete() { | |
| 1360 | + return (($this->head['name'] > '') && ($this->head['master'] > '') && ($this->head['owner'] >0)); | |
| 1361 | + } | |
| 1362 | + | |
| 1363 | + public function doCommit() { | |
| 1364 | + if (!$this->is_complete()) { | |
| 1365 | + ob_start(); | |
| 1366 | + var_dump($this->head); | |
| 1367 | + $this->err .= "Zone head is not complete" . "\n" . ob_get_clean(); | |
| 1368 | + error_log($this->err); | |
| 1369 | + return false; | |
| 1370 | + } | |
| 1371 | + $res = $this->db->query("UPDATE slave_zones SET " . | |
| 1372 | + "updated = 'no' " . | |
| 1373 | + "WHERE id = " . $this->head['id']); | |
| 1374 | + if (MDB2::isError($res)) { | |
| 1375 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1376 | + error_log($this->err); | |
| 1377 | + return false; | |
| 1378 | + } | |
| 1379 | + return $this->loadZoneHead(); | |
| 1380 | + } | |
| 1381 | + | |
| 1382 | + public function saveZoneHead() { | |
| 1383 | + if (!$this->is_complete()) { | |
| 1384 | + ob_start(); | |
| 1385 | + var_dump($this->head); | |
| 1386 | + $this->err .= "Zone head is not complete" . "\n" . ob_get_clean(); | |
| 1387 | + error_log($this->err); | |
| 1388 | + return false; | |
| 1389 | + } | |
| 1390 | + if (!isset($this->head['id'])) { | |
| 1391 | + $vld = (isset($this->head['valid'])) ? $this->head['valid'] : 'may'; | |
| 1392 | + $upd = 'yes'; | |
| 1393 | + $res = $this->db->query("INSERT INTO slave_zones " . | |
| 1394 | + "(name, master, valid, owner, updated) " . | |
| 1395 | + "VALUES ('" . $this->head['name'] . | |
| 1396 | + "', '" . $this->head['master'] . | |
| 1397 | + "', '" . $vld . | |
| 1398 | + "', " . $this->head['owner'] . | |
| 1399 | + ", '" . $upd . | |
| 1400 | + "')"); | |
| 1401 | + if (MDB2::isError($res)) { | |
| 1402 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1403 | + error_log($this->err); | |
| 1404 | + return false; | |
| 1405 | + } | |
| 1406 | + return $this->loadZoneHead(); | |
| 1407 | + } else { | |
| 1408 | + $vld = (($this->head['valid'] == 'yes') || ($this->head['valid'] == 'no')) ? $this->head['valid'] : 'may'; | |
| 1409 | + $upd = ((isset($this->head['updated'])) && ($this->head['updated'] != 'del')) ? 'yes' : $this->head['updated']; | |
| 1410 | + $res = $this->db->query("UPDATE slave_zones SET " . | |
| 1411 | + "name = '" . $this->head['name'] . "', " . | |
| 1412 | + "master = '" . $this->head['master'] . "', " . | |
| 1413 | + "valid = '" . $vld . "', " . | |
| 1414 | + "owner = " . $this->head['owner'] . ", " . | |
| 1415 | + "updated = '" . $upd . "' " . | |
| 1416 | + "WHERE id = " . $this->head['id']); | |
| 1417 | + if (MDB2::isError($res)) { | |
| 1418 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1419 | + error_log($this->err); | |
| 1420 | + return false; | |
| 1421 | + } | |
| 1422 | + return $this->loadZoneHead(); | |
| 1423 | + } | |
| 1424 | + } | |
| 1425 | + | |
| 1426 | + } | |
| 1427 | + | |
| 1428 | + class masterZone { | |
| 1429 | + | |
| 1430 | + private $head = array( | |
| 1431 | + 'id' => NULL, | |
| 1432 | + 'name' => '', | |
| 1433 | + 'pri_dns' => '', | |
| 1434 | + 'sec_dns' => '', | |
| 1435 | + 'serial' => 0, | |
| 1436 | + 'refresh' => 0, | |
| 1437 | + 'retry' => 0, | |
| 1438 | + 'expire' => 0, | |
| 1439 | + 'ttl' => 0, | |
| 1440 | + 'valid' => 'may', | |
| 1441 | + 'owner' => 0, | |
| 1442 | + 'updated' => 'no', | |
| 1443 | + 'secured' => 'no', | |
| 1444 | + ); | |
| 1445 | + private $db = NULL; | |
| 1446 | + private $records = array(); | |
| 1447 | + private $err = ''; | |
| 1448 | + private $isloaded = FALSE; | |
| 1449 | + private $msg = ''; | |
| 1450 | + | |
| 1451 | + public function __debugInfo() { | |
| 1452 | + return array( | |
| 1453 | + 'head' => $this->head, | |
| 1454 | + 'records' => $this->records, | |
| 1455 | + 'err' => $this->err, | |
| 1456 | + 'isloaded' => $this->isloaded, | |
| 1457 | + 'msg' => $this->msg, | |
| 1458 | + 'db' => NULL, | |
| 1459 | + ); | |
| 1460 | + } | |
| 1461 | + | |
| 1462 | + public function __construct($param = NULL) { | |
| 1463 | + global $db; | |
| 1464 | + if (is_object($db)) { | |
| 1465 | + $this->db = &$db; | |
| 1466 | + } | |
| 1467 | + if (!is_null($param)) { | |
| 1468 | + return $this->setZoneHead($param); | |
| 1469 | + } | |
| 1470 | + return true; | |
| 1471 | + } | |
| 1472 | + | |
| 1473 | + public function getZoneHeadRaw() { | |
| 1474 | + return $this->head; | |
| 1475 | + } | |
| 1476 | + | |
| 1477 | + private function tab_to_space($line, $tab = 8, $nbsp = FALSE) { | |
| 1478 | + while (($t = mb_strpos($line,"\t")) !== FALSE) { | |
| 1479 | + $preTab = $t ? mb_substr($line, 0, $t) : ''; | |
| 1480 | + $line = $preTab . str_repeat($nbsp?chr(7):' ', $tab-(mb_strlen($preTab)%$tab)) . mb_substr($line, $t+1); | |
| 1481 | + } | |
| 1482 | + return $nbsp ? str_replace($nbsp?chr(7):' ', ' ', $line) : $line; | |
| 1483 | + } | |
| 1484 | + | |
| 1485 | + private function split_text_record($line, $length = 76) { | |
| 1486 | + $line = $this->tab_to_space($line); | |
| 1487 | + $slices = $line; | |
| 1488 | + if(strlen($line) > $length) { | |
| 1489 | + $pos = stripos($line, "\""); | |
| 1490 | + if ($pos !== false) { | |
| 1491 | + if($pos>$length-2) { | |
| 1492 | + $slices = substr($line, 0, $pos) . "(\n"; | |
| 1493 | + $line = $this->tab_to_space("\t\t\t\t\t" . substr($line,$pos) . " )"); | |
| 1494 | + } else { | |
| 1495 | + $allline = substr($line,0,$pos) . "( " . substr($line,$pos) . " )"; | |
| 1496 | + $slices = substr($allline,0,$length-1) . "\"\n"; | |
| 1497 | + $line = $this->tab_to_space("\t\t\t\t\t\t \"" . substr($allline,$length-1)); | |
| 1498 | + } | |
| 1499 | + while (strlen($line) > $length) { | |
| 1500 | + $slices .= substr($line, 0, $length-1) . "\"\n"; | |
| 1501 | + $line = $this->tab_to_space("\t\t\t\t\t\t \"" . substr($line,$length-1)); | |
| 1502 | + } | |
| 1503 | + if(strlen($line) > 0) { $slices .= $line; } | |
| 1504 | + } | |
| 1505 | + } | |
| 1506 | + return $slices; | |
| 1507 | + } | |
| 1508 | + | |
| 1509 | + private function prettyer($name,$ttl,$type,$pri,$target) { | |
| 1510 | + $line = str_pad($name, 31) . " " . $ttl . "\t" . "IN " . "$type"; | |
| 1511 | + if (strlen($type)<5) { | |
| 1512 | + $line .= "\t"; | |
| 1513 | + } | |
| 1514 | + $line .= " " . $pri; | |
| 1515 | + if (strlen($pri) > 0){ | |
| 1516 | + $line .= " "; | |
| 1517 | + } | |
| 1518 | + if ($type == "TXT"){ | |
| 1519 | + $target = "\"" . $target . "\""; | |
| 1520 | + } | |
| 1521 | + return $this->split_text_record($line . $target, 116); | |
| 1522 | + } | |
| 1523 | + | |
| 1524 | + | |
| 1525 | + public function getConf($hostmaster) { | |
| 1526 | + $out = "\$TTL " . $this->head['ttl'] . "\n"; | |
| 1527 | + $out .= $this->prettyer("@", "", "SOA", "", $this->head['pri_dns'] . ". " . $hostmaster . ".") . " (\n"; | |
| 1528 | + $out .= $this->tab_to_space("\t\t\t\t\t" . $this->head['serial'] . "\t; Serial\n") . | |
| 1529 | + $this->tab_to_space("\t\t\t\t\t" . $this->head['refresh'] . "\t\t; Refresh\n") . | |
| 1530 | + $this->tab_to_space("\t\t\t\t\t" . $this->head['retry'] . "\t\t; Retry\n") . | |
| 1531 | + $this->tab_to_space("\t\t\t\t\t" . $this->head['expire'] . "\t\t; Expire\n") . | |
| 1532 | + $this->tab_to_space("\t\t\t\t\t" . $this->head['ttl'] . ")\t\t; Negative Cache TTL\n;\n"); | |
| 1533 | + foreach (array('pri_dns', 'sec_dns') as $ns) { | |
| 1534 | + $out .= ($this->head[$ns] != '') ? $this->prettyer("@",'','NS','',$this->head[$ns] . ".") . "\n" : ""; | |
| 1535 | + } | |
| 1536 | + foreach ($this->getRecordsRaw() as $record) { | |
| 1537 | + $row = $record->getRecordRaw(); | |
| 1538 | + $pri = ($row['type'] == 'MX') ? $row['pri'] : ''; | |
| 1539 | + $ttl = ($row['ttl'] > 0) ? $row['ttl'] : ''; | |
| 1540 | + $out .= $this->prettyer($row['host'],$ttl,$row['type'],$pri,$row['destination']) . "\n"; | |
| 1541 | + } | |
| 1542 | + return $out; | |
| 1543 | + } | |
| 1544 | + | |
| 1545 | + public function getMsg() { | |
| 1546 | + return $this->msg; | |
| 1547 | + } | |
| 1548 | + | |
| 1549 | + public function writeZone($file, $hostmaster) { | |
| 1550 | + if (!$this->isloaded) { | |
| 1551 | + if (!$this->loadZone()) { | |
| 1552 | + $this->err .= "Unable to load zone\n"; | |
| 1553 | + error_log ($this->err); | |
| 1554 | + return false; | |
| 1555 | + } | |
| 1556 | + } | |
| 1557 | + $zonedata = $this->getConf($hostmaster); | |
| 1558 | + $fh = fopen($file, "w"); | |
| 1559 | + fwrite($fh, $zonedata . "\n"); | |
| 1560 | + fclose($fh); | |
| 1561 | + return true; | |
| 1562 | + } | |
| 1563 | + | |
| 1564 | + public function validateZone($file, $hostmaster, $checkzonecmd) { | |
| 1565 | + if ($this->writeZone($file, $hostmaster)) { | |
| 1566 | + $cmd = $checkzonecmd . " -i local " . $this->head['name'] . " " . $file . " 2>/dev/stdout"; | |
| 1567 | + unset($coutput); | |
| 1568 | + exec($cmd, $coutput, $exit); | |
| 1569 | + $rows = sizeof($coutput); | |
| 1570 | + $return[0] = ($coutput[$rows-1] == 'OK'); | |
| 1571 | + if (($return[0]) && ($exit == 0)) { | |
| 1572 | + $rows--; | |
| 1573 | + $return[1] = ''; | |
| 1574 | + } else { | |
| 1575 | + $return[1] = 'Exitcode: ' . $exit . "\n"; | |
| 1576 | + } | |
| 1577 | + $return[1] .= implode("<br />", $coutput); | |
| 1578 | + if (!$return[0]) { | |
| 1579 | + $this->err = $return[1]; | |
| 1580 | + error_log("ERROR\nCMD: " . $cmd . "\nExit: " . $exit . "\n" . implode("\n", $coutput)); | |
| 1581 | + $this->head['valid'] = 'no'; | |
| 1582 | + } else { | |
| 1583 | + $this->head['valid'] = 'yes'; | |
| 1584 | + } | |
| 1585 | + $this->saveZoneHead(); | |
| 1586 | + return $return; | |
| 1587 | + } | |
| 1588 | + $log = "Zone cannot be validate\n"; | |
| 1589 | + $this->err .= $log; | |
| 1590 | + error_log($log); | |
| 1591 | + return array(false,"Problem in prerequisites\n"); | |
| 1592 | + } | |
| 1593 | + | |
| 1594 | + public function getZoneHead() { | |
| 1595 | + $out = array(); | |
| 1596 | + foreach ($this->head as $key => $value) { | |
| 1597 | + switch ($key) { | |
| 1598 | + case 'pri_dns': | |
| 1599 | + case 'sec_dns': | |
| 1600 | + case 'name': | |
| 1601 | + $out[$key] = hostToIdn($value); | |
| 1602 | + break; | |
| 1603 | + default: | |
| 1604 | + $out[$key] = $value; | |
| 1605 | + } | |
| 1606 | + } | |
| 1607 | + return $out; | |
| 1608 | + } | |
| 1609 | + | |
| 1610 | + public function getErr() { | |
| 1611 | + return $this->err; | |
| 1612 | + } | |
| 1613 | + | |
| 1614 | + public function getId() { | |
| 1615 | + return $this->head['id']; | |
| 1616 | + } | |
| 1617 | + | |
| 1618 | + private function fill_head($param) { | |
| 1619 | + foreach ($param as $key => $value) { | |
| 1620 | + switch ($key) { | |
| 1621 | + case 'id': | |
| 1622 | + case 'serial': | |
| 1623 | + case 'retry': | |
| 1624 | + case 'refresh': | |
| 1625 | + case 'expire': | |
| 1626 | + case 'ttl': | |
| 1627 | + case 'owner': | |
| 1628 | + $this->head[$key] = intval($value); | |
| 1629 | + break; | |
| 1630 | + case 'pri_dns': | |
| 1631 | + case 'sec_dns': | |
| 1632 | + case 'name': | |
| 1633 | + $this->head[$key] = idnToHost($value); | |
| 1634 | + break; | |
| 1635 | + default: | |
| 1636 | + $this->head[$key] = $value; | |
| 1637 | + } | |
| 1638 | + } | |
| 1639 | + } | |
| 1640 | + | |
| 1641 | + public function setZoneHead($param) { | |
| 1642 | + if (is_string($param)) { | |
| 1643 | + $this->head['name'] = idnToHost($param); | |
| 1644 | + } elseif (is_numeric($param)) { | |
| 1645 | + $this->head['id'] = $param; | |
| 1646 | + } elseif (is_array($param)) { | |
| 1647 | + $this->fill_head($param); | |
| 1648 | + } else { | |
| 1649 | + ob_start(); | |
| 1650 | + var_dump($param); | |
| 1651 | + $this->err .= "Unidentified parameter" . "\n" . ob_get_clean(); | |
| 1652 | + error_log($this->err); | |
| 1653 | + return false; | |
| 1654 | + } | |
| 1655 | + return true; | |
| 1656 | + } | |
| 1657 | + | |
| 1658 | + private function is_identified() { | |
| 1659 | + return ((isset($this->head['id'])) || ($this->head['name'] > '')); | |
| 1660 | + } | |
| 1661 | + | |
| 1662 | + private function notIdent($complete = false) { | |
| 1663 | + ob_start(); | |
| 1664 | + var_dump($this->head); | |
| 1665 | + $head = ob_get_clean(); | |
| 1666 | + if ($complete) { | |
| 1667 | + $this->err .= "Zone is not complete" . "\n" . $head; | |
| 1668 | + error_log($this->err); | |
| 1669 | + } else { | |
| 1670 | + $this->err .= "Unidentified zone" . "\n" . $head; | |
| 1671 | + error_log($this->err); | |
| 1672 | + } | |
| 1673 | + } | |
| 1674 | + | |
| 1675 | + public function loadZoneHead() { | |
| 1676 | + if ($this->is_identified()) { | |
| 1677 | + $where = ' WHERE '; | |
| 1678 | + if (isset($this->head['id'])) { | |
| 1679 | + $where .= "id = " . $this->head['id']; | |
| 1680 | + } else { | |
| 1681 | + $where .= "name = '" . $this->head['name'] . "'"; | |
| 1682 | + } | |
| 1683 | + $res = $this->db->query("SELECT * FROM zones" . $where); | |
| 1684 | + if (MDB2::isError($res)) { | |
| 1685 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1686 | + error_log($this->err); | |
| 1687 | + return false; | |
| 1688 | + } else { | |
| 1689 | + $row = $res->fetchRow(); | |
| 1690 | + if (is_array($row)) { | |
| 1691 | + $this->fill_head($row); | |
| 1692 | + return true; | |
| 1693 | + } else { | |
| 1694 | + return NULL; | |
| 1695 | + } | |
| 1696 | + } | |
| 1697 | + } else { | |
| 1698 | + $this->notIdent(); | |
| 1699 | + return false; | |
| 1700 | + } | |
| 1701 | + } | |
| 1702 | + | |
| 1703 | + public function loadZoneRecords() { | |
| 1704 | + if ($this->is_complete()) { | |
| 1705 | + $res = $this->db->query("SELECT id FROM records WHERE zone = " . $this->head['id']); | |
| 1706 | + if (MDB2::isError($res)) { | |
| 1707 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 1708 | + error_log($this->err); | |
| 1709 | + return false; | |
| 1710 | + } else { | |
| 1711 | + while ($row = $res->fetchRow()) { | |
| 1712 | + $id = intval($row['id']); | |
| 1713 | + $this->records[$id] = new masterRecord($row); | |
| 1714 | + if (!$this->records[$id]->loadRecord()) { | |
| 1715 | + $this->err .= $this->records[$id]->getErr(); | |
| 1716 | + error_log($this->err); | |
| 1717 | + return false; | |
| 1718 | + } | |
| 1719 | + } | |
| 1720 | + return true; | |
| 1721 | + } | |
| 1722 | + } else { | |
| 1723 | + notIdent(true); | |
| 1724 | + return false; | |
| 1725 | + } | |
| 1726 | + } | |
| 1727 | + | |
| 1728 | + public function eraseRecord($id) { | |
| 1729 | + $found = false; | |
| 1730 | + foreach ($this->records as $key => $entry) { | |
| 1731 | + if ($key == $id) { | |
| 1732 | + $found = true; | |
| 1733 | + if (!$entry->eraseRecord()) { | |
| 1734 | + $this->err .= $entry->getErr(); | |
| 1735 | + error_log($this->err); | |
| 1736 | + return false; | |
| 1737 | + } | |
| 1738 | + } | |
| 1739 | + } | |
| 1740 | + if ($found) { | |
| 1741 | + $this->head['valid'] = 'may'; | |
| 1742 | + $this->saveZoneHead(); | |
| 1743 | + $this->records = array(); | |
| 1744 | + $this->loadZoneRecords(); | |
| 1745 | + return true; | |
| 1746 | + } | |
| 1747 | + $this->err .= "Record id not found" . "\n" . $id; | |
| 1748 | + error_log($this->err); | |
| 1749 | + return false; | |
| 1750 | + } | |
| 1751 | + | |
| 1752 | + public function addRecord($param = NULL) { | |
| 1753 | + if ((is_numeric($this->head['id'])) && ($this->head['id'] > 0)) { | |
| 1754 | + $nrec = new masterRecord($param); | |
| 1755 | + $nrec->setRecord(array( 'zone' => $this->head['id'])); | |
| 1756 | + $urec = $nrec->getRecord(); | |
| 1757 | + if (( | |
| 1758 | + ($urec['host'] > '') || | |
| 1759 | + ($urec['destination'] > '') | |
| 1760 | + ) && | |
| 1761 | + ($urec['host'] != $urec['destination']) && | |
| 1762 | + ($urec['type'] > '')) { | |
| 1763 | + $this->records[] = $nrec; | |
| 1764 | + $this->head['valid'] = 'may'; | |
| 1765 | + return true; | |
| 1766 | + } else { | |
| 1767 | + ob_start(); | |
| 1768 | + var_dump($param); | |
| 1769 | + $this->err .= "Record is empty" . "\n" . ob_get_clean(); | |
| 1770 | + error_log($this->err); | |
| 1771 | + return false; | |
| 1772 | + } | |
| 1773 | + } else { | |
| 1774 | + ob_start(); | |
| 1775 | + var_dump($this->head); | |
| 1776 | + $this->err .= "Zone has not defined yet" . "\n" . ob_get_clean(); | |
| 1777 | + error_log($this->err); | |
| 1778 | + return false; | |
| 1779 | + } | |
| 1780 | + } | |
| 1781 | + | |
| 1782 | + private function bind_time_format($value) { | |
| 1783 | + if (preg_match(BIND_TIME_PATTERN, strtolower($value), $match)) { | |
| 1784 | + $value = $match[1]; | |
| 1785 | + switch ($match[2]) { | |
| 1786 | + case "s": | |
| 1787 | + $multiplier = 1; | |
| 1788 | + break; | |
| 1789 | + case "m": | |
| 1790 | + $multiplier = 60; | |
| 1791 | + break; | |
| 1792 | + case "h": | |
| 1793 | + $multiplier = 3600; | |
| 1794 | + break; | |
| 1795 | + case "d": | |
| 1796 | + $multiplier = 86400; | |
| 1797 | + break; | |
| 1798 | + case "w": | |
| 1799 | + $multiplier = 604800; | |
| 1800 | + break; | |
| 1801 | + } | |
| 1802 | + $value = $value*$multiplier; | |
| 1803 | + } | |
| 1804 | + return $value; | |
| 1805 | + } | |
| 1806 | + | |
| 1807 | + | |
| 1808 | + public function parseZone($rows, $zonename, $owner = 1) { | |
| 1809 | + if (!is_array($rows)) { | |
| 1810 | + ob_start(); | |
| 1811 | + var_dump($rows); | |
| 1812 | + $this->err .= "Zone can be parsed from an array only" . "\n" . ob_get_clean(); | |
| 1813 | + error_log($this->err); | |
| 1814 | + return false; | |
| 1815 | + } else { | |
| 1816 | + $this->clearZone(); | |
| 1817 | + $this->head['name'] = idnToHost($zonename); | |
| 1818 | + $soafound = false; | |
| 1819 | + $soabegins = false; | |
| 1820 | + $soadata = ''; | |
| 1821 | + $recrow = ''; | |
| 1822 | + foreach ($rows as $row) { | |
| 1823 | + $row = preg_replace(COMMENT_PATTERN, ' ', trim($row)); | |
| 1824 | + $row = ($row == " ") ? '' : $row; | |
| 1825 | + if ($soafound === false) { | |
| 1826 | + if (preg_match(ORIGIN_PATTERN, $row, $match)) { | |
| 1827 | + $zone = strtolower($match[1]); | |
| 1828 | + if ($zone != $expectedname) { | |
| 1829 | + $this->clearZone(); | |
| 1830 | + $this->err .= "Given zone not matches with the expected (" . $zone . "<=>" . $expectedzone . ")"; | |
| 1831 | + error_log($this->err); | |
| 1832 | + return false; | |
| 1833 | + } | |
| 1834 | + } | |
| 1835 | + if (preg_match(SOA_BEGINS_PATTERN, $row, $match)) { | |
| 1836 | + $soabegins = true; | |
| 1837 | + } | |
| 1838 | + if ($soabegins) { | |
| 1839 | + $soadata .= $row; | |
| 1840 | + } | |
| 1841 | + if (preg_match(FULL_SOA_PATTERN, $soadata, $match)) { | |
| 1842 | + $prins = $match[3]; | |
| 1843 | + if(preg_match(TIMES_PATTERN, $match[5], $match2)) { | |
| 1844 | + $soafound = true; | |
| 1845 | + $serial = $match2[1]; | |
| 1846 | + $refresh = $this->bind_time_format($match2[2]); | |
| 1847 | + $retry = $this->bind_time_format($match2[3]); | |
| 1848 | + $expire = $this->bind_time_format($match2[4]); | |
| 1849 | + $ttl = $this->bind_time_format($match2[5]); | |
| 1850 | + if (($this->setZoneHead( | |
| 1851 | + array( | |
| 1852 | + 'serial' => intval($serial), | |
| 1853 | + 'refresh' => intval($refresh), | |
| 1854 | + 'retry' => intval($retry), | |
| 1855 | + 'expire' => intval($expire), | |
| 1856 | + 'ttl' => intval($ttl), | |
| 1857 | + 'owner' => intval($owner), | |
| 1858 | + 'pri_dns' => strval($prins), | |
| 1859 | + 'sec_dns' => '##EMPTY##', | |
| 1860 | + ))) && ($this->saveZoneHead())) { | |
| 1861 | + $soafound = true; | |
| 1862 | + } else { | |
| 1863 | + $this->err .= "Head cannot be set" . "\n" . $soadata; | |
| 1864 | + $this->clearZone(); | |
| 1865 | + return false; | |
| 1866 | + } | |
| 1867 | + } else { | |
| 1868 | + $this->err .= "SOA record cannot be parsed" . "\n" . $soadata; | |
| 1869 | + error_log($this->err); | |
| 1870 | + return false; | |
| 1871 | + } | |
| 1872 | + } | |
| 1873 | + } else { | |
| 1874 | + if ($recrow != '') { | |
| 1875 | + $rowpart = trim($row); | |
| 1876 | + $recrow .= $rowpart; | |
| 1877 | + $end = strpos($recrow, ')'); | |
| 1878 | + if ($end > 0) { | |
| 1879 | + $recrow = substr($recrow, 0, $end); | |
| 1880 | + $recd = new masterRecord(array('zone' => $this->head['id'])); | |
| 1881 | + if ($recd->setRecord($recrow)) { | |
| 1882 | + $parsed = $recd->getRecordRaw(); | |
| 1883 | + if ( | |
| 1884 | + ($this->head['sec_dns'] == '##EMPTY##') && | |
| 1885 | + ($parsed['type'] == 'NS') && | |
| 1886 | + ($parsed['destination'] != $self->head['pri_dns']) && | |
| 1887 | + ( | |
| 1888 | + ($parsed['host'] == '@') || | |
| 1889 | + ($parsed['host'] == '') | |
| 1890 | + ) | |
| 1891 | + ) { | |
| 1892 | + $self->head['sec_dns'] == $parsed['destination']; | |
| 1893 | + } | |
| 1894 | + $this->records[] = $recd; | |
| 1895 | + $recrow = ''; | |
| 1896 | + } else { | |
| 1897 | + $this->err .= $recd->getErr(); | |
| 1898 | + return false; | |
| 1899 | + } | |
| 1900 | + } | |
| 1901 | + } elseif ($row > '') { | |
| 1902 | + $end = strpos($row, '('); | |
| 1903 | + if ($end > 0) { | |
| 1904 | + $row = preg_replace('/\(/', '', $row); | |
| 1905 | + $recrow = $row; | |
| 1906 | + } | |
| 1907 | + $end = strpos($recrow, ')'); | |
| 1908 | + if ($end > 0) { | |
| 1909 | + $recrow = substr($recrow, 0, $end); | |
| 1910 | + $recd = new masterRecord(array('zone' => $this->head['id'])); | |
| 1911 | + if ($recd->setRecord($recrow, $this->head['name'])) { | |
| 1912 | + $this->records[] = $recd; | |
| 1913 | + $recrow = ''; | |
| 1914 | + } else { | |
| 1915 | + $this->err .= $recd->getErr(); | |
| 1916 | + return false; | |
| 1917 | + } | |
| 1918 | + } elseif ($recrow == '') { | |
| 1919 | + $recd = new masterRecord(array('zone' => $this->head['id'])); | |
| 1920 | + if ($recd->setRecord($row, $this->head['name'])) { | |
| 1921 | + $this->records[] = $recd; | |
| 1922 | + } else { | |
| 1923 | + $this->err .= $recd->getErr(); | |
| 1924 | + return false; | |
| 1925 | + } | |
| 1926 | + } | |
| 1927 | + } | |
| 1928 | + } | |
| 1929 | + } | |
| 1930 | + $recs = array(); | |
| 1931 | + foreach ($this->records as $each) { | |
| 1932 | + $rhd = $each->getRecordRaw(); | |
| 1933 | + if (($rhd['type'] == 'NS')) { | |
| 1934 | + if (($rhd['host'] == '@') && ($rhd['destination'] == $this->head['pri_dns'] . '.')) { | |
| 1935 | + continue; | |
| 1936 | + } elseif ($rhd['host'] == '@') { | |
| 1937 | + $this->head['sec_dns'] = ($this->head['sec_dns'] == '##EMPTY##') ? preg_replace('/\.$/', '', $rhd['destination']) : $this->head['sec_dns']; | |
| 1938 | + continue; | |
| 1939 | + } | |
| 1940 | + } | |
| 1941 | + $recs[] = $each; | |
| 1942 | + } | |
| 1943 | + $this->records = $recs; | |
| 1944 | + $this->saveZone(); | |
| 1945 | + } | |
| 1946 | + return true; | |
| 1947 | + } | |
| 1948 | + | |
| 1949 | + public function loadZone() { | |
| 1950 | + $ret = $this->loadZoneHead(); | |
| 1951 | + if (($ret) && (!is_null($this->head['id']))) { | |
| 1952 | + $this->isloaded = $this->loadZoneRecords(); | |
| 1953 | + return $this->isloaded; | |
| 1954 | + } elseif (is_null($ret)) { | |
| 1955 | + return NULL; | |
| 1956 | + } else { | |
| 1957 | + return false; | |
| 1958 | + } | |
| 1959 | + } | |
| 1960 | + | |
| 1961 | + public function getRecordsRaw() { | |
| 1962 | + return $this->records; | |
| 1963 | + } | |
| 1964 | + | |
| 1965 | + public function getRecords($ordered = false) { | |
| 1966 | + $out = array(); | |
| 1967 | + foreach ($this->records as $key => $each) { | |
| 1968 | + if ($ordered) { | |
| 1969 | + $out[] = $each->getRecord(); | |
| 1970 | + } else { | |
| 1971 | + $out[$key] = $each->getRecord(); | |
| 1972 | + } | |
| 1973 | + } | |
| 1974 | + return $out; | |
| 1975 | + } | |
| 1976 | + | |
| 1977 | + public function getZoneRaw() { | |
| 1978 | + $out = array(); | |
| 1979 | + $out[] = $this->getZoneHeadRaw(); | |
| 1980 | + $out[] = $this->getRecordsRaw(); | |
| 1981 | + } | |
| 1982 | + | |
| 1983 | + public function getZone() { | |
| 1984 | + $out = array(); | |
| 1985 | + $out[] = $this->getZoneHead(); | |
| 1986 | + $out[] = $this->getRecords(); | |
| 1987 | + return $out; | |
| 1988 | + } | |
| 1989 | + | |
| 1990 | + public function refresh_secure($zonedir) { | |
| 1991 | + | |
| 1992 | + $files = glob($zonedir . "{K,dsset-,}" . $this->head['name'] . ".{*private,*key,krf,}", GLOB_BRACE); | |
| 1993 | + $hit = 0; | |
| 1994 | + $names = array(); | |
| 1995 | + foreach ($files as $key => $file) { | |
| 1996 | + $name = basename($file); | |
| 1997 | + switch ($name) { | |
| 1998 | + case $this->head['name'] . '.krf': | |
| 1999 | + case 'dsset-' . $this->head['name'] . '.': | |
| 2000 | + $hit++; | |
| 2001 | + break; | |
| 2002 | + default: | |
| 2003 | + $pattern = '/^K' . $this->head['name'] . '\.\+\d+\+\d+\.(private|key)/'; | |
| 2004 | + preg_match($pattern, $name, $match); | |
| 2005 | + $hit += ($match[0] == $name) ? 1 : 0; | |
| 2006 | + } | |
| 2007 | + $names[$key] = $name; | |
| 2008 | + } | |
| 2009 | + $filesok = ($hit >= 8); | |
| 2010 | + $res = $this->db->query("SELECT id, dsset, krf FROM dnssec_zones WHERE zone = " . $this->head['id']); | |
| 2011 | + if (MDB2::isError($res)) { | |
| 2012 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2013 | + error_log($this->err); | |
| 2014 | + return false; | |
| 2015 | + } | |
| 2016 | + $dbok = ($res->numRows() == 1); | |
| 2017 | + if ($dbok) { | |
| 2018 | + $sel = $res->fetchRow(); | |
| 2019 | + $id = $sel['id']; | |
| 2020 | + $dsset = $sel['dsset']; | |
| 2021 | + $krf = $sel['krf']; | |
| 2022 | + if ($filesok) { | |
| 2023 | + $dssetf = file_get_contents($zonedir . "dsset-" . $this->head['name'] . '.'); | |
| 2024 | + $krff = file_get_contents($zonedir . $this->head['name'] . '.krf'); | |
| 2025 | + if (($dsset != $dssetf) || ($krf != $krff)) { | |
| 2026 | + $res = $this->db->query("UPDATE dnssec_zones SET " . | |
| 2027 | + "dsset = '" . $dssetf . "', " . | |
| 2028 | + "krf = '" . $krff . "' WHERE id = " . $id | |
| 2029 | + ); | |
| 2030 | + if (MDB2::isError($res)) { | |
| 2031 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2032 | + error_log($this->err); | |
| 2033 | + return false; | |
| 2034 | + } | |
| 2035 | + } | |
| 2036 | + $skeys = array(); | |
| 2037 | + $keys = array(); | |
| 2038 | + foreach ($names as $name) { | |
| 2039 | + $bn = basename($name, '.key'); | |
| 2040 | + if ($bn . '.key' == $name) { | |
| 2041 | + $keys[] = $bn; | |
| 2042 | + $skeys[] = "'" . $bn . "'"; | |
| 2043 | + } | |
| 2044 | + } | |
| 2045 | + $res = $this->db->query("UPDATE dnssec_keys SET archive = 'yes' WHERE " . | |
| 2046 | + "dszone = " . $id . " AND " . | |
| 2047 | + "archive = 'no'"); | |
| 2048 | + if (MDB2::isError($res)) { | |
| 2049 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2050 | + error_log($this->err); | |
| 2051 | + return false; | |
| 2052 | + } | |
| 2053 | + $res = $this->db->query("UPDATE dnssec_keys SET archive = 'no' WHERE " . | |
| 2054 | + "dszone = " . $id . " AND " . | |
| 2055 | + "filename IN (" . implode(",", $skeys) . ")"); | |
| 2056 | + if (MDB2::isError($res)) { | |
| 2057 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2058 | + error_log($this->err); | |
| 2059 | + return false; | |
| 2060 | + } | |
| 2061 | + foreach ($keys as $keyf) { | |
| 2062 | + $res = $this->db->query("SELECT id, fkey, fprivate FROM dnssec_keys WHERE filename = '" . $keyf . "' AND dszone = " . $id . " AND archive = 'no'"); | |
| 2063 | + if (MDB2::isError($res)) { | |
| 2064 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2065 | + error_log($this->err); | |
| 2066 | + return false; | |
| 2067 | + } | |
| 2068 | + $kfile = file_get_contents($zonedir . $keyf . '.key'); | |
| 2069 | + $pfile = file_get_contents($zonedir . $keyf . '.private'); | |
| 2070 | + if ($res->numRows() == 0) { | |
| 2071 | + $this->db->query("INSERT INTO dnssec_keys (dszone, filename, fkey, fprivate, archive) VALUES ('" . $id . "','" . | |
| 2072 | + $keyf . "', '" . $kfile . "', '" . | |
| 2073 | + $pfile . "', 'no');" | |
| 2074 | + ); | |
| 2075 | + if (MDB2::isError($res)) { | |
| 2076 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2077 | + error_log($this->err); | |
| 2078 | + return false; | |
| 2079 | + } | |
| 2080 | + } else { | |
| 2081 | + $row = $res->fetchRow(); | |
| 2082 | + if (($kfile != $row['fkey']) || ($pfile != $row['fprivate'])) { | |
| 2083 | + $res = $this->db->query("UPDATE dnssec_keys SET " . | |
| 2084 | + "fkey = '" . $kfile . "', " . | |
| 2085 | + "fprivate = '" . $pfile . | |
| 2086 | + "' WHERE dszone = " . $id . | |
| 2087 | + " AND filename = '" . $keyf . | |
| 2088 | + "' AND archive = 'no'" | |
| 2089 | + ); | |
| 2090 | + if (MDB2::isError($res)) { | |
| 2091 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2092 | + error_log($this->err); | |
| 2093 | + return false; | |
| 2094 | + } | |
| 2095 | + } | |
| 2096 | + } | |
| 2097 | + } | |
| 2098 | + } else { | |
| 2099 | + $fh = fopen($zonedir . "dsset-" . $this->head['name'] . ".", 'w'); | |
| 2100 | + fwrite($fh, $sel['dsset']); | |
| 2101 | + fclose($fh); | |
| 2102 | + $fh = fopen($zonedir . $this->head['name'] . ".krf", 'w'); | |
| 2103 | + fwrite($fh, $sel['krf'] . "\n\n"); | |
| 2104 | + fclose($fh); | |
| 2105 | + $id = $sel['id']; | |
| 2106 | + $res = $this->db->query("SELECT * FROM dnssec_keys WHERE " . | |
| 2107 | + " dszone = " . $id . " AND " . | |
| 2108 | + " archive = 'no'" | |
| 2109 | + ); | |
| 2110 | + if (MDB2::isError($res)) { | |
| 2111 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2112 | + error_log($this->err); | |
| 2113 | + return false; | |
| 2114 | + } | |
| 2115 | + if ($res->numRows() < 3) { | |
| 2116 | + $this->err .= "Missing key records\n"; | |
| 2117 | + error_log($this->err); | |
| 2118 | + return false; | |
| 2119 | + } | |
| 2120 | + while ($rec = $res->fetchRow()) { | |
| 2121 | + foreach (array('private', 'key') as $ext) { | |
| 2122 | + $fh = fopen($zonedir . $rec['filename'] . "." . $ext, 'w'); | |
| 2123 | + fwrite($fh, $rec['f' . $ext] . "\n"); | |
| 2124 | + fclose($fh); | |
| 2125 | + } | |
| 2126 | + } | |
| 2127 | + } | |
| 2128 | + } elseif ($filesok) { | |
| 2129 | + $dsset = ''; | |
| 2130 | + $krf = ''; | |
| 2131 | + $keyset = array(); | |
| 2132 | + foreach ($names as $name) { | |
| 2133 | + switch ($name) { | |
| 2134 | + case 'dsset-' . $this->head['name'] . '.': | |
| 2135 | + $dsset = file_get_contents($zonedir . $name); | |
| 2136 | + break; | |
| 2137 | + case $this->head['name'] . '.krf': | |
| 2138 | + $krf = file_get_contents($zonedir . $name); | |
| 2139 | + break; | |
| 2140 | + default: | |
| 2141 | + $ext = (basename($name, '.key') == $name) ? 'private' : 'key'; | |
| 2142 | + $base = basename($name, '.' . $ext); | |
| 2143 | + $keyset[$base][$ext] = file_get_contents($zonedir . $name); | |
| 2144 | + } | |
| 2145 | + } | |
| 2146 | + if (($krf == '') || ($dsset == '')) { | |
| 2147 | + $this->err .= "Incomplete DSSET\n"; | |
| 2148 | + error_log($this->err); | |
| 2149 | + return false; | |
| 2150 | + } else { | |
| 2151 | + $res = $this->db->query("INSERT INTO dnssec_zones (zone, krf, dsset) VALUES ('" . | |
| 2152 | + $this->head['id'] . "', '" . | |
| 2153 | + $krf . "', '" . | |
| 2154 | + $dsset . "')" | |
| 2155 | + ); | |
| 2156 | + if (MDB2::isError($res)) { | |
| 2157 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2158 | + error_log($this->err); | |
| 2159 | + return false; | |
| 2160 | + } | |
| 2161 | + $res = $this->db->query("SELECT id FROM dnssec_zones WHERE zone = " . $this->head['id']); | |
| 2162 | + if (MDB2::isError($res)) { | |
| 2163 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2164 | + error_log($this->err); | |
| 2165 | + return false; | |
| 2166 | + } | |
| 2167 | + $rec = $res->fetchRow(); | |
| 2168 | + $id = $rec['id']; | |
| 2169 | + $ok = 0; | |
| 2170 | + foreach ($keyset as $name => $arr) { | |
| 2171 | + $key = $arr['key']; | |
| 2172 | + $private = $arr['private']; | |
| 2173 | + if (($key == '') || ($private == '')) { | |
| 2174 | + $this->err .= "Incomplete KEYSET\n"; | |
| 2175 | + error_log($this->err); | |
| 2176 | + return false; | |
| 2177 | + } | |
| 2178 | + $res = $this->db->query("INSERT INTO dnssec_keys (dszone, filename, fkey, fprivate, archive) VALUES (" . | |
| 2179 | + $id . ", '" . | |
| 2180 | + $name . "', '" . | |
| 2181 | + $key . "', '" . | |
| 2182 | + $private . "', 'no')" | |
| 2183 | + ); | |
| 2184 | + if (MDB2::isError($res)) { | |
| 2185 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2186 | + error_log($this->err); | |
| 2187 | + return false; | |
| 2188 | + } | |
| 2189 | + $ok++; | |
| 2190 | + } | |
| 2191 | + if ($ok < 3) { | |
| 2192 | + $this->err .= "Not enough KEYSET\n"; | |
| 2193 | + error_log($this->err); | |
| 2194 | + return false; | |
| 2195 | + } | |
| 2196 | + } | |
| 2197 | + } else { | |
| 2198 | + return false; | |
| 2199 | + } | |
| 2200 | + return true; | |
| 2201 | + } | |
| 2202 | + | |
| 2203 | + public function doSecure($zonedir, $zonesigner, $rollinit, $rollerconf) { | |
| 2204 | + if (!$this->is_complete()) { | |
| 2205 | + ob_start(); | |
| 2206 | + var_dump($this->head); | |
| 2207 | + $this->err .= "Zone head is not complete" . "\n" . ob_get_clean(); | |
| 2208 | + error_log($this->err); | |
| 2209 | + return false; | |
| 2210 | + } | |
| 2211 | + $err = $this->err; | |
| 2212 | + $param = (($this->refresh_secure($zonedir)) && ($err == $this->err)) ? '' : ' -genkeys -usensec3'; | |
| 2213 | + if ($err != $this->err) return false; | |
| 2214 | + $cmd = $zonesigner . $param . " -zone " . $this->head['name'] . " " . $zonedir . $this->head['name'] . " 2>/dev/stdout"; | |
| 2215 | + unset($coutput); | |
| 2216 | + $currpath = getcwd(); | |
| 2217 | + chdir($zonedir); | |
| 2218 | + exec($cmd, $coutput, $signexit); | |
| 2219 | + chdir($currpath); | |
| 2220 | + if ($signexit != 0) { | |
| 2221 | + $this->err .= "Zonesigner error (" . $signexit . "):\n" . implode("\n",$coutput); | |
| 2222 | + error_log($this->err); | |
| 2223 | + return false; | |
| 2224 | + } else { | |
| 2225 | + $this->msg .= "Zonesigner output (" . $signexit . "):\n " . implode("\n ",$coutput) . "\n"; | |
| 2226 | + } | |
| 2227 | + if (!$this->refresh_secure($zonedir)) return false; | |
| 2228 | + $rollf = file($rollerconf, FILE_IGNORE_NEW_LINES ); | |
| 2229 | + $noroll = false; | |
| 2230 | + foreach ($rollf as $row) { | |
| 2231 | + preg_match('/^\s*roll\s+"' . $this->head['name'] . '"\s*/', $row, $match); | |
| 2232 | + $noroll = (isset($match[0]) && ($row == $match[0])); | |
| 2233 | + if ($noroll) break; | |
| 2234 | + } | |
| 2235 | + if (!$noroll) { | |
| 2236 | + $cmd = $rollinit . " " . $this->head['name'] . | |
| 2237 | + " -zone " . $zonedir . $this->head['name'] . '.signed' . | |
| 2238 | + " -keyrec " . $zonedir . $this->head['name'] . ".krf " . | |
| 2239 | + " -directory " . $zonedir . " 2>/dev/stdout"; | |
| 2240 | + unset($coutput); | |
| 2241 | + exec($cmd, $coutput, $exit); | |
| 2242 | + if ($exit != 0) { | |
| 2243 | + $this->err .= "Rollerd error(" . $exit . "):\n" . implode("\n ",$coutput) . "\n"; | |
| 2244 | + error_log($this->err); | |
| 2245 | + return false; | |
| 2246 | + } else { | |
| 2247 | + $fh = fopen($rollerconf, "a+"); | |
| 2248 | + fwrite($fh, "\n# rollinit config for zone " . hostToIdn($this->head['name']) . ":\n" . implode("\n", $coutput) . "\n"); | |
| 2249 | + fclose($fh); | |
| 2250 | + $this->msg .= "\n Rollerd for zone " . hostToIdn($this->head['name']) . " is configured now\n"; | |
| 2251 | + } | |
| 2252 | + } else { | |
| 2253 | + $this->msg .= "\n Rollerd for zone " . hostToIdn($this->head['name']) . " has already set\n"; | |
| 2254 | + } | |
| 2255 | + return true; | |
| 2256 | + } | |
| 2257 | + | |
| 2258 | + private function is_complete() { | |
| 2259 | + return (($this->head['name'] > '') && | |
| 2260 | + ($this->head['pri_dns'] > '') && | |
| 2261 | + ($this->head['sec_dns'] > '') && | |
| 2262 | + ($this->head['refresh'] > 0) && | |
| 2263 | + ($this->head['retry'] > 0) && | |
| 2264 | + ($this->head['expire'] > 0) && | |
| 2265 | + ($this->head['ttl'] > 0) && | |
| 2266 | + ($this->head['owner'] > 0)); | |
| 2267 | + } | |
| 2268 | + | |
| 2269 | + public function doCommit() { | |
| 2270 | + if (!$this->is_complete()) { | |
| 2271 | + ob_start(); | |
| 2272 | + var_dump($this->head); | |
| 2273 | + $this->err .= "Zone head is not complete" . "\n" . ob_get_clean(); | |
| 2274 | + error_log($this->err); | |
| 2275 | + return false; | |
| 2276 | + } | |
| 2277 | + $res = $this->db->query("UPDATE zones SET " . | |
| 2278 | + "updated = 'no' " . | |
| 2279 | + "WHERE id = " . $this->head['id']); | |
| 2280 | + if (MDB2::isError($res)) { | |
| 2281 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2282 | + error_log($this->err); | |
| 2283 | + return false; | |
| 2284 | + } | |
| 2285 | + return $this->loadZoneHead(); | |
| 2286 | + } | |
| 2287 | + | |
| 2288 | + public function saveZoneHead() { | |
| 2289 | + if (!$this->is_complete()) { | |
| 2290 | + ob_start(); | |
| 2291 | + var_dump($this->head); | |
| 2292 | + $this->err .= "Zone head is not complete" . "\n" . ob_get_clean(); | |
| 2293 | + error_log($this->err); | |
| 2294 | + return false; | |
| 2295 | + } | |
| 2296 | + if (!isset($this->head['id'])) { | |
| 2297 | + $srl =intval(date('Ymd') . '01'); | |
| 2298 | + $vld = (isset($this->head['valid'])) ? $this->head['valid'] : 'may'; | |
| 2299 | + $upd = 'yes'; | |
| 2300 | + $res = $this->db->query("INSERT INTO zones " . | |
| 2301 | + "(name, pri_dns, sec_dns, serial, refresh, retry, expire, ttl, valid, owner, updated, secured) " . | |
| 2302 | + "VALUES ('" . $this->head['name'] . | |
| 2303 | + "', '" . $this->head['pri_dns'] . | |
| 2304 | + "', '" . $this->head['sec_dns'] . | |
| 2305 | + "', " . $srl . | |
| 2306 | + ", " . $this->head['refresh'] . | |
| 2307 | + ", " . $this->head['retry'] . | |
| 2308 | + ", " . $this->head['expire'] . | |
| 2309 | + ", " . $this->head['ttl'] . | |
| 2310 | + ", '" . $vld . | |
| 2311 | + "', " . $this->head['owner'] . | |
| 2312 | + ", '" . $upd . | |
| 2313 | + "', '" . $this->head['secured'] . "')"); | |
| 2314 | + if (MDB2::isError($res)) { | |
| 2315 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2316 | + error_log($this->err); | |
| 2317 | + return false; | |
| 2318 | + } | |
| 2319 | + return $this->loadZone(); | |
| 2320 | + } else { | |
| 2321 | + $srl = ($this->head['updated'] == 'no') ? intval(date('Ymd') . '01') : $this->head['serial']; | |
| 2322 | + if ($srl <= $this->head['serial']) { | |
| 2323 | + $srl = ($this->head['updated'] == 'no') ? $this->head['serial'] + 1 : $this->head['serial']; | |
| 2324 | + } | |
| 2325 | + $vld = (($this->head['valid'] == 'yes') || ($this->head['valid'] == 'no')) ? $this->head['valid'] : 'may'; | |
| 2326 | + $upd = ((isset($this->head['updated'])) && ($this->head['updated'] != 'del')) ? 'yes' : $this->head['updated']; | |
| 2327 | + $res = $this->db->query("UPDATE zones SET " . | |
| 2328 | + "name = '" . $this->head['name'] . "', " . | |
| 2329 | + "pri_dns = '" . $this->head['pri_dns'] . "', " . | |
| 2330 | + "sec_dns = '" . $this->head['sec_dns'] . "', " . | |
| 2331 | + "serial = " . $srl . ", " . | |
| 2332 | + "refresh = " . $this->head['refresh'] . ", " . | |
| 2333 | + "retry = " . $this->head['retry'] . ", " . | |
| 2334 | + "expire = " . $this->head['expire'] . ", " . | |
| 2335 | + "ttl = " . $this->head['ttl'] . ", " . | |
| 2336 | + "valid = '" . $vld . "', " . | |
| 2337 | + "owner = " . $this->head['owner'] . ", " . | |
| 2338 | + "updated = '" . $upd . "', " . | |
| 2339 | + "secured = '" . $this->head['secured'] . "' " . | |
| 2340 | + "WHERE id = " . $this->head['id']); | |
| 2341 | + if (MDB2::isError($res)) { | |
| 2342 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2343 | + error_log($this->err); | |
| 2344 | + return false; | |
| 2345 | + } | |
| 2346 | + return $this->loadZoneHead(); | |
| 2347 | + } | |
| 2348 | + } | |
| 2349 | + | |
| 2350 | + public function saveZone() { | |
| 2351 | + if ($this->saveZoneHead()) { | |
| 2352 | + foreach ($this->records as $each) { | |
| 2353 | + if (!$each->saveRecord()) { | |
| 2354 | + $this->err = $each->getErr(); | |
| 2355 | + return false; | |
| 2356 | + } | |
| 2357 | + } | |
| 2358 | + return true; | |
| 2359 | + } else { | |
| 2360 | + return false; | |
| 2361 | + } | |
| 2362 | + } | |
| 2363 | + | |
| 2364 | + public function eraseZone() { | |
| 2365 | + if (!$this->is_identified()) { | |
| 2366 | + ob_start(); | |
| 2367 | + var_dump($this->head); | |
| 2368 | + $this->err .= "Zone head is not complete" . "\n" . ob_get_clean(); | |
| 2369 | + error_log($this->err); | |
| 2370 | + return false; | |
| 2371 | + } else { | |
| 2372 | + $where = ' WHERE '; | |
| 2373 | + if ($this->head['id'] >>= 0) { | |
| 2374 | + $where .= "id = " . $this->head['id']; | |
| 2375 | + } else { | |
| 2376 | + $where .= "name = '" . $this->head['name'] . "'"; | |
| 2377 | + } | |
| 2378 | + $res = $this->db->query("DELETE FROM zones " . $where); | |
| 2379 | + if (MDB2::isError($res)) { | |
| 2380 | + $this->err .= $res->getMessage() . "\n" . $res->getDebugInfo(); | |
| 2381 | + error_log($this->err); | |
| 2382 | + return false; | |
| 2383 | + } | |
| 2384 | + $this->clearZone(); | |
| 2385 | + return true; | |
| 2386 | + } | |
| 2387 | + } | |
| 2388 | + | |
| 2389 | + public function clearZone() { | |
| 2390 | + $id = $this->head['id']; | |
| 2391 | + $head = array( | |
| 2392 | + 'id' => $id, | |
| 2393 | + 'name' => '', | |
| 2394 | + 'pri_dns' => '', | |
| 2395 | + 'sec_dns' => '', | |
| 2396 | + 'serial' => 0, | |
| 2397 | + 'refresh' => 0, | |
| 2398 | + 'retry' => 0, | |
| 2399 | + 'expire' => 0, | |
| 2400 | + 'ttl' => 0, | |
| 2401 | + 'valid' => 'may', | |
| 2402 | + 'owner' => 0, | |
| 2403 | + 'updated' => 'no', | |
| 2404 | + 'secured' => 'no', | |
| 2405 | + ); | |
| 2406 | + $this->head = $head; | |
| 2407 | + $this->records = array(); | |
| 2408 | + $this->isloaded = FALSE; | |
| 2409 | + } | |
| 2410 | + } | ... | ... |
src/chpass.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * chpass.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************* | |
| 23 | + * | |
| 24 | + * Provides the ligin form | |
| 25 | + * | |
| 26 | + * | |
| 27 | + */ | |
| 28 | + | |
| 29 | +require_once "include.php"; | |
| 30 | + | |
| 31 | +$smarty->assign("pagetitle", "Change password"); | |
| 32 | +$smarty->assign("template", "chpass.tpl"); | |
| 33 | +$smarty->assign("help", help("chpass")); | |
| 34 | +$smarty->assign("menu_button", menu_buttons()); | |
| 35 | +$smarty->display("main.tpl"); | |
| 36 | +?> | ... | ... |
src/commit.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * commit.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************** | |
| 23 | + * | |
| 24 | + * Applies the zone/record changes to the system | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +require_once "include.php"; | |
| 29 | + | |
| 30 | +$dslave = array(); | |
| 31 | +$dmaster = array(); | |
| 32 | + | |
| 33 | +$dslave = $user->getDeletedZones('slave'); | |
| 34 | +$dmaster = $user->getDeletedZones('master'); | |
| 35 | +$cslave = $user->getCommitableZones('slave'); | |
| 36 | +$cmaster = $user->getCommitableZones('master'); | |
| 37 | +$allz = count($dmaster) + count($dslave) + count($cmaster) + count($cslave); | |
| 38 | +$done = 0; | |
| 39 | + | |
| 40 | +if (isset($_SERVER['HTTP_REFERER']) && | |
| 41 | + (preg_replace('/https?:\/\/[^\/]+/', '', $_SERVER['HTTP_REFERER']) != $_SERVER['PHP_SELF']) && | |
| 42 | + (!isset($_GET['commit'])) && | |
| 43 | + ($allz >0)) { | |
| 44 | + $smarty->assign("pagetitle", "Commit changes"); | |
| 45 | + $smarty->assign("template", "commit.tpl"); | |
| 46 | + $smarty->assign("help", help("precommit")); | |
| 47 | + $smarty->assign("menu_button", menu_buttons()); | |
| 48 | + $smarty->display("main.tpl"); | |
| 49 | + die(); | |
| 50 | +} elseif ((isset($_GET['commit'])) && ($_GET['commit'] != 'y')) { | |
| 51 | + problem(); | |
| 52 | +} elseif (count($dmaster) + | |
| 53 | + count($dslave) + | |
| 54 | + count($cmaster) + | |
| 55 | + count($cslave) == 0) { | |
| 56 | + problem("nocommit"); | |
| 57 | +} | |
| 58 | + | |
| 59 | +$bind = new bindConfig($conf->conf); | |
| 60 | + | |
| 61 | +$deleted = ''; | |
| 62 | +$commited = ''; | |
| 63 | +$error = ''; | |
| 64 | + | |
| 65 | +$delm = (count($dmaster) > 0) ? "<strong>" . "Deleting master records" . "</strong>\n\n" : ''; | |
| 66 | + | |
| 67 | +foreach ($dmaster as $master) { | |
| 68 | + $dmz = new masterZone(intval($master['id'])); | |
| 69 | + $dmz->loadZoneHead(); | |
| 70 | + $hd = $dmz->getZoneHead(); | |
| 71 | + $hdr = $dmz->getZoneHeadRaw(); | |
| 72 | + $dmz->eraseZone(); | |
| 73 | + $err = $dmz->getErr(); | |
| 74 | + if ($err > '') { | |
| 75 | + $error .= "<u>" . $hd['name'] . ":</u> " . "Error in deleting" . "\n" . $err . '\n\n'; | |
| 76 | + } else { | |
| 77 | + $deleted .= "<u>" . $hd['name'] . ":</u> Deleting success.\n\n"; | |
| 78 | + $bind->eraseConfig($hdr['name']); | |
| 79 | + $done++; | |
| 80 | + } | |
| 81 | +} | |
| 82 | + | |
| 83 | +$error = ($error > '') ? $delm . $error : ''; | |
| 84 | +$deleted = ($deleted > '') ? $delm . $deleted : ''; | |
| 85 | + | |
| 86 | +$errors = ''; | |
| 87 | +$deleteds = ''; | |
| 88 | +$delm .= (count($dslave) > 0) ? "<strong>" . "Deleting slave records" . "</strong>\n\n" : ''; | |
| 89 | +$delm = ($deleted > '') ? "\n" . $delm : $delm; | |
| 90 | + | |
| 91 | +foreach ($dslave as $slave) { | |
| 92 | + $dsz = new slaveZone(intval($slave['id'])); | |
| 93 | + $dsz->loadZoneHead(); | |
| 94 | + $hd = $dsz->getZoneHead(); | |
| 95 | + $hdr = $dsz->getZoneHeadRaw(); | |
| 96 | + $dsz->eraseZone(); | |
| 97 | + $err = $dsz->getErr(); | |
| 98 | + if ($err > '') { | |
| 99 | + $errors .= "<u>" . $hd['name'] . ":</u> Error in deleting\n" . $err . '\n\n'; | |
| 100 | + } else { | |
| 101 | + $deleteds .= "<u>" . $hd['name'] . "</u>: Deleting success.\n\n"; | |
| 102 | + $bind->eraseConfig($hdr['name']); | |
| 103 | + $done++; | |
| 104 | + } | |
| 105 | +} | |
| 106 | + | |
| 107 | +$error .= ($errors > '') ? $delm . $errors : ''; | |
| 108 | +$deleted .= ($deleteds > '') ? $delm . $deleteds : ''; | |
| 109 | +$errors = ''; | |
| 110 | + | |
| 111 | +$comm = (count($cmaster) > 0) ? "<strong>" . "Committing master records" . "</strong>\n\n" : ''; | |
| 112 | +$mcomm = ''; | |
| 113 | + | |
| 114 | +foreach ($cmaster as $master) { | |
| 115 | + $cmz = new masterZone(intval($master['id'])); | |
| 116 | + $cmz->loadZoneHead(); | |
| 117 | + $hd = $cmz->getZoneHead(); | |
| 118 | + $hdr = $cmz->getZoneHeadRaw(); | |
| 119 | + $cmz->writeZone($conf->path . $hdr['name'], $conf->hostMaster); | |
| 120 | + $zarray = array( | |
| 121 | + 'type' => 'master', | |
| 122 | + 'file' => $hdr['name'], | |
| 123 | + ); | |
| 124 | + $zarray['file'] .= (($hd['secured'] == 'yes') && ($cmz->doSecure($conf->path, $conf->zoneSigner, $conf->rollInit, $conf->rollerConf))) ? ".signed" : ""; | |
| 125 | + $cmz->doCommit(); | |
| 126 | + $err = $cmz->getErr(); | |
| 127 | + if ($err > '') { | |
| 128 | + $errors .= "<u>" . $hd['name'] . ":</u> Error in committing\n" . $err . '\n\n'; | |
| 129 | + } else { | |
| 130 | + $mcomm .= "<u>" . $hd['name'] . "</u>: Committing success.\n" . $cmz->getMsg() . "\n"; | |
| 131 | + $bind->addConfig($hdr['name'], $zarray); | |
| 132 | + $done++; | |
| 133 | + } | |
| 134 | +} | |
| 135 | + | |
| 136 | +$error .= ($errors > '') ? $comm . $errors : ''; | |
| 137 | +$commited .= ($mcomm > '') ? $comm . $mcomm: ''; | |
| 138 | +$errors = ''; | |
| 139 | + | |
| 140 | +$comm = (count($cslave) > 0) ? "<strong>" . "Committing slave records" . "</strong>\n\n" : ''; | |
| 141 | +$commited .= ($comm > '') ? "\n" : ''; | |
| 142 | +$scomm = ''; | |
| 143 | + | |
| 144 | +foreach ($cslave as $slave) { | |
| 145 | + $csz = new slaveZone(intval($slave['id'])); | |
| 146 | + $csz->loadZoneHead(); | |
| 147 | + $hd = $csz->getZoneHead(); | |
| 148 | + $hdr = $csz->getZoneHeadRaw(); | |
| 149 | + $err = $csz->getErr(); | |
| 150 | + if ($err > '') { | |
| 151 | + $errors .= "<u>" . $hd['name'] . ":</u> Error in committing\n" . $err . '\n\n'; | |
| 152 | + } else { | |
| 153 | + $csz->doCommit(); | |
| 154 | + $scomm .= "<u>" . $hd['name'] . "</u>: Committing success.\n\n"; | |
| 155 | + $bind->addConfig($hdr['name'], array ( | |
| 156 | + 'type' => 'slave', | |
| 157 | + 'masters' => $hdr['master'], | |
| 158 | + 'file' => $hdr['name'], | |
| 159 | + )); | |
| 160 | + $done++; | |
| 161 | + } | |
| 162 | +} | |
| 163 | + | |
| 164 | +$error .= ($errors > '') ? $comm . $errors : ''; | |
| 165 | +$commited .= ($scomm > '') ? $comm . $scomm : ''; | |
| 166 | +$bind->saveConfig($conf->conf); | |
| 167 | + | |
| 168 | +if ($done > 0) { | |
| 169 | + $cmd = $conf->rndc . " reload 2> /dev/stdout"; | |
| 170 | + unset($coutput); | |
| 171 | + exec($cmd, $coutput, $exit); | |
| 172 | + if ($exit != 0) { | |
| 173 | + $error .= "Rndc error(" . $exit . "):\n" . implode("\n", $coutput); | |
| 174 | + } else { | |
| 175 | + $multi = ($done > 1) ? "zones" : "zone"; | |
| 176 | + $commited .= "<b>" . $done . " " . $multi . " has been commited and reloaded:" . "</b>\n " . implode("\n ", $coutput) . "\n"; | |
| 177 | + } | |
| 178 | +} else { | |
| 179 | + $commited .= "<b>" . "There wasn't commited zone" . "</b>"; | |
| 180 | +} | |
| 181 | + | |
| 182 | +$error = implode("<br />", explode("\n", $error)); | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | +//~ $currpath = getcwd(); | |
| 192 | +//~ $signexit = 0; | |
| 193 | +//~ $log = ""; | |
| 194 | +//~ | |
| 195 | +//~ $zoneres = $dbconnect->query("SELECT * FROM zones WHERE updated = 'yes'"); | |
| 196 | +//~ is_error($zoneres); | |
| 197 | +//~ | |
| 198 | +//~ while($zone = $zoneres->fetchrow()) { | |
| 199 | + //~ $recordres = $dbconnect->query("SELECT * FROM records " . | |
| 200 | + //~ "WHERE zone = " . $zone[0] . " AND valid != 'no' " . | |
| 201 | + //~ "ORDER BY host, type, pri, destination"); | |
| 202 | + //~ is_error($recordres); | |
| 203 | + //~ $out = | |
| 204 | +//~ "\$TTL " . $zone[8] . " | |
| 205 | +//~ @ IN SOA " . $zone[2] . ". " . $conf->hostmaster . ". ( | |
| 206 | + //~ " . $zone[4] . " \t; Serial | |
| 207 | + //~ " . $zone[5] . " \t\t; Refresh | |
| 208 | + //~ " . $zone[6] . " \t\t; Retry | |
| 209 | + //~ " . $zone[7] . " \t; Expire | |
| 210 | + //~ " . $zone[8] . ")\t\t; Negative Cache TTL | |
| 211 | +//~ ;\n" ; | |
| 212 | + //~ if ($zone[2] != '') { | |
| 213 | + //~ $out .= prettyer("@",'','NS','',$zone[2] . ".") . "\n"; | |
| 214 | + //~ } | |
| 215 | + //~ if ($zone[3] != '') { | |
| 216 | + //~ $out .= prettyer("@",'','NS','',$zone[3] . ".") . "\n"; | |
| 217 | + //~ } | |
| 218 | + //~ $fd = fopen($conf->path . preg_replace('/\//','-',$zone[1]), "w") | |
| 219 | + //~ or die("Cannot open: " . $conf->path . preg_replace('/\//','-',$zone[1])); | |
| 220 | + //~ fwrite($fd, $out); | |
| 221 | +//~ | |
| 222 | + //~ while($record = $recordres->fetchrow()) { | |
| 223 | + //~ if($record[3] == "MX") { | |
| 224 | + //~ $pri = $record[4]; | |
| 225 | + //~ } | |
| 226 | + //~ else { | |
| 227 | + //~ $pri = ""; | |
| 228 | + //~ } | |
| 229 | + //~ if(($record[7] == NULL) || ($record[7] == 0)){ $record[7]=''; } | |
| 230 | + //~ if( | |
| 231 | + //~ ($record[3] == "NS" || | |
| 232 | + //~ $record[3] == "PTR" || | |
| 233 | + //~ $record[3] == "CNAME" || | |
| 234 | + //~ $record[3] == "MX" || | |
| 235 | + //~ $record[3] == "SRV") && | |
| 236 | + //~ ($record[5] != "@")) { | |
| 237 | + //~ $destination = $record[5] . "."; | |
| 238 | + //~ } | |
| 239 | + //~ else { | |
| 240 | + //~ $destination = $record[5]; | |
| 241 | + //~ } | |
| 242 | + //~ $out = prettyer($record[2],$record[7],$record[3],$pri,$destination) . "\n"; | |
| 243 | + //~ fwrite($fd, $out); | |
| 244 | + //~ } | |
| 245 | + //~ fclose($fd); | |
| 246 | +//~ | |
| 247 | + //~ // Check the full zone only | |
| 248 | + //~ $cmd = $conf->namedcheckzone . " " . $zone[1] . " " . $_CONF['path'] . preg_replace('/\//','-',$zone[1]) . " 2>/dev/stdout"; | |
| 249 | + //~ unset($coutput); | |
| 250 | + //~ exec($cmd, $coutput, $exit); | |
| 251 | + //~ $log = "<big><u>Master zones</u>\n<b>" . idn2host($zone[1]) . " (SEC: $zone[12]) output:</b></big>\n"; | |
| 252 | + //~ $log .= "<b> Zonecheck:</b>\n"; | |
| 253 | + //~ $loglevel=LOG_INFO; | |
| 254 | + //~ // Log the output | |
| 255 | + //~ openlog('CHECKZONE', LOG_PID, LOG_SYSLOG); | |
| 256 | + //~ if ($exit != 0) { | |
| 257 | + //~ $loglevel=LOG_ERR; | |
| 258 | + //~ } | |
| 259 | + //~ syslog($loglevel, "Exitcode: $exit"); | |
| 260 | + //~ $log .= " <b>Exitcode:</b> $exit\n"; | |
| 261 | + //~ foreach ($coutput as $line) { | |
| 262 | + //~ syslog($loglevel, $line); | |
| 263 | + //~ $log .= " $line\n"; | |
| 264 | + //~ } | |
| 265 | + //~ closelog(); | |
| 266 | +//~ | |
| 267 | + //~ if ($exit == 0) { | |
| 268 | + //~ $updateres = $dbconnect->query("UPDATE zones SET updated = 'no', valid = 'yes' " . | |
| 269 | + //~ "WHERE id = " . $zone[0]); | |
| 270 | + //~ is_error($updateres); | |
| 271 | + //~ $testres = $dbconnect->query("UPDATE records SET valid = 'yes' " . | |
| 272 | + //~ "WHERE zone = " . $zone[0]); | |
| 273 | + //~ is_error($testres); | |
| 274 | + //~ $rebuild = "yes"; | |
| 275 | + //~ $zonefile = $conf->path . preg_replace('/\//','-',$zone[1]); | |
| 276 | + //~ if ($zone[12] == "yes") { | |
| 277 | + //~ chdir($conf->path); | |
| 278 | + //~ $cmd = ''; | |
| 279 | + //~ if (file_exists($zonefile . '.signed')) { | |
| 280 | + //~ $cmd = $conf->zonesigner . " -zone " . $zone[1] . " " . $zonefile . " 2>/dev/stdout"; | |
| 281 | + //~ } else { | |
| 282 | + //~ $cmd = $conf->zonesigner . " -genkeys -usensec3 -zone " . $zone[1] . " " . $zonefile . " 2>/dev/stdout"; | |
| 283 | + //~ } | |
| 284 | + //~ unset($coutput); | |
| 285 | + //~ exec($cmd, $coutput, $signexit); | |
| 286 | + //~ $loglevel=LOG_INFO; | |
| 287 | + //~ openlog('DNSSEC', LOG_PID, LOG_SYSLOG); | |
| 288 | + //~ if ($signexit != 0) { | |
| 289 | + //~ $loglevel=LOG_ERR; | |
| 290 | + //~ } | |
| 291 | + //~ syslog($loglevel, "Exitcode: $signexit"); | |
| 292 | + //~ $log .= "<b> Zonesign:</b>\n"; | |
| 293 | + //~ $log .= " <b>Exitcode:</b> $signexit\n"; | |
| 294 | + //~ foreach ($coutput as $line) { | |
| 295 | + //~ syslog($loglevel, $line); | |
| 296 | + //~ $log .= " $line\n"; | |
| 297 | + //~ } | |
| 298 | + //~ closelog(); | |
| 299 | + //~ chdir($currpath); | |
| 300 | + //~ if($signexit == 0) { | |
| 301 | +//~ | |
| 302 | + //~ // Check the signed zone again | |
| 303 | + //~ $cmd = $conf->namedcheckzone . " " . $zone[1] . " " . $_CONF['path'] . preg_replace('/\//','-',$zone[1]) . ".signed 2>/dev/stdout"; | |
| 304 | + //~ unset($coutput); | |
| 305 | + //~ exec($cmd, $coutput, $exit); | |
| 306 | + //~ $loglevel=LOG_INFO; | |
| 307 | + //~ // Log the output | |
| 308 | + //~ $log .= " <b>Zonecheck(signed):</b>\n"; | |
| 309 | + //~ openlog('CHECKZONE', LOG_PID, LOG_SYSLOG); | |
| 310 | + //~ if ($exit != 0) { | |
| 311 | + //~ $loglevel=LOG_ERR; | |
| 312 | + //~ } | |
| 313 | + //~ syslog($loglevel, "Exitcode: $exit"); | |
| 314 | + //~ $log .= " <b>Exitcode:</b> $exit\n"; | |
| 315 | + //~ foreach ($coutput as $line) { | |
| 316 | + //~ syslog($loglevel, $line); | |
| 317 | + //~ $log .= " $line\n"; | |
| 318 | + //~ } | |
| 319 | + //~ closelog(); | |
| 320 | +//~ | |
| 321 | + //~ $zonefile .= ".signed"; | |
| 322 | + //~ } | |
| 323 | + //~ } | |
| 324 | + //~ } | |
| 325 | + //~ else { | |
| 326 | + //~ $updateres = $dbconnect->query("UPDATE zones SET updated = 'yes', valid = 'no' " . | |
| 327 | + //~ "WHERE id = " . $zone[0]); | |
| 328 | + //~ is_error($updateres); | |
| 329 | + //~ $testres = $dbconnect->query("UPDATE records SET valid = 'no' " . | |
| 330 | + //~ "WHERE zone = " . $zone[0]); | |
| 331 | + //~ is_error($testres); | |
| 332 | + //~ } | |
| 333 | +//~ } | |
| 334 | +//~ | |
| 335 | +//~ $fd = fopen($conf->slave_conf, "w"); | |
| 336 | +//~ fwrite($fd, "// Slave zones\n\n"); | |
| 337 | +//~ | |
| 338 | +//~ $confres = $dbconnect->query("SELECT name, master, updated FROM slave_zones where name <> 'DUMMY' ORDER BY name"); | |
| 339 | +//~ is_error($confres); | |
| 340 | +//~ | |
| 341 | +//~ while($conf = $confres->fetchrow()) { | |
| 342 | + //~ $cout = "zone \"" . $conf[0] . "\" {\n\t" . | |
| 343 | + //~ "type slave;\n\t" . | |
| 344 | + //~ "masters {" . $conf[1] . ";};\n\t" . | |
| 345 | + //~ "file \"" . preg_replace('/\//','-',$conf[0]) . "\";\n};\n\n"; | |
| 346 | + //~ fwrite($fd, $cout); | |
| 347 | + //~ $updateres = $dbconnect->query("UPDATE slave_zones SET updated = 'no', valid = 'yes' " . | |
| 348 | + //~ "WHERE name = \"" . $conf[0] . "\""); | |
| 349 | + //~ is_error($updateres); | |
| 350 | + //~ if($conf[2] == 'yes'){ $rebuild = "yes";} | |
| 351 | +//~ } | |
| 352 | +//~ | |
| 353 | +//~ $res = $dbconnect->query("SELECT updated " . | |
| 354 | + //~ "FROM slave_zones " . | |
| 355 | + //~ "WHERE name = 'DUMMY'"); | |
| 356 | +//~ $row = $res->fetchrow(); | |
| 357 | +//~ if($row[0] == "yes"){ $rebuild = "yes";} | |
| 358 | +//~ | |
| 359 | +//~ $updateres = $dbconnect->query("UPDATE slave_zones SET updated = 'no', valid = 'unknown' " . | |
| 360 | + //~ "WHERE name = 'DUMMY'"); | |
| 361 | +//~ is_error($updateres); | |
| 362 | +//~ | |
| 363 | +//~ fclose($fd); | |
| 364 | +//~ | |
| 365 | +//~ if (isset($rebuild)) { | |
| 366 | + //~ $log .= "<big><b>Config rebuild output</b></big>\n"; | |
| 367 | + //~ $confres = $dbconnect->query("SELECT name, secured FROM zones ORDER BY name"); | |
| 368 | + //~ is_error($confres); | |
| 369 | + //~ $cout = "// Master zones\n\n"; | |
| 370 | + //~ while($conf = $confres->fetchrow()) { | |
| 371 | + //~ $zonefile = preg_replace('/\//','-',$conf[0]); | |
| 372 | + //~ $signed = $zonefile . '.signed'; | |
| 373 | + //~ if(($conf[1] == "yes") && (file_exists($conf->path . $signed))) { | |
| 374 | + //~ $log .= " <big>" . host2idn($zonefile) . " rolling</big>\n"; | |
| 375 | + //~ $search = "roll\t\"$zonefile\""; | |
| 376 | + //~ $exists = false; | |
| 377 | + //~ $lines = file($conf->rollerconf); | |
| 378 | + //~ while (list($key, $line) = each($lines) and !$exists) { | |
| 379 | + //~ $exists = (strpos($line, $search) !== FALSE); | |
| 380 | + //~ } | |
| 381 | + //~ if (!$exists) { | |
| 382 | + //~ unset($coutput); | |
| 383 | + //~ $cmd = $conf->rollinit . " " . $zonefile . " -zone " . $_CONF['path'] . $signed . " -keyrec " . $_CONF['path'] . $zonefile . ".krf -directory " . $_CONF['path'] . " 2>/dev/stdout"; | |
| 384 | + //~ exec($cmd, $coutput, $exit); | |
| 385 | + //~ $loglevel=LOG_INFO; | |
| 386 | + //~ $log .= " <b> Rollerconfig:</b>\n"; | |
| 387 | + //~ // Log the output | |
| 388 | + //~ openlog('ROLLERCONF', LOG_PID, LOG_SYSLOG); | |
| 389 | + //~ if ($exit != 0) { | |
| 390 | + //~ $loglevel=LOG_ERR; | |
| 391 | + //~ } | |
| 392 | + //~ syslog($loglevel, "Exitcode: $exit"); | |
| 393 | + //~ $log .= " <b>Exitcode:</b> $exit\n"; | |
| 394 | + //~ $roll = ""; | |
| 395 | + //~ foreach ($coutput as $line) { | |
| 396 | + //~ syslog($loglevel, $line); | |
| 397 | + //~ $roll .= "$line\n"; | |
| 398 | + //~ $log .= " $linr\n"; | |
| 399 | + //~ } | |
| 400 | + //~ $fd = fopen($conf->rollerconf,"a+"); | |
| 401 | + //~ fwrite($fd, $roll); | |
| 402 | + //~ fclose($fd); | |
| 403 | + //~ } else { | |
| 404 | + //~ $log .= " <b> Rollerconfig exists</b>\n"; | |
| 405 | + //~ } | |
| 406 | + //~ $zonefile = $signed; | |
| 407 | + //~ } | |
| 408 | + //~ $cout .= "zone \"" . $conf[0] . "\" {\n\ttype master;\n\tfile \"" . $zonefile . "\";\n};\n\n"; | |
| 409 | + //~ } | |
| 410 | + //~ $fd = fopen($conf->conf,"w"); | |
| 411 | + //~ fwrite($fd, $cout); | |
| 412 | + //~ fclose($fd); | |
| 413 | +//~ | |
| 414 | + //~ // Check the master config | |
| 415 | + //~ $cmd = $conf->namedcheckconf . " " . $_CONF['conf'] . " 2> /dev/stdout"; | |
| 416 | + //~ unset($coutput); | |
| 417 | + //~ exec($cmd, $coutput, $exit); | |
| 418 | + //~ $loglevel=LOG_INFO; | |
| 419 | + //~ $log .= " <b>Master configcheck:</b>\n"; | |
| 420 | + //~ // Log the output | |
| 421 | + //~ openlog('CHECKCONF', LOG_PID, LOG_SYSLOG); | |
| 422 | + //~ if ($exit != 0) { | |
| 423 | + //~ $loglevel=LOG_ERR; | |
| 424 | + //~ } | |
| 425 | + //~ syslog($loglevel, "Exitcode: $exit"); | |
| 426 | + //~ $log .= " <b>Exitcode:</b> $exit\n"; | |
| 427 | + //~ foreach ($coutput as $line) { | |
| 428 | + //~ syslog($loglevel, $line); | |
| 429 | + //~ $log .= " $line\n"; | |
| 430 | + //~ } | |
| 431 | + //~ closelog(); | |
| 432 | +//~ | |
| 433 | + //~ // Check the slave config | |
| 434 | + //~ $cmd = $conf->namedcheckconf . " " . $_CONF['slave_conf'] . " 2> /dev/stdout"; | |
| 435 | + //~ unset($coutput); | |
| 436 | + //~ exec($cmd, $coutput, $slave_exit); | |
| 437 | + //~ $loglevel=LOG_INFO; | |
| 438 | + //~ $log .= " <b>Slave configcheck:</b>\n"; | |
| 439 | + //~ // Log the output | |
| 440 | + //~ openlog('CHECKCONF', LOG_PID, LOG_SYSLOG); | |
| 441 | + //~ if ($slave_exit != 0) { | |
| 442 | + //~ $loglevel=LOG_ERR; | |
| 443 | + //~ $updateres = $dbconnect->query("UPDATE slave_zones SET updated = 'yes', valid = 'no' " . | |
| 444 | + //~ "WHERE name = 'DUMMY'"); | |
| 445 | + //~ is_error($updateres); | |
| 446 | + //~ } else { | |
| 447 | + //~ $updateres = $dbconnect->query("UPDATE slave_zones SET updated = 'no', valid = 'yes' " . | |
| 448 | + //~ "WHERE name = 'DUMMY'"); | |
| 449 | + //~ is_error($updateres); | |
| 450 | + //~ } | |
| 451 | + //~ syslog($loglevel, "Exitcode: $slave_exit"); | |
| 452 | + //~ $log .= " <b>Exitcode:</b> $slave_exit\n"; | |
| 453 | + //~ foreach ($coutput as $line) { | |
| 454 | + //~ syslog($loglevel, $line); | |
| 455 | + //~ $log .= " $line\n"; | |
| 456 | + //~ } | |
| 457 | + //~ closelog(); | |
| 458 | + //~ $exit += $slave_exit; | |
| 459 | +//~ | |
| 460 | + //~ if ($exit == 0) { | |
| 461 | +//~ | |
| 462 | + //~ // Reaload zones | |
| 463 | + //~ $cmd = $conf->rndc . " reload 2> /dev/stdout"; | |
| 464 | + //~ unset($coutput); | |
| 465 | + //~ exec($cmd, $coutput, $exit); | |
| 466 | + //~ $loglevel=LOG_INFO; | |
| 467 | + //~ $log .= " <b>Reload zones:</b>\n"; | |
| 468 | + //~ // Log the output | |
| 469 | + //~ openlog('DNS reload', LOG_PID, LOG_SYSLOG); | |
| 470 | + //~ if ($exit != 0) { | |
| 471 | + //~ $loglevel=LOG_ERR; | |
| 472 | + //~ } | |
| 473 | + //~ syslog($loglevel, "Exitcode: $exit"); | |
| 474 | + //~ $log .= " <b>Exitcode:</b> $exit\n"; | |
| 475 | + //~ foreach ($coutput as $line) { | |
| 476 | + //~ syslog($loglevel, $line); | |
| 477 | + //~ $log .= " $line\n"; | |
| 478 | + //~ } | |
| 479 | + //~ closelog(); | |
| 480 | + //~ } | |
| 481 | +//~ } | |
| 482 | +//~ | |
| 483 | +$smarty->assign("popuperror", $error); | |
| 484 | +$smarty->assign("success", $deleted . $commited); | |
| 485 | +$smarty->assign("pagetitle", "Commit changes"); | |
| 486 | +$smarty->assign("template", "commitdone.tpl"); | |
| 487 | +$smarty->assign("help", help("commit")); | |
| 488 | +$smarty->assign("menu_button", menu_buttons()); | |
| 489 | +$smarty->display("main.tpl"); | |
| 490 | +?> | ... | ... |
src/convert.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * convert.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************* | |
| 23 | + * | |
| 24 | + * Processes the inport form and do the import. | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +require_once "include.php"; | |
| 29 | + | |
| 30 | +$out = array(); | |
| 31 | + | |
| 32 | +if($user->isAdmin()) { | |
| 33 | + if(($_SERVER['REQUEST_METHOD'] == 'POST') && (isset($_POST['method']))) { | |
| 34 | + $method = $_POST['method']; | |
| 35 | + $valid = true; | |
| 36 | + $problem = ''; | |
| 37 | + $zone = ''; | |
| 38 | + $content = array(); | |
| 39 | + $temp = ''; | |
| 40 | + switch ($method) { | |
| 41 | + case "file": | |
| 42 | + $zone = ((isset($_POST['fil_domain'])) && (isset($_FILES['fil']['tmp_name']))) ? $zone = $_POST['fil_domain'] : ''; | |
| 43 | + $content = ($zone > '') ? file($_FILES['fil']['tmp_name']) :array(); | |
| 44 | + $smarty->assign("method", "Upload from file"); | |
| 45 | + break; | |
| 46 | + case "list": | |
| 47 | + $zone = ((isset($_POST['sel_domain'])) && ($_POST['sel'] != '- select file -')) ? $_POST['sel_domain'] : ''; | |
| 48 | + $content = ($zone > '') ? file($conf->path . idnToHost($_POST['sel'])) : array(); | |
| 49 | + $smarty->assign("method", "Select orphan file from list"); | |
| 50 | + break; | |
| 51 | + case "text": | |
| 52 | + $zone = ((isset($_POST['txt_domain'])) && (isset($_POST['txt']))) ? $_POST['txt_domain'] : ''; | |
| 53 | + $content = ($zone > '') ? explode("\n", $_POST['txt']) : array(); | |
| 54 | + $smarty->assign("method", "Write zone manually or pasted from clipboard"); | |
| 55 | + break; | |
| 56 | + default: | |
| 57 | + problem(); | |
| 58 | + } | |
| 59 | + if (count($content) < 4) { | |
| 60 | + problem("nocontent"); | |
| 61 | + } | |
| 62 | + $gzone = $zone; | |
| 63 | + $zone = hostToIdn($zone); | |
| 64 | + if ($method != 'list') { | |
| 65 | + $temp = tempnam($conf->tmp_path, "$zone"); | |
| 66 | + $fh = fopen($temp, "w"); | |
| 67 | + fwrite($fh, implode("\n", $content)); | |
| 68 | + fclose($fh); | |
| 69 | + $check = checkZoneFile($temp, $zone); | |
| 70 | + unlink($temp); | |
| 71 | + if (!$check) { | |
| 72 | + problem("nocontent"); | |
| 73 | + } | |
| 74 | + } | |
| 75 | + $mz = new masterZone($gzone); | |
| 76 | + $sz = new slaveZone($gzone); | |
| 77 | + if (($mz->loadZoneHead()) || ($sz->loadZoneHead())) { | |
| 78 | + $mz = array(); | |
| 79 | + $sz = array(); | |
| 80 | + problem("existzone"); | |
| 81 | + } | |
| 82 | + $smarty->assign("zone", $gzone); | |
| 83 | + $nz = new masterZone(); | |
| 84 | + if (($nz->parseZone($content, $zone, $user->getId())) && ($nz->getId() > 0)) { | |
| 85 | + $smarty->assign("pagetitle", "Review imported records"); | |
| 86 | + $smarty->assign("template", "uploadreview.tpl"); | |
| 87 | + $smarty->assign("output", explode("\n", $nz->getConf($conf->hostMaster))); | |
| 88 | + $smarty->assign("help", help("uploadreview")); | |
| 89 | + $smarty->assign("menu_button", menu_buttons()); | |
| 90 | + } else { | |
| 91 | + $smarty->assign("problem", explode("\n", $nz->getErr())); | |
| 92 | + $smarty->assign("pagetitle", "Import error"); | |
| 93 | + $smarty->assign("template", "uploadproblem.tpl"); | |
| 94 | + $smarty->assign("help", help("uploadproblem")); | |
| 95 | + $smarty->assign("menu_button", menu_buttons()); | |
| 96 | + } | |
| 97 | + $smarty->display("main.tpl"); | |
| 98 | + } else { | |
| 99 | + problem(); | |
| 100 | + } | |
| 101 | +} else { | |
| 102 | + access_denied(); | |
| 103 | +} | |
| 104 | +?> | ... | ... |
src/deleteuser.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * deleteuser.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************* | |
| 23 | + * | |
| 24 | + * Check what need to delete and provides info for confirmation | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +require_once "include.php"; | |
| 29 | + | |
| 30 | +if($user->isAdmin()) { | |
| 31 | + $num = intval($_GET['i']); | |
| 32 | + switch ($num) { | |
| 33 | + case 0: | |
| 34 | + case 1: | |
| 35 | + problem("deleteadmin"); | |
| 36 | + break; | |
| 37 | + case $user->getId(); | |
| 38 | + problem("deleteys"); | |
| 39 | + break; | |
| 40 | + default: | |
| 41 | + $smarty->assign("pagetitle", "Delete user"); | |
| 42 | + $duser = new User($num); | |
| 43 | + $smarty->assign("user", $duser->getUser()); | |
| 44 | + $smarty->assign("template", "deleteuser.tpl"); | |
| 45 | + $smarty->assign("help", help("deleteuser")); | |
| 46 | + $smarty->assign("menu_button", menu_buttons()); | |
| 47 | + $smarty->display("main.tpl"); | |
| 48 | + } | |
| 49 | +} else { | |
| 50 | + access_denied(); | |
| 51 | +} | |
| 52 | +?> | ... | ... |
src/deletezone.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * deletezone.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + * | |
| 23 | + ********************************************************************** | |
| 24 | + * | |
| 25 | + * Check what need to delete and provides info for confirmation | |
| 26 | + * | |
| 27 | + */ | |
| 28 | + | |
| 29 | +require_once "include.php"; | |
| 30 | + | |
| 31 | +$zoneid = intval($_GET['i']); | |
| 32 | + | |
| 33 | +if ($zoneid > 0) { | |
| 34 | + if ($user->isOwned($zoneid, 'master')) { | |
| 35 | + $smarty->assign("pagetitle", "Delete master zone"); | |
| 36 | + $zone = new masterZone($zoneid); | |
| 37 | + $zone->loadZoneHead(); | |
| 38 | + $res = $zone->getZoneHead(); | |
| 39 | + $smarty->assign("zone", $res['name']); | |
| 40 | + $smarty->assign("zoneid", $zoneid); | |
| 41 | + $smarty->assign("template", "deletezone.tpl"); | |
| 42 | + $smarty->assign("help", help("deletezone")); | |
| 43 | + $smarty->assign("menu_button", menu_buttons()); | |
| 44 | + $smarty->display("main.tpl"); | |
| 45 | + } else { | |
| 46 | + problem('notown'); | |
| 47 | + } | |
| 48 | +} else { | |
| 49 | + problem(); | |
| 50 | +} | |
| 51 | + | |
| 52 | +?> | ... | ... |
src/end.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * end.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************** | |
| 23 | + * | |
| 24 | + * Destroy the session | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +require_once "include.php"; | |
| 29 | + | |
| 30 | +$session->destroy(); | |
| 31 | +die(); | |
| 32 | + | |
| 33 | +?> | ... | ... |
src/include.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * include.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************** | |
| 23 | + * | |
| 24 | + * Contains the main definitions, functions and elements | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +$base = preg_replace('/(\/src\/([^\/]+\.php)).*/', '/', $_SERVER['REQUEST_URI']); | |
| 29 | +$src = $base . 'src/'; | |
| 30 | +$config = 'config/config.php'; | |
| 31 | +$lib = 'lib/'; | |
| 32 | + | |
| 33 | +if (stripos($_SERVER['REQUEST_URI'], '/src/')) { | |
| 34 | + $config = '../' . $config; | |
| 35 | + $lib = '../' . $lib; | |
| 36 | +} | |
| 37 | + | |
| 38 | +set_include_path(get_include_path() . ":" . $lib); | |
| 39 | +require_once("smbind.class.php"); | |
| 40 | +$conf = new Configuration($config); | |
| 41 | +$session = new Session(); | |
| 42 | + | |
| 43 | +if ($conf->ReCaptcha == "yes") { | |
| 44 | + require_once("recaptchalib.php"); | |
| 45 | +} | |
| 46 | + | |
| 47 | +set_include_path(get_include_path() . ":" . $conf->Smarty_Path); | |
| 48 | + | |
| 49 | +header("Content-Type: text/html; charset=UTF-8"); | |
| 50 | +header("X-Content-Security-Policy: default-src 'self'; script-src 'self' self www.gstatic.com www.google.com google.com; img-src 'self' data: www.gstatic.com www.google.com google.com; style-src 'self'; font-src 'self'; frame-src 'self'; connect-src 'self' apis.google.com; object-src 'self'"); | |
| 51 | + | |
| 52 | +$dbconnect = &$db; | |
| 53 | + | |
| 54 | +if (MDB2::isError($dbconnect)) { | |
| 55 | + die("Database error: " . MDB2::errorMessage($dbconnect)); | |
| 56 | +} else { | |
| 57 | + $dbconnect->setFetchMode(MDB2_FETCHMODE_ASSOC); | |
| 58 | +} | |
| 59 | + | |
| 60 | +require_once("Smarty.class.php"); | |
| 61 | +$smarty = new Smarty; | |
| 62 | +$smarty->assign('TITLE',$var = $conf->Title); | |
| 63 | +$smarty->assign('footerleft',$conf->Footer); | |
| 64 | +$smarty->assign('footerright',$conf->Marker); | |
| 65 | +$smarty->assign('sdomain',$conf->StaticDomain); | |
| 66 | +$smarty->assign('skin',$conf->Template); | |
| 67 | +$smarty->template_dir = $conf->Smbind_Ng . "templates"; | |
| 68 | +$smarty->compile_dir = $conf->Smbind_Ng . "templates_c"; | |
| 69 | +$smarty->assign("base", $base); | |
| 70 | +$smarty->assign("static", $base . "static/"); | |
| 71 | +$smarty->assign("src", $src); | |
| 72 | +$smarty->assign("captcha","no"); | |
| 73 | +$smarty->assign("recaptcha",""); | |
| 74 | +$smarty->assign("menu_button",""); | |
| 75 | +$smarty->assign("donotcommit","no"); | |
| 76 | +$smarty->assign('popuperror',NULL); | |
| 77 | + | |
| 78 | +$cap_rsp = NULL; | |
| 79 | +if(isset($_POST["recaptcha_response_field"])){ | |
| 80 | + if ($_POST["recaptcha_response_field"]!=''){ | |
| 81 | + $rsp = recaptcha_check_answer ( | |
| 82 | + $conf->RC_PrivKey, | |
| 83 | + $_SERVER["REMOTE_ADDR"], | |
| 84 | + $_POST["recaptcha_challenge_field"], | |
| 85 | + $_POST["recaptcha_response_field"] | |
| 86 | + ); | |
| 87 | + if(!$rsp->is_valid) { | |
| 88 | + $cap_rsp = $rsp->error; | |
| 89 | + } | |
| 90 | + } else { | |
| 91 | + $cap_rsp = 'incorrect-captcha-sol'; | |
| 92 | + } | |
| 93 | +} | |
| 94 | + | |
| 95 | +if (isset($_POST['username']) && isset($_POST['password']) && ($cap_rsp == NULL)) { | |
| 96 | + $session->login($_POST['username'], $_POST['password']); | |
| 97 | +} | |
| 98 | + | |
| 99 | +$user = new User(); | |
| 100 | +$smarty->assign("loggedinuser",$user->getFullName()); | |
| 101 | + | |
| 102 | +if ($user->getId() == 0) { | |
| 103 | + login_page($smarty); | |
| 104 | +} | |
| 105 | + | |
| 106 | +if ((isset($_SERVER['PHP_SELF'])) && (basename($_SERVER['PHP_SELF']) != 'index.php')) { | |
| 107 | + $smarty->assign("menu_current", $src . basename($_SERVER['PHP_SELF'])); | |
| 108 | +} else { | |
| 109 | + $smarty->assign("menu_current", $base); | |
| 110 | +} | |
| 111 | + | |
| 112 | +if($user->isAdmin()) { | |
| 113 | + $smarty->assign("admin", "yes"); | |
| 114 | +} else { | |
| 115 | + $smarty->assign("admin", "no"); | |
| 116 | +} | |
| 117 | + | |
| 118 | +/* | |
| 119 | + * | |
| 120 | + * name: debug | |
| 121 | + * @param variable type a count of parameters for dumping it to the | |
| 122 | + * error_log | |
| 123 | + * | |
| 124 | + * @return <empty> | |
| 125 | + * | |
| 126 | + */ | |
| 127 | +function debug() { | |
| 128 | + for($i = 0 ; $i < func_num_args(); $i++) { | |
| 129 | + $param = func_get_arg($i); | |
| 130 | + $dump = ''; | |
| 131 | + if ((is_array($param)) || (is_object($param))) { | |
| 132 | + ob_start(); | |
| 133 | + if (is_object($param)) { | |
| 134 | + $phpv = explode('.', phpversion()); | |
| 135 | + if (intval($phpv[0] . $phpv[1]) < 56) { | |
| 136 | + var_dump($param->__debugInfo()); | |
| 137 | + } else { | |
| 138 | + var_dump($param); | |
| 139 | + } | |
| 140 | + } else { | |
| 141 | + var_dump($param); | |
| 142 | + } | |
| 143 | + $dump .= ob_get_clean(); | |
| 144 | + } else { | |
| 145 | + $dump .= $param; | |
| 146 | + } | |
| 147 | + $bt = debug_backtrace(); | |
| 148 | + error_log($bt[0]['file'] . "(" . $bt[0]['line'] . "):\n" . $dump); | |
| 149 | + } | |
| 150 | +} | |
| 151 | + | |
| 152 | +/* | |
| 153 | + * | |
| 154 | + * name: makePart | |
| 155 | + * | |
| 156 | + * Creates paging feature | |
| 157 | + * | |
| 158 | + * @param | |
| 159 | + * $all -> lentgt of the listed elements | |
| 160 | + * $page -> actual page count | |
| 161 | + * | |
| 162 | + * @return range for this page | |
| 163 | + * | |
| 164 | + */ | |
| 165 | +function makePart($all, $page) { | |
| 166 | + global $smarty; | |
| 167 | + global $conf; | |
| 168 | + $from = 0; | |
| 169 | + $to = $all; | |
| 170 | + $pages = 0; | |
| 171 | + $max = 0; | |
| 172 | + if ($conf->isExists('range')) { | |
| 173 | + $max = $conf->Range; | |
| 174 | + } | |
| 175 | + if ($max > 0) { | |
| 176 | + $pages = (int)($all/$max); | |
| 177 | + $mod = $all % $max; | |
| 178 | + if ($mod > 0) { | |
| 179 | + $pages++; | |
| 180 | + } | |
| 181 | + if ($pages < $page) { | |
| 182 | + $page = $pages; | |
| 183 | + } | |
| 184 | + $from = ($page-1) * $max; | |
| 185 | + $to = $from; | |
| 186 | + if (($page == $pages) && ($mod > 0)) { | |
| 187 | + $to += $mod; | |
| 188 | + } else { | |
| 189 | + $to += $max; | |
| 190 | + } | |
| 191 | + $from = ($from < 0) ? 0 : $from; | |
| 192 | + } | |
| 193 | + $pagelist = array(); | |
| 194 | + for ($i=1;$i<=$pages;$i++) { | |
| 195 | + $pagelist[] = $i; | |
| 196 | + } | |
| 197 | + $pagelist = (sizeof($pagelist) > 1) ? $pagelist : NULL; | |
| 198 | + $smarty->assign("current_page", $page); | |
| 199 | + $smarty->assign("pages", $pagelist); | |
| 200 | + return array($from, $to); | |
| 201 | +} | |
| 202 | + | |
| 203 | +/* | |
| 204 | + * | |
| 205 | + * name: rndc_status | |
| 206 | + * @param no | |
| 207 | + * @return the status of rndc command | |
| 208 | + * | |
| 209 | + */ | |
| 210 | +function rndc_status() { | |
| 211 | + global $conf; | |
| 212 | + $cmd = $conf->Rndc . " status > /dev/null"; | |
| 213 | + system($cmd, $exit); | |
| 214 | + return $exit; | |
| 215 | +} | |
| 216 | + | |
| 217 | +/* | |
| 218 | + * | |
| 219 | + * name: logout | |
| 220 | + * @param no | |
| 221 | + * @return no | |
| 222 | + * | |
| 223 | + * Displays the logout page and destroy the http session | |
| 224 | + * | |
| 225 | + */ | |
| 226 | +function logout() { | |
| 227 | + global $smarty; | |
| 228 | + global $session; | |
| 229 | + $session->destroy(); | |
| 230 | + $smarty->assign("menu_button", array()); | |
| 231 | + $smarty->assign("pagetitle", "Logout"); | |
| 232 | + $smarty->assign("template", "logout.tpl"); | |
| 233 | + $smarty->assign("help", help("logout")); | |
| 234 | + $smarty->display("main.tpl"); | |
| 235 | +} | |
| 236 | + | |
| 237 | +/* | |
| 238 | + * | |
| 239 | + * name: login_page | |
| 240 | + * @param Smarty object | |
| 241 | + * @return no | |
| 242 | + * | |
| 243 | + * Checks the captcha requirements and provides the login page | |
| 244 | + * | |
| 245 | + */ | |
| 246 | +function login_page($smarty) { | |
| 247 | + global $cap_rsp; | |
| 248 | + global $base; | |
| 249 | + global $conf; | |
| 250 | + | |
| 251 | + if($conf->ReCaptcha == "yes") { | |
| 252 | + $nocap = false; | |
| 253 | + foreach ($conf->NoCaptcha as $ip) { | |
| 254 | + $nocap = ($nocap or ($ip == $_SERVER['REMOTE_ADDR'])); | |
| 255 | + } | |
| 256 | + if(!$nocap) { | |
| 257 | + $smarty->assign("captcha","yes"); | |
| 258 | + $smarty->assign("recaptcha",recaptcha_get_html($conf->Rc_Pubkey,$cap_rsp,true)); | |
| 259 | + } | |
| 260 | + } | |
| 261 | + $smarty->assign("action", $base); | |
| 262 | + $smarty->assign("pagetitle", "Login"); | |
| 263 | + $smarty->assign("template", "login.tpl"); | |
| 264 | + $smarty->assign("help", help("login")); | |
| 265 | + $smarty->display("main.tpl"); | |
| 266 | + die(); | |
| 267 | +} | |
| 268 | + | |
| 269 | +/* | |
| 270 | + * | |
| 271 | + * name: problem | |
| 272 | + * @param | |
| 273 | + * $reason -> short tag for the problem | |
| 274 | + * $title -> header title | |
| 275 | + * | |
| 276 | + * @return no | |
| 277 | + * | |
| 278 | + * Provides a kind of error page | |
| 279 | + * | |
| 280 | + */ | |
| 281 | +function problem($reason = NULL, $title = NULL) { | |
| 282 | + global $smarty; | |
| 283 | + $tit = (isset($title)) ? $title : title($reason); | |
| 284 | + $smarty->assign("pagetitle", $tit); | |
| 285 | + $smarty->assign("template", "accessdenied.tpl"); | |
| 286 | + $smarty->assign("reason", reason($reason)); | |
| 287 | + $smarty->assign("help", help("accessdenied")); | |
| 288 | + $smarty->assign("menu_button", menu_buttons()); | |
| 289 | + $smarty->display("main.tpl"); | |
| 290 | + die(); | |
| 291 | +} | |
| 292 | + | |
| 293 | +/* | |
| 294 | + * | |
| 295 | + * name: access_denied | |
| 296 | + * @param no | |
| 297 | + * @return no | |
| 298 | + * | |
| 299 | + * Generates the access denied problem | |
| 300 | + * | |
| 301 | + */ | |
| 302 | +function access_denied() { | |
| 303 | + problem("notadmin"); | |
| 304 | +} | |
| 305 | + | |
| 306 | +/* | |
| 307 | + * | |
| 308 | + * name: reason | |
| 309 | + * @param optional | |
| 310 | + * $reason -> short tag of the problem | |
| 311 | + * | |
| 312 | + * @return description string | |
| 313 | + * | |
| 314 | + * Generates description string for the known reason | |
| 315 | + * | |
| 316 | + */ | |
| 317 | +function reason($reason = '') { | |
| 318 | + switch ($reason) { | |
| 319 | + case "notown": | |
| 320 | + return "You don't own this zone."; | |
| 321 | + case "unauth": | |
| 322 | + return "You are not authorized for this procedure"; | |
| 323 | + case "notadmin": | |
| 324 | + return "You are not an administrator."; | |
| 325 | + case "noslave": | |
| 326 | + return "The slave zone hasn't replicated yet. Try again later."; | |
| 327 | + case "existzone": | |
| 328 | + return "The zone already exists in the database."; | |
| 329 | + case "existfile": | |
| 330 | + return "The zonefile already exists on the system."; | |
| 331 | + case "existuser": | |
| 332 | + return "The user already exists in the database."; | |
| 333 | + case "nozonename": | |
| 334 | + return "That's not much of a zone name."; | |
| 335 | + case "deleteadmin": | |
| 336 | + return "You may not delete the default admin user."; | |
| 337 | + case "deleteys": | |
| 338 | + return "You may not delete yourself."; | |
| 339 | + case "nocontent": | |
| 340 | + return "The given content empty or invalid."; | |
| 341 | + case "nocommit": | |
| 342 | + return "There is no commitable content."; | |
| 343 | + default: | |
| 344 | + return "Unknown error. Please it report to your administrator"; | |
| 345 | + } | |
| 346 | +} | |
| 347 | + | |
| 348 | +/* | |
| 349 | + * | |
| 350 | + * name: title | |
| 351 | + * @param optional | |
| 352 | + * $reason -> short tag of the problem | |
| 353 | + * | |
| 354 | + * @return title string | |
| 355 | + * | |
| 356 | + * Generates title string for the known reason | |
| 357 | + * | |
| 358 | + */ | |
| 359 | + function title($reason = '') { | |
| 360 | + switch ($reason) { | |
| 361 | + case "notown": | |
| 362 | + case "notadmin": | |
| 363 | + case "deleteadmin": | |
| 364 | + case "deleteys": | |
| 365 | + case "unauth": | |
| 366 | + return "Access denied"; | |
| 367 | + case "noslave": | |
| 368 | + case "nocontent": | |
| 369 | + return "No data"; | |
| 370 | + case "nocommit": | |
| 371 | + case "existzone": | |
| 372 | + case "existfile": | |
| 373 | + case "existuser": | |
| 374 | + case "nozonename": | |
| 375 | + return "Error in process"; | |
| 376 | + default: | |
| 377 | + return "Something wrong happened"; | |
| 378 | + } | |
| 379 | +} | |
| 380 | + | |
| 381 | +/* | |
| 382 | + * | |
| 383 | + * name: help | |
| 384 | + * @param | |
| 385 | + * $help tag for the info footer | |
| 386 | + * | |
| 387 | + * @return the info footer | |
| 388 | + * | |
| 389 | + * Generates the info footer | |
| 390 | + * | |
| 391 | + */ | |
| 392 | +function help($help) { | |
| 393 | + switch ($help) { | |
| 394 | + case "login": | |
| 395 | + return "Please log in."; | |
| 396 | + case "mainpage": | |
| 397 | + return "User status and Server status are displayed, along with any zone informations."; | |
| 398 | + case "zoneview": | |
| 399 | + return "Your zone is dumped. Here you can view the zone in bind syntax.<small><br />" . | |
| 400 | + "<span class=attention>You cannot edit the zonefile directly!</span></small>"; | |
| 401 | + case "zonepview": | |
| 402 | + return "Your zone will look like as above. You can view it in bind syntax.<small><br />" . | |
| 403 | + "<span class=attention>This zone hasn't commited yet!</span></small>"; | |
| 404 | + case "zoneread": | |
| 405 | + return "Your zones are displayed. Here you can create a zone, edit a zone, view a zone, or delete a zone."; | |
| 406 | + case "newzone": | |
| 407 | + return "Enter your new zone's domain name, name servers and smbind-ng owner. " . | |
| 408 | + "This will create a new zone with a SOA and NS record.<small><br />" . | |
| 409 | + "The Web/Mail/FTP fields will create these A, CNAME, and MX template records for you. " . | |
| 410 | + "Otherwise, leave them blank.<br />In these fields you can use IP addresses or hostnames too. In this case you need to take care of the trailing dots.</small>"; | |
| 411 | + case "newslavezone": | |
| 412 | + return "Enter your new slave zone's domain name, address of the master server and smbind-ng owner."; | |
| 413 | + case "recordread": | |
| 414 | + return "Here you can modify your zone's SOA record, or add, edit, or delete resource records."; | |
| 415 | + case "userlistread": | |
| 416 | + return "Here you can add, edit, or delete smbind-ng users."; | |
| 417 | + case "commit": | |
| 418 | + return "Your zone files are commited to disk, error checked, and reloaded."; | |
| 419 | + case "precommit": | |
| 420 | + return "Your modifications will be applied to the system, and the related services will notified about the changes."; | |
| 421 | + case "optionsread": | |
| 422 | + return "Here you can change options that define how smbind-ng works."; | |
| 423 | + case "deletezone": | |
| 424 | + return "Please confirm."; | |
| 425 | + case "uploadreview": | |
| 426 | + return "Please confirm your uploaded data. Some records may be missig basad on your handled record-type options"; | |
| 427 | + case "uploadproblem": | |
| 428 | + return "Please fix the errors. The file output of namedcheckzone has errors."; | |
| 429 | + case "upload": | |
| 430 | + return "Here you can import a zone what is in legal bind zonefile format. Choose import method!" . | |
| 431 | + " Available methods:<small><br /><strong>Orphan files:</strong>(maybe disabled) Some file in" . | |
| 432 | + " your config directory without database records. <strong>Browse:</strong> Zone file upload" . | |
| 433 | + " from your computer. <strong>Edit:</strong> Paste contents into the box from your clipboard.</small>"; | |
| 434 | + case "deleteuser": | |
| 435 | + return "Please confirm."; | |
| 436 | + case "newuser": | |
| 437 | + return "Here can you add a new user.<br />" . | |
| 438 | + "<span class=attention>Password requirements:</span> You must use letters (both upper- and lowercase), numbers and symols. Minimum length is 8 characters. " . | |
| 439 | + "10 charachers length, and using more uppercase letters and numbers is recommended."; | |
| 440 | + case "userread": | |
| 441 | + return "Here can you change the user's properties. If you don't want to change the password, leave it empty." . | |
| 442 | + "<br /><span class=attention>Password requirements:</span> You must use letters (both upper- and lowercase), numbers and symols. Minimum length is 8 characters. " . | |
| 443 | + "10 charachers length, and using more uppercase letters and numbers is recommended."; | |
| 444 | + case "chpass": | |
| 445 | + return "Here can you change your password. <small>You need to give your current password before the new!</small><br />" . | |
| 446 | + "<span class=attention>Password requirements:</span> You must use letters (both upper- and lowercase), numbers and symols. Minimum length is 8 characters. " . | |
| 447 | + "10 charachers length, and using more uppercase letters and numbers is recommended."; | |
| 448 | + case "savepass": | |
| 449 | + return "Login using your new password." . | |
| 450 | + "<small><br />This page automatically open it within 10 seconds</small>"; | |
| 451 | + case "accessdenied": | |
| 452 | + return "<span class=attention>Access denied.</span><br />This procedure not allowed with your privileges."; | |
| 453 | + case "problem": | |
| 454 | + return "A problem has occurred."; | |
| 455 | + case "logout": | |
| 456 | + return "You have been successfully logged out. Click <a class=attention id=reload href=\"../\">here</a> if you wish to log in again." . | |
| 457 | + "<small><br />This page automatically open it within <span id=counter>10</span> seconds</small>"; | |
| 458 | + default: | |
| 459 | + return ""; | |
| 460 | + } | |
| 461 | +} | |
| 462 | + | |
| 463 | +/* | |
| 464 | + * | |
| 465 | + * name: getorphan | |
| 466 | + * @param no | |
| 467 | + * @return an array with found filenames | |
| 468 | + * | |
| 469 | + * Find and check local files for importing | |
| 470 | + * | |
| 471 | + */ | |
| 472 | +function getorphan() { | |
| 473 | + global $conf; | |
| 474 | + global $user; | |
| 475 | + | |
| 476 | + $files = ' ' . implode(' ', scandir($conf->Path)) . ' '; | |
| 477 | + $mzones = $user->getMasters(); | |
| 478 | + $szones = $user->getSlaves(); | |
| 479 | + foreach ($mzones as $id) { | |
| 480 | + $z = new masterZone(intval($id)); | |
| 481 | + $z->loadZoneHead(); | |
| 482 | + $zone = $z->getZoneHeadRaw(); | |
| 483 | + $files = str_replace(' ' . $zone['name'] . ' ', ' ', $files); | |
| 484 | + } | |
| 485 | + foreach ($szones as $id) { | |
| 486 | + $z = new slaveZone(intval($id)); | |
| 487 | + $z->loadZoneHead(); | |
| 488 | + $zone = $z->getZoneHeadRaw(); | |
| 489 | + $files = str_replace(' ' . $zone['name'] . ' ', ' ', $files); | |
| 490 | + } | |
| 491 | + $vzf = array(); | |
| 492 | + foreach (explode(' ', trim($files)) as $entry) { | |
| 493 | + if ((is_file($conf->Path . $entry)) && (preg_replace('/\.(signed|private|key|krf|jnl|bind)$/', '', $entry) == $entry)) { | |
| 494 | + if (checkZoneFile($conf->Path . $entry, $entry)) { | |
| 495 | + $vzf[] = hostToIdn($entry); | |
| 496 | + } | |
| 497 | + } | |
| 498 | + } | |
| 499 | + | |
| 500 | + return $vzf; | |
| 501 | +} | |
| 502 | + | |
| 503 | +/* | |
| 504 | + * | |
| 505 | + * name: checkZoneFile | |
| 506 | + * @param | |
| 507 | + * $file -> path the file | |
| 508 | + * $zone -> zonename | |
| 509 | + * | |
| 510 | + * @return true/false (aftert chacking the zoneile) | |
| 511 | + * | |
| 512 | + */ | |
| 513 | +function checkZoneFile($file, $zone) { | |
| 514 | + global $conf; | |
| 515 | + | |
| 516 | + $cmd = $conf->namedCheckZone . " -i local " . $zone. " " . $file . " 2>/dev/stdout"; | |
| 517 | + unset($coutput); | |
| 518 | + exec($cmd, $coutput, $exit); | |
| 519 | + return ($coutput[sizeof($coutput)-1] == 'OK'); | |
| 520 | +} | |
| 521 | + | |
| 522 | +/* | |
| 523 | + * | |
| 524 | + * name: menu_buttons | |
| 525 | + * @param no | |
| 526 | + * @return no | |
| 527 | + * | |
| 528 | + * Generates the menu entries | |
| 529 | + * | |
| 530 | + */ | |
| 531 | +function menu_buttons() { | |
| 532 | + global $user; | |
| 533 | + global $smarty; | |
| 534 | + global $src; | |
| 535 | + global $base; | |
| 536 | + | |
| 537 | + $cmasters = $user->getCommitableZones('master'); | |
| 538 | + $cmc = (is_array($cmasters)) ? sizeof($cmasters) : 0; | |
| 539 | + $cslaves = intval($user->getCommitableZones('slave')); | |
| 540 | + $csc = (is_array($cslaves)) ? sizeof($cslaves) : 0; | |
| 541 | + $commitables = $cmc + $csc; | |
| 542 | + if($commitables == 0) { | |
| 543 | + $committext = ""; | |
| 544 | + $smarty->assign("donotcommit","yes"); | |
| 545 | + } | |
| 546 | + else { | |
| 547 | + $committext = "\" id=\"commitable\" class=\"attention"; | |
| 548 | + } | |
| 549 | + | |
| 550 | + if (sizeof($user->getUnvalidatedZones('master')) + | |
| 551 | + sizeof($user->getUnvalidatedZones('slave')) + | |
| 552 | + sizeof($user->getDeletedZones('slave')) + | |
| 553 | + sizeof($user->getDeletedZones('master')) > 0) { | |
| 554 | + $maintext = "\" class=\"attention"; | |
| 555 | + } | |
| 556 | + else { | |
| 557 | + $maintext = ""; | |
| 558 | + } | |
| 559 | + | |
| 560 | + return array( | |
| 561 | + array("title" => "Main", "link" => $base . $maintext), | |
| 562 | + array("title" => "Master zones", "link" => $src . "zonelist.php"), | |
| 563 | + array("title" => "Slave zones", "link" => $src . "slave_zonelist.php"), | |
| 564 | + array("title" => "Import zones", "link" => $src . "upload.php"), | |
| 565 | + array("title" => "Users", "link" => $src . "userlist.php"), | |
| 566 | + array("title" => "Change password", "link" => $src . "chpass.php"), | |
| 567 | + array("title" => "Commit changes", "link" => $src . "commit.php" . $committext), | |
| 568 | + array("title" => "Options", "link" => $src . "options.php"), | |
| 569 | + array("title" => "Log out", "link" => $src . "logout.php") | |
| 570 | + ); | |
| 571 | +} | |
| 572 | + | |
| 573 | +?> | ... | ... |
src/logout.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * logout.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************** | |
| 23 | + * | |
| 24 | + * Call the logout | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +require_once "include.php"; | |
| 29 | + | |
| 30 | +logout(); | |
| 31 | + | |
| 32 | +?> | ... | ... |
src/newuser.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * newuser.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************** | |
| 23 | + * | |
| 24 | + * Provides info for the user creation page. | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +require_once "include.php"; | |
| 29 | + | |
| 30 | +if($user->isAdmin()) { | |
| 31 | + $smarty->assign("pagetitle", "New user"); | |
| 32 | + $smarty->assign("admin_array", array("yes", "no")); | |
| 33 | + $smarty->assign("template", "newuser.tpl"); | |
| 34 | + $smarty->assign("help", help("newuser")); | |
| 35 | + $smarty->assign("menu_button", menu_buttons()); | |
| 36 | + $smarty->display("main.tpl"); | |
| 37 | +} | |
| 38 | +else { | |
| 39 | + access_denied(); | |
| 40 | +} | |
| 41 | + | |
| 42 | +?> | ... | ... |
src/newzone.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * newzone.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************** | |
| 23 | + * | |
| 24 | + * Gathering data for the new master zone form | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +require_once "include.php"; | |
| 29 | + | |
| 30 | +if($user->isAdmin()) { | |
| 31 | + $smarty->assign("pagetitle", "New master zone"); | |
| 32 | + $smarty->assign("userlist", $user->getAllusers()); | |
| 33 | + $smarty->assign("current_user", $user->getId()); | |
| 34 | + $smarty->assign("pri_dns", $conf->pri_dns); | |
| 35 | + $smarty->assign("sec_dns", $conf->sec_dns); | |
| 36 | + $smarty->assign("template", "newzone.tpl"); | |
| 37 | + $smarty->assign("help", help("newzone")); | |
| 38 | + $smarty->assign("menu_button", menu_buttons()); | |
| 39 | + $smarty->display("main.tpl"); | |
| 40 | +} | |
| 41 | +else { | |
| 42 | + access_denied(); | |
| 43 | +} | |
| 44 | +?> | ... | ... |
src/options.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * options.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************** | |
| 23 | + * | |
| 24 | + * Options entry page | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +if($_SERVER['REQUEST_METHOD'] == 'POST') { | |
| 29 | + include("optionswrite.php"); | |
| 30 | +} | |
| 31 | +include("optionsread.php"); | |
| 32 | + | |
| 33 | +?> | ... | ... |
src/optionsread.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * optionsread.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************** | |
| 23 | + * | |
| 24 | + * Reads and provides informations for the options page | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +require_once "include.php"; | |
| 29 | + | |
| 30 | +if($user->isAdmin()) { | |
| 31 | + $res = $db->query("SELECT prefkey, prefval FROM options " . | |
| 32 | + "WHERE preftype = 'record' ORDER by prefkey" | |
| 33 | + ); | |
| 34 | + if (MDB2::isError($res)) { | |
| 35 | + $smarty->assign("popuperror", $res->getMessage() . "<br />" . $res->getDebugInfo()); | |
| 36 | + problem(); | |
| 37 | + } | |
| 38 | + $recordarray = array(); | |
| 39 | + $rows = $res->numRows(); | |
| 40 | + for($x=0, $y=0, $i=0; $i<$rows; $y++, $i++) { | |
| 41 | + if($y == 4) { | |
| 42 | + $x++; | |
| 43 | + $y = 0; | |
| 44 | + } | |
| 45 | + $recordarray[$x][$y] = $res->fetchRow(); | |
| 46 | + } | |
| 47 | + $options = array(); | |
| 48 | + $res = $db->query("SELECT prefkey, prefval FROM options " . | |
| 49 | + "WHERE preftype = 'normal' ORDER by prefkey" | |
| 50 | + ); | |
| 51 | + if (MDB2::isError($res)) { | |
| 52 | + $smarty->assign("popuperror", $res->getMessage() . "<br />" . $res->getDebugInfo()); | |
| 53 | + problem(); | |
| 54 | + } | |
| 55 | + while ($rec = $res->fetchRow()) { | |
| 56 | + switch ($rec['prefkey']) { | |
| 57 | + case 'hostmaster': | |
| 58 | + $key = 0; | |
| 59 | + break; | |
| 60 | + case 'prins': | |
| 61 | + $key = 1; | |
| 62 | + $rec['prefval'] = idnToHost($rec['prefval']); | |
| 63 | + break; | |
| 64 | + case 'secns': | |
| 65 | + $key = 2; | |
| 66 | + $rec['prefval'] = idnToHost($rec['prefval']); | |
| 67 | + break; | |
| 68 | + case 'master': | |
| 69 | + $key = 3; | |
| 70 | + $rec['prefval'] = idnToHost($rec['prefval']); | |
| 71 | + break; | |
| 72 | + default: | |
| 73 | + $key = 4; | |
| 74 | + } | |
| 75 | + $options[$key] = $rec; | |
| 76 | + } | |
| 77 | + $smarty->assign("records", $recordarray); | |
| 78 | + $smarty->assign("options", $options); | |
| 79 | + $smarty->assign("pagetitle", "Options"); | |
| 80 | + $smarty->assign("template", "optionsread.tpl"); | |
| 81 | + $smarty->assign("help", help("optionsread")); | |
| 82 | + $smarty->assign("menu_button", menu_buttons()); | |
| 83 | + $smarty->display("main.tpl"); | |
| 84 | +} else { | |
| 85 | + access_denied(); | |
| 86 | +} | |
| 87 | + | |
| 88 | +?> | ... | ... |
src/optionswrite.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * optionswrite.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + ********************************************************************** | |
| 23 | + * | |
| 24 | + * Process the options form and save the changes | |
| 25 | + * | |
| 26 | + */ | |
| 27 | + | |
| 28 | +require_once "include.php"; | |
| 29 | + | |
| 30 | +if($user->isAdmin()) { | |
| 31 | + $allrec = array(); | |
| 32 | + foreach($_POST as $key => $value) { | |
| 33 | + $val = $value; | |
| 34 | + switch ($key) { | |
| 35 | + case 'master': | |
| 36 | + case 'prins': | |
| 37 | + case 'secns': | |
| 38 | + $val = hostToIdn(preg_replace('/([\s\r\n]+|\.$)/', '', $value)); | |
| 39 | + break; | |
| 40 | + case 'range': | |
| 41 | + $val = (intval($value) > 0) ? intval($value) : 10; | |
| 42 | + break; | |
| 43 | + case 'hostmaster': | |
| 44 | + $val = preg_replace('/([\s\r\n]+|\.$)/', '', $value); | |
| 45 | + break; | |
| 46 | + default: | |
| 47 | + $val = ((strtolower($value) == 'on') || (strtolower($value) == 'off')) ? strtolower($value) : 'off'; | |
| 48 | + } | |
| 49 | + $allrec[$key] = $val; | |
| 50 | + } | |
| 51 | + foreach($allrec as $key => $value) { | |
| 52 | + $res = $db->query("UPDATE options SET prefval = '" . $value . "' " . | |
| 53 | + "WHERE prefkey = '" . $key . "'" | |
| 54 | + ); | |
| 55 | + } | |
| 56 | +} | |
| 57 | +else { | |
| 58 | + access_denied(); | |
| 59 | +} | |
| 60 | + | |
| 61 | +?> | ... | ... |
src/record.php
0 → 100644
src/recordread.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$znum = (intval($_GET['i']) > 0) ? intval($_GET['i']) : NULL; | |
| 5 | + | |
| 6 | +if ($znum) { | |
| 7 | + if ($user->isOwned($znum, 'master', 'live')) { | |
| 8 | + $zone = new masterZone(array('id' => $znum)); | |
| 9 | + $zone->loadZone(); | |
| 10 | + $zonerec = $zone->getZoneHead(); | |
| 11 | + $currpage = ((isset($_GET['page'])) && (intval($_GET['page']) > 0)) ? $currpage = intval($_GET['page']) : 1; | |
| 12 | + $allrec = $zone->getRecords(true); | |
| 13 | + $count = sizeof($allrec); | |
| 14 | + $fromto = makePart($count, $currpage); | |
| 15 | + $rec = array(); | |
| 16 | + | |
| 17 | + for ($i=$fromto[0];$i<$fromto[1];$i++) { | |
| 18 | + $allrec[$i]['ttl'] = ($allrec[$i]['ttl'] > 0) ? $allrec[$i]['ttl'] : ''; | |
| 19 | + $rec[] = $allrec[$i]; | |
| 20 | + } | |
| 21 | + | |
| 22 | + $users = $user->getAllusers(); | |
| 23 | + $types = $conf->parameters; | |
| 24 | + $err = ''; | |
| 25 | + $err .= ((!is_array($zonerec)) || (!is_array($rec))) ? $zone->getErr() : ''; | |
| 26 | + $err .= (!is_array($users)) ? $user->getErr() : ''; | |
| 27 | + $err .= (!is_array($types)) ? "Record types not foud\n" : ''; | |
| 28 | + if ($err > '') { | |
| 29 | + $smarty->assign("popuperror",implode("<br />", explode("\n", $err))); | |
| 30 | + } | |
| 31 | + $smarty->assign("zone", $zonerec); | |
| 32 | + $smarty->assign("pagetitle", "Editing master zone"); | |
| 33 | + $smarty->assign("rcount", sizeof($rec)); | |
| 34 | + $smarty->assign("record",$rec); | |
| 35 | + $smarty->assign("types", $types); | |
| 36 | + $smarty->assign("userlist", $users); | |
| 37 | + $smarty->assign("template", "recordread.tpl"); | |
| 38 | + $smarty->assign("help", help("recordread")); | |
| 39 | + $smarty->assign("menu_button", menu_buttons()); | |
| 40 | + $smarty->assign("page_root", $src . "record.php?i=" . $_GET['i'] . "&"); | |
| 41 | + $smarty->display("main.tpl"); | |
| 42 | + } else { | |
| 43 | + problem("notown"); | |
| 44 | + } | |
| 45 | +} else { | |
| 46 | + access_denied(); | |
| 47 | +} | |
| 48 | + | |
| 49 | +?> | ... | ... |
src/recordwrite.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$znum = (intval($_GET['i']) > 0) ? intval($_GET['i']) : NULL; | |
| 5 | + | |
| 6 | +if ($znum) { | |
| 7 | + if ($user->isOwned($znum, 'master', 'live')) { | |
| 8 | + $zone = new masterZone(array('id' => $znum)); | |
| 9 | + $zone->loadZone(); | |
| 10 | + $zonerec = $zone->getZoneHead(); | |
| 11 | + $zrec = array(); | |
| 12 | + foreach (array('refresh', 'expire', 'retry', 'ttl', 'secured', 'pri_dns', 'sec_dns', 'owner') as $key) { | |
| 13 | + $zrec[$key] = ((isset($_POST[$key])) and ($_POST[$key] > '')) ? $_POST[$key] : $zonerec[$key]; | |
| 14 | + } | |
| 15 | + $zrec['valid'] = 'may'; | |
| 16 | + $zone->setZoneHead($zrec); | |
| 17 | + $zone->saveZoneHead(); | |
| 18 | + $total = ((isset($_POST['total'])) && ($_POST['total'] > 0)) ? $_POST['total'] : 0; | |
| 19 | + for ($x = 0; $x < $total; $x++) { | |
| 20 | + if (isset($_POST['delete'][$x])) { | |
| 21 | + $zone->eraseRecord(intval($_POST['host_id'][$x])); | |
| 22 | + } else { | |
| 23 | + $nrec=array(); | |
| 24 | + foreach (array('host', 'ttl', 'type', 'pri', 'destination') as $key) { | |
| 25 | + $pkey = ($key == 'ttl') ? 'rttl' : $key; | |
| 26 | + $nrec[$key] = (isset($_POST[$pkey][$x])) ? $_POST[$pkey][$x] : ''; | |
| 27 | + $nrec[$key] = (($key == 'ttl') && ($nrec[$key] == '')) ? 0 :$nrec[$key]; | |
| 28 | + $nrec[$key] = (($key == 'pri') && ($nrec[$key] == '')) ? 10 :$nrec[$key]; | |
| 29 | + $nrec[$key] = (($key == 'host') && ($nrec[$key] == '')) ? '@' :$nrec[$key]; | |
| 30 | + $nrec[$key] = (($key == 'destination') && ($nrec[$key] == '')) ? '@' :$nrec[$key]; | |
| 31 | + } | |
| 32 | + if ($nrec['host'] != $nrec['destination']) { | |
| 33 | + $urec = new masterRecord(intval($_POST['host_id'][$x])); | |
| 34 | + $urec->loadRecord(); | |
| 35 | + $urec->setRecord($nrec); | |
| 36 | + $xrec = $urec->getRecordRaw(); | |
| 37 | + $urec->saveRecord(); | |
| 38 | + } | |
| 39 | + } | |
| 40 | + } | |
| 41 | + $zone->clearZone(); | |
| 42 | + $zone->loadZone(); | |
| 43 | + $nrec = array(); | |
| 44 | + foreach (array('host', 'ttl', 'type', 'pri', 'destination') as $key) { | |
| 45 | + $nrec[$key] = ((isset($_POST['new' . $key])) && ($_POST['new' . $key] > '')) ? $_POST['new' . $key] : NULL; | |
| 46 | + } | |
| 47 | + if ($nrec['host'] != $nrec['destination']) { | |
| 48 | + $nrec['pri'] = ($nrec['type'] == 'MX') ? 10 : 0; | |
| 49 | + $nrec['ttl'] = intval($nrec['ttl']); | |
| 50 | + $nrec['zone'] = $znum; | |
| 51 | + $zone->addRecord($nrec); | |
| 52 | + } | |
| 53 | + $zone->saveZone(); | |
| 54 | + } else { | |
| 55 | + problem("notown"); | |
| 56 | + } | |
| 57 | +} else { | |
| 58 | + access_denied(); | |
| 59 | +} | |
| 60 | + | |
| 61 | +?> | ... | ... |
src/savepass.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +if ($user->getPasswordHash() == $_POST['password_old']) { | |
| 5 | + if ((strlen($_POST['password_one']) == 32) && ($session->isEnoughOld())) { | |
| 6 | + $user->set(NULL, $_POST['password_one']); | |
| 7 | + $_SESSION['p'] = $user->getPasswordHash(); | |
| 8 | + $smarty->assign("pagetitle", "Change password"); | |
| 9 | + $smarty->assign("template", "savepass.tpl"); | |
| 10 | + $smarty->assign("help", help("savepass")); | |
| 11 | + $smarty->assign("menu_button", menu_buttons()); | |
| 12 | + $smarty->display("main.tpl"); | |
| 13 | + } else { | |
| 14 | + problem(); | |
| 15 | + } | |
| 16 | +} else { | |
| 17 | + problem("unauth"); | |
| 18 | +} | |
| 19 | + | |
| 20 | +?> | ... | ... |
src/slave_deletezone.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$zoneid = intval($_GET['i']); | |
| 5 | + | |
| 6 | +if ($zoneid > 0) { | |
| 7 | + if ($user->isOwned($zoneid, 'slave')) { | |
| 8 | + $smarty->assign("pagetitle", "Delete slave zone"); | |
| 9 | + $zone = new slaveZone($zoneid); | |
| 10 | + $zone->loadZoneHead(); | |
| 11 | + $res = $zone->getZoneHead(); | |
| 12 | + $smarty->assign("zone", $res['name']); | |
| 13 | + $smarty->assign("zoneid", $zoneid); | |
| 14 | + $smarty->assign("template", "slave_deletezone.tpl"); | |
| 15 | + $smarty->assign("help", help("deletezone")); | |
| 16 | + $smarty->assign("menu_button", menu_buttons()); | |
| 17 | + $smarty->display("main.tpl"); | |
| 18 | + } else { | |
| 19 | + problem('notown'); | |
| 20 | + } | |
| 21 | +} else { | |
| 22 | + problem(); | |
| 23 | +} | |
| 24 | + | |
| 25 | +?> | ... | ... |
src/slave_newzone.php
0 → 100644
| 1 | +<?php | |
| 2 | +/* | |
| 3 | + * slave_newzone.php | |
| 4 | + * | |
| 5 | + * Copyright 2015 Péter Szládovics <peti@szladovics.hu> | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License as published by | |
| 9 | + * the Free Software Foundation; either version 2 of the License, or | |
| 10 | + * (at your option) any later version. | |
| 11 | + * | |
| 12 | + * This program is distributed in the hope that it will be useful, | |
| 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | + * GNU General Public License for more details. | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License | |
| 18 | + * along with this program; if not, write to the Free Software | |
| 19 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
| 20 | + * MA 02110-1301, USA. | |
| 21 | + * | |
| 22 | + * Gathers data from config and the db to present informations to the | |
| 23 | + * template. | |
| 24 | + * | |
| 25 | + */ | |
| 26 | + | |
| 27 | +require_once "include.php"; | |
| 28 | + | |
| 29 | +if($user->isAdmin()) { | |
| 30 | + $smarty->assign("pagetitle", "New slave zone"); | |
| 31 | + $smarty->assign("userlist", $user->getAllusers()); | |
| 32 | + $smarty->assign("current_user", $user->getId()); | |
| 33 | + $smarty->assign("master", $conf->master); | |
| 34 | + $smarty->assign("template", "slave_newzone.tpl"); | |
| 35 | + $smarty->assign("help", help("newslavezone")); | |
| 36 | + $smarty->assign("menu_button", menu_buttons()); | |
| 37 | + $smarty->display("main.tpl"); | |
| 38 | +} | |
| 39 | +else { | |
| 40 | + access_denied(); | |
| 41 | +} | |
| 42 | + | |
| 43 | +?> | ... | ... |
src/slave_record.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$i = intval($_GET['i']); | |
| 5 | + | |
| 6 | +if ($i > 0) { | |
| 7 | + if ($user->isOwned($i, 'slave', 'live')) { | |
| 8 | + $sz = new slaveZone($i); | |
| 9 | + $sz->loadZoneHead(); | |
| 10 | + $zone = $sz->getZoneHead(); | |
| 11 | + $smarty->assign("zone", $zone); | |
| 12 | + $smarty->assign("pagetitle", "Editing slave zone"); | |
| 13 | + $smarty->assign("userlist", $user->getAllusers()); | |
| 14 | + $smarty->assign("template", "slave_recordread.tpl"); | |
| 15 | + $smarty->assign("help", help("recordread")); | |
| 16 | + $smarty->assign("menu_button", menu_buttons()); | |
| 17 | + $smarty->assign("page_root", $src . "slave_record.php?i=" . $_GET['i'] . "&"); | |
| 18 | + $smarty->display("main.tpl"); | |
| 19 | + } else { | |
| 20 | + problem('notown'); | |
| 21 | + } | |
| 22 | +} else { | |
| 23 | + problem(); | |
| 24 | +} | |
| 25 | + | |
| 26 | +?> | ... | ... |
src/slave_zoneadd.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +if($user->isAdmin()) { | |
| 5 | + $arr = array(); | |
| 6 | + foreach (array('name', 'master', 'owner') as $key) { | |
| 7 | + $arr[$key] = $_POST[$key]; | |
| 8 | + } | |
| 9 | + $nz = new slaveZone($arr); | |
| 10 | + if (!$nz->loadZoneHead()) { | |
| 11 | + $nz->setZoneHead($arr); | |
| 12 | + $nz->saveZoneHead(); | |
| 13 | + $user->loadUserZones(); | |
| 14 | + } else { | |
| 15 | + problem("existzone"); | |
| 16 | + } | |
| 17 | +} else { | |
| 18 | + access_denied(); | |
| 19 | +} | |
| 20 | + | |
| 21 | +?> | ... | ... |
src/slave_zonedelete.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$zoneid = intval($_GET['i']); | |
| 5 | + | |
| 6 | +if($user->isOwned($zoneid, 'slave')) { | |
| 7 | + if($zoneid > 0) { | |
| 8 | + $zone = new slaveZone($zoneid); | |
| 9 | + $zone->loadZoneHead(); | |
| 10 | + $zone->setZoneHead(array('updated' => 'del')); | |
| 11 | + $zone->saveZoneHead(); | |
| 12 | + } | |
| 13 | + else { | |
| 14 | + problem(); | |
| 15 | + } | |
| 16 | +} | |
| 17 | +else { | |
| 18 | + problem("notown"); | |
| 19 | +} | |
| 20 | + | |
| 21 | +?> | ... | ... |
src/slave_zonelist.php
0 → 100644
| 1 | +<?php | |
| 2 | +if($_SERVER['REQUEST_METHOD'] == 'POST') { | |
| 3 | + if($_POST['Submit'] == 'Add zone') { | |
| 4 | + include("slave_zoneadd.php"); | |
| 5 | + } | |
| 6 | + if($_POST['Submit'] == 'Save') { | |
| 7 | + include("slave_zonewrite.php"); | |
| 8 | + } | |
| 9 | +} | |
| 10 | +if(isset($_GET['delete']) && $_GET['delete'] == 'y') { | |
| 11 | + include("slave_zonedelete.php"); | |
| 12 | +} | |
| 13 | + | |
| 14 | +include("slave_zoneread.php"); | |
| 15 | + | |
| 16 | +?> | ... | ... |
src/slave_zoneread.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$zones = $user->getSlaves('live'); | |
| 5 | +$count = sizeof($zones); | |
| 6 | +$maxitems = intval($conf->range); | |
| 7 | +$currpage = ((isset($_GET['page'])) && (intval($_GET['page']) > 0)) ? $currpage = intval($_GET['page']) : 1; | |
| 8 | +$fromto = makePart($count, $currpage); | |
| 9 | +$buffer = array(); | |
| 10 | + | |
| 11 | +$i = (isset($_GET['i'])) ? intval($_GET['i']) : NULL; | |
| 12 | + | |
| 13 | +if ((isset($i)) && (isset($_GET['check'])) && ($_GET['check'] = 'y') ) { | |
| 14 | + if ($i > 0) { | |
| 15 | + if ($user->isOwned($i, 'slave', 'live')) { | |
| 16 | + $sz = new slaveZone($i); | |
| 17 | + if ($sz->validateZone($conf->dig)) { | |
| 18 | + $arr = $sz->getZoneHead($i); | |
| 19 | + $arr['updated'] = 'yes'; | |
| 20 | + $arr['valid'] = 'yes'; | |
| 21 | + $sz->setZoneHead($arr); | |
| 22 | + $sz->saveZoneHead(); | |
| 23 | + } else { | |
| 24 | + $smarty->assign("popuperror", $sz->getErr()); | |
| 25 | + } | |
| 26 | + } else { | |
| 27 | + problem('notown'); | |
| 28 | + } | |
| 29 | + } else { | |
| 30 | + problem(); | |
| 31 | + } | |
| 32 | +} | |
| 33 | + | |
| 34 | +for ($i=$fromto[0];$i<$fromto[1];$i++) { | |
| 35 | + $zone = new slaveZone(array('id' => $zones[$i])); | |
| 36 | + $zone->loadZoneHead(); | |
| 37 | + $buffer[] = $zone->getZoneHead(); | |
| 38 | + unset($zone); | |
| 39 | +} | |
| 40 | + | |
| 41 | +$smarty->assign("zonelist", $buffer); | |
| 42 | +$smarty->assign("pagetitle", "Slave zones"); | |
| 43 | +$smarty->assign("template", "slave_zoneread.tpl"); | |
| 44 | +$smarty->assign("help", help("zoneread")); | |
| 45 | +$smarty->assign("menu_button", menu_buttons()); | |
| 46 | +$smarty->assign("page_root", $src . "zonelist.php?"); | |
| 47 | +$smarty->display("main.tpl"); | |
| 48 | + | |
| 49 | +?> | ... | ... |
src/slave_zoneview.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$param = intval($_GET['i']); | |
| 5 | + | |
| 6 | +if ($param > 0) { | |
| 7 | + if ($user->isOwned($param, 'slave')) { | |
| 8 | + $smarty->assign("pagetitle", "Dump slave zone"); | |
| 9 | + $zone = new slaveZone(array('id' => $_GET['i'])); | |
| 10 | + $zone->loadZoneHead(); | |
| 11 | + $zonedef = ''; | |
| 12 | + $head = $zone->getZoneHead(); | |
| 13 | + $headraw = $zone->getZoneHeadRaw(); | |
| 14 | + $name = $head['name']; | |
| 15 | + $zonetype = "slave zone "; | |
| 16 | + $ownerid = $head['owner']; | |
| 17 | + $ouser = new User(array('id' => $ownerid)); | |
| 18 | + $owner = $ouser->getFullName(); | |
| 19 | + if ((isset($_GET['pre'])) && ($_GET['pre'] == 'y')) { | |
| 20 | + $zonedef = $zone->dumpZone($conf->dig); | |
| 21 | + $zonetype .= "(AXFR dump from it's master)"; | |
| 22 | + } else { | |
| 23 | + $zonetype .= "(locally mirrored)"; | |
| 24 | + $lines = file($conf->path . $headraw['name']); | |
| 25 | + $zonedef = ''; | |
| 26 | + foreach ($lines as $line) { | |
| 27 | + $zonedef .= $line; | |
| 28 | + } | |
| 29 | + } | |
| 30 | + $smarty->assign("zonename", $name); | |
| 31 | + $smarty->assign("zonetype", $zonetype); | |
| 32 | + $smarty->assign("owner", $owner); | |
| 33 | + $smarty->assign("zonedef", $zonedef); | |
| 34 | + $smarty->assign("template", "zoneview.tpl"); | |
| 35 | + $smarty->assign("help", help("zoneview")); | |
| 36 | + $smarty->assign("menu_button", menu_buttons()); | |
| 37 | + $smarty->display("main.tpl"); | |
| 38 | + } else { | |
| 39 | + problem('notown'); | |
| 40 | + } | |
| 41 | +} else { | |
| 42 | + problem(); | |
| 43 | +} | |
| 44 | + | |
| 45 | +?> | ... | ... |
src/slave_zonewrite.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$i = intval($_GET['i']); | |
| 5 | +$name = (isset($_POST['name']) && (trim($_POST['name']) > '')) ? trim($_POST['name']) : ''; | |
| 6 | +$owner = intval($_POST['owner']); | |
| 7 | +$master = (isset($_POST['master']) && (trim($_POST['master']) > '')) ? trim($_POST['master']) : ''; | |
| 8 | + | |
| 9 | +if ((($i * $owner) > 0) && ($name > '') && ($master > '')) { | |
| 10 | + if ($user->isOwned($i, 'master', 'live')) { | |
| 11 | + $sz = new slaveZone(array( | |
| 12 | + 'id' => $i, | |
| 13 | + 'name' => $name, | |
| 14 | + 'master' => $master, | |
| 15 | + 'owner' => $owner, | |
| 16 | + 'updated' => 'yes', | |
| 17 | + 'valid' => 'may', | |
| 18 | + )); | |
| 19 | + $sz->saveZoneHead(); | |
| 20 | + } else { | |
| 21 | + problem('notown'); | |
| 22 | + } | |
| 23 | +} else { | |
| 24 | + problem(); | |
| 25 | +} | |
| 26 | +?> | ... | ... |
src/upload.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +if($user->isAdmin()) { | |
| 5 | + $files = getorphan(); | |
| 6 | + $smarty->assign("pagetitle", "Import master zones"); | |
| 7 | + $smarty->assign("count",sizeof($files)); | |
| 8 | + $smarty->assign("files",$files); | |
| 9 | + $smarty->assign("template", "upload.tpl"); | |
| 10 | + $smarty->assign("help", help("upload")); | |
| 11 | + $smarty->assign("menu_button", menu_buttons()); | |
| 12 | + $smarty->display("main.tpl"); | |
| 13 | +} | |
| 14 | +else { | |
| 15 | + access_denied(); | |
| 16 | +} | |
| 17 | +?> | ... | ... |
src/user.php
0 → 100644
src/useradd.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +if ($user->isAdmin()) { | |
| 5 | + if ((strlen($_POST['password_']) == 32) && | |
| 6 | + (isset($_POST['username_'])) && | |
| 7 | + (strlen($_POST['username_']) > 2)) { | |
| 8 | + $real = ((isset($_POST['realname'])) && ($_POST['realname'] >= '')) ? $_POST['realname'] : $_POST['username_']; | |
| 9 | + $urec = array( | |
| 10 | + 'id' => 0, | |
| 11 | + 'username' => $_POST['username_'], | |
| 12 | + 'realname' => $real, | |
| 13 | + 'admin' => $_POST['admin'], | |
| 14 | + 'password' => $_POST['password_'], | |
| 15 | + ); | |
| 16 | + $nuser = new User($urec); | |
| 17 | + if ($nuser->getId() == 0) { | |
| 18 | + problem(); | |
| 19 | + } | |
| 20 | + } else { | |
| 21 | + problem(); | |
| 22 | + } | |
| 23 | +} else { | |
| 24 | + access_denied(); | |
| 25 | +} | |
| 26 | + | |
| 27 | +?> | ... | ... |
src/userdelete.php
0 → 100644
src/userlist.php
0 → 100644
src/userlistread.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +if($user->isAdmin()) { | |
| 5 | + $smarty->assign("pagetitle", "Users"); | |
| 6 | + $usermap = $user->getAllusers(); | |
| 7 | + $currpage = ((isset($_GET['page'])) && (intval($_GET['page']) > 0)) ? $currpage = intval($_GET['page']) : 1; | |
| 8 | + $count = sizeof($usermap); | |
| 9 | + $fromto = makePart($count, $currpage); | |
| 10 | + $listed = array(); | |
| 11 | + for ($i=$fromto[0];$i<$fromto[1];$i++) { | |
| 12 | + $listed[] = $usermap[$i]; | |
| 13 | + } | |
| 14 | + $smarty->assign("userlist", $listed); | |
| 15 | + $smarty->assign("template", "userlistread.tpl"); | |
| 16 | + $smarty->assign("help", help("userlistread")); | |
| 17 | + $smarty->assign("menu_button", menu_buttons()); | |
| 18 | + $smarty->assign("page_root", $src . "userlist.php?"); | |
| 19 | + $smarty->display("main.tpl"); | |
| 20 | +} | |
| 21 | +else { | |
| 22 | + access_denied(); | |
| 23 | +} | |
| 24 | + | |
| 25 | +?> | ... | ... |
src/userread.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +if($user->isAdmin()) { | |
| 5 | + $i = (isset($_GET['i'])) ? intval($_GET['i']) : 0; | |
| 6 | + if ($i > 1) { | |
| 7 | + $smarty->assign("pagetitle", "Viewing user"); | |
| 8 | + $smarty->assign("admin_array", array("yes", "no")); | |
| 9 | + $xuser = new User($i); | |
| 10 | + $data = $xuser->getUser(); | |
| 11 | + $smarty->assign("user", $data); | |
| 12 | + $xuser->loadUserZones(); | |
| 13 | + $masters = $xuser->getMasters('live'); | |
| 14 | + $masterlist = array(); | |
| 15 | + foreach ($masters as $id) { | |
| 16 | + $temp = new masterZone(intval($id)); | |
| 17 | + $temp->loadZoneHead(); | |
| 18 | + $head = $temp->getZoneHead(); | |
| 19 | + $temp = array(); | |
| 20 | + foreach (array('id', 'name', 'serial') as $key) { | |
| 21 | + $temp[$key] = $head[$key]; | |
| 22 | + } | |
| 23 | + $masterlist[] = $temp; | |
| 24 | + } | |
| 25 | + $slaves = $xuser->getSlaves('live'); | |
| 26 | + $slavelist = array(); | |
| 27 | + foreach ($slaves as $id) { | |
| 28 | + $temp = new slaveZone(intval($id)); | |
| 29 | + $temp->loadZoneHead(); | |
| 30 | + $head = $temp->getZoneHead(); | |
| 31 | + $temp = array(); | |
| 32 | + foreach (array('id', 'name', 'master') as $key) { | |
| 33 | + $temp[$key] = $head[$key]; | |
| 34 | + } | |
| 35 | + $slavelist[] = $temp; | |
| 36 | + $temp = array(); | |
| 37 | + } | |
| 38 | + $smarty->assign("zonelist", $masterlist); | |
| 39 | + $smarty->assign("szonelist", $slavelist); | |
| 40 | + $smarty->assign("template", "userread.tpl"); | |
| 41 | + $smarty->assign("help", help("userread")); | |
| 42 | + $smarty->assign("menu_button", menu_buttons()); | |
| 43 | + $smarty->display("main.tpl"); | |
| 44 | + } else { | |
| 45 | + problem(); | |
| 46 | + } | |
| 47 | +} else { | |
| 48 | + access_denied(); | |
| 49 | +} | |
| 50 | + | |
| 51 | +?> | ... | ... |
src/userwrite.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +if($user->isAdmin()) { | |
| 5 | + $adm = (isset($_POST['admin'])) ? $_POST['admin'] : ''; | |
| 6 | + $pass = (isset($_POST['password'])) ? $_POST['password'] : ''; | |
| 7 | + $rnam = (isset($_POST['realname'])) ? $_POST['realname'] : ''; | |
| 8 | + $i = (isset($_GET['i'])) ? intval($_GET['i']) : 0; | |
| 9 | + if (($i > 1) && ($session->isEnoughOld())) { | |
| 10 | + $smarty->assign("pagetitle", "Viewing user"); | |
| 11 | + $newu = new User($i); | |
| 12 | + $newu->set($rnam, $pass, $adm); | |
| 13 | + if ($i == $user->getId() && ( | |
| 14 | + ($newu->isAdmin() xor $user->isAdmin()) || | |
| 15 | + ($newu->getPasswordHash() <> $user->getPasswordHash()) | |
| 16 | + )) { | |
| 17 | + logout(); | |
| 18 | + die(); | |
| 19 | + } | |
| 20 | + $smarty->assign("success","The user properties has been modified"); | |
| 21 | + } else { | |
| 22 | + problem(); | |
| 23 | + } | |
| 24 | +} else { | |
| 25 | + access_denied(); | |
| 26 | +} | |
| 27 | + | |
| 28 | +?> | ... | ... |
src/zoneadd.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +if($user->isAdmin()) { | |
| 5 | + $arr = array( | |
| 6 | + 'name' => $_POST['name'], | |
| 7 | + 'pri_dns' => $_POST['pri_dns'], | |
| 8 | + 'sec_dns' => $_POST['sec_dns'], | |
| 9 | + 'refresh' => $_POST['refresh'], | |
| 10 | + 'retry' => $_POST['retry'], | |
| 11 | + 'expire' => $_POST['expire'], | |
| 12 | + 'ttl' => $_POST['ttl'], | |
| 13 | + 'owner' => $_POST['owner'], | |
| 14 | + ); | |
| 15 | + $nz = new masterZone($arr); | |
| 16 | + if (!$nz->loadZoneHead()) { | |
| 17 | + $nz->setZoneHead($arr); | |
| 18 | + $nz->saveZoneHead(); | |
| 19 | + $www = ((isset($_POST['www'])) && ($_POST['www'] >'')) ? $_POST['www'] : NULL; | |
| 20 | + if ($www){ | |
| 21 | + $type = (filter_var($www, FILTER_VALIDATE_IP)) ? 'A' : 'CNAME'; | |
| 22 | + if ($type == 'A') { | |
| 23 | + $nz->addRecord(array( | |
| 24 | + 'host' => '@', | |
| 25 | + 'type' => 'A', | |
| 26 | + 'destination' => $www, | |
| 27 | + )); | |
| 28 | + $nz->addRecord(array( | |
| 29 | + 'host' => 'www', | |
| 30 | + 'type' => 'CNAME', | |
| 31 | + 'destination' => '@', | |
| 32 | + )); | |
| 33 | + } else { | |
| 34 | + $nz->addRecord(array( | |
| 35 | + 'host' => 'www', | |
| 36 | + 'type' => 'CNAME', | |
| 37 | + 'destination' => $www, | |
| 38 | + )); | |
| 39 | + } | |
| 40 | + } | |
| 41 | + $ftp = ((isset($_POST['ftp'])) && ($_POST['ftp'] >'')) ? $_POST['ftp'] : NULL; | |
| 42 | + if ($ftp) { | |
| 43 | + $type = (filter_var($ftp, FILTER_VALIDATE_IP)) ? 'A' : 'CNAME'; | |
| 44 | + $nz->addRecord(array( | |
| 45 | + 'host' => 'ftp', | |
| 46 | + 'type' => $type, | |
| 47 | + 'destination' => $ftp, | |
| 48 | + )); | |
| 49 | + } | |
| 50 | + $mail = ((isset($_POST['mail'])) && ($_POST['mail'] >'')) ? $_POST['mail'] : NULL; | |
| 51 | + if ($mail) { | |
| 52 | + $type = (filter_var($mail, FILTER_VALIDATE_IP)) ? 'A' : 'MX'; | |
| 53 | + $destination = ($type == 'A') ? 'mail' : $mail; | |
| 54 | + if ($type == 'A') { | |
| 55 | + $nz->addRecord(array( | |
| 56 | + 'host' => 'mail', | |
| 57 | + 'type' => $type, | |
| 58 | + 'destination' => $mail, | |
| 59 | + )); | |
| 60 | + $type = 'MX'; | |
| 61 | + } | |
| 62 | + $nz->addRecord(array( | |
| 63 | + 'host' => '@', | |
| 64 | + 'type' => $type, | |
| 65 | + 'destination' => $destination, | |
| 66 | + 'pri' => 10, | |
| 67 | + )); | |
| 68 | + } | |
| 69 | + $nz->saveZone(); | |
| 70 | + $user->loadUserZones(); | |
| 71 | + } else { | |
| 72 | + problem("existzone"); | |
| 73 | + } | |
| 74 | +} | |
| 75 | + | |
| 76 | +?> | ... | ... |
src/zonecheck.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$param = (isset($_GET['i'])) ? intval($_GET['i']) : 0; | |
| 5 | + | |
| 6 | +if($user->isOwned($param, 'master')) { | |
| 7 | + $zone = new masterZone(array('id' => $_GET['i'])); | |
| 8 | + $file = tempnam($conf->Tmp_Path,"zone_"); | |
| 9 | + $check = $zone->validateZone($file, $conf->HostMaster, $conf->NamedCheckZone); | |
| 10 | + if (!$check[0]) { | |
| 11 | + $smarty->assign("popuperror",$check[1]); | |
| 12 | + } | |
| 13 | + if (file_exists($file)) { | |
| 14 | + unlink($file); | |
| 15 | + } | |
| 16 | +} else { | |
| 17 | + problem('notown'); | |
| 18 | +} | |
| 19 | + | |
| 20 | +?> | ... | ... |
src/zonedelete.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$zoneid = intval($_GET['i']); | |
| 5 | + | |
| 6 | +if($user->isOwned($zoneid, 'master')) { | |
| 7 | + if($zoneid > 0) { | |
| 8 | + $zone = new masterZone($zoneid); | |
| 9 | + $zone->loadZoneHead(); | |
| 10 | + $zone->setZoneHead(array('updated' => 'del')); | |
| 11 | + $zone->saveZoneHead(); | |
| 12 | + } | |
| 13 | + else { | |
| 14 | + problem(); | |
| 15 | + } | |
| 16 | +} | |
| 17 | +else { | |
| 18 | + problem("notown"); | |
| 19 | +} | |
| 20 | + | |
| 21 | +?> | ... | ... |
src/zonelist.php
0 → 100644
| 1 | +<?php | |
| 2 | +if ($_SERVER['REQUEST_METHOD'] == 'POST') { | |
| 3 | + include("zoneadd.php"); | |
| 4 | +} | |
| 5 | +if ((isset($_GET['delete'])) && | |
| 6 | + ($_GET['delete'] == 'y') && | |
| 7 | + (isset($_GET['i'])) && | |
| 8 | + (is_numeric($_GET['i']))) { | |
| 9 | + include("zonedelete.php"); | |
| 10 | +} | |
| 11 | +if ((isset($_GET['check'])) && | |
| 12 | + ($_GET['check'] == 'y') && | |
| 13 | + (isset($_GET['i'])) && | |
| 14 | + (is_numeric($_GET['i']))) { | |
| 15 | + include "zonecheck.php"; | |
| 16 | +} | |
| 17 | + | |
| 18 | +include("zoneread.php"); | |
| 19 | + | |
| 20 | +?> | ... | ... |
src/zonepview.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$param = (isset($_GET['i'])) ? intval($_GET['i']) : 0; | |
| 5 | + | |
| 6 | +if ($param > 0) { | |
| 7 | + if($user->isOwned($param, 'master')) { | |
| 8 | + $smarty->assign("pagetitle", "Preview master zone"); | |
| 9 | + $zone = new masterZone(array('id' => $_GET['i'])); | |
| 10 | + $fname = tempnam($conf->Tmp_Path,"zone_"); | |
| 11 | + $zone->writeZone($fname, $conf->HostMaster); | |
| 12 | + $head = $zone->getZoneHead(); | |
| 13 | + $name = $head['name']; | |
| 14 | + $issec = ($head['secured'] == "yes"); | |
| 15 | + $sec = (($_GET['s'] == "1") && ($issec)); | |
| 16 | + $zonetype = "master zone"; | |
| 17 | + $zonetype .= (!$issec) ? " not" : ""; | |
| 18 | + $zonetype .= " secured, displayed as plain"; | |
| 19 | + $ownerid = $head['owner']; | |
| 20 | + $ouser = new User(array('id' => $ownerid)); | |
| 21 | + $owner = $ouser->getFullName(); | |
| 22 | + if (file_exists($fname)) { | |
| 23 | + $lines = file($fname); | |
| 24 | + $zonedef = implode("", $lines); | |
| 25 | + unlink($fname); | |
| 26 | + } else { | |
| 27 | + $zonedef = NULL; | |
| 28 | + $smarty->assign("popuperror", "There is a problem with this zone!"); | |
| 29 | + } | |
| 30 | + $smarty->assign("zonename", $name); | |
| 31 | + $smarty->assign("zonetype", $zonetype); | |
| 32 | + $smarty->assign("owner", $owner); | |
| 33 | + $smarty->assign("zonedef", $zonedef); | |
| 34 | + $smarty->assign("template", "zoneview.tpl"); | |
| 35 | + $smarty->assign("help", help("zonepview")); | |
| 36 | + $smarty->assign("menu_button", menu_buttons()); | |
| 37 | + $smarty->display("main.tpl"); | |
| 38 | + } else { | |
| 39 | + problem('notown'); | |
| 40 | + } | |
| 41 | +} else { | |
| 42 | + problem(); | |
| 43 | +} | |
| 44 | +?> | ... | ... |
src/zoneread.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$zones = $user->getMasters('live'); | |
| 5 | +$count = sizeof($zones); | |
| 6 | +$maxitems = intval($conf->range); | |
| 7 | +$currpage = ((isset($_GET['page'])) && (intval($_GET['page']) > 0)) ? $currpage = intval($_GET['page']) : 1; | |
| 8 | +$fromto = makePart($count, $currpage); | |
| 9 | +$buffer = array(); | |
| 10 | + | |
| 11 | +for ($i=$fromto[0];$i<$fromto[1];$i++) { | |
| 12 | + $zone = new masterZone(array('id' => $zones[$i])); | |
| 13 | + $zone->loadZoneHead(); | |
| 14 | + $buffer[] = $zone->getZoneHead(); | |
| 15 | + unset($zone); | |
| 16 | +} | |
| 17 | + | |
| 18 | +$smarty->assign("zonelist", $buffer); | |
| 19 | +$smarty->assign("pagetitle", "Master zones"); | |
| 20 | +$smarty->assign("template", "zoneread.tpl"); | |
| 21 | +$smarty->assign("help", help("zoneread")); | |
| 22 | +$smarty->assign("menu_button", menu_buttons()); | |
| 23 | +$smarty->assign("page_root", $src . "zonelist.php?"); | |
| 24 | +$smarty->display("main.tpl"); | |
| 25 | + | |
| 26 | +?> | ... | ... |
src/zoneview.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once "include.php"; | |
| 3 | + | |
| 4 | +$param = (isset($_GET['i'])) ? intval($_GET['i']) : 0; | |
| 5 | + | |
| 6 | +if ($param > 0) { | |
| 7 | + if($user->isOwned($param, 'master')) { | |
| 8 | + $smarty->assign("pagetitle", "Dump master zone"); | |
| 9 | + $zone = new masterZone(array('id' => $_GET['i'])); | |
| 10 | + $zone->loadZoneHead(); | |
| 11 | + $head = $zone->getZoneHead(); | |
| 12 | + $headraw = $zone->getZoneHeadRaw(); | |
| 13 | + $name = $head['name']; | |
| 14 | + $fname = $headraw['name']; | |
| 15 | + $issec = ($head['secured'] == "yes"); | |
| 16 | + $sec = (($_GET['s'] == "1") && ($issec)); | |
| 17 | + $zonetype = "master zone"; | |
| 18 | + $zonetype .= (!$issec) ? " not" : ""; | |
| 19 | + $zonetype .= " secured, displayed as "; | |
| 20 | + $zonetype .= ($sec) ? "secured" : "plain"; | |
| 21 | + $fname .= ($issec) ? '.signed' : ""; | |
| 22 | + $ownerid = $head['owner']; | |
| 23 | + $ouser = new User(array('id' => $ownerid)); | |
| 24 | + $owner = $ouser->getFullName(); | |
| 25 | + $filename = $conf->path . $fname; | |
| 26 | + if (file_exists($filename)) { | |
| 27 | + $lines = file($conf->path . $fname); | |
| 28 | + $zonedef = ''; | |
| 29 | + foreach ($lines as $line) { | |
| 30 | + $zonedef .= $line; | |
| 31 | + } | |
| 32 | + } else { | |
| 33 | + $zonedef = NULL; | |
| 34 | + $smarty->assign("popuperror", "There is no saved zonefile in the system!"); | |
| 35 | + } | |
| 36 | + $smarty->assign("zonename", $name); | |
| 37 | + $smarty->assign("zonetype", $zonetype); | |
| 38 | + $smarty->assign("owner", $owner); | |
| 39 | + $smarty->assign("zonedef", $zonedef); | |
| 40 | + $smarty->assign("template", "zoneview.tpl"); | |
| 41 | + $smarty->assign("help", help("zoneview")); | |
| 42 | + $smarty->assign("menu_button", menu_buttons()); | |
| 43 | + $smarty->display("main.tpl"); | |
| 44 | + } else { | |
| 45 | + problem('notown'); | |
| 46 | + } | |
| 47 | +} else { | |
| 48 | + problem(); | |
| 49 | +} | |
| 50 | +?> | ... | ... |
static/default.css
0 → 100755
| 1 | +body { | |
| 2 | +margin:0; | |
| 3 | +padding:0; | |
| 4 | +background-color:#e0f0ff; | |
| 5 | +background-image:url(data:image/png;base64,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); | |
| 6 | +background-repeat:no-repeat; | |
| 7 | +background-attachment:fixed; | |
| 8 | +background-position:top-left; | |
| 9 | +font-family:Verdana; | |
| 10 | +font-size:12px; | |
| 11 | +} | |
| 12 | +div.title { | |
| 13 | +position:fixed; | |
| 14 | +opacity:.7; | |
| 15 | +box-shadow:3px 3px 10px black; | |
| 16 | +border-radius:5px; | |
| 17 | +top:15; | |
| 18 | +left:170; | |
| 19 | +right:15; | |
| 20 | +background-color:#000820; | |
| 21 | +padding:10px 15px; | |
| 22 | +color:white; | |
| 23 | +text-shadow:3px 3px 8px black; | |
| 24 | +font-size:18px; | |
| 25 | +font-weight:bold; | |
| 26 | +text-align:left; | |
| 27 | +} | |
| 28 | +div.loggeduser { | |
| 29 | +position:fixed; | |
| 30 | +top:28; | |
| 31 | +right:40; | |
| 32 | +color:yellow; | |
| 33 | +text-shadow:2 2 3 black; | |
| 34 | +font-size:12px; | |
| 35 | +text-align:right; | |
| 36 | +} | |
| 37 | +.desc { | |
| 38 | +font-size:11px; | |
| 39 | +font-weight:normal; | |
| 40 | +margin:5px 0px; | |
| 41 | +} | |
| 42 | +.copy { | |
| 43 | +font-size:11px; | |
| 44 | +margin:5px 0px; | |
| 45 | +font-weight:normal; | |
| 46 | +float:right; | |
| 47 | +color:orange; | |
| 48 | +} | |
| 49 | +div.menu { | |
| 50 | +position:fixed; | |
| 51 | +opacity:.8; | |
| 52 | +border-radius:5px; | |
| 53 | +top:142; | |
| 54 | +left:10; | |
| 55 | +width:130; | |
| 56 | +background-color:white; | |
| 57 | +padding:3px 5px 30px 5px; | |
| 58 | +color:back; | |
| 59 | +text-shadow:3px 3px 8px black; | |
| 60 | +font-size:12px; | |
| 61 | +text-align:left; | |
| 62 | +border-style:inset; | |
| 63 | +border-color:#80a0ff; | |
| 64 | +line-height:200%; | |
| 65 | +} | |
| 66 | +.tag { | |
| 67 | +font-size:18px; | |
| 68 | +margin:5px 5px; | |
| 69 | +font-weight:bold; | |
| 70 | +text-align:center; | |
| 71 | +color:black; | |
| 72 | +} | |
| 73 | +.currmenu { | |
| 74 | +float:right; | |
| 75 | +color:darkgreen; | |
| 76 | +} | |
| 77 | +a, a:visited, a:active { | |
| 78 | +text-decoration:none; | |
| 79 | +color:darkblue; | |
| 80 | +} | |
| 81 | +.deleted { | |
| 82 | +color:black; | |
| 83 | +text-decoration:line-through; | |
| 84 | +} | |
| 85 | +.attention, a.attention:visited, a.attention:active { | |
| 86 | +color:red; | |
| 87 | +} | |
| 88 | +a:hover { | |
| 89 | +color:red; | |
| 90 | +text-decoration:underline; | |
| 91 | +} | |
| 92 | +div.main { | |
| 93 | +position:absolute; | |
| 94 | +top:0; | |
| 95 | +left:0; | |
| 96 | +min-height:300px; | |
| 97 | +min-width:350px; | |
| 98 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUgAAAD4BAMAAAB8h2LBAAAAHlBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3KG9qAAAACnRSTlMABCUgCQ0XGxMRWRrLZAAAAoFJREFUeNrt3b1q21AchvFz7sAHzgX0g5K1REPWGqS9hQiqrZOVsWCI1k6qu3VJkO62kuXUVmRoA7Lz/vHzoFXw4z1HsxxdYD68Ti8xhq4YTlVchv/pn8b01XpOXSyOG31nzM/bxLocQf2RIWOWt+3mRP1q2+4Zl+cPD0e8o0EnQxZNvTpLe/ugfaIeWdT7ETJmzaqsztF9WT5x7/bUwTlhukNlN2RdJWfopqq6Z9uh9O+ge+X0xEPWlOvkfI2hw60d1rzdGtPljukOlDF7rJLrd6ft/THnRJkOyjAoF6MrWa9PbhxBb5Jkr7w7OPFnX7k/QBY/T4icekdz3vfM/Za3O+V0yaJMupevvjjdnpCfnHA75FunnI9fy0R8yB3yykk3ID846bZI8Su5Q75x0oEEqRZIkGqBBKkWSJBqgQSpFkiQaoEEqRZIkGqBBKkWSJBqgQSpFkiQaoEEqRZIkGqBBKkWSJBqgQSpFkiQaoEEqRZIkGqBBKkWSJBqgQSplo8FSJBS2UCmFpAmlgQJUiw7yGuQIHUCCVKtHrlOQILUyQqyBglSKZAg1RqQH510PbICCVIoI8jcCHINcg5kVpcmkBXIWZCPFpANSJBK9chV9d1JB3JWZAlyJuTKALJWRzojyNYCstBHhh75zWnXITcgLweZFpvaALLZgJwFmYOcC9lufjjtzCAbA8iiBTkLMjOC/O20CzHLTSALC8hcH5mCnA/52WnnjSAzkJeETPWRIU0zC8gU5FxI7b8Qm0FGkJeDdDaQASRIrUKIFpAhyiN9p5RHdsalPLJfcuHEAwlSLpAXhfQWkM4CcmEB6bw+0nvn5JFbpnwGiEaWJCIiIpqzPzRW7lFKbYgjAAAAAElFTkSuQmCC); | |
| 99 | +background-repeat:no-repeat; | |
| 100 | +background-position:top-left; | |
| 101 | +padding:20px 35px; | |
| 102 | +color:black; | |
| 103 | +text-shadow:3px 3px 8px grey; | |
| 104 | +text-align:left; | |
| 105 | +} | |
| 106 | +div.loginform { | |
| 107 | +position:absolute; | |
| 108 | +box-shadow:3px 3px 10px black; | |
| 109 | +border-radius:5px; | |
| 110 | +top:10; | |
| 111 | +width:90%; | |
| 112 | +height:350px; | |
| 113 | +background:linear-gradient(to bottom,rgba(255,255,255,0.2)0%,rgba(255,255,255,0.5)100%); | |
| 114 | +padding:10px 15px; | |
| 115 | +color:black; | |
| 116 | +text-shadow:3px 3px 8px grey; | |
| 117 | +text-align:left; | |
| 118 | +} | |
| 119 | +div.loginend { | |
| 120 | +position:absolute; | |
| 121 | +width:100%; | |
| 122 | +bottom:20; | |
| 123 | +color:black; | |
| 124 | +text-shadow:3px 3px 8px grey; | |
| 125 | +text-align:left; | |
| 126 | +} | |
| 127 | +div.footer { | |
| 128 | +position:fixed; | |
| 129 | +bottom:0; | |
| 130 | +left:0; | |
| 131 | +right:0; | |
| 132 | +height:18px; | |
| 133 | +background-color:darkblue; | |
| 134 | +padding:5px 15px; | |
| 135 | +color:lightgrey; | |
| 136 | +text-shadow:3px 3px 8px black; | |
| 137 | +text-align:left; | |
| 138 | +} | |
| 139 | +.disabled { | |
| 140 | +color:darkgrey; | |
| 141 | +} | |
| 142 | +.submit-button { | |
| 143 | +border-stile:outset; | |
| 144 | +background-color:#6080ff; | |
| 145 | +border-color:#6080ff; | |
| 146 | +border-radius:5px; | |
| 147 | +text-shadow:2px 2px 5px white; | |
| 148 | +color:#000838; | |
| 149 | +padding:3px 10px; | |
| 150 | +font-size:14px; | |
| 151 | +font-weight:bold; | |
| 152 | +text-decoration:none; | |
| 153 | +vertical-align:middle; | |
| 154 | +min-width:100px; | |
| 155 | +} | |
| 156 | +.submit-button:hover { | |
| 157 | +border-stile:outset; | |
| 158 | +background-color:#4058df; | |
| 159 | +border-color:#4058df; | |
| 160 | +text-shadow:2px 2px 5px black; | |
| 161 | +color:white; | |
| 162 | +} | |
| 163 | +.submit-button:active { | |
| 164 | +border-stile:inset; | |
| 165 | +background-color:#4058df; | |
| 166 | +border-color:#4058df; | |
| 167 | +text-shadow:2px 2px 5px black; | |
| 168 | +color:white; | |
| 169 | +} | |
| 170 | +#cancel.submit-button { | |
| 171 | +color:#682830; | |
| 172 | +} | |
| 173 | +#cancel.submit-button:active, #cancel.submit-button:hover { | |
| 174 | +color:red; | |
| 175 | +} | |
| 176 | +.form-field { | |
| 177 | +border-style:inset; | |
| 178 | +border-color:#6080ff; | |
| 179 | +background-color:#6080ff; | |
| 180 | +text-shadow:2px 2px 5px black; | |
| 181 | +border-radius:5px; | |
| 182 | +color:white; | |
| 183 | +min-width:20px; | |
| 184 | +padding:3px 3px; | |
| 185 | +} | |
| 186 | +.form-field:focus { | |
| 187 | +background-color:white; | |
| 188 | +color:black; | |
| 189 | +text-shadow:2px 2px 5px #6080ff; | |
| 190 | +} | |
| 191 | +textarea { | |
| 192 | +margin-top: 8px; | |
| 193 | +border-style:inset; | |
| 194 | +border-color:#6080ff; | |
| 195 | +background-color:#6080ff; | |
| 196 | +text-shadow:2px 2px 5px black; | |
| 197 | +border-radius:5px; | |
| 198 | +color:white; | |
| 199 | +padding:3px 10px; | |
| 200 | +display:block; | |
| 201 | +font-family:"Courier new"; | |
| 202 | +font-size:11px; | |
| 203 | +} | |
| 204 | +textarea:focus, textarea.ro { | |
| 205 | +background-color:white; | |
| 206 | +color:black; | |
| 207 | +text-shadow:2px 2px 5px #6080ff; | |
| 208 | +} | |
| 209 | +div.section { | |
| 210 | +position:absolute; | |
| 211 | +opacity:0.9; | |
| 212 | +display:block; | |
| 213 | +top:70px; | |
| 214 | +left:170px; | |
| 215 | +right:15px; | |
| 216 | +height:60px; | |
| 217 | +font-size:18px; | |
| 218 | +background-color:#101850; | |
| 219 | +color:white; | |
| 220 | +font-weight:bold; | |
| 221 | +text-shadow:2px 2px 5px #000810; | |
| 222 | +border-radius:15px; | |
| 223 | +padding:0px 15px; | |
| 224 | +} | |
| 225 | +div.hint { | |
| 226 | +position:fixed; | |
| 227 | +border-style:inset; | |
| 228 | +border-color:#a0d0ff; | |
| 229 | +border-radius:5px; | |
| 230 | +background-image:url(data:image/png;base64,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); | |
| 231 | +background-repeat:no-repeat; | |
| 232 | +background-position:0 5; | |
| 233 | +bottom:33; | |
| 234 | +left:5; | |
| 235 | +right:5; | |
| 236 | +min-height:70px; | |
| 237 | +background-color:#a0d0ff; | |
| 238 | +padding:0px 0px 2px 55px; | |
| 239 | +color:darkblue; | |
| 240 | +text-shadow:1px 1px 8px black; | |
| 241 | +text-align:left; | |
| 242 | +} | |
| 243 | +div.clear { | |
| 244 | +position:fixed; | |
| 245 | +top:130; | |
| 246 | +left:155; | |
| 247 | +right:0; | |
| 248 | +bottom:115; | |
| 249 | +overflow:auto; | |
| 250 | +} | |
| 251 | +div.login { | |
| 252 | +position:fixed; | |
| 253 | +top:142; | |
| 254 | +left:30%; | |
| 255 | +right:30%; | |
| 256 | +min-width:500; | |
| 257 | +bottom:105; | |
| 258 | +overflow:auto; | |
| 259 | +} | |
| 260 | +pre { | |
| 261 | +display:block; | |
| 262 | +font-family:"Courier New"; | |
| 263 | +font-size:12px; | |
| 264 | +} | |
| 265 | +th { | |
| 266 | +text-align:center; | |
| 267 | +font-size:12px; | |
| 268 | +} | |
| 269 | +td { | |
| 270 | +vertical-align:middle; | |
| 271 | +font-size:12px; | |
| 272 | +} | |
| 273 | +td.cb { | |
| 274 | +vertical-align:middle; | |
| 275 | +font-size:10px; | |
| 276 | +height:14px; | |
| 277 | +} | |
| 278 | +td.ok { | |
| 279 | +height:24px; | |
| 280 | +width:25px; | |
| 281 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAB41BMVEUAAAAAgABXynkAdhdatmFPr1MFfwAAewtZu2ZZu2ZWumRAxGggliEGgwAAlRQApS0AlRMArTIIewAAnBoAoScApTAAZgAAVQBZvm9WslxWsltOtVlMtltJwGpJsVRItVpIrEs5oDYlsUolmykgr0QArjQAoCoAjAQAnSIAjwD///8ClxUDlhMmozM7x0EMmh38/PxKy0wzvjsCnCICmRoEmBcDkg/y8vIFrzcBpCmm3LQxq0MusDkAqC8Apy0KoCkCnygCoSQKnCIYoCAOnCAAnB4Hmx0DlBHs7Ox1oH0urzkHqjMjrCwAoiocnSgHnCYXlyYPlh/3+vfG5su/w7+s37mb1KB5on8oqEAppjo3uTgOpzIlojEJqDAlsCoQoCUOnCQhoSMHmB0IkRT3+/f29vb19fXp9uri8+Tj4+Pb7+DZ2dnP69XIyMi64sS84b+y37u3ubew1rSf06yqqqqfrqCJ0JuXr5qJ0JmSoJR2y4yIp4xwt3hnv3JnxWxPu2thnmhhlWhYumZcm2Nao2JNomJVsVlQnldMnlVJjlJGuksprUhAkEg8qkU+ykQ6t0IsqD8zlT81wD4YqD4xsz0tsDgYqjctvTYCrjUPqjIjmDIUmiINnR8SoBwSlxgIlBgLkBd8M8BNAAAAKnRSTlMAAugG/M1IEfbz5qyGbWldVlBBKyASCgPx5OTIw76+u7udioqGa0M+PBmTh5YkAAABkElEQVQoz4XRVVfjQACG4dBtyy6yLL64W2ZKQ2OkpU7dcXd3d3d395/KJOUEDjc8F7n43jOZi8F+EhIfHS6RhEfHf5vjJM1Wc3u72dooif2y/4q6NzeUCBqeb/JCxD3b0nJSjBzsoE9La1rix3+iKPeFCjmtrVq5VancrbnBEKd/uSpDro+n2Rq30+k0n+ULB/4zXoVgd7iixtvUpPDCMP6aUBOjLEeeHubtvctAidg0hSj8gzaGsUE6sD6IjwY63zoZyCj/opABAIAQvh5VEV0TW5tre34bhKko/AE0HfD7z6dYHCdYO9u/BGjwmw801bG/ODtux4P6NgAlhHTKanKwBIF/qKyjrCCFv5wmfY5utIjBQpr4y4uUPp+j5zOMkaRFU4AhUou+lhD3ijnSQIUl8CH20bA9qVaPDAh16NBAKuSYIKKD83g8l6sz6upq9UKjoS0HC0qUmTiXS6vT6VzNOi3XlhkqPkhWvVFbyrvTGusj0C6SJ2v0Ro4z6jVJ8uADiodiImVSqSwyJgH7wTvKvGKP1m610QAAAABJRU5ErkJggg==); | |
| 282 | +background-repeat:no-repeat; | |
| 283 | +background-position:center; | |
| 284 | +} | |
| 285 | +td.check, td.almost, td.enough, td.perfect { | |
| 286 | +height:24px; | |
| 287 | +width:25px; | |
| 288 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAACVVBMVEUAAAAe5i4AziEApSwVnUF4/XwGkitf+2UChyZ4+4Bo924KgyoEfSQAlARc/2EKmzmh/qlX/m6g/qIJsD8KnzwM/hAAsicA3R47/UEA1R0A3i6A/YN+/YMA1S6U/Zab/aEo/ElM/GEPtkEElikAoiYAliYA8BYA9hJd/GIAsSEA5ix3/H0FzjRG+15s+3le+2MAqSMAvR8dqkcI+hkA6BocnkYA6iwK+RgIvjgA3hlN+lUAwhww+VAgsUoAnCUgmUYn+TEA1RsD6ioNsjsTqz////+o/qyR/5gC/xK9/795/34AnzIAsSsA8SYA1yGR/5V6/4Z5/4Jd/3Ba/2I3/1Az/0AApTEA4jAAqS4AyCYA4iEA3SEA+h8A8BsA/Rr8/v3r+u6p/q+S/5xc/2tc/2c2/0gBxzgv/zcAzzYAtTYDoDYA1zUAuTQAsDQAvC0A5ywArCwA7ykAvCkA2iYA0iYAxSYE/yAA5R8A7B4A9hoB/xcA/hP7/vv6/ft6/4pj0HxQ/Fo51VkAvjcAqjUApTUAsC8Asy4AxCwAtiwAvyoAwSkAuCkA3SYAwCUA+CMA5yMA0SMA9yEA6R0D/xsA+BgA+RQB/w4A/Q0A/wLw/fLJ9NK6/76l/6eU/5542ZCF+Yx9/oBbynZl6XVe2HVT13Vc0nRb4XBj+Gtf72tB22ZIxWVX82RV6WNL2GM921o/41kvz1BA9Ek47kg0/0Uu5kMJqz8Kpj8Jvz4ArTcG3TUAwDUB4C4A4S0AtioAzykAyikAziYAyiYF+yUA0iUA9CIA5hsA8ho195xdAAAARXRSTlMAC/7+r6CWZl1SIyAJBPz8+fn4+Pj49/fAv7y7u7u4t7e1tbOzs6+vraWgn5+enZ2amZiXlpVoZ2ZmW1hST09MMzIkIwqdu/PUAAABsElEQVQoz2IgBBi52LVlpFnZuRhRxTnl3WZ7gsAcOU5kcT2BxMRENwgQYuWFiyvOTUpKcgcDfyDQgInr1tUFAEEgEHiBwAJ9iLiNYBAQJCcnp6SkBAcHNzQE81mB3aMQAgSpqambQ4EgfXX8/PR0CZDbnA6VlZVNnlxV5QEE0zfOdF0+Y4aoA1DCrG9iXwwQxMXFVVVvSnBdMX3aNA9zoIRWYWGhLwgcmVi5xdV1zdS46moPY6CEVDgQ7NyTn5/fv762ZlFsZeWUKVPVgRKAyWZnZ6+c1Vi8u2ddguuy8oqK2NjYY2pACZ2MjIwl8TWNJRtcXddGR0WV90+aVGEClLBIS0trnxefUO9au/hwcXEPSO6oJVDCeXtT0668eldX16WR+0pK/Pz8oqPFHYESLkqZmTk5OQtdV3W2R+4/eGDCBD8/SXDg2wrvyM3N9CnoyMvr7CotjWRiYrKGBJbR1pbm5tzWtraO7qKirt7SSENY8LJsy2oJC4soaPXx2dtd1KuJiChTkSxvb6BURIGPj5gBL1IU2rPwA6W8mSOYVexQI52Hm4NNWZWNg5uHULIBALcOlKJvvIoTAAAAAElFTkSuQmCC); | |
| 289 | +background-repeat:no-repeat; | |
| 290 | +background-position:center; | |
| 291 | +} | |
| 292 | +td.nok, td.bad, td.notenough { | |
| 293 | +height:24px; | |
| 294 | +width:25px; | |
| 295 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAABv1BMVEUAAACTJy2kLDOrMjiSJCq3OkCPIympKTHVUFaTJSrTUFauLDPIRkyrLTSTJCrHRUujKC+UJSueKC5hERZyFx28PEGXJSvZQEbLNTzTSlCcKC7IPUSUJCqzLjXVU1i1LDOvKzKyKzLNOkHOQUeeJy26Lza4MjmrKjHMSlDIPUPHP0W7MjirLTSbKC60MTi5NDuUJCqSJSuPJCq0MTegKTCjKjCnLjWOIymvMjiQIymMICVnFBlcEhfAKzO5JzCpJS3HLzeyJS6tJS2lJCzOMjufJCubJCvVN0DhQ0qXIyrpTFLcPUT////lSE+SJCmPIyjsUVeUJCqSIif+/Pz79vbsV1ygJy6cJy78+fn47u7qqazMgYXlcHXmV13mUFbJTlS+Rk3lRUzjREvZO0KuJy+UIiixHCaQGyH8+fj58/Pft7nloKTSnqHhmZ3ckpbQkZXWi4/ShIjAdHi5bnG4ZmraYmeyX2ToXmPhXGLWW2G7WV65VlrRVVrfTFLnS1LaSlCxRky4REvfP0fSPkXcPUWwO0LVNj7PNDyqMzmeMznVMDirLDPPKzPJKDC0JzCYJizCJCyjIyuoIiu7ICmqGyRC316rAAAAPXRSTlMADAIgj2A97uPfysmnoqGYimJOEA0H/Pny6Obk5OHg4N3b19PPzcrBv7+5ramfm4WFfn51a2NLSkdHIhIOijmOJgAAAUtJREFUKM+F0VVXAkEYxvF16Q7B7u5uJRQkdHeFpbvB7u7u1g/s7OyChyt+V895/2euBimkaEwm5POFshE1mnfm1By4bIDLVc5R/99Z4pBtLivcwcrd20IxHMdj8ThOOW9kSpE4bAGuD4PBMwvUroKBczFPefYvYnsJat2W9sIHlQkz5dWPYUf3ZqhhAgTljRF6W8GwU3o+lA2C0GPUQ59rDiyiZ3SC0KKh/aw7HBENoxmEai0tvel1RrWMWhDqpmnpLacvyuz3ehBaZ2i/Aa/vitlJEQjypA76vjs+edExJCBwdQbo63Ij8Gig8YZBQJtmacsYtu2GyyCapMK42wStLjl3PXDxhhAKyjZZgdTTzr7HSnFLst8kLUmRBEFmMiRBklZPV3HuA/uqCGIBsn9UyOGdho5KBQRhBwTdSiSPiqsYYLP7FdwppIA/M91t59KIatsAAAAASUVORK5CYII=); | |
| 296 | +background-repeat:no-repeat; | |
| 297 | +background-position:center; | |
| 298 | +} | |
| 299 | +td.ed { | |
| 300 | +height:24px; | |
| 301 | +width:25px; | |
| 302 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAACRlBMVEUAAAAPGCQAAAADBAYqChEOFiAxNUUBAAAFAAAHDAyPHx+dRVtUQzPKQESdssyWrc1YHiI3MzDefX1VDBGpMjEAAADbdXgOFyETHCcCAwQQGSYAAAEAAgEAAAArCQkBAQEAAAAmNkoBAQFHV2shBAaYJDD///+gttPU4O7j6vXc5vLY4vDO2+zM2evM1eG8ydr9/f7f5/L8/f35+v3v8/jR3ezE0+X1+Pzz9vrr8Pfn7fX1lhb8rRXS3uz8ryTn5+a2xtutvdGUq8q8v7+Lor96kbCIio3vjzf5qx77rR3Zcwr5/Pzg6fPk6fDj6fDL2evAzuCetNKpuc2Zr83g3Mlzi6rQyKmem5WMkpX5y42Qj4t4fYf4xYN3eXxydHZ3dXVbWlprRir8sSjniCjhgiggHhrWbgbv9fzo7vbs7fPd5vLw8PDr7O3N2uzh4eTa3eTI1OTQ2ePw6968y97H0dzW19rR09auwNbMz9Kbss/Nzc23wMumtsvy58qNpsqltsno4sjFx8ePpsT+w8OstbyGnbuDmrnVzbf3t7eAl7axsbKdprCPnbCnqKhwhqdthaWfoKGOlZ/60p5ifJ3MuZuampvkuYjuh4f2hYWBgIHAgICAf374wnrnrHi9dnW2pG+kmW5QWmekTV2UhVdcWVPVq1LeUVF0a01tY0dfTkJuYkGPQkHqkEDEQkBFRD+3iz7YiDu1OztCQTrBOjjoqDNlSDDxiy7opCkvLijmhydtRifigCHHdCBmPSCTHSD2lhb/rxPDaQ7I9twOAAAAJnRSTlMAoxaUBKVPNigc/vr5+PTv6+jn3NrPsrCmpZyakIp1dGhVTT0sF3ISilYAAAF3SURBVCjPYsAN6tQRIJBfmQUuEehXEKAPBSbGfGxwicosf38zMAhw8FUzcGJThWoKNtSFglyghJoRN68YJ0TCRwcGHPwMvBetndEsxAHS5KRpamoLhECyuLw+wnlWx/RlIipgCQ04sHVrdI6bt3EzlxxQoilDGwby12zoip8ZsXqfsAJQwsVSCwa2JcdsiZ7QGy8gywGSMDEEA58895Q5dge2h88WlGEHWd5qogkB7skxSTYe+/fwSIPFGQBrs7ACAXv3lEg7G09rr72iShAfdppbAkHm3J2RQPXWaYkLJTkhPnc1NjExSZ+2exJY/a64HmYmqISRhYWFfdgUO7D62ApHuISaubl5SHvIUqD6rbFlFnCJUDVjY+OGorAF6w+udCs1N0aSMFKL2lQ7f/GqJVPtvY2MgmASfWoGajtSVyxPcHPOMQACuES/mlp46rqEqKpsIzUQqIFJTC7Ua5kY3V1dogcBLjAJRSlxVlZWRjiQkAdK4AEA+il2ExPxslwAAAAASUVORK5CYII=); | |
| 303 | +background-repeat:no-repeat; | |
| 304 | +background-position:center; | |
| 305 | +} | |
| 306 | +td.some { | |
| 307 | +height:24px; | |
| 308 | +width:25px; | |
| 309 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAABDlBMVEUAAABSUmZPT2xSUmpLS19ZWXdQUGtQUGlbW3VOTm5NTWxOTm1eXoNUVHVOTmxdXYFgYIRPT2tQUGxZWXRRUWU/P1BUVGg3N0RUVGZfX4ZsbJdkZItubplbW31mZoxfX4BQUGxbW3pRUWxXV3FSUmpMTGJUVGv///+dnd6Li8RgYImBgbZlZY5PT3CFhb1qapZaWn9WVnpUVHeZmdmUlNJ+frNoaJRcXIKIiMF6eq2Xl9Z8fLCTk8+Pj8yCgrheXoWjo+eenuCbm9uOjspubpxSUnT6+vqamtqWltSHh7+EhLt5eax3d6lzc6NsbJpmZpGNjcd0dKRxcZ/29vapqe+mpuvW1vK4uPChoeRYWHweFNUfAAAAJ3RSTlMAGuZ+M8nIlnD79vLx8e7r493OoicdFBQK+fX17+nm0dHDw5aJiWtudu4FAAABd0lEQVQoz4WR51qDMBRAa7XDvbXuLZAQCIRQNqWF7j0c7/8iXmqt+qvn5zlf7neTZFaxVsztyPL+Q3Htnz49vsROBXDw9dP5r9/Yt5i4gEkHG0tPDYexRhVoMMfxbk8Wc258w3CcahRFIms2DcO6+w7Hbs33jKaQMhE9z/ftwnyfq5aUFmFO3fBrknSRLlCMFUsa1moRa3xAYUPJUjovEHKdAAowbHl1QTDAYzcHYdfmgdKyLAk34MBUUdqB2z2AoHU7HLcVBTPwM9xuY7cz2oGwafZsl+MggDlNO8DctXvmLoQ9Hakjm3OlLkwx59zuqaGehfCYUDRQ47E7EWbd0ThWB4gmeQiv5DOUTbVvjrux2u+rphxqZD294J5OEZSe+B7FqUdU3yplgALRykiWW7CUbYIvzw8AZ4cJFKRW3sTBYO6Pfp49SzQahmWZIhRSjRwuf/HknugaLQNU08kR+CWFTZLoQEK2YP5fzp7z2e3tbH69lFnBF01/TOuZl9vyAAAAAElFTkSuQmCC); | |
| 310 | +background-repeat:no-repeat; | |
| 311 | +background-position:center; | |
| 312 | +} | |
| 313 | +td.del { | |
| 314 | +height:24px; | |
| 315 | +width:25px; | |
| 316 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAACGVBMVEUAAAAAVbYAS9ILKTcAUKAASqsATp0ATacATaMAUrMACiEAYcIAEyUAWcMAFSsAQ6MACgoAIkoAXLY4xgAAKFI0wwAAK1UarwAAeesAKUwAK1kAIkUAdeYAdegAIkgAUqYAHzsABggAWbwAHUAAfnQAS8UARY4AEyQ3xgA5xgA2wwAAGzUAIEAAIkIAMGQwvQAANm8AOncAee4AUaMAU6Y3xgAAVaoAUKIAHDQAT58AR5EAceIAKE4ANmkAMF8AGjkASq4AQYIALVgAJ1AAN3AAIT0AMGIAijsAVa8uwgAAd/QACxUASpMAeeoAjCgowQAAa+YAJEQAemwAGDAAcvwAYrcALF8AJUsAb4wAiTIAhf8AJEkABw0AHDUAFDsAWU44xgA4xAA2xgAAGCwANWgAFSo0wgAuvAAAJUcAQ4AvwAAAT50ADRkARIgAM2YANmkAVq0AQIIAKVQAIkcAGzsAXrgqtwAAducAXrkAChYpwAAATJgAR40AI0wAbtkAQIAAduULowAAa9MAJD8Ae/EAI0gpvAAgsQAAIDsAeO0ATqUATpgyvgAAWrUAfO4AY8IOowA0wQAAChEAZ80vvgAOrAAAQroAMFgAKUoRpwAAeVYAXsAAZdQAOm8AO3sAYbIAgFwAHzkAQY0AAAYsvAAAaJEAhSMARIkAVcQABwcAZ+MAMFAAGiwASbYAkgkAO/8AijUAqiQAQOD80Dn4AAAAs3RSTlMAJAoDGyJhIEofBikjGhgSCU0t1YVqX11cWllRTkVDQTg0MismIyAV3s6mm5WQiIV9cnFsaWZhYF5bW1NSUE9NSUdHR0NDQj48PDs6ODUzMzIuLSopKCUlJCMiFRIRDQuurJ2XkZCPiomGfXp5eHh3c3BwcHBvbmpqamloZWVkZGNeXV1ZWFhYV1NSUlJPTEtLSklIR0dGQD49Ozk1NTQyMjEvLi4sLCknJiUgHRwcGhgVCIB3Y5gAAAGgSURBVCjPYsALmJnjw2dIt0pKStrIBcYyM8PEo+3yM7MrmqxlZGQn91oZ5omFQ6S4igqMjMobJKxlZL18Q0KiovpT+CASIrmldRISLZ19QImAgDmzOfR4IBIltSJ6Bob1Vt0c8h5KQj6OLsUxEKvtV4e5SYmJSdm5zFvOzsLPz9QsAJFQUGZiYVFTYwUCdnZ+JiYGCy6Iq3jkgBIsnJzsrIyMjEAJpg6og/kEgRJAYVVGv5lZnvFMYa4wCWkmoHpWRtUJwsKipks2TQ+GedCefy07UHy9uLB+5BT/jYJroBKAxbmq8bIzMqqI64sHBa0T9RTkg0pwKczlZWQMXaCl0S7EvcHUX1odFlgL3YAS3O6a6ZF+ET0TlwnGwiSUnUASS8sSNRPakqoWyQnAJIKBEqHc3BFpGlpTRVUcFeDhzuPMySgkNF9pVqP7CpVVtoHwiFJ39pHnAAKHaQ7AYLRVhksI2NSYs0GApWWXFA8ibr0zDKrNTIyNTczMC0Us4hASAoqVqdo6uro62sk5k6C+gHkyhmexorfiSj4BZgb8AADrIlTIFASIAwAAAABJRU5ErkJggg==); | |
| 317 | +background-repeat:no-repeat; | |
| 318 | +background-position:center; | |
| 319 | +} | |
| 320 | +td.view, td.preview { | |
| 321 | +height:24px; | |
| 322 | +width:25px; | |
| 323 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAABgFBMVEUAAACybgQ9erjEfwwMV6TBgBE4erwWX6cyc7RMh8K0cgS5dQhUicCvbwKuyOg8eriscg14SzURW6XSjh4qb7LUjhfShgZIgrzjjgJqc2Vpb1/Mihslaq00dLTQkSgpbLA9ercmaa47ebk0d7gATJxCf77BfAq6dgi6dgVCYW68dwi9egpMhL06eLW4dgceZaq6eApOhr4+fbm6eAtdkMRCfbi6eQ24dgxVi8FFf7uDqdJynsu4dge3eApLhr+00ueqbAA3drpkl8Xo8v7C3fu62fqp0Pjc7P7P5f2y1frJ4vvZ6vzu9/8kaa33/f/m8f33uVLlqUXq9P/Y5/fP4fRwo9Z3pNE9e7oeZq35v131tEf0sEDzrjryqC3toSLtmxD0+v/x+P/e7v673P7K4/vT5vnB2fK/1u2jxeiSvOaqx+SRtdmKsdd/qdJsntBfl9ByoM1hlcpPisWCpMRckMQ4eLkwcbLxtVD4t0vlpj3jojb0rTXlnyrXlSjuoBzgkxJ4t3KIAAAAQ3RSTlMAGPTu6NfFvWZfXEg6LhoSCwT+/vz6+vn59/Xz8vDu7efk4N7XwcG3rqqpnZeWkY51cm5ta1JNTEpCJycnIRgODgwGy8ozJgAAAPpJREFUKM99zmVvQlEMgOFiY0MGzN3d3f3A7uQq7szdBZe/TgghPeEQno9907RQl2VOLQjC0PpJ1Xy5/919JUovf/pmoK21uEmJk7xq6WIZdjlJmfi1CGjFe8NV3PtsGEaeztB3E4Y2hx15xjH4b8+RpwGDcEr5pMLoswP9UDcaP+4uKuz/xxgOBh+4yzLOO20FaiX+yEuESIT/7e6aMgPa8r+JPH/t8vV0xGIaA6AdvVbd2Tc2DzOFfLR9VgVo17RtOgQ4mohGIlmdERhmTSYcDvUu2JhiaA0Fg8ncHjCW0rIsp4xssE4mAgFlA1gqnaIM7EOtsrqJD7OKPBJCztYjIqEAAAAASUVORK5CYII=); | |
| 324 | +background-repeat:no-repeat; | |
| 325 | +background-position:center; | |
| 326 | +} | |
| 327 | +td.no { | |
| 328 | +height:24px; | |
| 329 | +width:25px; | |
| 330 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYBAMAAAASWSDLAAAAG1BMVEUAAACNAAB5AQB3AQByAACGAAB/AABrAQFqAAFgNiydAAAACXRSTlMA8/T19fPys7EGJ6HTAAAAIklEQVQY02MYDMBUEAyCwRy3QBBbNAXMKTFSAgJlD4bBBgBrrgPcZyYWLAAAAABJRU5ErkJggg==); | |
| 331 | +background-repeat:no-repeat; | |
| 332 | +background-position:center; | |
| 333 | +} | |
| 334 | +td.bad, td.enough { | |
| 335 | +opacity:.5; | |
| 336 | +} | |
| 337 | +td.notenough, td.almost { | |
| 338 | +opacity:.1; | |
| 339 | +} | |
| 340 | +td.first, td.firstno { | |
| 341 | +height:24px; | |
| 342 | +width:25px; | |
| 343 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAABxVBMVEUAAAASEhJzr90SEhISEhIrRVqFyulcndZnptRYlMRnpM5KfKiK0euEyOiL0uuFyukgLzyIz+p6uuQbJS0SEhIbJi4SEhKCxucSEhJeoNiIz+qFy+lprNx7u+OIzuphoteFy+lbm9RopNRdndJoo9BhodJendBalslWk8h2tN9ppNFno9Bmo8xQh7Z1s95qp9NTiK+CxOeL0utFc5xtqNVfmbyIz+pZj7J+wOVHcpJzsttOfZsfLjwxTWCL0uv///9mns+DwOaKyel6teP8/v+Oz+uMzOp/veXt9/2IzeqIxehxrt9tptfY7vmT1+2Jx+iFw+eBwud+uuR4suBuqNpxqdmp1/CKzOp8veV1seB0rt9nqt1zrNtdoNppodPx+v3X6/m42fKj1e6S1OyQ0euDwud9uON4t+Jvq95lp9xipNtwrNpoo9j6/P6/4fWb2u+m1e+V2e6i0+6i0e2g0e2NzuqQyuqFy+mKv+eCv+V+v+V2ueNxtOF3s+Fwq99rptlspNRro9RnoNDm8fvO5vfB5PXI4/Ws1/CW2u6R0uyL0OuXzuuRzeuNzeqSyeqEveWGu+R5ueOEuOJ1tuJzteFqrd5inc234DQrAAAAP3RSTlMABf5CC1gR9N7Hu52cb2ZOR0Y6OTIpIBwY+/n59vTw8O3t6OXl4N7R0c/JwrSwn52dnJCPjo2KgX5zXU9OLAaavyVQAAABoklEQVQoz32PRVvrQBRAmz6K60Ofu+DuEiaBhgjE6y1SF9zd3fX3cqdFN5zFLM65881cwyNdedl1mdk5yYbXJDd9ZVn2iGU/Zha/9Hnf5wcmB4DJg/lPWc8+y896fb1xDr0+ufbR5yxZe81mM0VRcM76vHJLwhd/8WMpHk+JokhZTk6ttvfxUBWkRI7jRkZJC8f1k30UxZTGP2SUJD9C06MkuS8NkWTfrMTZ8ZW2KEKLizM9JDmGwA+OWxEyNkCojjKMMg1+9/zBM8xqGYT0aEBZwPPMHvg5xASUgPobQrlAK2cQhukdeGCBxhh/QqjYUmnZgovSD+VCVVW7ngqh8c5lpOUJXBAuVw6XqzsdQrtT112rSyNQJiQo2w5djzVDSEqNCYJmt0GZssmwoF1Y/9xpAFqd2saGwF/OzQQdQZsFOQRnDYFDSVpY83g8Gs+HNjfX+DUt/KcQNJD/N8J7uh/YCoW/mYhEIHL/RVb4daxjoevIL1MSyETJz0hxO1eWl29u3R8qc8E/UdRRn/bD7U75n2EqJAwvIUoK3gEFRTD+NvetwnhfPecH4gAAAABJRU5ErkJggg==); | |
| 344 | +background-repeat:no-repeat; | |
| 345 | +background-position:center; | |
| 346 | +} | |
| 347 | +td.last, td.lastno { | |
| 348 | +height:24px; | |
| 349 | +width:25px; | |
| 350 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAABuVBMVEUAAAASEhISEhJdn9krRVofLzwSEhKFyukSEhJzst+HzepcndZcnNNopNJfn9FnptRYlclnpM5KfKiEyOiL0uuIz+ofLDcTFhiCxueCxOdprNx7u+OIzuphoteFy+l2tN9ppNFUkMNcmMVno9Bmo8xQh7aIz+p1s95qp9NTiK+CxOeL0uuL0utFc5xtqNVfmbyIz+pZj7J+wOVHcpJzsttOfZuL0ut/weZ7u+R4ueMxTWAkN0USEhISEhISEhKL0uv///9nntB6teKLy+l3suH7/f+Oz+uJyelxrt/a7vmMzOqIxeiGw+eCwOZ/vOV9ueRzrdxuptdrpNSGy+mJx+hvq99xqdprpdiU1+2S1e2Q0eyJzup/veV7vOR3uONys+Foq96o2fC11/Cn1O+V2u6l0+6CxOeDweZ/weZlp9xoodLu+P3r9fzq9Pzl9Pvi8fvc8PrA5PWn1u+e0O2WzeuQy+qEwueFweaGu+V6t+N2tOJ1rt5uqNthpNtwrNpeodpvqthmpNhlnM7Q5vfN5ve63POs3PGa2O6h0+6W0+2L0Oudy+uTx+mKwOeDt+J1tuJmqd1jpdtinc2DobtnAAAAQHRSTlMAA0L+WEkfEQn9+fTp59/e0budb2ZGOjQc/Pb08PDtz8nIxsK0sJ+fnZ2cmZCPjo2KgX5zXU9OTjw5LCsoFA8GGATzoAAAAZ9JREFUKM99zlV34kAYxnFYoN3K1m19t+7uOoHQpDEiJcGhLcXq7u4un7jvhEPlpv+LuXh+c+aMIdVIcVFjQ1F3uuFj6a2/vIr3WvFmVpe934v/KK6wy+1yhcNKZuHbXvhdcXtG9TxuT6Q+tffEbKMMY9NjgGLtyb3sZ4Sh1ibGoctVirIxNn+vDjUBapydR2MsN4XsUyxLUb6/+ocyOG6dmkdoDADZp9c5js3oA+jcj/I8czEDsrGEheejYjNA7aFPEHjvFRZWF8FH/gPI33dAguNuFqFT4QwhdCuQ3wAqJKveJsCJdRJg1SFiqCRI3OYcPIV3+zlvPcwFaHkWxZ2de7xv4X0iZhWJfICukKqq4gJCi9EbvPtIVT1qAxjOPZKk7QW0GPGvIPuyn5Qk7Ue/AeoI7crBjWX/Nr21shagZVl6rDNiGCqP78pO2inDQWuJhBbPGTDoleQ80QkilTP+22xMgtGStxekNeL4mNCcD3vZ5q8wJqWkIOsgFAwEgqEDU5UF9ldJszT9zzaZsvIKzIP4nfdU+gUqTYPrn/cCD9B3xI0Q9tUAAAAASUVORK5CYII=); | |
| 351 | +background-repeat:no-repeat; | |
| 352 | +background-position:center; | |
| 353 | +} | |
| 354 | +td.prev, td.prevno { | |
| 355 | +height:24px; | |
| 356 | +width:25px; | |
| 357 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAABnlBMVEUAAAASEhISEhIfLzwSEhKFyulcndaHzepfn9FnptRYlclopNFlo8xKfKiEyOiL0uspQlaFyumIz+oSEhISEhIbJS0SEhIbJi6CxueCxOdeoNhzsd6Iz+qFy+lprNx7u+Nhotdbm9RopNRdndJoo9B2tN9ppNFUkMNcmMVQh7aIz+p1s95qp9NTiK+CxOeL0uuL0utFc5xtqNVfmbyIz+pZj7J+wOVHcpJzstsuS2FOfZt7u+R4ueMxTWASEhKL0uv///9/u+Vnn9B6teJ4suCDweZ9uORzrNxtpteKyumJyOmGxOeOz+uCv+V1rt9rpNSLzOmIzOlxqdpvqNnt9v2U1+2MzOqDw+d3t+Jxrd+S1OyP0Ot/veV7vOVoq95dn9lpodLx+/294fS64POV2u6IxeiGu+RytOFlp9xwrNr4/P7m9Pu53/Olz+2KzuqSy+qFy+mAwuZ+wOV2ueN0s+B2sd9vq95fo9tkpdprptloo9dlnM7E5va+3vOz3vKe3fCa2e6l0+6X1e2L0Ot7t+Nmqd1uqNtqotNnoc9inc0eCz8NAAAAQHRSTlMABQtJHxH079/e0b+4nW9mWU5GRUA5Mikc/Pv6+fn29PDt6OXlz8nIxrCfn52dnJmQj46NioF+c11WTzw5LBQGie+1rQAAAYpJREFUKM99z1VDg1AYxnFws7u7u7trbOA5DB0wlFirm9vs7m6/te9hzrjxd/Xy/LkAKmm+KH+gP78wlfordSRdlnefZLmmq+L3XpS+vxJeAeHwfm3ez55XKXu8i4TX4/Fqfcm98FBaVFWJ53lJUqEdjCX2inpN5Z3E+ubWHi+pvH/aDN260xkRwJrNZruVIk7e12p+ULUgaBxYh331kdcEIXI8A2EiznFLYJvsd7twcxwagtAT9zHghuz38hK5fWwbhOz4AtiBfXmPYxZMbAsJ2OFwMA8kbDi+oCYIOe8nLMto12ZhTSdKJoThD4RcLt/BmllcACF7DoSpgNvtRuj50CwsQvB4PgohJfMSY0VRdD/5kR1DwfiibpYC4wFFFDHGx/7tzS3GgPullyZhriP2Ggq9iaJL9+uGGMKxjHLKVJpxboTsSaexhkk6EWhL1lnUuLBfXdkvT/Wz5oIUGBOlNDctGIgeHUUDwapOC+zfrJbB9sZgMC0rt6Ccpn6jrWUlxcUlZVZ4/X+fEgZ011jIKjMAAAAASUVORK5CYII=); | |
| 358 | +background-repeat:no-repeat; | |
| 359 | +background-position:center; | |
| 360 | +} | |
| 361 | +td.next, td.nextno { | |
| 362 | +height:24px; | |
| 363 | +width:25px; | |
| 364 | +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAABoVBMVEUAAAASEhISEhKCxOddn9kSEhKFyukSEhJcndZnptRYlclopNFnpM5KfKiEyOiL0ustSV+FyukgLzyIz+p6uuQbJS0SEhIqQlOCxudzsd6Iz+qFy+lprNx7u+OIzuphoteFy+lbm9RopNRdndJoo9BhodJendB2tN9UkMNcmMVmo8xQh7aIz+p1s95qp9NTiK+CxOeL0uuL0utFc5xtqNVfmbyIz+pZj7J+wOVHcpJzstsmPVBOfZsfLjwSEhISEhISEhKL0uv///94suBnn9CKyel6teJ9uONup9eHxeh/veXl9PuCvuV/u+R1rt9yq9xspNVpodKT1+2Q0OuNzuuNzOqEweZzrdxvqNmLzOmGy+mFw+dxqdqKy+l4t+Nxrt9spdjc8PqR1eyIzuqJx+iFwueCwOZ8uuR1teJxtOFwq95nq91lptxhpNv8/v/1+/7N6/jF4PWV2e6Q0uyL0OuLw+h+weZ7vOR2ueN1sd9eodpvq9lno9ZlnM7o9vzR7/na7PnJ5PbC5PXH4fW/4vS82fGW2u6MyOlqrd5pqd1inc3fzcNaAAAAQnRSTlMAA0L+/h8RCfTe0ca7nW9mWE5HRjo5Misc+vn59vTw8O3t6OXl4N7PyMa0sJ+fnZ2cmZCPjo2KgX5zXVlPTigUDwZQTPziAAABkUlEQVQoz32PZVcjMRRA223p4rqwrC/u7g6dCc0M9XGpC1Xc3e1X80KZA3zhfnq5Ny/nxGSwVFc1PFRVYzN9xDb+N6bGdtTYz97G977uv+rf8gNbd+qvyjdfaVGjHMfzPMdt+7ctg4av2VN4QVAQQooi8Fx0b7LgG/9YBJBXaxEhHkcoIAT2v72EviCKMwyzbrev3DMAQmwH8bYfmpYQRX7DDmVXFBOaxhySlWmPmHQ6nUr0nJQEjElRGoXQf8yyLiCwU9hxsSxLlUEoP3asOgguxyWUCxccqVYIZXjZ4BpCxAmD1Ayhm6Ze2QR/xrEUdYhLIIw9SZKbQPxKgKXckkSXQ5h91HUPcEs8WnV7dF0/mYCwWHKCsSxnyAe1oEeWMQ7//m4CprKy1+tN3axFkimMYcTZATMJC1052ecLBfeDIa8PCOfaYIFQ354P+WiDTO5ftbkQzLWl+XQoTJ+e0uFMKt9S/RVkodRXFB9l0wcH6Ycja08t8UYpmhvpbLJai0srZubJO+9TwxegoQiuf84zATd21V0d5SoAAAAASUVORK5CYII=); | |
| 365 | +background-repeat:no-repeat; | |
| 366 | +background-position:center; | |
| 367 | +} | |
| 368 | +td.nextno, td.prevno, td.firstno, td.lastno { | |
| 369 | +opacity:.5; | |
| 370 | +} | |
| 371 | +td.preview { | |
| 372 | +opacity:.3; | |
| 373 | +} | |
| 374 | +td.empty { | |
| 375 | +height:24px; | |
| 376 | +width:25px; | |
| 377 | +} | |
| 378 | +td.ok a, td.nok a, td.ed a, td.some a, td.del a, td.preview a, td.view a, td.first a, td.last a, td.prev a, td.next a, td.check a { | |
| 379 | +height:24px; | |
| 380 | +min-width:24px; | |
| 381 | +display:block; | |
| 382 | +width:100%; | |
| 383 | +text-decoration:none; | |
| 384 | +} | |
| 385 | +td.nocap { | |
| 386 | +height:130px; | |
| 387 | +width:320px; | |
| 388 | +background-image:url(data:image/png;base64,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); | |
| 389 | +background-repeat:no-repeat; | |
| 390 | +background-position:center; | |
| 391 | +text-align:center; | |
| 392 | +text-shadow: 0px 0px 7px #000000; | |
| 393 | +} | |
| 394 | +.disablestamp { | |
| 395 | +color: #FF0000; | |
| 396 | +display:block; | |
| 397 | +font-size: 28px; | |
| 398 | +opacity:.5; | |
| 399 | +transform: rotate(330deg); | |
| 400 | +text-transform:uppercase; | |
| 401 | +letter-spacing:3px; | |
| 402 | +word-spacing:15px; | |
| 403 | +font-weight:bold; | |
| 404 | +} | |
| 405 | +.whitelist { | |
| 406 | +opacity:.5; | |
| 407 | +} | |
| 408 | +[type="checkbox"]:not(:checked), [type="checkbox"]:checked, [type="radio"]:not(:checked), [type="radio"]:checked { | |
| 409 | +position:absolute; | |
| 410 | +left:-9999px; | |
| 411 | +} | |
| 412 | +[type="checkbox"]:not(:checked) + label, [type="checkbox"]:checked + label, [type="radio"]:not(:checked) + label, [type="radio"]:checked + label { | |
| 413 | +position:relative; | |
| 414 | +padding-left:25px; | |
| 415 | +cursor:pointer; | |
| 416 | +} | |
| 417 | +[type="checkbox"]:not(:checked) + label:before, [type="checkbox"]:checked + label:before, [type="radio"]:not(:checked) + label:before, [type="radio"]:checked + label:before { | |
| 418 | +content:''; | |
| 419 | +position:absolute; | |
| 420 | +left:0; | |
| 421 | +top:2px; | |
| 422 | +width:12px; | |
| 423 | +height:12px; | |
| 424 | +border:1px inset #6080ff; | |
| 425 | +background:#6080ff; | |
| 426 | +border-radius:3px; | |
| 427 | +box-shadow:inset 0 1px 3px rgba(0,0,0,.3) | |
| 428 | +} | |
| 429 | +[type="checkbox"]:not(:checked) + label:after, [type="checkbox"]:checked + label:after, [type="radio"]:not(:checked) + label:after, [type="radio"]:checked + label:after { | |
| 430 | +content:'✔'; | |
| 431 | +position:absolute; | |
| 432 | +top:1; | |
| 433 | +left:3px; | |
| 434 | +font-size:10px; | |
| 435 | +color:white; | |
| 436 | +transition:all .4s; | |
| 437 | +} | |
| 438 | +[type="checkbox"]:not(:checked) + label:after, [type="radio"]:not(:checked) + label:after { | |
| 439 | +opacity:0; | |
| 440 | +transform:scale(0); | |
| 441 | +} | |
| 442 | +[type="checkbox"]:checked + label:after, [type="radio"]:checked + label:after { | |
| 443 | +opacity:1; | |
| 444 | +transform:scale(1); | |
| 445 | +} | |
| 446 | +[type="checkbox"]:disabled:not(:checked) + label:before, [type="checkbox"]:disabled:checked + label:before, [type="radio"]:disabled:not(:checked) + label:before, [type="radio"]:disabled:checked + label:before { | |
| 447 | +box-shadow:none; | |
| 448 | +border-color:#6080ff; | |
| 449 | +background-color:#6080ff; | |
| 450 | +opacity:.5; | |
| 451 | +} | |
| 452 | +[type="checkbox"]:disabled:checked + label:after, [type="radio"]:disabled:checked + label:after { | |
| 453 | +color:#fff; | |
| 454 | +} | |
| 455 | +[type="checkbox"]:disabled + label, [type="radio"]:disabled + label { | |
| 456 | +color:black; | |
| 457 | +opacity:.5; | |
| 458 | +} | |
| 459 | +[type="checkbox"]:checked:focus + label:before, [type="checkbox"]:not(:checked):focus + label:before, [type="radio"]:checked:focus + label:before, [type="radio"]:not(:checked):focus + label:before { | |
| 460 | +border:1px dotted blue; | |
| 461 | +} | |
| 462 | +label:hover:before { | |
| 463 | +border:1px solid #4778d9!important; | |
| 464 | +} | |
| 465 | +hr { | |
| 466 | +size:100%; | |
| 467 | +border:0; | |
| 468 | +height:2px; | |
| 469 | +background-image:linear-gradient(to right,rgba(0,0,0,0),rgba(16,32,175,1),rgba(0,0,0,0)); | |
| 470 | +} | |
| 471 | +.highlight { | |
| 472 | +color:red; | |
| 473 | +text-transform:uppercase; | |
| 474 | +font-weight:bold; | |
| 475 | +} | |
| 476 | +div.pages { | |
| 477 | +position:fixed; | |
| 478 | +top:132; | |
| 479 | +right:15; | |
| 480 | +height:30; | |
| 481 | +padding:0px 5px; | |
| 482 | +background-color:white; | |
| 483 | +border:1px solid #80a0e0; | |
| 484 | +border-radius:30px; | |
| 485 | +} | |
| 486 | +td.pages { | |
| 487 | +color:darkblue; | |
| 488 | +vertical-align:middle; | |
| 489 | +height:24px; | |
| 490 | +min-width:12px; | |
| 491 | +font-weight:bold; | |
| 492 | +text-align:center; | |
| 493 | +} | |
| 494 | +td.actualpage { | |
| 495 | +color:white; | |
| 496 | +text-shadow:0px 0px 4px black; | |
| 497 | +} | |
| 498 | +td.pages a { | |
| 499 | +height:24px; | |
| 500 | +min-width:12px; | |
| 501 | +width:100%; | |
| 502 | +vertical-align:middle; | |
| 503 | +text-decoration:none; | |
| 504 | +} | |
| 505 | +div.submit { | |
| 506 | +position:fixed; | |
| 507 | +top:132; | |
| 508 | +left:165; | |
| 509 | +height:30; | |
| 510 | +padding:0px 20px; | |
| 511 | +} | |
| 512 | +a.new { | |
| 513 | +background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAABX1BMVEUAAAAMNBgAnzEBAAAAky8AuzIBAAAAvjEAdjIAsTEApzIArDAAqjAAty4AhSoAcTQAai4AqzAAyCoAvS8Amy8AaC0AwDEAnDEAhzIAwi4Ady8AuzMAxyoAYS8AUBUAZR4AxS4AhzUAtzMAajAAjTcAYS8AlS4BAAAAZTIDBgEAAAAAoTMAvi0ApjEAtTMAxi0AyCoAjywAvSwAszQAcS4Aci4AmjAAnjEAky0AnjMAqjQApi0AuTAAli4AqTIAgzEAgzAArTEAnjAAmDMArDQAlzMAqzUAZRkAaxoAbhoAYx4BSxYBTBgAsDMAxysAxisArjQBAAAAky4BAAABAAAAdzQBAAAAfDYAnTAAjSsAySoAvDEAwTAAkCwAojEAmi8AlC4AsjIAujMAqTMAxS4AxywAvjEAnzAAly4AtzMAwy8ArTMAmC8AwSsAiioAtTMApTEAky0AhCwAfiwAiSp827BQAAAAWHRSTlMABN1F8RIyMBIN/vLy8Eoy+Pfj397X0tLCwsHAsKWhgnd2dnVdWkUwFxEJ+Pj39fX19PHw8O/u5+fj4uLe3dbT0tG/sK+lpJSSkIF8amFgYFpKQjs1MCAXHLGCHQAAAV5JREFUKM+FklVzwzAQhNNAw9wwM5SZmZnbpHYVO7bjxHYb/P/Tk+Nxk5f2e9m7XWlO0kjzDxPmu6iH4zzRe/PEqG9ILnwozCcNv74xxHLc0OdYIWRUfT8pQPIFsKxAkn4lMUQaJMmyM/HLi/Ml8BtExCDPTdeJRoMU7M/lcslLkgRRb6XxCcxzrToBkX0SFnkJ7LeX8ZZbmm7jSA526mDTNP0AwYlI026b1bpdgODQarO5aVE8g2CLES3xR51OV4LmBfSaYZg9qC0MgxKgKvkOY5kFRajDJ0bfwYE6aBp0E6HK1VjAIxQAPeZ5fk2r1QbeoDmCYp2vVE6hzlaG6PFxp5Qmiy+orwFqUMPoTfhJUpTUbEqSvgDNrtQEqJQ80xTsUsDizVPesUFRXaobfNfIvB5UPzFVRfadGgVnuFdV6YWxr1DMrPQH38Cgv5opjn0GUy7mc7l8sZwJ5v7JD9pHX8JdXH+sAAAAAElFTkSuQmCC) no-repeat center left; | |
| 514 | +display:table; | |
| 515 | +padding:0px 10px 5px 30px; | |
| 516 | +line-height:25px; | |
| 517 | +height:25px; | |
| 518 | +color:darkred; | |
| 519 | +font-weight:bold; | |
| 520 | +text-decoration:none; | |
| 521 | +} | |
| 522 | +input[disabled], select[disabled], textarea[disabled] { | |
| 523 | +opacity:.5; | |
| 524 | +} | |
| 525 | +div.shadow { | |
| 526 | +display:none; | |
| 527 | +position:absolute; | |
| 528 | +top:0px; | |
| 529 | +background-color:white; | |
| 530 | +background-image:url(data:image/gif;base64,R0lGODlhVgAiAOfEAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQsLCwwMDA0NDQ4ODhAQEBERERISEhMTExQUFBUVFRYWFhcXFxoaGhsbGxwcHB4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJigoKCkpKS4uLi8vLzExMTY2Njg4ODk5OTs7Oz09PUBAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISEpKSktLS0xMTE1NTU5OTlBQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVtbW11dXV9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2lpaWpqamtra2xsbG1tbW9vb3BwcHFxcXJycnNzc3R0dHZ2dnd3d3h4eHl5eXx8fH19fX5+fn9/f4CAgIODg4SEhIWFhYaGhoqKipCQkJOTk5SUlJWVlZaWlpiYmJmZmZqampubm56enp+fn6CgoKGhoaOjo6SkpKampqenp6mpqaqqqqurq6ysrK2tra6urq+vr7GxsbKysrS0tLW1tbe3t7m5ubq6uru7u7y8vL6+vr+/v8DAwMLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy83Nzc7Ozs/Pz9HR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb293d3d7e3t/f3+Hh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6+vv7+/z8/P39/f///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCAD/ACwAAAAAVgAiAAAI/gCJCRxIsOBAJ1QSKlzIsKHDhxAVOjFIsaJFgwAyatzIsaPHjyA5XhxJciCABSgZoFzJUiXLli9jyowJoKTNkoNMVcxZUdCpioF+Ugx6s2hJ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); | |
| 531 | +background-repeat:no-repeat; | |
| 532 | +background-attachment:fixed; | |
| 533 | +background-position:center; | |
| 534 | +opacity:.6; | |
| 535 | +width:100%; | |
| 536 | +height:100%; | |
| 537 | +} | |
| 538 | +div.errorbox { | |
| 539 | +position:fixed; | |
| 540 | +top:30%; | |
| 541 | +left:30%; | |
| 542 | +right:30%; | |
| 543 | +max-height:40%; | |
| 544 | +padding:5px 10px; | |
| 545 | +background-color:darkred; | |
| 546 | +color:white; | |
| 547 | +box-shadow:3px 3px 10px black; | |
| 548 | +border-radius:5px; | |
| 549 | +overflow:auto; | |
| 550 | +} | |
| 551 | +div.errshadow { | |
| 552 | +position:fixed; | |
| 553 | +top:0px; | |
| 554 | +left:0px; | |
| 555 | +background-color:black; | |
| 556 | +opacity:.7; | |
| 557 | +width:100%; | |
| 558 | +height:100%; | |
| 559 | +} | |
| 560 | +td.close { | |
| 561 | +height:24px; | |
| 562 | +width:40px; | |
| 563 | +text-align:center; | |
| 564 | +vertical-align:middle; | |
| 565 | +background-color:white; | |
| 566 | +color:black; | |
| 567 | +font-size:14px; | |
| 568 | +font-weight:bold; | |
| 569 | +cursor:pointer; | |
| 570 | +} | |
| 571 | +div.pwc{ | |
| 572 | +position:relative; | |
| 573 | +font-weight:normal; | |
| 574 | +top:10; | |
| 575 | +font-size:10px; | |
| 576 | +color:red; | |
| 577 | +} | ... | ... |
static/default.js
0 → 100755
| 1 | +var link=document.createElement('link'); | |
| 2 | +link.type='image/png'; | |
| 3 | +link.rel='shortcut icon'; | |
| 4 | +link.href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAC+lBMVEUAAACKyO6Yw9MeGC5glcltBAY/aaSCmLs4XZhloc9OAQE0Tn5EVX8hBQ0mUZREbqo6YZaBpdJcBgpxAAAlOmgyUIRqmb07AAA3AwRQZZ3b8vtqAgMzX5UsbbcrW6M/XV+EAACfAAFQfrZGAAA2BwtkodM5WpqJAQJuocqOweDa6e9rkKIaP4BTe7Xr+f1xlK09WZbn9/iz0eQ8XoDT5uR5pqoyUZI6VHF6t+i12e5zr9aQn8FdgYcuYqdkZmo/GhiavLcnQHKlscpamM0PIVcFFEYLG0tRXVQFCzMfS5MPMnM9fMgfP3ckSIQPL2sYKFYtX6YcMWK7AQItWJsqUI81VYguSHp5CAuhAgMsZrUZRIwwUYAlOWYJKGURKV/i5ckJHlNKV051hqolWKU/aKFAXI4YQYM9THNBUUQDCz0qSByZBAZums6Rp8fG2cBYgbA4aKtTYogsSoYSN3cZN20CBCkwSyYlRBisAwRBbrAKI1tNVUcyFyqQAwXIAADx89jl69fT48g4dcAhUp1zhIUSOHwvO1giJEY9KkMLEzphFxtNCQl+qtttlMJUhL1OfbdLdKxObp5FaJUzV5BGZDY0VCNOFyCS2Pjm9PdDerg6bbfO2629y6tkfKUqPW09UzKEBgjR6PNfrO309ufm8OdWmeFUjMvU2r2xw5sxRjg/DxwrThqo2feDy/bI5e6ryeZEhNNjhbi80rVljK640I+WtIJkd3csSHGLqWvPAAC42+WFuOSy1dOtyKuhwZhkd5ZcbZJMSmNpb19+q1xbY0BpMT1SJzQgEy4+XCnN8f254/RwufFzruSa099intsvbsBTd6J3ipBwf1WAIShxHiEcCSCKERX2/f6WxemlvNmCwM3d4bjB1p+ElZqouotdfYqsyYl2nnNValtNbTxSMyHU6NpvotCX0r13sbyUnZWhxG5FNlFBSzZ8xdxKkNmhv7WcqKx+tZuGh5FrfX+Fs3ccNhFRdZOPkYJ6f2krPSIiPhtxmFsmNxWjIiSCxoH+AAAARXRSTlMAChsN/v5Q/v4t2yn9HOF2G/3957eLaVw9+/XKxZWR+/Lxvrl5Sj3eknl28fDgzMOvqadsP/vy5+Ti2dfWzrCmpFfqxo7R0+pFAAAJw0lEQVRYw+ySV0xTYRzFFdE6MO6Bmrh33HtEjUnrpQiVirRqV6q1aTqwVZJK6HJQrAVXYittSQel1XRAR+ymUoF0aiwbgpDIEEWCIb4YEy8YE9zj2fN0X87vnnP+35j/+o3GjugfrQnb123ZuADUxo1b1m1PGPt39oR1W6SNjdIFKlcoGBz+2rN17Z8zErYf0ukY/FJQKpdJqgoukDaqDIY9ayf9EWLsyq16h0UuF+gEXS6XwWUyGYxul9kdczftXjvp9/7pa3Z7fPaOjvZ2uUAVDAYZDE/UrS2jiRPLY2733rm/C7FqWSTqZTAEer1db7F4TSa9XMAYaIrQaLTLqU1u8d41Cb/0T9jgNnj0DD5P1tZhd7TrLR65nCG321vC4ptn7nfTirKLlv2qxlyI2BD0yks1PLzM5nB4LRaHz2LxDLTsaAmnnmFlni26lXZu0ZSf/x9iVklL+fjPgEDngC8Q8Fl89h5JYm9YrU1Jv1uReOsoYfb0n/WnzzA3SjV8eTueh2/r6Ot45fUyBN6hzsEWtdooEUOsheCWmQTMgXE/3j9ZMcOkkmp4rXwer9XWZ7PrBQJBF2NAon57JY00w9xMpxfSaBVZ0MVzfghY1syC0MwaDZ8v0/NaZTJbR5uAz+hyhdWX4DhmUomCTi+5XVh28xYCs2vCD/zTFEQSpNmk4evwch2Px5f12QSlDJ9HnVpIzMBlMSuZZHLGuaLilDRMFm7R98eckpycSZeqTOCGeFkrvlXWNuxvD/SmVnggGNzpDEwSLhd76vyxlHQEIjdp7neAzaRjM1Rmc0jK0+E14IY2OV7QZh/q1d4l0hXpR3FQKAUKg586cwqeDlyHpe2f9O0FdmYWNdO6mwwmPujXtMoYOq/PHug30vyVRBL84iMMDEohXLtyHA6DATnQi+vnfhuAlXLpUrHYHFIx9Hgdnt8VcvX3t3QaJXQ6kUnOQJDJMAoFei3lAgwAcnKuX7Ru+nqFSftYE7NPFovFTSGPQ4fXdUkMxnBY4ouGQICfmQFDIKAgAH4OS8kBBaQ/W7/yK8A6IgvSXPy0vFzbJBmy4dujEXEsEjFGJaFmiMJfSUYQYBQQkH6BAIwAcs/uWDvaP24rkZVMP1OcWq5Vh3scMkckFjNKjP3RqMRgBiP4/eSRBNhhwHUAAAh3ew+N7jBlH5GkuHXy8jBAPRjo+9CiNvb0FF663z3YK04sJBKJlRjECCAXyAEAGAybad00+g4TDtMhyVdOpoIVtNrEJy+fdEp6hjof52dmvr+TOPjitkLhTxLW1wPYayDguhBDuHDuzv4Jo18hseJ2Wsr5y2Xlb99qy+qQoueBvsARJYoZ6Y5lW7Ot1lg2Jo/NAbDw4QTCEkza0UeLt33pP3/evANEIrMkK4mcXMFk3iyLO0WPrz7vrHp5z5p9h5VFZpJOnGXmP0SiAWw6Flpfn19Qm4/LeHBw/vx580H/itVLligLKuPUmRw0SkRFV9+MOzkoaryqSokiFXBmotgNr5OqqRwUF11PyYULUUoRBz1TKEShl8yiLh83ZupC7qzJM/PefQRdSK6ygdtAijvZcSqyugqJJtc40Sg2t/o1G1mndKLra2uFQipXieKya+9xly5c6lw4FUywdOmS8TX+Bq4on4OsKWBTyXXO+Ltqjug1G/24Bjn+jYhb9xLJIRcg0Xk3xt/IoyIf1qKReSLkwhWrucOAT+2XW2zSYBTHpw5FVKbOqYk675dEjSYm+mSM0RZb2lJWCpQCGaEgMg0IhA2KPnAbDMcdEpY4fFoCe3ExAX0yW+bc2+aivi1LNmOyuJhFM+8Pfmg0unh98M1/0qYv/985p+33nfNt2i1q7HgcFly9d/lGS+RZR9tg153HL+4JyhG12jDSERvuann4pKONH2lRR/JdZQDwdV5p8eVb9p/af1W0pm7N7p2NIrWqM9Z274VAHRm8IRjMd6geq1XgURXOA8DDtofDqisqVcuVwUyvvPNKh69T1fbIJ7ghaAMAkMGWxsZYpNdXjqwu58Pn8+VqJO/LC0bG747kVz/ryg8/iT0Z4rvWx2KxtyxCRMux+zC4On2i3Y1qAKhbtmbz5g04RbNOSqGgSIpiSIokOf9NKSf03JoYnhl1W0dHi0Xrhw8LJRaFotFzEAzDvvUi0Q4B+Aqf1CREEEporIlhxsbG/FKp9LmUYfzvZ7LZbK6/vR3crO0Lb0sY6oUhCDoXvV+OrReINtV91jEhpdHYBzykkWTG/GMMU19gpIBiu53LjuZy/f1Wa3u7272w8O5dKYyhetk5yLV1z55Nm5d97WikGRm4lCQ9wOVnSKOdDBhJuzE+kR2dmemvAdzFfjdgvC2VtrNge4Cd25Z8uxqPJAJkvNsY8AC/xx4IIIgGSLFiYiY7k63FB7K63UXeIJFYwnAUhsXf72kHuj099fEE2dc3xlCIBvjNISeqoyY/VQDMNcA76xzPA4AsGpXpT678vquuS/TUP/X3+KXgG4RCmoAm5CQInbfwBgBybmsuB2pwuy28xWCo6qOw7NB3FYAadg144n098b6LPQEFnkEQxBxCdV4odHBiNJsFuWeLEr4E8jcYwi49LOsVL+5NTZ6khylclEoLdkrBAQDuwFohCMZfv5mYthaL09MSUH9NVUIm12YWJQBSEHu6mUJ3D0OSiFljNjtREAgAnOdfvh4qFi28gZdM1/zbWb1c6xDvrVuspuOJi4WL9cYAogk5nCim8+pb4VaCaJVdnn0zzM/NWYDbIDGcx1wyOQ4SWKy1Yipxbd26uF2jyWAo4cQIbyuM6sA/p52fHZorWSw8eAH8dpyAIWzrj8ac04cUie54ITGQNOMoihIunZdwQRfOQdr510MWS4k3ALFmHcjr0PK6H+kspkja7XaSslHmUAgldK5aS4Xg8PysxFJTKYwAv54INfx41lsG1iRHAQTFcbizVoXLW63qW8/PTwYrlcr0tIU1Yy6zJtD8s1lxzYaMrdtmSwoVjlSKxpVKmlWycvnd2ckHD4IvK5VXybRJETBu+/mkuGrD5etpjssoHBhuSqXGx8dNvdrq1ORksAZIK1y9LEfW/L8grFambUKHEsMzNJ0aT4HBhAbhg8HKVFop18rpww1Lfz0pN51gbTZaibEs5qLTNKbX3q35py5n5DI5hm9dvuR3s/rpDcIk5zApq5iSNtG0i52qBB+8EuJymVIhbv79tA7KOLY1yaXTyl6lKZ1KmYRTlZfjdlwmR8XNX8L/FtGwi8vQgMDSptT1yeD1QiHBnWxevrbuj7V2X8NRsYOlaVpoW3Grr/7Mgb3gtPJ3WrZ23/KGpqbm5oaNe1eC49J//UN9BEKHcc0j8sAbAAAAAElFTkSuQmCC'; | |
| 5 | +document.getElementsByTagName('head')[0].appendChild(link); | |
| 6 | +var actual=document.URL; | |
| 7 | +var previous=''; | |
| 8 | +if(actual.search('/record.php')>0||actual.search('/newzone.php')>0){ | |
| 9 | + previous='zonelist.php'; | |
| 10 | +}else if(actual.search('/slave_record.php')>0||actual.search('/slave_newzone.php')>0){ | |
| 11 | + previous='slave_zonelist.php'; | |
| 12 | +}else if(actual.search('/upload.php')>0||actual.search('/chpass.php')>0||actual.search('/options.php')>0){ | |
| 13 | + previous='../'; | |
| 14 | +}else if(actual.search('/convert.php')>0){ | |
| 15 | + previous='upload.php'; | |
| 16 | +}else if(actual.search('/user.php')>0||actual.search('/newuser.php')>0){ | |
| 17 | + previous='userlist.php'; | |
| 18 | +} | |
| 19 | +var md5 = function (string) { | |
| 20 | + | |
| 21 | + function RotateLeft(lValue, iShiftBits) { | |
| 22 | + return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits)); | |
| 23 | + } | |
| 24 | + | |
| 25 | + function AddUnsigned(lX,lY) { | |
| 26 | + var lX4,lY4,lX8,lY8,lResult; | |
| 27 | + lX8 = (lX & 0x80000000); | |
| 28 | + lY8 = (lY & 0x80000000); | |
| 29 | + lX4 = (lX & 0x40000000); | |
| 30 | + lY4 = (lY & 0x40000000); | |
| 31 | + lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF); | |
| 32 | + if (lX4 & lY4) { | |
| 33 | + return (lResult ^ 0x80000000 ^ lX8 ^ lY8); | |
| 34 | + } | |
| 35 | + if (lX4 | lY4) { | |
| 36 | + if (lResult & 0x40000000) { | |
| 37 | + return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); | |
| 38 | + } else { | |
| 39 | + return (lResult ^ 0x40000000 ^ lX8 ^ lY8); | |
| 40 | + } | |
| 41 | + } else { | |
| 42 | + return (lResult ^ lX8 ^ lY8); | |
| 43 | + } | |
| 44 | + } | |
| 45 | + | |
| 46 | + function F(x,y,z) { return (x & y) | ((~x) & z); } | |
| 47 | + function G(x,y,z) { return (x & z) | (y & (~z)); } | |
| 48 | + function H(x,y,z) { return (x ^ y ^ z); } | |
| 49 | + function I(x,y,z) { return (y ^ (x | (~z))); } | |
| 50 | + | |
| 51 | + function FF(a,b,c,d,x,s,ac) { | |
| 52 | + a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac)); | |
| 53 | + return AddUnsigned(RotateLeft(a, s), b); | |
| 54 | + }; | |
| 55 | + | |
| 56 | + function GG(a,b,c,d,x,s,ac) { | |
| 57 | + a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac)); | |
| 58 | + return AddUnsigned(RotateLeft(a, s), b); | |
| 59 | + }; | |
| 60 | + | |
| 61 | + function HH(a,b,c,d,x,s,ac) { | |
| 62 | + a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac)); | |
| 63 | + return AddUnsigned(RotateLeft(a, s), b); | |
| 64 | + }; | |
| 65 | + | |
| 66 | + function II(a,b,c,d,x,s,ac) { | |
| 67 | + a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac)); | |
| 68 | + return AddUnsigned(RotateLeft(a, s), b); | |
| 69 | + }; | |
| 70 | + | |
| 71 | + function ConvertToWordArray(string) { | |
| 72 | + var lWordCount; | |
| 73 | + var lMessageLength = string.length; | |
| 74 | + var lNumberOfWords_temp1=lMessageLength + 8; | |
| 75 | + var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64; | |
| 76 | + var lNumberOfWords = (lNumberOfWords_temp2+1)*16; | |
| 77 | + var lWordArray=Array(lNumberOfWords-1); | |
| 78 | + var lBytePosition = 0; | |
| 79 | + var lByteCount = 0; | |
| 80 | + while ( lByteCount < lMessageLength ) { | |
| 81 | + lWordCount = (lByteCount-(lByteCount % 4))/4; | |
| 82 | + lBytePosition = (lByteCount % 4)*8; | |
| 83 | + lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition)); | |
| 84 | + lByteCount++; | |
| 85 | + } | |
| 86 | + lWordCount = (lByteCount-(lByteCount % 4))/4; | |
| 87 | + lBytePosition = (lByteCount % 4)*8; | |
| 88 | + lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition); | |
| 89 | + lWordArray[lNumberOfWords-2] = lMessageLength<<3; | |
| 90 | + lWordArray[lNumberOfWords-1] = lMessageLength>>>29; | |
| 91 | + return lWordArray; | |
| 92 | + }; | |
| 93 | + | |
| 94 | + function WordToHex(lValue) { | |
| 95 | + var WordToHexValue="",WordToHexValue_temp="",lByte,lCount; | |
| 96 | + for (lCount = 0;lCount<=3;lCount++) { | |
| 97 | + lByte = (lValue>>>(lCount*8)) & 255; | |
| 98 | + WordToHexValue_temp = "0" + lByte.toString(16); | |
| 99 | + WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2); | |
| 100 | + } | |
| 101 | + return WordToHexValue; | |
| 102 | + }; | |
| 103 | + | |
| 104 | + function Utf8Encode(string) { | |
| 105 | + string = string.replace(/\r\n/g,"\n"); | |
| 106 | + var utftext = ""; | |
| 107 | + for (var n = 0; n < string.length; n++) { | |
| 108 | + var c = string.charCodeAt(n); | |
| 109 | + | |
| 110 | + if (c < 128) { | |
| 111 | + utftext += String.fromCharCode(c); | |
| 112 | + } | |
| 113 | + else if((c > 127) && (c < 2048)) { | |
| 114 | + utftext += String.fromCharCode((c >> 6) | 192); | |
| 115 | + utftext += String.fromCharCode((c & 63) | 128); | |
| 116 | + } | |
| 117 | + else { | |
| 118 | + utftext += String.fromCharCode((c >> 12) | 224); | |
| 119 | + utftext += String.fromCharCode(((c >> 6) & 63) | 128); | |
| 120 | + utftext += String.fromCharCode((c & 63) | 128); | |
| 121 | + } | |
| 122 | + } | |
| 123 | + return utftext; | |
| 124 | + }; | |
| 125 | + var x=Array(); | |
| 126 | + var k,AA,BB,CC,DD,a,b,c,d; | |
| 127 | + var S11=7, S12=12, S13=17, S14=22; | |
| 128 | + var S21=5, S22=9 , S23=14, S24=20; | |
| 129 | + var S31=4, S32=11, S33=16, S34=23; | |
| 130 | + var S41=6, S42=10, S43=15, S44=21; | |
| 131 | + string = Utf8Encode(string); | |
| 132 | + x = ConvertToWordArray(string); | |
| 133 | + a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476; | |
| 134 | + for (k=0;k<x.length;k+=16) { | |
| 135 | + AA=a; BB=b; CC=c; DD=d; | |
| 136 | + a=FF(a,b,c,d,x[k+0], S11,0xD76AA478); | |
| 137 | + d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756); | |
| 138 | + c=FF(c,d,a,b,x[k+2], S13,0x242070DB); | |
| 139 | + b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE); | |
| 140 | + a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF); | |
| 141 | + d=FF(d,a,b,c,x[k+5], S12,0x4787C62A); | |
| 142 | + c=FF(c,d,a,b,x[k+6], S13,0xA8304613); | |
| 143 | + b=FF(b,c,d,a,x[k+7], S14,0xFD469501); | |
| 144 | + a=FF(a,b,c,d,x[k+8], S11,0x698098D8); | |
| 145 | + d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF); | |
| 146 | + c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1); | |
| 147 | + b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE); | |
| 148 | + a=FF(a,b,c,d,x[k+12],S11,0x6B901122); | |
| 149 | + d=FF(d,a,b,c,x[k+13],S12,0xFD987193); | |
| 150 | + c=FF(c,d,a,b,x[k+14],S13,0xA679438E); | |
| 151 | + b=FF(b,c,d,a,x[k+15],S14,0x49B40821); | |
| 152 | + a=GG(a,b,c,d,x[k+1], S21,0xF61E2562); | |
| 153 | + d=GG(d,a,b,c,x[k+6], S22,0xC040B340); | |
| 154 | + c=GG(c,d,a,b,x[k+11],S23,0x265E5A51); | |
| 155 | + b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA); | |
| 156 | + a=GG(a,b,c,d,x[k+5], S21,0xD62F105D); | |
| 157 | + d=GG(d,a,b,c,x[k+10],S22,0x2441453); | |
| 158 | + c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681); | |
| 159 | + b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8); | |
| 160 | + a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6); | |
| 161 | + d=GG(d,a,b,c,x[k+14],S22,0xC33707D6); | |
| 162 | + c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87); | |
| 163 | + b=GG(b,c,d,a,x[k+8], S24,0x455A14ED); | |
| 164 | + a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905); | |
| 165 | + d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8); | |
| 166 | + c=GG(c,d,a,b,x[k+7], S23,0x676F02D9); | |
| 167 | + b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A); | |
| 168 | + a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942); | |
| 169 | + d=HH(d,a,b,c,x[k+8], S32,0x8771F681); | |
| 170 | + c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122); | |
| 171 | + b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C); | |
| 172 | + a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44); | |
| 173 | + d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9); | |
| 174 | + c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60); | |
| 175 | + b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70); | |
| 176 | + a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6); | |
| 177 | + d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA); | |
| 178 | + c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085); | |
| 179 | + b=HH(b,c,d,a,x[k+6], S34,0x4881D05); | |
| 180 | + a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039); | |
| 181 | + d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5); | |
| 182 | + c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8); | |
| 183 | + b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665); | |
| 184 | + a=II(a,b,c,d,x[k+0], S41,0xF4292244); | |
| 185 | + d=II(d,a,b,c,x[k+7], S42,0x432AFF97); | |
| 186 | + c=II(c,d,a,b,x[k+14],S43,0xAB9423A7); | |
| 187 | + b=II(b,c,d,a,x[k+5], S44,0xFC93A039); | |
| 188 | + a=II(a,b,c,d,x[k+12],S41,0x655B59C3); | |
| 189 | + d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92); | |
| 190 | + c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D); | |
| 191 | + b=II(b,c,d,a,x[k+1], S44,0x85845DD1); | |
| 192 | + a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F); | |
| 193 | + d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0); | |
| 194 | + c=II(c,d,a,b,x[k+6], S43,0xA3014314); | |
| 195 | + b=II(b,c,d,a,x[k+13],S44,0x4E0811A1); | |
| 196 | + a=II(a,b,c,d,x[k+4], S41,0xF7537E82); | |
| 197 | + d=II(d,a,b,c,x[k+11],S42,0xBD3AF235); | |
| 198 | + c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB); | |
| 199 | + b=II(b,c,d,a,x[k+9], S44,0xEB86D391); | |
| 200 | + a=AddUnsigned(a,AA); | |
| 201 | + b=AddUnsigned(b,BB); | |
| 202 | + c=AddUnsigned(c,CC); | |
| 203 | + d=AddUnsigned(d,DD); | |
| 204 | + } | |
| 205 | + var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d); | |
| 206 | + return temp.toLowerCase(); | |
| 207 | +} | |
| 208 | + | |
| 209 | +function passwordMD5(fromid,toid){ | |
| 210 | + if (document.getElementById(fromid).value.length>0){ | |
| 211 | + document.getElementById(toid).value=md5(document.getElementById(fromid).value); | |
| 212 | + }else{ | |
| 213 | + document.getElementById(toid).value="#"; | |
| 214 | + } | |
| 215 | +} | |
| 216 | + | |
| 217 | +function passwordChanged(fromid,toid) { | |
| 218 | + var strength = document.getElementById('pwmeter'); | |
| 219 | + var hardRegex = new RegExp(/^(?=.{10,})(?=.*[A-Z].*[A-Z])(?=.*[a-z])(?=.*[0-9].*[0-9])(?=.*\W).*$/g); | |
| 220 | + var fairRegex = new RegExp(/^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\W).*$/g); | |
| 221 | + var mediRegex = new RegExp(/^(?=.{6,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$/g); | |
| 222 | + var weakRegex = new RegExp(/(?=.{4,}).*/g); | |
| 223 | + var pwd = document.getElementById(fromid); | |
| 224 | + var pwto = document.getElementById(toid); | |
| 225 | + if (pwd.value.length==0) { | |
| 226 | + strength.className='nok'; | |
| 227 | + pwto.disabled=true; | |
| 228 | + } else if (false == weakRegex.test(pwd.value)) { | |
| 229 | + strength.className='bad'; | |
| 230 | + pwto.disabled=true; | |
| 231 | + } else if (hardRegex.test(pwd.value)) { | |
| 232 | + strength.className='perfect'; | |
| 233 | + pwto.disabled=false; | |
| 234 | + } else if (fairRegex.test(pwd.value)) { | |
| 235 | + strength.className='enough'; | |
| 236 | + pwto.disabled=false; | |
| 237 | + } else if (mediRegex.test(pwd.value)) { | |
| 238 | + strength.className='almost'; | |
| 239 | + pwto.disabled=true; | |
| 240 | + } else { | |
| 241 | + strength.className='notenough'; | |
| 242 | + pwto.disabled=true; | |
| 243 | + } | |
| 244 | + strength.setAttribute("tag", document.getElementById(strength.className).value); | |
| 245 | + strength.setAttribute("title", document.getElementById(strength.className).value); | |
| 246 | + document.getElementById("pwc").innerHTML=document.getElementById(strength.className).value; | |
| 247 | +} | |
| 248 | +window.addEventListener('load',function(){ | |
| 249 | + var tags=document.body.getElementsByTagName('*'); | |
| 250 | + for(var tg=0;tg<tags.length;tg++){ | |
| 251 | + var tag=tags[tg]; | |
| 252 | + if(tag.id=='reload'){ | |
| 253 | + (function myLoop(i){ | |
| 254 | + setTimeout(function(){ | |
| 255 | + --i; | |
| 256 | + document.getElementById('counter').className='attention'; | |
| 257 | + document.getElementById('counter').innerHTML=i; | |
| 258 | + if(i){myLoop(i)}else{location.href='../';}; | |
| 259 | + }, 1000) | |
| 260 | + })(10); | |
| 261 | + }else if(tag.id=='commitlink'){ | |
| 262 | + document.getElementById('commitlink').addEventListener('click',function(){ | |
| 263 | + document.getElementById('wait').style.display='block'; | |
| 264 | + }); | |
| 265 | + }else if(tag.id=='commitable'){ | |
| 266 | + var link=document.createElement('link'); | |
| 267 | + link.type='image/png'; | |
| 268 | + link.rel='shortcut icon'; | |
| 269 | + link.href='data:image/png;base64,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'; | |
| 270 | + document.getElementsByTagName('head')[0].appendChild(link); | |
| 271 | + }else if(tag.id.search('doitlink')>0){ | |
| 272 | + document.getElementById(tag.id).addEventListener('click',function(){ | |
| 273 | + document.getElementById('wait').style.display='block'; | |
| 274 | + }); | |
| 275 | + }else if(tag.id=='choose'){ | |
| 276 | + function disable(element){ | |
| 277 | + document.getElementById(element).disabled=true; | |
| 278 | + document.getElementById(element+'_domain').disabled=true; | |
| 279 | + } | |
| 280 | + function enable(element){ | |
| 281 | + document.getElementById(element).disabled=false; | |
| 282 | + document.getElementById(element+'_domain').disabled=false; | |
| 283 | + if(element=='sel'){ | |
| 284 | + document.getElementById(element).focus(); | |
| 285 | + }else{ | |
| 286 | + document.getElementById(element+'_domain').focus(); | |
| 287 | + } | |
| 288 | + } | |
| 289 | + document.getElementById('file').addEventListener('click',function(){ | |
| 290 | + disable('txt'); | |
| 291 | + disable('sel'); | |
| 292 | + enable('fil'); | |
| 293 | + }); | |
| 294 | + document.getElementById('text').addEventListener('click',function(){ | |
| 295 | + disable('fil'); | |
| 296 | + disable('sel'); | |
| 297 | + enable('txt'); | |
| 298 | + }); | |
| 299 | + document.getElementById('sel').addEventListener('change',function(){ | |
| 300 | + var selvalue=document.getElementById('sel').value; | |
| 301 | + if(selvalue=='- select file -'){ | |
| 302 | + selvalue=''; | |
| 303 | + } | |
| 304 | + document.getElementById('sel_domain').value=selvalue; | |
| 305 | + }); | |
| 306 | + document.getElementById('list').addEventListener('click',function(){ | |
| 307 | + disable('fil'); | |
| 308 | + disable('txt'); | |
| 309 | + enable('sel'); | |
| 310 | + }); | |
| 311 | + disable('fil'); | |
| 312 | + disable('txt'); | |
| 313 | + disable('sel'); | |
| 314 | + }else if(tag.id=='password'){ | |
| 315 | + document.getElementById('normal').addEventListener('submit', function(){ | |
| 316 | + passwordMD5('password', 'pwmd5'); | |
| 317 | + }); | |
| 318 | + window.addEventListener('keyup',function(keyevent){ | |
| 319 | + if(!keyevent)keyevent=event; | |
| 320 | + var code=keyevent.keyCode; | |
| 321 | + if(code==13){ | |
| 322 | + document.getElementById('submit').click(); | |
| 323 | + } | |
| 324 | + }); | |
| 325 | + }else if(tag.id=='pass1'){ | |
| 326 | + document.getElementById('new').addEventListener('submit', function(){ | |
| 327 | + passwordMD5('pass1', 'pwmd5n'); | |
| 328 | + }); | |
| 329 | + window.addEventListener('keyup',function(keyevent){ | |
| 330 | + if(!keyevent)keyevent=event; | |
| 331 | + var code=keyevent.keyCode; | |
| 332 | + if(code==13){ | |
| 333 | + document.getElementById('submit').click(); | |
| 334 | + } | |
| 335 | + passwordChanged('pass1','pass2'); | |
| 336 | + }); | |
| 337 | + }else if(tag.id=='pass_o'){ | |
| 338 | + document.getElementById('chg').addEventListener('submit', function(){ | |
| 339 | + passwordMD5('pass_n1', 'pwmd5n'); | |
| 340 | + passwordMD5('pass_o', 'pwmd5'); | |
| 341 | + }); | |
| 342 | + window.addEventListener('keyup',function(keyevent){ | |
| 343 | + if(!keyevent)keyevent=event; | |
| 344 | + var code=keyevent.keyCode; | |
| 345 | + if(code==13){ | |
| 346 | + document.getElementById('submit').click(); | |
| 347 | + } | |
| 348 | + passwordChanged('pass_n1','pass_n2'); | |
| 349 | + }); | |
| 350 | + }else if(tag.id=='pass2'){ | |
| 351 | + window.addEventListener('keyup',function(keyevent){ | |
| 352 | + if(!keyevent)keyevent=event; | |
| 353 | + var code=keyevent.keyCode; | |
| 354 | + if(code==13){ | |
| 355 | + document.getElementById('submit').click(); | |
| 356 | + } | |
| 357 | + alfa=document.getElementById('pass1').value; | |
| 358 | + beta=document.getElementById('pass2').value; | |
| 359 | + need=document.getElementById('notempty').value; | |
| 360 | + if(alfa==beta&&(need=='0'||beta.length>0)){ | |
| 361 | + document.getElementById('submit').disabled=false; | |
| 362 | + }else{ | |
| 363 | + document.getElementById('submit').disabled=true; | |
| 364 | + } | |
| 365 | + }); | |
| 366 | + }else if(tag.id=='pass_n2'){ | |
| 367 | + window.addEventListener('keyup',function(keyevent){ | |
| 368 | + if(!keyevent)keyevent=event; | |
| 369 | + var code=keyevent.keyCode; | |
| 370 | + if(code==13){ | |
| 371 | + document.getElementById('submit').click(); | |
| 372 | + } | |
| 373 | + alfa=document.getElementById('pass_n1').value; | |
| 374 | + beta=document.getElementById('pass_n2').value; | |
| 375 | + if(alfa==beta&&beta.length>0){ | |
| 376 | + document.getElementById('submit').disabled=false; | |
| 377 | + }else{ | |
| 378 | + document.getElementById('submit').disabled=true; | |
| 379 | + } | |
| 380 | + }); | |
| 381 | + }else if(tag.id=='nofile'){ | |
| 382 | + document.getElementById('list').disabled=true; | |
| 383 | + }else if(tag.id=='close'){ | |
| 384 | + document.getElementById('close').addEventListener('click',function(){ | |
| 385 | + document.getElementById('errorbox').style.display='none'; | |
| 386 | + document.getElementById('errshadow').style.display='none'; | |
| 387 | + }); | |
| 388 | + }else if(tag.id=='cancel'){ | |
| 389 | + window.addEventListener('keyup',function(keyevent){ | |
| 390 | + if(!keyevent)keyevent=event; | |
| 391 | + var code=keyevent.keyCode; | |
| 392 | + if(code==27){ | |
| 393 | + document.getElementById('cancel').click(); | |
| 394 | + } | |
| 395 | + }); | |
| 396 | + document.getElementById('cancel').addEventListener('click',function(){ | |
| 397 | + location.href=previous; | |
| 398 | + }); | |
| 399 | + }else if(tag.id=='prev'){ | |
| 400 | + window.addEventListener('keyup',function(keyevent){ | |
| 401 | + if(!keyevent)keyevent=event; | |
| 402 | + var code=keyevent.keyCode; | |
| 403 | + if(code==37&keyevent.ctrlKey){ | |
| 404 | + document.getElementById('prev').click(); | |
| 405 | + } | |
| 406 | + }); | |
| 407 | + }else if(tag.id=='next'){ | |
| 408 | + window.addEventListener('keyup',function(keyevent){ | |
| 409 | + if(!keyevent)keyevent=event; | |
| 410 | + var code=keyevent.keyCode; | |
| 411 | + if(code==39&keyevent.ctrlKey){ | |
| 412 | + document.getElementById('next').click(); | |
| 413 | + } | |
| 414 | + }); | |
| 415 | + }else if(tag.id=='first'){ | |
| 416 | + window.addEventListener('keyup',function(keyevent){ | |
| 417 | + if(!keyevent)keyevent=event; | |
| 418 | + var code=keyevent.keyCode; | |
| 419 | + if(code==38&keyevent.ctrlKey){ | |
| 420 | + document.getElementById('first').click(); | |
| 421 | + } | |
| 422 | + }); | |
| 423 | + }else if(tag.id=='last'){ | |
| 424 | + window.addEventListener('keyup',function(keyevent){ | |
| 425 | + if(!keyevent)keyevent=event; | |
| 426 | + var code=keyevent.keyCode; | |
| 427 | + if(code==40&keyevent.ctrlKey){ | |
| 428 | + document.getElementById('last').click(); | |
| 429 | + } | |
| 430 | + }); | |
| 431 | + }else if(tag.id=='new'){ | |
| 432 | + window.addEventListener('keyup',function(keyevent){ | |
| 433 | + if(!keyevent)keyevent=event; | |
| 434 | + var code=keyevent.keyCode; | |
| 435 | + if(code==45){ | |
| 436 | + document.getElementById('new').click(); | |
| 437 | + } | |
| 438 | + }); | |
| 439 | + } | |
| 440 | + } | |
| 441 | +}); | |
| 442 | +var RecaptchaOptions={theme:'white'}; | ... | ... |
templates/accessdenied.tpl
0 → 100644
| 1 | +<div class=clear><div class=main><p> | |
| 2 | +<h4>A general error has occurred.</h4> | |
| 3 | +<strong>Reason:</strong> | |
| 4 | +{if $reason}{$reason} | |
| 5 | +{else}Perhaps you are trying to view a page that you are not allowed to view, or that one of the filters has detected an injection attack. If you are seeing this message, there's a good chance we haven't written a decent error message yet. | |
| 6 | +{/if} | |
| 7 | +</p></div></div> | ... | ... |
templates/chpass.tpl
0 → 100644
| 1 | +<div class=clear><div class=main><h4>Edit your password:</h4> | |
| 2 | +<table width=580> | |
| 3 | +<tr> | |
| 4 | +<td width=120 align=right>Old password:</td> | |
| 5 | +<td> | |
| 6 | +<input class=form-field type=password name=password_oldx id=pass_o tabindex=1 autofocus></td> | |
| 7 | +<th width=180>Password quality meter<div class=pwc id=pwc>Cannot be empty!</div></th> | |
| 8 | +</tr> | |
| 9 | +<tr> | |
| 10 | +<td width=120 align=right>New password:</td> | |
| 11 | +<td><input class=form-field type=password name=pass1 id=pass_n1 tabindex=2 ></td> | |
| 12 | +<td rowspan=2 id=pwmeter class=nok width=180 title="Cannot be empty!" alt="Cannot be empty!"></tr> | |
| 13 | +<tr> | |
| 14 | +<td width=120 align=right>Confirm it:</td> | |
| 15 | +<td><input class=form-field type=password name=pass2 id=pass_n2 tabindex=3 disabled></td> | |
| 16 | +</tr> | |
| 17 | +</table> | |
| 18 | +<form name=chg id=chg method="post" action="{$src}savepass.php"><input type=hidden id=pwmd5 name=password_old><input type=hidden id=pwmd5n name=password_one> | |
| 19 | +<div class=submit><input class=submit-button type=submit name=Submit value="Save" id=submit tabindex=4 disabled> <input type=button class=submit-button id=cancel value="Cancel" name ="cancel"></div> | |
| 20 | +</form> | |
| 21 | +<input type=hidden name=bad id=bad value="The password is too short"> | |
| 22 | +<input type=hidden name=nok id=nok value="Cannot be empty!"> | |
| 23 | +<input type=hidden name=notenough id=notenough value="Need to be longer!"> | |
| 24 | +<input type=hidden name=almost id=almost value="Need to be complex and/or longer!"> | |
| 25 | +<input type=hidden name=enough id=enough value="Complexity is fair"> | |
| 26 | +<input type=hidden name=perfect id=perfect value="Complexity is perfect"> | |
| 27 | +</div></div> | ... | ... |
templates/commit.tpl
0 → 100644
templates/commitdone.tpl
0 → 100644
templates/deleteuser.tpl
0 → 100644
| 1 | +<div class=clear><div class=main><p>Please confirm that you wish to delete the user <strong>{$user.realname} ({$user.username}).</strong></p> | |
| 2 | +<p> | |
| 3 | +Any current zone ownership will reset to the main admin user. | |
| 4 | +</p> | |
| 5 | +<p> | |
| 6 | +<a class=attention href="{$src}userlist.php?i={$user.id}&delete=y">Yes</a> - <a href="{$src}userlist.php">No</a>. | |
| 7 | +</p></div></div> | ... | ... |
templates/deletezone.tpl
0 → 100644
| 1 | +<div class=clear><div class=main><p>Please confirm that you wish to delete the master zone <strong>{$zone}.</strong></p> | |
| 2 | +<p><br /> | |
| 3 | +All resource records associated with this zone will be deleted. | |
| 4 | +</p><p><a class=attention href="{$src}zonelist.php?i={$zoneid}&delete=y">Yes</a> - <a href="{$src}zonelist.php">No</a>. | |
| 5 | +</p></div></div> | ... | ... |
templates/footer.tpl
0 → 100644
| 1 | +<div class=footer>{$footerleft}<span class=copy>{$footerright}</span></div> | |
| 2 | +<div class=shadow id=wait></div>{if $popuperror}<div class=errshadow id=errshadow></div><div class=errorbox id=errorbox><p><strong>Error:</strong></p><p>{$popuperror}</p><table align=center><tr><td class=close id=close>Ok</td></tr></table><p></p></div>{/if} | |
| 3 | +</body> | |
| 4 | +</html> | ... | ... |
templates/header.tpl
0 → 100644
| 1 | +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> | |
| 2 | +<html> | |
| 3 | +<head> | |
| 4 | +<title>{$TITLE} - {$pagetitle}</title> | |
| 5 | +<meta http-equiv="Content-Language" content="en"> | |
| 6 | +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
| 7 | +<link rel="stylesheet" type=text/css href="{if $sdomain}//{$sdomain}{/if}{$static}{$skin}.css" /> | |
| 8 | +<script src="{if $sdomain}//{$sdomain}{/if}{$static}{$skin}.js"></script> | |
| 9 | +</head> | |
| 0 | 10 | \ No newline at end of file | ... | ... |
templates/login.tpl
0 → 100644
| 1 | +<div class=login><div class=loginform> | |
| 2 | +<h4>Enter your credentials:</h4> | |
| 3 | +<form method="post" name=login action="{if $action}{$action}{/if}" id=normal> | |
| 4 | +<table align=center width=400> | |
| 5 | +<tr> | |
| 6 | +<td align=right>Username:</td> | |
| 7 | +<td align=right><input class=form-field type=text name=username autofocus tabindex=1></td> | |
| 8 | +</tr> | |
| 9 | +</table> | |
| 10 | +<div class=loginend> | |
| 11 | +<table align=center width=400> | |
| 12 | +{if $recaptcha != "" } | |
| 13 | +<tr> | |
| 14 | +<td colspan=2><label for="recaptcha">Fill the captcha:</label></td> | |
| 15 | +</tr> | |
| 16 | +<tr> | |
| 17 | +<td align=center colspan=2 id=captchaload>{nocache}{$recaptcha}{/nocache}</td> | |
| 18 | +</tr> | |
| 19 | +{else} | |
| 20 | +<tr> | |
| 21 | +<td colspan=2><span class=whitelist>You're allowed without captcha:</span></td> | |
| 22 | +</tr> | |
| 23 | +<tr> | |
| 24 | +<td colspan=2 class=nocap><span class=disablestamp>don't need</span></td> | |
| 25 | +</tr> | |
| 26 | +{/if} | |
| 27 | +<tr> | |
| 28 | +<td colspan=2><hr /></td> | |
| 29 | +</tr> | |
| 30 | +<tr> | |
| 31 | +<td colspan=2 align=center><input type=hidden name=password id=pwmd5><input class=submit-button type=submit name=Submit value="Login" id=submit tabindex=3></td> | |
| 32 | +</tr> | |
| 33 | +</table></div></form> | |
| 34 | +<table align=center width=400> | |
| 35 | +<tr> | |
| 36 | +<td align=right>Password:</td> | |
| 37 | +<td align=right><input class=form-field type=password name=password_local id=password tabindex=2></td> | |
| 38 | +</tr> | |
| 39 | +</table> | |
| 40 | +</div> | |
| 41 | +</div> | ... | ... |
templates/logout.tpl
0 → 100644
templates/main.tpl
0 → 100644
| 1 | +{include file="header.tpl"}<body> | |
| 2 | +<div class=title>{$TITLE}</div> | |
| 3 | +<div class=section><p>{$pagetitle}</p></div>{include file="menu.tpl"}{include file=$template} | |
| 4 | +<div class=hint><p>{$help}</p></div> | |
| 5 | +{if $loggedinuser}<div class=loggeduser>Logged in as: <strong>{$loggedinuser}</strong></div>{/if}{include file="footer.tpl"} | ... | ... |
templates/mainpage.tpl
0 → 100644
| 1 | +<div class=clear><div class=main> | |
| 2 | +<p><strong>Welcome, {$user}.</strong> | |
| 3 | +{if $admin == "yes"} (You have administrator privileges){/if}</p> | |
| 4 | +{if $status == 0}DNS Service is <b>running</b>.{/if} | |
| 5 | +{if $status == 1}DNS Service is <b><span class=attention>stopped</span></b>.{/if} | |
| 6 | +<p>You maintain <strong>{$zones}</strong> master zone{if $zones > 1}s{/if} and <strong>{$slave_zones}</strong> slave zone{if $slave_zones > 1}s{/if}.</p> | |
| 7 | +{if $bad || $bad_slaves}<h4>Zones need to be check or modify</h4><p>{if $bad}Master: {section name=i loop=$bad}<a class=attention href="{$src}record.php?i={$bad[i].id}"><b>{$bad[i].name}</b></a> {/section}<br />{/if} | |
| 8 | +{if $bad_slaves}Slave: {section name=i loop=$bad_slaves}<a class=attention href="{$src}slave_record.php?i={$bad_slaves[i].id}"><b>{$bad_slaves[i].name}</b></a> {/section}{/if}</p>{/if} | |
| 9 | +{if $comm || $comm_slaves}<h4>Zones need to be commit</h4><p>{if $comm}Master: {section name=i loop=$comm}<a class=attention href="{$src}record.php?i={$comm[i].id}"><b>{$comm[i].name}</b></a> {/section}<br />{/if} | |
| 10 | +{if $comm_slaves}Slave: {section name=i loop=$comm_slaves}<a class=attention href="{$src}slave_record.php?i={$comm_slaves[i].id}"><b>{$comm_slaves[i].name}</b></a> {/section}{/if}</p>{/if} | |
| 11 | +{if $del || $del_slaves}<h4>Zones mark as deleted</h4><p>{if $del}Master: {section name=i loop=$del}<span class=deleted><span class=attention><b>{$del[i].name}</b></span></span> {/section}<br />{/if} | |
| 12 | +{if $del_slaves}Slave: {section name=i loop=$del_slaves}<span class=deleted><span class=attention><b>{$del_slaves[i].name}</b></span></span> {/section}{/if}</p>{/if} | |
| 13 | +</div></div> | ... | ... |
templates/menu.tpl
0 → 100644
| 1 | +{if $menu_button}<div class=menu> | |
| 2 | +<p class=tag>Menu</p> | |
| 3 | +{section name=i loop=$menu_button} | |
| 4 | +{if $menu_button[i].title == "Commit changes"} | |
| 5 | +{if $donotcommit == "yes"}<span class=disabled>{$menu_button[i].title}<br /></span> | |
| 6 | +{else}<a href="{$menu_button[i].link}">{$menu_button[i].title}</a><br /> | |
| 7 | +{/if} | |
| 8 | +{elseif $menu_button[i].link != $menu_current}<a href="{$menu_button[i].link}">{$menu_button[i].title}</a><br /> | |
| 9 | +{else}<span class=currmenu>{$menu_button[i].title}</span><br /> | |
| 10 | +{/if} | |
| 11 | +{/section} | |
| 12 | +</div> | |
| 13 | +{/if} | |
| 0 | 14 | \ No newline at end of file | ... | ... |
templates/newuser.tpl
0 → 100644
| 1 | +<div class=clear><div class=main><form name=form1 method="post" action="{$src}userlist.php" id=new> | |
| 2 | +<h4>Properties of the new user:</h4><div class=submit> | |
| 3 | +<input class=submit-button type=submit name=Submit value="Save" disabled id=submit tabindex=6> <input type=button class=submit-button id=cancel value="Cancel" name ="cancel" tabindex=8></div> | |
| 4 | +<table width=580> | |
| 5 | +<tr> | |
| 6 | +<td align=right width=120><strong>Username:</strong></td> | |
| 7 | +<td><input type=text name=username_ class=form-field autofocus tabindex=1></td> | |
| 8 | +</tr> | |
| 9 | +<tr> | |
| 10 | +<td align=right width=120><strong>Full name:</strong></td> | |
| 11 | +<td><input type=text name=realname class=form-field tabindex=2></td> | |
| 12 | +</tr> | |
| 13 | +<tr> | |
| 14 | +<td align=right width=120><strong>Admin rights:</strong></td> | |
| 15 | +<td height="30"> | |
| 16 | +<input type=radio name=admin id=adminy value="yes" tabindex=3 /><label for="adminy">yes</label> | |
| 17 | +<input type=radio name=admin id=adminn value="no" checked="checked" tabindex=3 /><label for="adminn">no</label> | |
| 18 | +<input type=hidden name=password_ id=pwmd5n> | |
| 19 | +</td> | |
| 20 | +</tr> | |
| 21 | +</table></form> | |
| 22 | +<table width=580> | |
| 23 | +<tr> | |
| 24 | +<td align=right width=120><strong>Password:</strong></td> | |
| 25 | +<td><input type=password name=password_one class=form-field id=pass1 tabindex=4></td> | |
| 26 | +<th width=180>Password quality meter<div class=pwc id=pwc>Cannot be empty!</div></th> | |
| 27 | +</tr> | |
| 28 | +<tr> | |
| 29 | +<td align=right width=120><strong>Confirm it:</strong></td> | |
| 30 | +<td><input type=password name=confirm_password class=form-field id=pass2 disabled tabindex=5></td> | |
| 31 | +<td rowspan=2 id=pwmeter class=nok width=180 title="Cannot be empty!" alt="Cannot be empty!"> | |
| 32 | +<input type=hidden name=bad id=bad value="The password is too short"> | |
| 33 | +<input type=hidden name=nok id=nok value="Cannot be empty!"> | |
| 34 | +<input type=hidden name=notenough id=notenough value="Need to be longer!"> | |
| 35 | +<input type=hidden name=almost id=almost value="Need to be complex and/or longer!"> | |
| 36 | +<input type=hidden name=enough id=enough value="Complexity is fair"> | |
| 37 | +<input type=hidden name=perfect id=perfect value="Complexity is perfect"> | |
| 38 | +<input type=hidden name=notempty id=notempty value=1> | |
| 39 | +</td> | |
| 40 | +</tr> | |
| 41 | +<tr> | |
| 42 | +<td colspan=2 height=30></td> | |
| 43 | +</tr> | |
| 44 | +</table> | |
| 45 | +</div></div> | ... | ... |
templates/newzone.tpl
0 → 100644
| 1 | +<form name=form1 method="post" action="{$src}zonelist.php"> | |
| 2 | +<div class=clear><div class=main><h4>Properties of the new master zone:</h4> | |
| 3 | +<table> | |
| 4 | +<tr> | |
| 5 | +<td align=right><strong>Zone:</strong></td> | |
| 6 | +<td><input type=text name=name class=form-field autofocus></td> | |
| 7 | +</tr> | |
| 8 | +<tr> | |
| 9 | +<td align=right><strong>Refresh:</strong></td> | |
| 10 | +<td><input type=text name=refresh class=form-field value="86400"></td> | |
| 11 | +</tr> | |
| 12 | +<tr> | |
| 13 | +<td align=right><strong>Retry:</strong></td> | |
| 14 | +<td><input type=text name=retry class=form-field value="7200"></td> | |
| 15 | +</tr> | |
| 16 | +<tr> | |
| 17 | +<td align=right><strong>Expire:</strong></td> | |
| 18 | +<td><input type=text name=expire class=form-field value="3600000"></td> | |
| 19 | +</tr> | |
| 20 | +<tr> | |
| 21 | +<td align=right><strong>Time To Live:</strong></td> | |
| 22 | +<td><input type=text name=ttl class=form-field value="300"></td> | |
| 23 | +</tr> | |
| 24 | +<tr> | |
| 25 | +<td align=right><strong>Primary NS:</strong></td> | |
| 26 | +<td><input type=text name=pri_dns class=form-field value="{$pri_dns}"></td> | |
| 27 | +</tr> | |
| 28 | +<tr> | |
| 29 | +<td align=right><strong>Secondary NS:</strong></td> | |
| 30 | +<td><input type=text name=sec_dns class=form-field value="{$sec_dns}"></td> | |
| 31 | +</tr> | |
| 32 | +<tr> | |
| 33 | +<td align=right><strong>Web Server:</strong></td> | |
| 34 | +<td><input type=text name=www class=form-field value=""></td> | |
| 35 | +</tr> | |
| 36 | +<tr> | |
| 37 | +<td align=right><strong>Mail Server:</strong></td> | |
| 38 | +<td><input type=text name=mail class=form-field value=""></td> | |
| 39 | +</tr> | |
| 40 | +<tr> | |
| 41 | +<td align=right><strong>FTP Server:</strong></td> | |
| 42 | +<td><input type=text name=ftp class=form-field value=""></td> | |
| 43 | +</tr> | |
| 44 | +<tr> | |
| 45 | +<td colspan=2><hr /></td> | |
| 46 | +</tr> | |
| 47 | +<tr> | |
| 48 | +<td align=right><strong>Owner: </strong></td> | |
| 49 | +<td><select name=owner class=form-field> | |
| 50 | +{section name=i loop=$userlist} | |
| 51 | +<option value="{$userlist[i].id}" {if $current_user == $userlist[i].id}selected{/if}>{$userlist[i].realname}</option> | |
| 52 | +{/section} | |
| 53 | +</select> | |
| 54 | +</td> | |
| 55 | +</tr> | |
| 56 | +</table></div></div> | |
| 57 | +<div class=submit><input class=submit-button type=submit name=Submit value="Add zone"> <input type=button class=submit-button id=cancel value="Cancel" name ="cancel"></div> | |
| 58 | +</form> | ... | ... |
templates/optionsread.tpl
0 → 100644
| 1 | +<form name=form1 method="post" action="{$src}options.php"> | |
| 2 | +<div class=clear><div class=main> | |
| 3 | +<h4>Record Types</h4> | |
| 4 | +<table style="min-width:600"> | |
| 5 | +{section name=x loop=$records} | |
| 6 | +<tr> | |
| 7 | +{section name=y loop=$records[x]} | |
| 8 | +<td> | |
| 9 | +<input type=checkbox id={$records[x][y].prefkey} name={$records[x][y].prefkey} {if $records[x][y].prefval == "on"}checked{/if} /> | |
| 10 | +<label for="{$records[x][y].prefkey}" name={$records[x][y].prefkey}_lbl>{$records[x][y].prefkey}</label> | |
| 11 | +</td> | |
| 12 | +{/section} | |
| 13 | +</tr> | |
| 14 | +{/section} | |
| 15 | +</table> | |
| 16 | +<table> | |
| 17 | +<tr><td colspan=2><hr /></td></tr> | |
| 18 | +{section name=prefkey loop=$options} | |
| 19 | +<tr> | |
| 20 | +<td align=right> | |
| 21 | +{if $options[prefkey].prefkey == "hostmaster"}Site Hostmaster Address:{/if} | |
| 22 | +{if $options[prefkey].prefkey == "range"}Items Per Page:{/if} | |
| 23 | +{if $options[prefkey].prefkey == "prins"}Default Primary NS:{/if} | |
| 24 | +{if $options[prefkey].prefkey == "secns"}Default Secondary NS:{/if} | |
| 25 | +{if $options[prefkey].prefkey == "master"}Default master for slaves:{/if} | |
| 26 | +</td> | |
| 27 | +<td><input class=form-field type=text size="35" name={$options[prefkey].prefkey} value="{$options[prefkey].prefval}" {if $options[prefkey].prefkey == "hostmaster"}autofocus{/if}></td> | |
| 28 | +</tr> | |
| 29 | +{/section} | |
| 30 | +</table> | |
| 31 | +</div></div> | |
| 32 | +<div class=submit><input class=submit-button type=submit name=Submit value="Save"> <input type=button class=submit-button id=cancel value="Cancel" name ="cancel"></div> | |
| 33 | +</form> | ... | ... |
templates/pages.tpl
0 → 100644
| 1 | +{if $pages} | |
| 2 | +<div class=pages> | |
| 3 | +<table> | |
| 4 | +<tr> | |
| 5 | +<td class=pages>Paging:</td> | |
| 6 | +{foreach name=pages from=$pages item=page} | |
| 7 | +{if $smarty.foreach.pages.first} | |
| 8 | +{if $current_page == $page} | |
| 9 | +<td class=firstno> </td> | |
| 10 | +<td class=prevno> </td> | |
| 11 | +{else} | |
| 12 | +<td class=first><a class=first id=first href="{$page_root}page={$page}" alt="First page" title="First page"> </a></td> | |
| 13 | +<td class=prev><a class=prev id=prev href="{$page_root}page={math equation="$current_page - 1"}" alt="Previous page" title="Previous page"> </a></td> | |
| 14 | +{/if} | |
| 15 | +{/if} | |
| 16 | +{if $current_page == $page} | |
| 17 | +<td class="pages actualpage">{$page}</td> | |
| 18 | +{else} | |
| 19 | +<td class=pages><a href="{$page_root}page={$page}" alt="Go to {$page} page" title="Go to {$page}. page">{$page}</a></td> | |
| 20 | +{/if} | |
| 21 | +{if $smarty.foreach.pages.last} | |
| 22 | +{if $current_page == $page} | |
| 23 | +<td class=nextno> </td> | |
| 24 | +<td class=lastno> </td> | |
| 25 | +{else} | |
| 26 | +<td class=next><a class=next id=next href="{$page_root}page={math equation="$current_page + 1"}" alt="Next page" title="Next page"> </a></td> | |
| 27 | +<td class=last><a class=last id=last href="{$page_root}page={$page}" alt="Last page" title="Last page"> </a></td> | |
| 28 | +{/if} | |
| 29 | +{/if} | |
| 30 | +{/foreach} | |
| 31 | +</tr> | |
| 32 | +</table> | |
| 33 | +</div> | |
| 34 | +{/if} | ... | ... |
templates/recordread.tpl
0 → 100644
| 1 | +<form name=form1 method="post" action="{$src}record.php?i={$zone.id}"> | |
| 2 | +<div class=clear><div class=main> | |
| 3 | +<h4>Edit zone records</h4> | |
| 4 | +<table style="min-width:820"> | |
| 5 | +<tr> | |
| 6 | +<td><strong>New:</strong></td> | |
| 7 | +<td><input type=text name=newhost class=form-field size="16" autofocus></td> | |
| 8 | +<td><input type=text name=newttl class=form-field size="1"></td> | |
| 9 | +<td><select name=newtype class=form-field> | |
| 10 | +{html_options values=$types output=$types} | |
| 11 | +</select></td> | |
| 12 | +<td><input type=text name=newdestination class=form-field size="32"></td> | |
| 13 | +</tr> | |
| 14 | +<tr> | |
| 15 | +<td colspan=5><hr /></td> | |
| 16 | +</tr> | |
| 17 | +</table> | |
| 18 | +<table style="min-width:820"> | |
| 19 | +<tr> | |
| 20 | +<td align=right><strong>Zone:</strong></td> | |
| 21 | +<td class=highlight>{$zone.name}</td> | |
| 22 | +<td align=right><strong>Serial:</strong></td> | |
| 23 | +<td>{$zone.serial}</td> | |
| 24 | +</tr> | |
| 25 | +<tr> | |
| 26 | +<td align=right><strong>Refresh:</strong></td> | |
| 27 | +<td><input type=text name=refresh size="28" class=form-field value="{$zone.refresh}"></td> | |
| 28 | +<td align=right><strong>Retry:</strong></td> | |
| 29 | +<td><input type=text name=retry size="28" class=form-field value="{$zone.retry}"></td> | |
| 30 | +</tr> | |
| 31 | +<tr> | |
| 32 | +<td align=right><strong>Expire:</strong></td> | |
| 33 | +<td><input type=text name=expire size="28" class=form-field value="{$zone.expire}"></td> | |
| 34 | +<td align=right><strong>TTL:</strong></td> | |
| 35 | +<td><input type=text name=ttl size="28" class=form-field value="{$zone.ttl}"></td> | |
| 36 | +</tr> | |
| 37 | +<tr> | |
| 38 | +<td align=right><strong>NS1:</strong></td> | |
| 39 | +<td><input type=text name=pri_dns size="28" class=form-field value="{$zone.pri_dns}"></td> | |
| 40 | +<td align=right><strong>NS2:</strong></td> | |
| 41 | +<td><input type=text name=sec_dns size="28" class=form-field value="{$zone.sec_dns}"></td> | |
| 42 | +</tr> | |
| 43 | +{if $admin == "yes"} | |
| 44 | +<tr> | |
| 45 | +<td align=right><strong>Owner:</strong></td> | |
| 46 | +<td align=left><select name=owner class=form-field> | |
| 47 | +{section name=i loop=$userlist} | |
| 48 | +<option value="{$userlist[i].id}"{if $userlist[i].id == $zone.owner} selected{/if}>{$userlist[i].realname}</option> | |
| 49 | +{/section} | |
| 50 | +</select> | |
| 51 | +</td> | |
| 52 | +<td align=right><strong>Secure:</strong></td> | |
| 53 | +<td align=left><select name=secured class=form-field> | |
| 54 | +<option value="yes"{if $zone.secured == "yes"} selected{/if}>yes</option> | |
| 55 | +<option value="no"{if $zone.secured == "no"} selected{/if}>no</option> | |
| 56 | +</select> | |
| 57 | +</td> | |
| 58 | +</tr> | |
| 59 | +{/if} | |
| 60 | +</table> | |
| 61 | +<input type=hidden name=zone value="{$zone.name}"> | |
| 62 | +<input type=hidden name=zoneid value="{$zone.id}"> | |
| 63 | +{if $rcount > 0} | |
| 64 | +<table style="min-width:780"> | |
| 65 | +<tr> | |
| 66 | +<th>Host</th> | |
| 67 | +<th>TTL</th> | |
| 68 | +<th>Type</th> | |
| 69 | +<th colspan=2>Destination</th> | |
| 70 | +<th>Delete</th> | |
| 71 | +</tr> | |
| 72 | +{section name=i loop=$record} | |
| 73 | +<tr> | |
| 74 | +<td> | |
| 75 | +<input type=text name=host[{$smarty.section.i.index}] class=form-field value="{$record[i].host}" size="16"> | |
| 76 | +<input type=hidden name=host_id[{$smarty.section.i.index}] value="{$record[i].id}"> | |
| 77 | +</td> | |
| 78 | +<td> | |
| 79 | +<input type=text name=rttl[{$smarty.section.i.index}] class=form-field value="{$record[i].ttl}" size="1"> | |
| 80 | +</td> | |
| 81 | +<td><select name=type[{$smarty.section.i.index}] class=form-field> | |
| 82 | +{html_options values=$types selected=$record[i].type output=$types} | |
| 83 | +</select></td> | |
| 84 | +{if $record[i].type == "MX"} | |
| 85 | +<td> | |
| 86 | +<input type=text name=pri[{$smarty.section.i.index}] class=form-field size="1" maxlength="3" value="{$record[i].pri}"> | |
| 87 | +</td><td> | |
| 88 | +<input type=text name=destination[{$smarty.section.i.index}] class=form-field size="25" value="{$record[i].destination}"> | |
| 89 | +</td> | |
| 90 | +{else} | |
| 91 | +<td colspan=2> | |
| 92 | +<input type=text name=destination[{$smarty.section.i.index}] class=form-field size="33" value="{$record[i].destination}"> | |
| 93 | +</td> | |
| 94 | +{/if} | |
| 95 | +<td align=center><input type=checkbox name=delete[{$smarty.section.i.index}] id=delete[{$smarty.section.i.index}]><label for="delete[{$smarty.section.i.index}]" name=delete[{$smarty.section.i.index}]_lbl> </label></td> | |
| 96 | +</tr> | |
| 97 | +{/section} | |
| 98 | +</table>{else}<p>There are no other records in this zone at the moment.</p>{/if} | |
| 99 | +<input type=hidden name=total value="{$smarty.section.i.total}"> | |
| 100 | +</div></div> | |
| 101 | +<div class=submit><input class=submit-button type=submit name=Submit value="Save"> <input type=button class=submit-button id=cancel value="Cancel" name ="cancel"></div> | |
| 102 | +</form> | |
| 103 | +{include file="pages.tpl"} | ... | ... |
templates/savepass.tpl
0 → 100644
templates/slave_deletezone.tpl
0 → 100644
| 1 | +<div class=clear><div class=main><p>Please confirm that you wish to delete the slave zone <strong>{$zone}.</strong></p> | |
| 2 | +<p><br /> | |
| 3 | +All resource records associated with this zone will be deleted. | |
| 4 | +</p> | |
| 5 | +<p> | |
| 6 | +<a class=attention href="{$src}slave_zonelist.php?i={$zoneid}&delete=y">Yes</a> - <a href="{$src}slave_zonelist.php">No</a>. | |
| 7 | +</p></div></div> | ... | ... |
templates/slave_newzone.tpl
0 → 100644
| 1 | +<form name=form1 method="post" action="{$src}slave_zonelist.php"> | |
| 2 | +<div class=clear><div class=main><h4>Properties of the new slave zone:</h4> | |
| 3 | +<table> | |
| 4 | +<tr> | |
| 5 | +<td align=right><strong>Zone:</strong></td> | |
| 6 | +<td><input type=text name=name class=form-field autofocus></td> | |
| 7 | +</tr> | |
| 8 | +<tr> | |
| 9 | +<td align=right><strong>Master:</strong></td> | |
| 10 | +<td><input type=text name=master class=form-field value="{$master}"></td> | |
| 11 | +</tr> | |
| 12 | +<tr> | |
| 13 | +<td colspan=2><hr /></td> | |
| 14 | +</tr> | |
| 15 | +<tr> | |
| 16 | +<td align=right><strong>Owner: </strong></td> | |
| 17 | +<td><select name=owner class=form-field> | |
| 18 | +{section name=i loop=$userlist} | |
| 19 | +<option value="{$userlist[i].id}" {if $current_user == $userlist[i].id}selected{/if}>{$userlist[i].realname}</option> | |
| 20 | +{/section} | |
| 21 | +</select> | |
| 22 | +</td> | |
| 23 | +</tr> | |
| 24 | +</table></div></div> | |
| 25 | +<div class=submit><input class=submit-button type=submit name=Submit value="Add zone"> <input type=button class=submit-button id=cancel value="Cancel" name ="cancel"></div> | |
| 26 | +</form> | ... | ... |
templates/slave_recordread.tpl
0 → 100644
| 1 | +<form name=form1 method="post" action="{$src}slave_zonelist.php?i={$zone.id}"> | |
| 2 | +<div class=clear><div class=main><h4>Edit properties of the slave zone:</h4> | |
| 3 | +<table> | |
| 4 | +<tr> | |
| 5 | +<td align=right><strong>Zone:</strong></td> | |
| 6 | +<td class=highlight>{$zone.name}</td> | |
| 7 | +</tr> | |
| 8 | +<tr> | |
| 9 | +<td align=right><strong>Master:</strong></td> | |
| 10 | +<td><input type=text name=master size="25" class=form-field value="{$zone.master}"></td> | |
| 11 | +</tr> | |
| 12 | +{if $admin == "yes"} | |
| 13 | +<tr> | |
| 14 | +<td align=right><strong>Owner:</strong></td> | |
| 15 | +<td align=left><select name=owner class=form-field> | |
| 16 | +{section name=i loop=$userlist} | |
| 17 | +<option value="{$userlist[i].id}"{if $userlist[i].id == $zone.owner} selected{/if}>{$userlist[i].realname}</option> | |
| 18 | +{/section} | |
| 19 | +</select> | |
| 20 | +</td> | |
| 21 | +</tr> | |
| 22 | +{/if} | |
| 23 | +</table> | |
| 24 | +<input type=hidden name=name value="{$zone.name}"> | |
| 25 | +</div></div> | |
| 26 | +<div class=submit><input class=submit-button type=submit name=Submit value="Save"> <input type=button class=submit-button id=cancel value="Cancel" name ="cancel"></div> | |
| 27 | +</form> | ... | ... |
templates/slave_zoneread.tpl
0 → 100644
| 1 | +<div class=clear><div class=main> | |
| 2 | +{if $admin == 'yes'}<p><a class=new id=new href="{$src}slave_newzone.php">Create a new slave zone</a></p>{else}<h4>List of your slave zones</h4>{/if} | |
| 3 | +{if $zonelist}<table style="min-width:500"> | |
| 4 | +<tr> | |
| 5 | +<th>Name</th> | |
| 6 | +<th>Master</th> | |
| 7 | +<th>Changed</th> | |
| 8 | +<th> </th> | |
| 9 | +<th colspan=2>Valid</th> | |
| 10 | +<th> </th> | |
| 11 | +<th colspan=2>Action</th> | |
| 12 | +</tr> | |
| 13 | +{section name=i loop=$zonelist} | |
| 14 | +<tr> | |
| 15 | +<td>{$zonelist[i].name}</td> | |
| 16 | +<td>{$zonelist[i].master}</td> | |
| 17 | + | |
| 18 | +{if $zonelist[i].updated == "yes"}<td class=ok title=Yes alt=Yes> </td> | |
| 19 | +{elseif $zonelist[i].updated == "no"}<td class=no title=No alt=No> </td> | |
| 20 | +{else}<td class=some title=Unknown alt=Unknown></td> | |
| 21 | +{/if} | |
| 22 | +<td class=empty> </td> | |
| 23 | +{if $zonelist[i].valid == "yes"}{if $zonelist[i].updated == "no"}<td class=ok title=Yes alt=Yes> </td><td class=view><a alt="View slave zone" title="View slave zone" href="{$src}slave_zoneview.php?i={$zonelist[i].id}"> </a></td>{else}<td class=ok title=Yes alt=Yes> </td><td class=preview><a alt="preview zone" title="Preview zone" href="{$src}slave_zoneview.php?i={$zonelist[i].id}&pre=y"> </a></td>{/if} | |
| 24 | +{elseif $zonelist[i].valid == "no"}<td class=nok title=No alt=No></td><td class=empty></td> | |
| 25 | +{else}<td class=some title=Maybe alt=Maybe></td><td class=check><a id=_doitlink_{$zonelist[i].id} alt="Check zone" title="Check zone" href="{$src}slave_zonelist.php?i={$zonelist[i].id}&check=y{if $pages}&page={$current_page}{/if}"> </a></td> | |
| 26 | +{/if} | |
| 27 | +<td class=empty> </td> | |
| 28 | +<td class=ed><a title="Edit zone" alt="Edit zone" href="{$src}slave_record.php?i={$zonelist[i].id}"> </a></td> | |
| 29 | +<td class=del><a alt="Remove zone" title="Remove zone" href="{$src}slave_deletezone.php?i={$zonelist[i].id}"> </a></td> | |
| 30 | +</tr> | |
| 31 | +{/section} | |
| 32 | +</table>{else}<p>You don't have slave zones.</p>{/if} | |
| 33 | +</div></div> | |
| 34 | +{include file="pages.tpl"} | ... | ... |
templates/upload.tpl
0 → 100644
| 1 | +<form name=upl enctype=multipart/form-data action="{$src}convert.php" method="post"> | |
| 2 | +<div class=clear><div class=main> | |
| 3 | +<h4 id=choose>Import a zone file</h4> | |
| 4 | +<p{if $count == 0} id=nofile{/if}>Choose an import method, a file/zone (don't forget to fill the domain part).</p> | |
| 5 | +<table> | |
| 6 | +<tr> | |
| 7 | +<td><input type=radio name=method id=list value="list"><label for="list">Orphan files</label></td> | |
| 8 | +<td class=empty> | |
| 9 | +<td><select class=form-field id=sel name=sel> | |
| 10 | +{if $count == 0}<option> NOT FOUND </option>{else}<option>- select file -</option>{/if} | |
| 11 | +{section name=i loop=$files} | |
| 12 | +<option>{$files[i]}</option> | |
| 13 | +{/section} | |
| 14 | +</select> <strong>Domain: </strong><input class=form-field id=sel_domain value="" name=sel_domain></td> | |
| 15 | +</tr> | |
| 16 | +<tr> | |
| 17 | +<td><input type=radio name=method id=file value="file"><label for="file">Browse</label></td> | |
| 18 | +<td class=empty> | |
| 19 | +<td><strong>Domain: </strong><input class=form-field id=fil_domain value="" name=fil_domain> <input type=file class=form-field id=fil name=fil></td> | |
| 20 | +</tr> | |
| 21 | +<tr> | |
| 22 | +<td style="vertical-align:top;padding-top:7px;"><input type=radio name=method id=text value="text"><label for="text">Edit</label></td> | |
| 23 | +<td class=empty> | |
| 24 | +<td><strong>Domain: </strong><input class=form-field id=txt_domain value="" name=txt_domain><br /><textarea id=txt name=txt cols="100" rows="18"></textarea></td> | |
| 25 | +</tr> | |
| 26 | +</table> | |
| 27 | +</div></div> | |
| 28 | +<div class=submit><input class=submit-button type=submit name=Submit value="Upload"> <input type=button class=submit-button id=cancel value="Cancel" name ="cancel"></div> | |
| 29 | +</form> | |
| 0 | 30 | \ No newline at end of file | ... | ... |
templates/uploadproblem.tpl
0 → 100644
| 1 | +<form name=rew target="{$src}--recordwrite.php" method="POST"> | |
| 2 | +<div class=clear><div class=main> | |
| 3 | +<h4>Committed zone has errors</h4> | |
| 4 | +<p><strong>Zone:</strong> <span class=highlight>{$zone}</span><br /> | |
| 5 | +<strong>Chosen method:</strong> {$method}</p><p>The zonefile is OK, but the import procedure has errors.<br />Please check it, fix it, and try again.</p> | |
| 6 | +<p><strong>Output:</strong></p> | |
| 7 | +<pre>{section name=i loop=$problem} | |
| 8 | +{$problem[i]} | |
| 9 | +{/section}</pre> | |
| 10 | +</div></div> | |
| 11 | +</form> | ... | ... |
templates/uploadreview.tpl
0 → 100644
| 1 | +<div class=clear><div class=main> | |
| 2 | +<h4>Review the imported zone</h4> | |
| 3 | +<p><strong>Zone:</strong> <span class=highlight>{$zone}</span><br /> | |
| 4 | +<strong>Chosen method:</strong> {$method}</p> | |
| 5 | +<p><strong>Preview your imported zone:</strong></p> | |
| 6 | +<textarea readonly autofocus wrap="off" cols="116" rows="30" class=ro>{section name=i loop=$output} | |
| 7 | +{$output[i]} | |
| 8 | +{/section}</textarea> | |
| 9 | +<p>Check and edit your imported zone between your <a href="zonelist.php" class=attention>master zones</a></p> | |
| 10 | +</div></div> | ... | ... |
templates/userlistread.tpl
0 → 100644
| 1 | +<div class=clear><div class=main> | |
| 2 | +{if $admin == 'yes'}<p><a class=new id=new href="{$src}newuser.php">Create a new user</a></p>{/if} | |
| 3 | +<table style="min-width:420;"> | |
| 4 | +<tr> | |
| 5 | +<th>Username</th> | |
| 6 | +<th>Full name</th> | |
| 7 | +<th>Admin</th> | |
| 8 | +<th></th> | |
| 9 | +<th colspan=2>Action</th> | |
| 10 | +</tr> | |
| 11 | +{section name=i loop=$userlist} | |
| 12 | +<tr> | |
| 13 | +<td align=center>{$userlist[i].username}</td> | |
| 14 | +<td align=center>{$userlist[i].realname}</td> | |
| 15 | +{if $userlist[i].admin == "yes"}<td class=ok title=Yes alt=Yes> </td> | |
| 16 | +{elseif $userlist[i].admin == "no"}<td class=no title=No alt=No> </td> | |
| 17 | +{/if} | |
| 18 | +<td class=empty></td> | |
| 19 | +{if $userlist[i].username != "admin"} | |
| 20 | +<td class=ed><a href="{$src}user.php?i={$userlist[i].id}" title="Edit user" alt="Edit user"> </a></td> | |
| 21 | +<td class=del><a href="{$src}deleteuser.php?i={$userlist[i].id}" title="Delete user" alt="Delete user"> </a></td> | |
| 22 | +{else} | |
| 23 | +<td class=no title="Cannot edit" alt="Cannot edit"> </td> | |
| 24 | +<td class=no title="Cannot delete" alt="Cannot delete"> </td> | |
| 25 | +{/if} | |
| 26 | +</tr> | |
| 27 | +{/section} | |
| 28 | +</table> | |
| 29 | +</div></div> | |
| 30 | +{include file="pages.tpl"} | ... | ... |
templates/userread.tpl
0 → 100644
| 1 | +<div class=clear><div class=main><h4>Edit user's credentials:</h4> | |
| 2 | +<form name=form1 method="post" action="{$src}user.php?i={$user.id}" id=new> | |
| 3 | +<table width=580> | |
| 4 | +<tr> | |
| 5 | +<td align=right width=120><strong>Username:</strong></td> | |
| 6 | +<td colspan=2 class=highlight>{$user.username}</td> | |
| 7 | +<th width=180>Password quality meter<div class=pwc id=pwc>Won't modified!</div></th> | |
| 8 | +</tr> | |
| 9 | +<tr> | |
| 10 | +<td align=right width=120><strong>Full name:</strong></td> | |
| 11 | +<td colspan=2><input type=text name=realname class=form-field value="{$user.realname}" autofocus tabindex=1</td> | |
| 12 | +<td rowspan=2 id=pwmeter class=nok width=180 title="Won't modified!" alt="Won't modified!"></td> | |
| 13 | +</tr> | |
| 14 | +<tr> | |
| 15 | +<td align=right width=120><strong>Admin rights:</strong></td> | |
| 16 | +<td colspan=2 height=32 valign=bottom> | |
| 17 | +<input type=radio name=admin id=adminy value="yes"{if $user.admin} checked="checked" tabindex=2{/if} /><label for="adminy">yes</label> | |
| 18 | +<input type=radio name=admin id=adminn value="no"{if !$user.admin} checked="checked" tabindex=2{/if} /><label for="adminn">no</label><input type=hidden name=password id=pwmd5n> | |
| 19 | +</td> | |
| 20 | +</tr> | |
| 21 | +</table> | |
| 22 | +<div class=submit><input class=submit-button type=submit name=Submit value="Save" id=submit tabindex=5> <input type=button class=submit-button id=cancel value="Cancel" name ="cancel" tabindex=6></div> | |
| 23 | +</form> | |
| 24 | +<table width=580> | |
| 25 | +<tr> | |
| 26 | +<td align=right width=120><strong>New password:</strong></td> | |
| 27 | +<td><input type=password name=password_one class=form-field id=pass1 autofocus tabindex=3></td> | |
| 28 | +<td width=180></td> | |
| 29 | +</tr> | |
| 30 | +<tr> | |
| 31 | +<td align=right width=120><strong>Confirm it:</strong></td> | |
| 32 | +<td><input type=password name=confirm_password class=form-field disabled id=pass2 tabindex=4></td> | |
| 33 | +<td width=180></td> | |
| 34 | +</tr> | |
| 35 | +{if $success}<tr><td colspan=3><hr /></td></tr><tr><td colspan=3 align=center><span class=attention>{$success}</span></td></tr>{/if} | |
| 36 | +</table> | |
| 37 | +{if $zonelist}<table width=580><tr> | |
| 38 | +<td colspan=3><hr /></td> | |
| 39 | +</tr> | |
| 40 | +<tr> | |
| 41 | +<th colspan=3><p>Master zones owned by this user:</p></th> | |
| 42 | +</tr> | |
| 43 | +<tr> | |
| 44 | +<th>Name</th> | |
| 45 | +<th>Serial</th> | |
| 46 | +<th>Action</th> | |
| 47 | +</tr> | |
| 48 | +{section name=i loop=$zonelist} | |
| 49 | +<tr> | |
| 50 | +<td align=center>{$zonelist[i].name}</td> | |
| 51 | +<td align=center>{$zonelist[i].serial}</td> | |
| 52 | +<td class=ed><a href="{$src}record.php?i={$zonelist[i].id}"> </a></td> | |
| 53 | +</tr>{/section}</table>{/if} | |
| 54 | +{if $szonelist}<table width=580><tr> | |
| 55 | +<td colspan=3><hr /></td> | |
| 56 | +</tr> | |
| 57 | +<tr> | |
| 58 | +<th colspan=3><p>Slave zones owned by this user:</p></th> | |
| 59 | +</tr> | |
| 60 | +<tr> | |
| 61 | +<th>Name</th> | |
| 62 | +<th>Master</th> | |
| 63 | +<th>Action</th> | |
| 64 | +</tr> | |
| 65 | +{section name=i loop=$szonelist} | |
| 66 | +<tr> | |
| 67 | +<td align=center>{$szonelist[i].name}</td> | |
| 68 | +<td align=center>{$szonelist[i].master}</td> | |
| 69 | +<td class=ed><a href="{$src}slave_record.php?i={$szonelist[i].id}"> </a></td> | |
| 70 | +</tr>{/section}</table>{/if} | |
| 71 | +<input type=hidden name=bad id=bad value="The password is too short"> | |
| 72 | +<input type=hidden name=nok id=nok value="Won't modified!"> | |
| 73 | +<input type=hidden name=notenough id=notenough value="Need to be longer!"> | |
| 74 | +<input type=hidden name=almost id=almost value="Need to be complex and/or longer!"> | |
| 75 | +<input type=hidden name=enough id=enough value="Complexity is fair"> | |
| 76 | +<input type=hidden name=perfect id=perfect value="Complexity is perfect"> | |
| 77 | +<input type=hidden name=notempty id=notempty value=0> | |
| 78 | +</div></div> | ... | ... |
templates/zonepview.tpl
0 → 100644
| 1 | +<div class=clear><div class=main> | |
| 2 | +<p><strong>Zone: <span class=highlight>{$zonename}</span></strong></p> | |
| 3 | +<p><strong>Type: </strong>{$zonetype}<br /><strong>Owner: </strong>{$owner}</p> | |
| 4 | +<textarea readonly autofocus wrap="off" cols="116" rows="30" class=ro>{if $zonedef}{$zonedef}{else}Zone cannot load{/if}</textarea> | |
| 5 | +</div></div> | ... | ... |
templates/zoneread.tpl
0 → 100644
| 1 | +<div class=clear><div class=main> | |
| 2 | +{if $admin == 'yes'}<p><a class=new id=new href="{$src}newzone.php">Create a new master zone</a></p>{else}<h4>List of your master zones</h4>{/if} | |
| 3 | +{if $zonelist}<table style="min-width:600"> | |
| 4 | +<tr> | |
| 5 | +<th>Name</th> | |
| 6 | +<th>Serial</th> | |
| 7 | +<th>Changed</th> | |
| 8 | +<th> </th> | |
| 9 | +<th colspan=2>Secure</th> | |
| 10 | +<th> </th> | |
| 11 | +<th colspan=2>Valid</th> | |
| 12 | +<th> </th> | |
| 13 | +<th colspan=2>Action</th> | |
| 14 | +</tr> | |
| 15 | +{section name=i loop=$zonelist} | |
| 16 | +<tr> | |
| 17 | +<td>{$zonelist[i].name}</td> | |
| 18 | +<td>{$zonelist[i].serial}</td> | |
| 19 | + | |
| 20 | +{if $zonelist[i].updated == "yes"}<td class=ok title=Yes alt=Yes> </td> | |
| 21 | +{elseif $zonelist[i].updated == "no"}<td class=no title=No alt=No> </td> | |
| 22 | +{else}<td class=some title=Unknown alt=Unknown></td> | |
| 23 | +{/if} | |
| 24 | +<td class=empty> </td> | |
| 25 | +{if $zonelist[i].secured == "yes"}<td class=ok title=Yes alt=Yes> </td> | |
| 26 | +{if $zonelist[i].valid == "yes" and $zonelist[i].updated == "no"}<td class=view><a alt="View zone as secured" title="View zone as secured" href="{$src}zoneview.php?i={$zonelist[i].id}&s=1"> </a></td> | |
| 27 | +{else}<td class=empty></td> | |
| 28 | +{/if} | |
| 29 | +{elseif $zonelist[i].secured == "no"}<td colspan=2 class=no title=No alt=No></td> | |
| 30 | +{/if} | |
| 31 | +<td class=empty> </td> | |
| 32 | +{if $zonelist[i].valid == "yes"}<td class=ok title=Yes alt=Yes> </td>{if $zonelist[i].updated == "no"}<td class=view><a alt="View zone as plain" title="View zone as plain" href="{$src}zoneview.php?i={$zonelist[i].id}&s=0"> </a></td>{else}<td class=preview><a alt="Preview zone" title="Preview zone" href="{$src}zonepview.php?i={$zonelist[i].id}&s=0"> </a></td>{/if} | |
| 33 | +{elseif $zonelist[i].valid == "no"}<td class=nok title=Problem alt=Problem></td><td class=empty></td> | |
| 34 | +{else}<td class=some title=Maybe alt=Maybe></td><td class=check><a alt="Check zone" title="Check zone" href="{$src}zonelist.php?i={$zonelist[i].id}&check=y{if $pages}&page={$current_page}{/if}"> </a></td> | |
| 35 | +{/if} | |
| 36 | +<td class=empty> </td> | |
| 37 | +<td class=ed><a title="Edit zone" alt="Edit zone" href="{$src}record.php?i={$zonelist[i].id}"> </a></td> | |
| 38 | +<td class=del><a alt="Remove zone" title="Remove zone" href="{$src}deletezone.php?i={$zonelist[i].id}{if $pages}&page={$current_page}{/if}"> </a></td> | |
| 39 | +</tr> | |
| 40 | +{/section} | |
| 41 | +</table>{else}<p>You don't have master zones.</p>{/if} | |
| 42 | +</div></div> | |
| 43 | +{include file="pages.tpl"} | ... | ... |
templates/zoneview.tpl
0 → 100644
| 1 | +<div class=clear><div class=main> | |
| 2 | +<p><strong>Zone: <span class=highlight>{$zonename}</span></strong></p> | |
| 3 | +<p><strong>Type: </strong>{$zonetype}<br /><strong>Owner: </strong>{$owner}</p> | |
| 4 | +<textarea readonly autofocus wrap="off" cols="116" rows="30" class=ro>{if $zonedef}{$zonedef}{else}Zone cannot load{/if}</textarea> | |
| 5 | +</div></div> | ... | ... |