EscapeHTML = false;
if (array_key_exists('in_transfer', $domain_info) && $domain_info['in_transfer'] === true)
{
$is_ok = false;
$status->Text .= ' Warning: This domain is being transfered between different master servers
';
}
if (array_key_exists('read_only', $domain_info) && $domain_info['read_only'] === true)
{
$is_ok = false;
$status->Text .= ' Warning: This domain is read only
';
}
if (!IsAuthorizedToRead($domain))
{
$is_ok = false;
$status->Text .= ' Can\'t read: you are not authorized to read this zone.
';
}
if (!IsAuthorizedToWrite($domain))
{
$is_ok = false;
$status->Text .= ' Can\'t write: you are not authorized to write this zone.
';
}
if (array_key_exists('maintenance_note', $domain_info))
{
$is_ok = false;
$status->Text .= ' Maintenance note: ' .$domain_info['maintenance_note'];
}
if (array_key_exists('note', $domain_info))
{
$is_ok = false;
$status->Text .= ' Note: ' .$domain_info['note'];
}
if ($is_ok)
return NULL;
return $status;
}
// This function will go through parsed zone data and will return SOA record if present, otherwise will return NULL
function GetSOAFromData($data)
{
$soa = NULL;
foreach ($data as $record)
{
if ($record[3] === 'SOA')
{
$soa = $record[4];
break;
}
}
return $soa;
}
//! Go through whole zone and check if SOA is present on end
function CheckIfZoneIsComplete($data)
{
if ($data[0][3] !== 'SOA')
return false;
if (end($data)[3] !== 'SOA')
return false;
return true;
}
function GetRecordList($zone)
{
global $g_caching_engine, $g_caching_engine_instance, $g_retry_on_error;
if (!IsAuthorizedToRead($zone))
return array();
// Check if zone data exist in cache
if ($g_caching_engine_instance->IsCached($zone))
{
// There is something in the zone cache
Debug('Zone ' . $zone . ' exist in cache, checking if SOA record is identical');
$current_soa = GetSOAFromData(get_zone_soa($zone));
$cached_soa = $g_caching_engine_instance->GetSOA($zone);
if ($current_soa === NULL)
{
// Something is very wrong - there is no SOA record in our query
// Check if retry on error is enabled, if yes, try N more times, if it doesn't help, show error
if ($g_retry_on_error > 0)
{
$retry = $g_retry_on_error;
$current_retry = 0;
while ($retry-- > 0)
{
$current_retry++;
Debug("Unable to retrieve SOA record for " . $zone . " (dig SOA returned no data), retrying dig ($current_retry/$g_retry_on_error)...");
$current_soa = GetSOAFromData(get_zone_soa($zone));
if ($current_soa !== NULL)
{
DisplayWarning("Transfer NS for " . $zone . " had troubles returning SOA record, had to retry $current_retry times, check your network");
break;
}
}
}
// if SOA is still NULL, show non-blocking error
if ($current_soa === NULL)
Error("Unable to retrieve SOA record for " . $zone . " - (dig SOA) transfer NS didn't return any data for it", false);
} else if ($current_soa != $cached_soa)
{
Debug("Cache miss: '$current_soa' != '$cached_soa'");
} else if ($current_soa == $cached_soa)
{
Debug("Cache match! Not running a full zone transfer");
// Return data from cache instead of running full zone transfer
$result = $g_caching_engine_instance->GetData($zone);
if ($result === false)
{
Debug('SOA exist in cache, but data not (corrupted cache), dropping memory and falling back to full zone transfer');
$g_caching_engine_instance->Drop($zone);
} else
{
WriteToAuditFile("display", $zone, "(cached)");
IncrementStat('display_zone_cached');
return $result;
}
}
} else if ($g_caching_engine !== NULL)
{
Debug('Zone ' . $zone . ' does not exist in cache, running full zone transfer');
}
WriteToAuditFile("display", $zone, "(full transfer)");
IncrementStat('display_zone');
Debug('Running full zone transfer for: ' . $zone);
$data = get_zone_data($zone);
$soa = GetSOAFromData($data);
if ($soa === NULL)
{
// Again - server returned no SOA record, there is some network issue
if ($g_retry_on_error > 0)
{
$retry = $g_retry_on_error;
$current_retry = 0;
while ($retry-- > 0)
{
$current_retry++;
Debug("Unable to retrieve SOA record for " . $zone . " (dig AXFR returned no data), retrying dig ($current_retry/$g_retry_on_error)...");
$data = get_zone_data($zone);
$soa = GetSOAFromData($data);
if ($soa !== NULL)
{
DisplayWarning("Transfer NS for " . $zone . " had troubles returning SOA record during AXFR, had to retry $current_retry times, check your network");
break;
}
}
}
if ($soa === NULL)
Error("Unable to retrieve SOA record for " . $zone . " - (dig AXFR) transfer NS didn't return any data for it", false);
else
$g_caching_engine_instance->CacheZone($zone, $soa, $data);
} else
{
$g_caching_engine_instance->CacheZone($zone, $soa, $data);
}
if (count($data) > 0 && !CheckIfZoneIsComplete($data))
DisplayWarning("Transfer NS for " . $zone . " didn't return full zone, last SOA record is missing, zone data are incomplete");
return $data;
}
function GetRecordListTable($parent, $domain)
{
global $g_editable, $g_show_hidden_types, $g_hidden_record_types, $g_hidden_types_present, $g_total_records_count, $g_hidden_records_count;
$table = new BS_Table($parent);
$table->Condensed = true;
$table->Headers = [ "Record", "TTL", "Scope", "Type", "Value", "Options" ];
$table->SetColumnWidth(2, '80px'); // Scope
$table->SetColumnWidth(3, '80px'); // Type
$table->SetColumnWidth(5, '80px'); // Options
$records = GetRecordList($domain);
$is_editable = Zones::IsEditable($domain) && IsAuthorizedToWrite($domain);
$has_ptr = Zones::HasPTRZones();
foreach ($records as $record)
{
$g_total_records_count++;
if (in_array($record[3], $g_hidden_record_types))
{
$g_hidden_types_present = true;
if (!$g_show_hidden_types)
{
$g_hidden_records_count++;
continue;
}
}
if (!$is_editable || !in_array($record[3], $g_editable))
{
$record[] = '';
} else
{
$delete_record = '';
$delete_record_with_ptr = '';
if ($has_ptr && $record[3] == 'A')
{
// Optional button to delete record together with PTR record, show only if there are PTR zones in cfg
$delete_record_with_ptr = '';
}
$large_space = ' ';
$record[] = $delete_record . $large_space . '' . $large_space . $delete_record_with_ptr;
}
$record[4] = '' . $record[4] . '';
$table->AppendRow($record);
}
if ($is_editable) {
$add = '';
$table->AppendRow(['', '', '', '', '', $add]);
}
return $table;
}
//! This return similar results to GetRecordListTable but without option buttons in format friendly for exporting
function GetRecordListTablePlainFormat($parent, $domain)
{
$table = new HtmlTable($parent);
$table->Headers = [ "Record", "TTL", "Scope", "Type", "Value" ];
$records = GetRecordList($domain);
foreach ($records as $record)
{
$table->AppendRow($record);
}
return $table;
}