Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions model/zone.php
Original file line number Diff line number Diff line change
Expand Up @@ -712,13 +712,14 @@ public function process_bulk_json_rrset_update($update, $author = null) {
$errors = array();
$revs_missing = array('A' => array(), 'AAAA' => array());
$revs_updated = array();
$acting_user = $author ?? $active_user;
$update = json_decode($update);
if(is_null($update)) throw new InvalidJSON(json_last_error_msg());
if(!isset($update->actions) && !is_array($update->actions)) throw new BadData('No actions provided.');
if(isset($config['web']['force_change_comment']) && intval($config['web']['force_change_comment']) == 1 && empty($update->comment)) throw new BadData('A change comment must be provided.');
foreach($update->actions as $action) {
try {
$changes[] = $this->process_rrset_action($action, $trash, $revs_missing, $revs_updated);
$changes[] = $this->process_rrset_action($action, $trash, $revs_missing, $revs_updated, $acting_user);
} catch(RuntimeException $e) {
$errors[] = $e->getMessage();
}
Expand Down Expand Up @@ -810,7 +811,7 @@ private function process_rrset_action($update, &$trash, &$revs_missing, &$revs_u
if(!$autocreate_ptr || $rr->disabled) {
$rr->{'set-ptr'} = false;
} else {
$rr->{'set-ptr'} = $zone_dir->check_reverse_record_zone($rrset->name, $rrset->type, $rr->content, $revs_missing, $revs_updated);
$rr->{'set-ptr'} = $zone_dir->check_reverse_record_zone($rrset->name, $rrset->type, $rr->content, $revs_missing, $revs_updated, $acting_user);
}
$rrset->add_resource_record($rr);
}
Expand Down Expand Up @@ -849,7 +850,7 @@ private function process_rrset_action($update, &$trash, &$revs_missing, &$revs_u
if(!$autocreate_ptr || $rr->disabled) {
$rr->{'set-ptr'} = false;
} else {
$rr->{'set-ptr'} = $zone_dir->check_reverse_record_zone($rrset->name, $rrset->type, $rr->content, $revs_missing, $revs_updated);
$rr->{'set-ptr'} = $zone_dir->check_reverse_record_zone($rrset->name, $rrset->type, $rr->content, $revs_missing, $revs_updated, $acting_user);
}
$rrset->add_resource_record($rr);
}
Expand Down
16 changes: 15 additions & 1 deletion model/zonedirectory.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,12 @@ public function list_accounts() {
* @param string $address that DNS record points to
* @param array $revs_missing keep track of reverse zones that are missing
* @param array $revs_updated keep track of reverse zones that will be updated
* @param User|null $acting_user The user on whose behalf this change is executed. If null,
* falls back to $active_user for backward-compatibility.
*/
public function check_reverse_record_zone($name, $type, $address, &$revs_missing, &$revs_notify) {
public function check_reverse_record_zone($name, $type, $address, &$revs_missing, &$revs_notify, $acting_user = null) {
global $zone_dir, $active_user;
$acting = $acting_user ?: $active_user;

if($type == 'A') {
$reverse_address = implode('.', array_reverse(explode('.', $address))).'.in-addr.arpa.';
Expand All @@ -248,6 +251,17 @@ public function check_reverse_record_zone($name, $type, $address, &$revs_missing
do {
try {
$reverse_zone = $zone_dir->get_zone_by_name($reverse_zone_name);
// only allow if acting user can administer the reverse zone
$level = ($acting->admin ? 'administrator' : $acting->access_to($reverse_zone));
if ($level !== 'administrator') {
// Don’t leak zone details if the user cannot actually access it
$alert = new UserAlert;
$alert->content = 'Reverse record could not be created for '.hesc($address).' in <a href="'.rrurl('/zones/'.urlencode(DNSZoneName::unqualify($reverse_zone->name))).'" class="alert-link">'.hesc(DNSZoneName::unqualify($reverse_zone->name)).'</a> because the original requester does not have permission to modify this reverse zone. Not creating PTR record for '.hesc($name);
$alert->class = 'warning';
$acting->add_alert($alert);
return false;
}

// See if a record already exists for this IP
foreach($reverse_zone->list_resource_record_sets() as $rrset) {
if($rrset->name == $reverse_address) {
Expand Down