Commit 9852a98c2a7918edbdc8a7860f035de556a1fa9c

Authored by Péter Szládovics
1 parent b075427b

add code

Too many changes to show.

To preserve performance only 23 of 79 files are displayed.

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 = "&amp;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):' ', '&nbsp;', $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
  1 +<?php
  2 +require_once "include.php";
  3 +
  4 +if($_SERVER['REQUEST_METHOD'] == 'POST') {
  5 + include("recordwrite.php");
  6 +}
  7 +include("recordread.php");
  8 +
  9 +?>
... ...
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'] . "&amp;");
  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 +?>
... ...