prepare("INSERT OR REPLACE INTO zones (zone, owner) VALUES (?, (SELECT id FROM users WHERE emailaddress = ?))"); $q->bindValue(1, $zonename, SQLITE3_TEXT); $q->bindValue(2, $ownername, SQLITE3_TEXT); $q->execute(); $db->close(); } function delete_db_zone($zonename) { if (!_valid_label($zonename)) { jtable_respond(null, 'error', "$zonename is not a valid zonename"); } $db = get_db(); $q = $db->prepare("DELETE FROM zones WHERE zone = ?"); $q->bindValue(1, $zonename, SQLITE3_TEXT); $q->execute(); $db->close(); } function get_zone_owner($zonename, $default) { if (!_valid_label($zonename)) { jtable_respond(null, 'error', "$zonename is not a valid zonename"); } $db = get_db(); $q = $db->prepare("SELECT u.emailaddress FROM users u, zones z WHERE z.owner = u.id AND z.zone = ?"); $q->bindValue(1, $zonename, SQLITE3_TEXT); $result = $q->execute(); $zoneinfo = $result->fetchArray(SQLITE3_ASSOC); $db->close(); if (isset($zoneinfo['emailaddress']) && $zoneinfo['emailaddress'] != null ) { return $zoneinfo['emailaddress']; } return $default; } function check_owner($zone) { return is_adminuser() or ($zone->account === get_sess_user()); } if (isset($_GET['action'])) { $action = $_GET['action']; } else { jtable_respond(null, 'error', 'No action given'); } try { $api = new PdnsAPI; switch ($action) { case "list": case "listslaves": $return = Array(); $q = isset($_POST['domsearch']) ? $_POST['domsearch'] : false; foreach ($api->listzones($q) as $sresult) { $zone = new Zone(); $zone->parse($sresult); $zone->setaccount(get_zone_owner($zone->name, 'admin')); if (!check_owner($zone)) continue; if ($action == "listslaves" and $zone->kind == "Slave") { array_push($return, $zone->export()); } elseif ($action == "list" and $zone->kind != "Slave") { if ($zone->dnssec) { $zone->setkeyinfo($api->getzonekeys($zone->id)); } array_push($return, $zone->export()); } } usort($return, "zone_compare"); jtable_respond($return); break; case "listrecords": $zonedata = $api->loadzone($_GET['zoneid']); $zone = new Zone(); $zone->parse($zonedata); $records = $zone->rrsets2records(); foreach ($records as &$record) { $record['id'] = json_encode($record); } usort($records, "record_compare"); jtable_respond($records); break; case "delete": $zone = $api->loadzone($_POST['id']); $api->deletezone($_POST['id']); delete_db_zone($zone['name']); jtable_respond(null, 'delete'); break; case "create": $zonename = isset($_POST['name']) ? $_POST['name'] : ''; $zonekind = isset($_POST['kind']) ? $_POST['kind'] : ''; if (!is_adminuser() and $allowzoneadd !== true) { jtable_respond(null, 'error', "You are not allowed to add zones"); } if (!_valid_label($zonename)) { jtable_respond(null, 'error', "Please only use [a-z0-9_/.-]"); } if (!$zonename || !$zonekind) { jtable_respond(null, 'error', "Not enough data"); } $zone = new Zone(); $zone->setkind($zonekind); $zone->setname($zonename); if ($zonekind != "Slave") { if (!isset($_POST['zone']) or isset($_POST['owns'])) { foreach ($_POST['nameserver'] as $ns) { $zone->addnameserver($ns); } } else { $zone->importdata($_POST['zone']); } if (isset($defaults['soa_edit_api'])) { $zone->setsoaeditapi($defaults['soa_edit_api']); } if (isset($defaults['soa_edit'])) { $zone->setsoaedit($defaults['soa_edit']); } } else { // Slave if (isset($_POST['masters'])) { foreach (preg_split('/[,;\s]+/', $_POST['masters'], null, PREG_SPLIT_NO_EMPTY) as $master) { $zone->addmaster($master); } } } // only admin user and original owner can "recreate" zones that are already // present in our own db but got lost in pdns. if (!is_adminuser() && get_sess_user() !== get_zone_owner($zonename, get_sess_user())) { jtable_respond(null, 'error', 'Zone already owned by someone else'); } $api->savezone($zone->export()); $zonename = $zone->name; if (is_adminuser() && isset($_POST['owner'])) { add_db_zone($zonename, $_POST['owner']); } else { add_db_zone($zonename, get_sess_user()); } if (isset($_POST['template']) && $_POST['template'] != 'None') { foreach (user_template_list() as $template) { if ($template['name'] !== $_POST['template']) continue; foreach ($template['records'] as $record) { $rrset = $zone->getrrset($record['label'], $record['type']); if ($rrset) { $rrset->delete(); } } $zone = $api->savezone($zone->export()); foreach ($template['records'] as $record) { $zone->addrecord($record['name'], $record['type'], $record['content']); } $zone = $api->savezone($zone->export()); break; } } jtable_respond($zone, 'single'); break; case "update": $zone = new Zone(); $zone->parse($api->loadzone($_POST['id'])); $zoneowner = isset($_POST['owner']) ? $_POST['owner'] : $zone->account; if ($zone->account !== $zoneowner) { if (!is_adminuser()) { header("Status: 403 Access denied"); jtable_respond(null, 'error', "Can't change owner"); } else { add_db_zone($zone->id, $zoneowner); $zone->setaccount($zoneowner); } } $update = false; if (isset($_POST['masters'])) { $zone->erasemasters(); foreach(preg_split('/[,;\s]+/', $_POST['masters'], null, PREG_SPLIT_NO_EMPTY) as $master) { $zone->addmaster($master); } } jtable_respond($api->savezone($zone->export()), 'single'); break; case "createrecord": $zone = new Zone(); $zone->parse($api->loadzone($_GET['zoneid'])); $name = isset($_POST['name']) ? $_POST['name'] : ''; $type = $_POST['type']; $content = $_POST['content']; if ('' == $name) { $name = $zone->name; } elseif (string_ends_with($name, '.')) { # "absolute" name, shouldn't append zone[name] - but check. $name = substr($name, 0, -1); if (!string_ends_with($name, $zone->name)) { jtable_respond(null, 'error', "Name $name not in zone ".$zone->name); } } else if (!string_ends_with($name, $zone->name)) { $name = $name . '.' . $zone->name; } if (!_valid_label($name)) { jtable_respond(null, 'error', "Please only use [a-z0-9_/.-]"); } if (!$type) { jtable_respond(null, 'error', "Require a type"); } if (!is_ascii($content)) { jtable_respond(null, 'error', "Please only use ASCII-characters in your fields"); } $record = $zone->addrecord($name, $type, $content, $_POST['disabled'], $_POST['ttl']); $api->savezone($zone->export()); jtable_respond($record, 'single'); break; case "editrecord": $zone = new Zone(); $zone->parse($api->loadzone($_GET['zoneid'])); $old_record = decode_record_id(isset($_POST['id']) ? $_POST['id'] : ''); $rrset = $zone->getrrset($old_record['name'], $old_record['type']); $rrset->deleteRecord($old_record['content']); $zone->addrecord($_POST['name'], $_POST['type'], $_POST['content'], $_POST['disabled'], $_POST['ttl']); $api->savezone($zone->export()); $record['id'] = json_encode($record); jtable_respond($zone->getrecord($_POST['name'], $_POST['type'], $_POST['content']), 'single'); break; case "deleterecord": $zone = new Zone(); $zone->parse($api->loadzone($_GET['zoneid'])); $old_record = decode_record_id(isset($_POST['id']) ? $_POST['id'] : ''); $rrset = $zone->getrrset($old_record['name'], $old_record['type']); $rrset->deleteRecord($old_record['content']); $api->savezone($zone->export()); jtable_respond(null, 'delete'); break; case "export": jtable_respond($api->exportzone($_GET['zoneid']), 'single'); break; case "gettemplatenameservers": $ret = array(); $type = $_GET['prisec']; foreach (user_template_list() as $template) { if ($template['name'] !== $_GET['template']) continue; $rc = 0; foreach ($template['records'] as $record) { if ($record['type'] == "NS") { if (($type == 'pri' && $rc == 0) or ($type == 'sec' && $rc == 1)) { echo $record['content']; exit(0); } $rc++; } } echo ""; } break; case "getformnameservers": $inputs = array(); foreach (user_template_list() as $template) { if ($template['name'] !== $_GET['template']) continue; foreach ($template['records'] as $record) { if ($record['type'] == "NS" and array_search($record['content'], $inputs) === false) { array_push($inputs, $record['content']); echo '
'; } } } break; default: jtable_respond(null, 'error', 'No such action'); break; } } catch (Exception $e) { jtable_respond(null, 'error', $e->getMessage()); }