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; }