Skip to content
This repository has been archived by the owner on May 22, 2023. It is now read-only.

Add cgi case for headers parsing #26

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion classes/AuthenticationResource.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function __construct($parameters) {
break;
}
} catch (Exception $e) {
trigger_error($e->message, E_USER_ERROR);
trigger_error($e, E_USER_ERROR);
}
}

Expand Down
186 changes: 161 additions & 25 deletions classes/ZoneFunctions.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public function get_all_zones($response, &$out = null, $query = null) {
$output = array();
while (($row = $result->fetch(PDO::FETCH_ASSOC)) !== false ) {
$zone = array();
$zone['z_id'] = $row['z_id'];
$zone['name'] = $row['z_name'];
$zone['type'] = $row['z_type'];
if (!empty($row['z_master'])) { $zone['master'] = $row['z_master']; }
Expand All @@ -86,7 +87,7 @@ public function query_zones($response, $query, &$out = null) {
return ZoneFunctions::get_all_zones($response, $out, $query);
}

public function get_zone($response, $identifier, &$out = null, $details = true, $arpa_expand = true, $include_zone_id = false) {
public function get_zone($response, $identifier, &$out = null, $details = true, $arpa_expand = true, $include_zone_id = true) {
$arpa = null;
if (preg_match(VALID_IPV4, $identifier) === 1) {
$arpa = HelperFunctions::ipv4_to_arpa($identifier);
Expand Down Expand Up @@ -162,6 +163,7 @@ public function get_zone($response, $identifier, &$out = null, $details = true,
}

$record = array();
$record['r_id'] = $row['r_id'];
$record['name'] = $row['r_name'];
$record['type'] = $row['r_type'];
$record['content'] = $row['r_content'];
Expand Down Expand Up @@ -215,7 +217,9 @@ public function create_zone($response, $data, &$out = null) {
foreach ($p['entries'] as $entry) {
$e = new stdClass();
$e->name = str_replace(array("[ZONE]"), array($data->name), $entry['name']);
$e->content = str_replace(array("[ZONE]"), array($data->name), $entry['content']);
$e->content = str_replace(
array("[ZONE]","[SERIAL]"),
array($data->name,date("Ymd00")), $entry['content']);
$e->type = $entry['type'];
$e->ttl = $entry['ttl'];
$e->priority = $entry['priority'];
Expand Down Expand Up @@ -494,18 +498,21 @@ public function modify_zone($response, $identifier, $data, &$out = null) {
if (isset($data->records)) {
$deletions = array();
$additions = array();
$updates = array();
foreach ($data->records as $record) {
if (isset($record->mode) && $record->mode == "delete") {
$deletions[] = $record;
} elseif (isset($record->mode) && $record->mode == "update") {
$updates[] = $record;
} else {
$additions[] = $record;
}
}

$records_responses = array();
if (!empty($deletions)) {
$obj = new StdClass();
$obj->records = $deletions;
ZoneFunctions::delete_records($response, $identifier, $obj, $out, $connection);
$records_responses[] = ZoneFunctions::delete_records($response, $identifier, $obj, $out, $connection);

if (!$out) {
$connection->rollback();
Expand All @@ -516,10 +523,24 @@ public function modify_zone($response, $identifier, $data, &$out = null) {
unset($obj);
}

if (!empty($updates)) {
$obj = new StdClass();
$obj->records = $updates;
$records_responses[] = ZoneFunctions::update_records($response, $identifier, $obj, $out, $connection);

if (!$out) {
$connection->rollback();
$out = false;
return $response;
}

unset($obj);
}

if (!empty($additions)) {
$obj = new StdClass();
$obj->records = $additions;
ZoneFunctions::create_records($response, $identifier, $obj, $out, true, $connection);
$records_responses[] = ZoneFunctions::create_records($response, $identifier, $obj, $out, true, $connection);

if (!$out) {
$connection->rollback();
Expand All @@ -536,7 +557,10 @@ public function modify_zone($response, $identifier, $data, &$out = null) {
$response->code = Response::OK;
$response->body = true;
if (isset($data->records)) {
$response->log_message = sprintf("Zone %s was modified, deleted %d records and added %d records.", $identifier, count($deletions), count($additions));
$response->log_message = sprintf("Zone %s was modified: [%s]",
$identifier,
implode("|",array_map(function ($v){return $v->log_message;}, $records_responses))
);
} else {
$response->log_message = sprintf("Zone %s was modified.", $identifier);
}
Expand All @@ -552,7 +576,7 @@ public function delete_zone($response, $identifier, &$out = null) {
$out = false;
return $response;
}

$z_id = $o['z_id'];
unset($o);

try {
Expand All @@ -567,6 +591,21 @@ public function delete_zone($response, $identifier, &$out = null) {

$connection->beginTransaction();

$statement = $connection->prepare(sprintf(
"DELETE FROM `%s` WHERE domain_id = :z_id;", PowerDNSConfig::DB_RECORD_TABLE
));

if ($statement->execute(array(":z_id" => $z_id)) === false) {
$response->code = Response::INTERNALSERVERERROR;
$response->error = "Could not query PowerDNS server.";
$response->error_detail = "INTERNAL_SERVER_ERROR";

$connection->rollback();
$out = false;

return $response;
}
$response->log_message = sprintf("Zone's %s records were deleted. ", $identifier);
$statement = $connection->prepare(sprintf(
"DELETE FROM `%s` WHERE name = :name;", PowerDNSConfig::DB_ZONE_TABLE
));
Expand All @@ -586,12 +625,105 @@ public function delete_zone($response, $identifier, &$out = null) {

$response->code = Response::OK;
$response->body = true;
$response->log_message = sprintf("Zone %s was deleted.", $identifier);
$response->log_message .= sprintf("Zone %s was deleted.", $identifier);
$out = true;

return $response;
}

public function update_records($response, $identifier, $data, &$out = null, $connection = null) {
if (!is_object($data) || !isset($data->records)) {
$response->code = Response::INTERNALSERVERERROR;
$response->error = "Updates data invalid";
$response->error_detail = "INTERNAL_SERVER_ERROR";
$out = false;
return $response;
}

ZoneFunctions::get_zone($response, $identifier, $o, false, true, true);

if (empty($o)) {
$out = false;
return $response;
}

if ($o['type'] == "SLAVE") {
$response->code = Response::CONFLICT;
$response->error = sprintf("Cannot update records from SLAVE zone %s", $identifier);
$response->error_detail = "ZONE_IS_SLAVE";
$out = false;
return $response;
}

$zone_id = $o['z_id'];

if (empty($zone_id) || !ctype_digit($zone_id)) {
$response->code = Response::INTERNALSERVERERROR;
$response->error = "Could not retrieve Zone ID to delete records from" . var_export($o, true);
$response->error_detail = "INTERNAL_SERVER_ERROR";
$out = false;
return $response;
}

unset($o);

$commit = false;
if ($connection === null) {
try {
$connection = Database::getConnection();
} catch (PDOException $e) {
$response->code = Response::INTERNALSERVERERROR;
$response->error = "Could not connect to PowerDNS server.";
$response->error_detail = "INTERNAL_SERVER_ERROR";
$out = false;
return $response;
}
$connection->beginTransaction();
$commit = true;
}

$updated = 0;
foreach ($data->records as $record) {
if ( !isset($record->r_id) ) {
continue;
}
//need at least 3 attributes. mode, r_id and something to update
if ( isset( $record->r_id ) && count( (array) $record) < 3 ){
continue;
}
foreach ( array_keys( (array)$record ) as $f_name ){
if ( !in_array($f_name, array( 'prio','content','name','ttl','type') ) ) continue;
$stmt = $connection->prepare(sprintf(
"UPDATE `%s` SET `%s` = :f_value WHERE domain_id = %s AND id = :r_id;", PowerDNSConfig::DB_RECORD_TABLE,$f_name,$zone_id
));
$stmt->bindParam(":r_id", $record->r_id);
$stmt->bindParam(":f_value", $record->$f_name);
//$r_id = $record->r_id;
//$f_value = $record->$f_name;
if ($stmt->execute() === false) {
$response->code = Response::INTERNALSERVERERROR;
$response->error = sprintf("Rolling back transaction, failed to update zone record - did: '%s', r_id: '%s', key: '%s', value: '%s'", $zone_id,$record->r_id, $f_name, $record->$f_name);
$response->error_detail = "RECORD_UPDATE_FAILED";
if ($commit == true) {
$connection->rollback();
}
$out = false;
return $response;
}
$updated++;
}
}

if ($commit == true) {
$connection->commit();
}

$response->code = Response::OK;
$response->body = true;
$response->log_message = sprintf("Zone %s updated %d of %d records.", $identifier, $updated,count($data->records));
$out = true;

return $response;
}
public function delete_records($response, $identifier, $data, &$out = null, $connection = null) {
if (!is_object($data) || !isset($data->records)) {
$response->code = Response::INTERNALSERVERERROR;
Expand Down Expand Up @@ -639,10 +771,10 @@ public function delete_records($response, $identifier, $data, &$out = null, $con
$out = false;
return $response;
}

$connection->beginTransaction();
$commit = true;
}


$statement = $connection->prepare(sprintf(
"DELETE FROM `%s` WHERE domain_id = :did AND name = :name AND type = :type AND prio = :priority AND content = :content;", PowerDNSConfig::DB_RECORD_TABLE
Expand All @@ -663,37 +795,41 @@ public function delete_records($response, $identifier, $data, &$out = null, $con
$statement_noprio->bindParam(":type", $r_type);
$statement_noprio->bindParam(":content", $r_content);

$statement_rid = $connection->prepare(sprintf("DELETE FROM `%s` WHERE id = :rid",PowerDNSConfig::DB_RECORD_TABLE));
$statement_rid->bindParam(":rid", $r_rid);

$r_did = $zone_id;

foreach ($data->records as $record) {
$stmt = $statement_noprio;
if (!isset($record->name) || !isset($record->type) || !isset($record->content)) {
if ( (!isset($record->name) || !isset($record->type) || !isset($record->content)) && !isset($record->r_id) ) {
continue;
}

if (($record->type == "MX") || ($record->type == "SRV")) {
if (!isset($record->priority)) {
continue;
} else {
$stmt = $statement;
if ( isset( $record->r_id ) ){
$stmt = $statement_rid;
$r_rid = $record->r_id;
} else {
if (($record->type == "MX") || ($record->type == "SRV")) {
if (!isset($record->priority)) {
continue;
} else {
$stmt = $statement;
}
}

$r_name = $record->name;
$r_type = $record->type;
$r_content = $record->content;
$r_prio = $record->priority;
}

$r_name = $record->name;
$r_type = $record->type;
$r_content = $record->content;
$r_prio = $record->priority;

if ($stmt->execute() === false) {
$response->code = Response::INTERNALSERVERERROR;
$response->error = sprintf("Rolling back transaction, failed to delete zone record - name: '%s', type: '%s', prio: '%s'", $r_name, $r_type, $r_prio);
$response->error_detail = "RECORD_DELETE_FAILED";

if ($commit == true) {
$connection->rollback();
}
$out = false;

return $response;
}
}
Expand Down
1 change: 1 addition & 0 deletions codes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ RECORD_CNAME_OTHER_INSERT
RECORD_CNAME_OTHER_PRESENT
RECORD_DELETE_FAILED
RECORD_INSERT_FAILED
RECORD_UPDATE_FAILED
RECORD_INVALID_CHANGE_DATE
RECORD_INVALID_CODE
RECORD_INVALID_NAME
Expand Down
2 changes: 1 addition & 1 deletion lib/pdo_token_backend.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function __construct() {
try {
$this->connection = Database::getConnection();
} catch (Exception $e) {
throw new Exception("Failed to open database connection");
throw new Exception("Failed to open database connection: $e");
}
}

Expand Down
6 changes: 5 additions & 1 deletion lib/tonic.php
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,11 @@ function __construct($config = array()) {
$raw_headers = apache_request_headers();
} else if (function_exists("nsapi_request_headers")) {
$raw_headers = nsapi_request_headers();
} else if (substr(php_sapi_name(), -3) == 'cgi' ) {
$this->requestType = $_SERVER['HTTP_CONTENT_TYPE'];
if (isset( $_SERVER['HTTP_X_AUTHENTICATION_TOKEN'] )){
$this->requestToken = $_SERVER['HTTP_X_AUTHENTICATION_TOKEN'];
}
}
foreach ($raw_headers as $k => $h) {
switch (strtolower($k)) {
Expand Down Expand Up @@ -761,7 +766,6 @@ class NoResource extends Resource {
* @return Response
*/
function exec($request) {

// send 404 not found
$response = new Response($request);
$response->code = Response::NOTFOUND;
Expand Down