Compare commits

...

12 commits

Author SHA1 Message Date
Petr Bena
79f283bdcb generic note 2024-04-17 10:34:25 +02:00
Petr Bena
75ebf21481
Update README.md 2024-01-10 13:37:43 +01:00
Petr Bena
fe8e330cc3 use new value when creating PTR 2023-12-19 11:44:02 +01:00
Petr Bena
a7a383f109 compatibility with older PHP 2023-12-18 13:37:59 +01:00
Petr Bena
1c5abafcbc updated year 2023-12-18 13:11:39 +01:00
Petr Bena
63c0835625 missing implementation of replace_record 2023-12-18 13:07:47 +01:00
Petr Bena
74226bb2e0 new config option -> default ttl per domain 2023-07-03 10:26:45 +02:00
Petr Bena
b55e907e1b use action=new instead of edit for new record
otherwise there are warnings for undefined variables produced with
debugging enabled
2023-01-02 11:16:09 +01:00
Henrik Nordstrom
c018918d8f Add new icon in record list
easier to find than navigating to the New/edit record tab
2023-01-02 11:12:18 +01:00
Petr Bena
d0164f3116 moved custom user config include
I think it needs to be included after session initialization, otherwise
the $_SESSION will not work as expected
2022-07-08 10:50:01 +02:00
Petr Bena
ccfb9721a9 updated PSF
previous commit changed it to some older version, just to make sure...
2022-07-08 10:45:28 +02:00
Henrik Nordström
d4729052a5
Adds the option of per-user configuration files (#16)
* Per user config file
2022-07-08 10:44:47 +02:00
12 changed files with 112 additions and 12 deletions

View file

@ -38,4 +38,10 @@ vi config.php
Now update `$g_domains` so that it contains information about zones you want to manage. Web server must have nsupdate and dig Linux commands installed in paths that are in config.php and it also needs to have firewall access to perform zone transfer and to perform nsupdate updates.
## Docker image
There is also a docker image maintained by Eugene Taylashev
* GitHub: https://github.com/eugene-taylashev/docker-dnsphpadmin
* Docker Hub: https://hub.docker.com/repository/docker/etaylashev/dnsphpadmin
**IMPORTANT:** DNS tool doesn't use any authentication by default, so everyone with access to web server will have access to DNS tool. If this is just a simple setup for 1 or 2 admins who should have unlimited access to everything, you should setup login via htaccess or similar see https://httpd.apache.org/docs/2.4/howto/auth.html for apache. If you have LDAP (active directory is also LDAP), you can configure this tool to use LDAP authentication as well.

39
api.php
View file

@ -239,7 +239,7 @@ function api_call_create_record($source)
$type = get_required_post_get_parameter('type');
$value = get_required_post_get_parameter('value');
$comment = get_optional_post_get_parameter('comment');
$ptr = get_optional_post_get_parameter('ptr');
$ptr = IsTrue(get_optional_post_get_parameter('ptr'));
$merge_record = true;
if ($zone === NULL)
@ -268,7 +268,7 @@ function api_call_create_record($source)
}
$n = "server " . $g_domains[$zone]['update_server'] . "\n";
$merged_record = "";
$merged_record = NULL;
if ($merge_record)
{
$n .= ProcessInsertFromPOST($zone, $record, $value, $type, $ttl);
@ -311,7 +311,7 @@ function api_call_replace_record($source)
$comment = get_optional_post_get_parameter('comment');
$new_record = get_optional_post_get_parameter('new_record');
$new_type = get_optional_post_get_parameter('new_type');
$ptr = get_optional_post_get_parameter('ptr');
$ptr = IsTrue(get_optional_post_get_parameter('ptr'));
$merge_record = true;
// Auto-fill optional
@ -343,16 +343,47 @@ function api_call_replace_record($source)
}
$old = NULL;
$old_record = NULL;
$merged_record = NULL;
if (!$merge_record)
{
$old = $record . ' 0 ' . $type;
else
$old_record = $record;
$merged_record = $new_record;
} else
{
$old = $record . '.' . $zone . ' 0 ' . $type;
$old_record = $record . '.' . $zone;
$merged_record = $new_record . '.' . $zone;
}
if ($value !== NULL)
$old .= ' ' . $value;
DNS_ModifyRecord($zone, $new_record, $new_value, $new_type, $ttl, $comment, $old, !$merge_record);
if ($ptr)
{
if ($type != 'A' && $new_type != 'A')
{
api_warning("You requested to modify underlying PTR record, but neither new or old record type is A record, ignoring PTR update request");
} else
{
// PTR update was requested, if old type was A, delete it. If new type is A, create it
if ($type == 'A')
{
if ($value === NULL)
api_warning("Old PTR record was not deleted, because parameter value was not provided - so we don't know what to delete");
else
DNS_DeletePTRForARecord($value, $old_record, $comment);
}
if (($new_type === NULL && $type == 'A') || $new_type == 'A')
{
DNS_InsertPTRForARecord($new_value, $merged_record, $ttl, $comment);
}
}
}
print_success();
return true;
}

View file

@ -30,8 +30,10 @@ $g_domains = [ 'example.domain' => [ 'transfer_server' => 'localhost', 'update_s
// 'read_only' => false, // by default false, if true domain will be read only
// 'in_transfer' => false, // if true domain will be marked as "in transfer" which means it's being transfered from one DNS master to another, so the records may not reflect truth
// 'maintenance_note' => 'This domain is being configured now', // maintenance note to display for this domain
// 'note' => 'This zone is very important', // generic note to display for this domain
// 'tsig' => true,
// 'tsig_key' => 'some_key' ] ];
// 'tsig_key' => 'some_key',
// 'ttl' => 3600 ] ]; // Overrides default global TTL for new records
// List of record types that can be edited
// https://en.wikipedia.org/wiki/List_of_DNS_record_types
@ -41,7 +43,7 @@ $g_editable = [ 'A', 'AAAA', 'CNAME', 'DNAME', 'DS', 'NS', 'PTR', 'SRV', 'SSHFP'
// API is not affected by this
$g_hidden_record_types = [ 'NSEC', 'RRSIG' ];
// Default TTL for new DNS records
// Default TTL for new DNS records (can be also specified per zone using ttl key)
$g_default_ttl = 3600;
// Path to executable of dig, you can also use this to specify some dig options for example:
@ -228,3 +230,6 @@ $g_caching_memcached_expiry = 0;
// You can optionally enable in-cache statistics that can be exported for use with monitoring, such as prometheus, to obtain usage metrics
$g_caching_stats_enabled = false;
// Per-user configuration location
$g_user_config_prefix = null;

View file

@ -13,6 +13,6 @@
if (!defined('G_DNSTOOL_ENTRY_POINT'))
die("Not a valid entry point");
define('G_DNSTOOL_VERSION', '1.11.0');
define('G_DNSTOOL_VERSION', '1.12.0');
define('G_API_ELOGIN', 2);
define('G_HEADER', 'DNS management tool');

View file

@ -151,3 +151,20 @@ function GetCurrentUserName()
return "unknown user";
return $_SERVER['REMOTE_USER'];
}
//! Required to handle various non-standard boolean interpretations, mostly for strings from API requests
function IsTrue($bool)
{
if ($bool === true)
return true;
// Check string version
if ($bool == "true" || $bool == "t")
return true;
// Check int version
if (is_numeric($bool) && $bool != 0)
return true;
return false;
}

View file

@ -68,6 +68,11 @@ function GetStatusOfZoneAsNote($domain)
$is_ok = false;
$status->Text .= '<span class="glyphicon glyphicon-alert"></span> <b>Maintenance note:</b> ' .$domain_info['maintenance_note'];
}
if (array_key_exists('note', $domain_info))
{
$is_ok = false;
$status->Text .= '<span class="glyphicon glyphicon-info"></span> <b>Note:</b> ' .$domain_info['note'];
}
if ($is_ok)
return NULL;
@ -248,6 +253,10 @@ function GetRecordListTable($parent, $domain)
$record[4] = '<span class="value">' . $record[4] . '</span>';
$table->AppendRow($record);
}
if ($is_editable) {
$add = '<a href="index.php?action=new&domain=' . $domain . '"><span title="Add New" class="glyphicon glyphicon-plus"></span></a>';
$table->AppendRow(['', '', '', '', '', $add]);
}
return $table;
}

View file

@ -118,7 +118,7 @@ class TabEdit
public static function GetInsertForm($parent, $edit_mode = false, $default_key = "", $default_ttl = NULL, $default_type = "A", $default_value = "", $default_comment = "")
{
global $g_audit, $g_selected_domain, $g_domains, $g_editable, $g_default_ttl;
global $g_audit, $g_selected_domain, $g_domains, $g_editable;
// In case we are returning to insert form from previous insert, make default type the one we used before
if (isset($_POST['type']))
@ -137,7 +137,7 @@ class TabEdit
// If ttl is not specified use default one from config file
if ($default_ttl === NULL)
$default_ttl = strval($g_default_ttl);
$default_ttl = strval(Zones::GetDefaultTTL($g_selected_domain));
$form = new Form("index.php?action=new", $parent);
$form->Method = FormMethod::Post;

View file

@ -45,6 +45,10 @@ class TabOverview
$is_ok = false;
$status .= '<span class="glyphicon glyphicon-alert" title="' . $domain_info['maintenance_note'] . '"></span>&nbsp;';
}
if (array_key_exists('note', $domain_info))
{
$status .= '&nbsp;<span class="glyphicon glyphicon-comment" title="' . $domain_info['note'] . '"></span>&nbsp;';
}
if ($is_ok)
return '<span class="glyphicon glyphicon-ok" title="OK"></span>' . $status;

View file

@ -30,6 +30,9 @@ class Zones
if (isset($properties['in_transfer']))
$result[$domain]['in_transfer'] = $properties['in_transfer'];
if (isset($properties['note']))
$result[$domain]['note'] = $properties['note'];
if (isset($properties['maintenance_note']))
$result[$domain]['maintenance_note'] = $properties['maintenance_note'];
@ -78,5 +81,23 @@ class Zones
}
return false;
}
public static function GetDefaultTTL($domain)
{
global $g_default_ttl, $g_domains;
if ($domain === NULL)
return $g_default_ttl;
if (!array_key_exists($domain, $g_domains))
die("No such zone: $domain");
$domain_info = $g_domains[$domain];
if (array_key_exists('ttl', $domain_info))
return $domain_info['ttl'];
return $g_default_ttl;
}
}

View file

@ -42,6 +42,9 @@ if ($g_use_local_bootstrap)
// Start up the program, initialize all sorts of resources, syslog, session data etc.
Initialize();
if ($g_user_config_prefix !== null)
include($g_user_config_prefix.GetCurrentUserName().".php");
// Save us some coding
$psf_containers_auto_insert_child = true;
@ -165,7 +168,7 @@ if (RequireLogin())
// Bug workaround - the footer seems to take up some space
$website->AppendHtml("<br><br><br>");
$website->AppendHtmlLine("<footer class='footer'><div class='container'>Created by Petr Bena [petr@bena.rocks] (c) 2018 - 2020, source code at ".
$website->AppendHtmlLine("<footer class='footer'><div class='container'>Created by Petr Bena [petr@bena.rocks] (c) 2018 - 2023, source code at ".
"<a href='https://github.com/benapetr/dnsphpadmin'>https://github.com/benapetr/dnsphpadmin</a> Version: " . G_DNSTOOL_VERSION . "</div></footer>");
$website->PrintHtml();

2
psf

@ -1 +1 @@
Subproject commit e436e7c3dfb34aaf8acb4cefa972474ebc09f199
Subproject commit 776af33fed083797593e1da7bb5ec902f7758322

View file

@ -38,11 +38,15 @@ function CheckZone($data)
$ut = new UnitTest();
$g_default_ttl = 3600;
$ut->Evaluate('Check for non-existence of PTR zones (none) in empty list', Zones::HasPTRZones() === false);
$g_domains['168.192.in-addr.arpa'] = [ ];
$g_domains['192.in-addr.arpa'] = [ ];
$g_domains['192.in-addr.arpa'] = [ 'ttl' => 200 ];
$ut->Evaluate('Check for non-existence of PTR zones (none) in empty list', Zones::HasPTRZones() === true);
$ut->Evaluate('Get zone for FQDN', Zones::GetZoneForFQDN('0.0.168.192.in-addr.arpa') == '168.192.in-addr.arpa');
$ut->Evaluate('Test GetDefaultTTL()', Zones::GetDefaultTTL('168.192.in-addr.arpa') == 3600);
$ut->Evaluate('Test GetDefaultTTL()', Zones::GetDefaultTTL('192.in-addr.arpa') == 200);
$dz1 = raw_zone_to_array(file_get_contents(dirname(__FILE__) . '/testdata/valid.zone1'));
$dz2 = raw_zone_to_array(file_get_contents(dirname(__FILE__) . '/testdata/invalid.zone'));