scripts/convertPTR2InvidiualDomains...

275 lines
7.6 KiB
PHP

<?php
$servername = 'mysql.ct';
$u = 'powerdns_usr';
$p = 'QYVdcqxK4XBVlWLM';
$db = 'powerdns_db';
$conn = new mysqli($servername, $u, $p, $db);
if (empty($conn->connect_error) === false) {
die('Connection failed: '.$conn->connect_error);
}
// Functions
class sqlQuery {
private $conn;
private $re;
function __construct($conn)
{
$this->conn = $conn;
}
private function getError()
{
return $this->conn->error;
}
private function getErrno()
{
return $this->conn->errno;
}
function exec(string $sql, bool $ignoreResultSet = false)
{
$ret = $this->conn->query($sql);
if ($ret === false && $this->getErrno() !== 0) {
$errMsg = $this->getError();
throw new Exception('Error Processing SQL query: '.$errMsg, 1);
}
if ($ret instanceof mysqli_result) {
throw new Exception('sqlQuery->exec(): Unexpected result set.', 1);
}
return true;
}
function query(string $sql)
{
if ($this->re instanceof mysqli_result) {
// Do not modify the result set
throw new Exception('sqlQuery->query(): We already contain a result set.', 1);
}
$this->re = $this->conn->query($sql);
if ($this->re === false) {
$errMsg = $this->getError();
throw new Exception('Error Processing SQL query: '.$errMsg, 1);
}
if (($this->re instanceof mysqli_result) === false) {
throw new Exception('sqlQuery->query(): This query didn\'t return any result set', 1);
}
return true;
}
function longQuery(string $sql)
{
if ($this->conn->multi_query($sql) === false) {
throw new Exception('Error Processing SQL query: '.$this->getError(), 1);
}
}
function fetchRow()
{
$obj = $this->re;
if (($obj instanceof mysqli_result) === false) {
throw new Exception('Error fetching row: There\'s no result set.', 1);
}
return $this->re->fetch_assoc();
}
function fetchAll()
{
$obj = $this->re;
if (($obj instanceof mysqli_result) === false) {
throw new Exception('Error fetching results: There\'s no result set.', 1);
}
return $this->re->fetch_all(MYSQLI_ASSOC);
}
function getNumRows()
{
$obj = &$this->re;
if ($obj instanceof mysqli_result) {
return $this->re->num_rows;
}
return false;
}
function getAffectedRows()
{
$obj = &$this->conn;
if ($obj instanceof mysqli) {
return $obj->affected_rows;
}
return false;
}
function freeResult()
{
$obj = $this->re;
if ($obj instanceof mysqli_result) {
$this->re->free_result();
$this->re = null;
}
}
}
echo <<<HERE
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Now converting PTR records to their !!
!! individual zones. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\n
HERE;
usleep(500);
$sqlQuery = new sqlQuery($conn);
// DNS SOA Serial format YYYYmmddss.
// Domain table format
// id,name,master,last_check,type,notified_serial,account
// We going to create domains for each subnet up to 10.0.9.0
// Query for PTR Domains
try {
$sqlQuery->query("SELECT `id`,`name`,`type` FROM `domains` WHERE `name` LIKE '%.0.10.in-addr.arpa'");
} catch (Exception $e) {
echo 'Error occurred on line '.__LINE__.': '.$e->getMessage()."\n";
exit(1);
}
$rows = $sqlQuery->fetchAll();
$sqlQuery->freeResult();
foreach ($rows as $row) {
$ptrDomains[] = ['id' => $row['id'], 'name' => $row['name']];
// While we are here, change ZONE from NATIVE to MASTER
if ($row['type'] === 'NATIVE') {
echo "DETECTED: Domain '{$row['name']}' is NATIVE, switching domain to MASTER.\n";
try {
$sqlQuery->exec("UPDATE `domains` SET `type` = 'MASTER' WHERE `id` = '{$row['id']}'");
} catch (Exception $e) {
echo 'Error occurred on line '.__LINE__.': '.$e->getMessage()."\n";
exit(1);
}
}
}
// Insert the missing records into the database
$found = false;
for ($net = 0; $net <= 10; $net++) {
$subnet = $net.'.0.10.in-addr.arpa';
foreach ($ptrDomains as $value) {
if ($value['name'] === $subnet) {
$found = true;
}
}
if ($found === false) {
echo "Domain record '$subnet' doesn't exists. Creating...\n";
try {
$sqlQuery->exec("INSERT INTO domains (name,type) VALUES ('$subnet','MASTER')");
$sqlQuery->query("SELECT `id`,`name` FROM `domains` WHERE `name` = '$subnet'");
} catch (Exception $e) {
echo 'Error occurred on line '.__LINE__.': '.$e->getMessage()."\n";
exit(1);
}
$row = $sqlQuery->fetchRow();
$sqlQuery->freeResult();
$ptrDomains[] = ['id' => $row['id'], 'name' => $row['name']];
}
$found = false;
}
// Create SOA and NS records
foreach ($ptrDomains as $value) {
echo "Checking for SOA record for zone '{$value['name']}'.\n";
try {
$sqlQuery->query("SELECT `domain_id`,`type`,`content` FROM `records` WHERE `type` = 'SOA' AND `domain_id` = '{$value['id']}'");
} catch (Exception $e) {
echo 'Error occurred on line '.__LINE__.': '.$e->getMessage()."\n";
exit(1);
}
if ($sqlQuery->getNumRows() === 0) {
echo "Missing SOA record, creating...\n";
$serial = date('Ymds');
$soaRecord = "0.dns.ct admin+dns.lhpmail.us $serial 60 60 60 60";
$sql = "INSERT INTO `records` (domain_id,name,type,content,ttl,prio) VALUES ('{$value['id']}','{$value['name']}','SOA','$soaRecord',10,0)";
try {
$sqlQuery->exec($sql);
} catch (Exception $e) {
echo 'Error occurred on line '.__LINE__.': '.$e->getMessage()."\n";
exit(1);
}
}
$sqlQuery->freeResult();
echo "Checking for NS records for zone '{$value['name']}'.\n";
$dnsNames = ['0.dns.ct', '1.dns.ct'];
foreach($dnsNames as $name) {
try {
$sqlQuery->query("SELECT `type`,`content` FROM `records` WHERE `content` = '$name' AND `type` = 'NS' AND `domain_id` = '{$value['id']}'");
} catch (Exception $e) {
echo 'Error occurred on line '.__LINE__.': '.$e->getMessage()."\n";
exit(1);
}
if ($sqlQuery->getNumRows() === 0) {
echo "Missing NS record '$name' for zone '{$value['name']}'. Creating...\n";
$sql = "INSERT INTO `records` (domain_id,name,type,content,ttl,prio) VALUES ('{$value['id']}','{$value['name']}','NS','$name',10,0)";
$sqlQuery->exec($sql);
}
$sqlQuery->freeResult();
}
echo "Associating related PTR records to new ZONE '{$value['name']}' from old ZONE.\n";
$sql = <<<HERE
UPDATE
`records` AS `dest`,
(
SELECT `id`
FROM `domains`
WHERE `name` = '{$value['name']}'
) AS `src`
SET
`dest`.`domain_id` = `src`.`id`
WHERE
`dest`.`name` LIKE '%.{$value['name']}';
HERE;
try {
$sqlQuery->exec($sql);
} catch (Exception $e) {
echo 'Error occurred on line '.__LINE__.': '.$e->getMessage()."\n";
exit(1);
}
echo 'Number of rows affected: '.$sqlQuery->getAffectedRows()."\n";
}
echo "Deleting '0.10.in-addr.arpa' ZONE and related PTR records.\n";
$sql = <<<HERE
DELETE `domains`,`records` FROM `domains`
INNER JOIN
`records` ON `records`.`domain_id` = 8
WHERE
`domains`.`id` = 8;
HERE;
$sqlQuery->exec($sql);
$conn->close();