From fb5626881336ea6c10f2d39daf6aaa6346adf3f7 Mon Sep 17 00:00:00 2001 From: Choong Wei Tjeng Date: Mon, 5 Nov 2018 20:49:33 +0100 Subject: [PATCH 01/23] #5161 DNSSEC support for PowerDNS --- interface/web/dns/lib/lang/ar_dns_soa.lng | 2 +- interface/web/dns/lib/lang/bg_dns_soa.lng | 2 +- interface/web/dns/lib/lang/br_dns_soa.lng | 2 +- interface/web/dns/lib/lang/ca_dns_soa.lng | 2 +- interface/web/dns/lib/lang/cz_dns_soa.lng | 2 +- interface/web/dns/lib/lang/de_dns_soa.lng | 2 +- interface/web/dns/lib/lang/dk_dns_soa.lng | 2 +- interface/web/dns/lib/lang/el_dns_soa.lng | 2 +- interface/web/dns/lib/lang/en_dns_soa.lng | 2 +- interface/web/dns/lib/lang/es_dns_soa.lng | 2 +- interface/web/dns/lib/lang/fi_dns_soa.lng | 2 +- interface/web/dns/lib/lang/fr_dns_soa.lng | 2 +- interface/web/dns/lib/lang/hr_dns_soa.lng | 2 +- interface/web/dns/lib/lang/hu_dns_soa.lng | 2 +- interface/web/dns/lib/lang/id_dns_soa.lng | 2 +- interface/web/dns/lib/lang/it_dns_soa.lng | 2 +- interface/web/dns/lib/lang/ja_dns_soa.lng | 2 +- interface/web/dns/lib/lang/nl_dns_soa.lng | 2 +- interface/web/dns/lib/lang/pl_dns_soa.lng | 2 +- interface/web/dns/lib/lang/pt_dns_soa.lng | 2 +- interface/web/dns/lib/lang/ro_dns_soa.lng | 2 +- interface/web/dns/lib/lang/ru_dns_soa.lng | 2 +- interface/web/dns/lib/lang/se_dns_soa.lng | 2 +- interface/web/dns/lib/lang/sk_dns_soa.lng | 2 +- interface/web/dns/lib/lang/tr_dns_soa.lng | 2 +- interface/web/dns/templates/dns_soa_edit.htm | 11 + .../plugins-available/powerdns_plugin.inc.php | 210 +++++++++++++++++- 27 files changed, 238 insertions(+), 33 deletions(-) diff --git a/interface/web/dns/lib/lang/ar_dns_soa.lng b/interface/web/dns/lib/lang/ar_dns_soa.lng index 98b79d5861..4e93c5b41c 100644 --- a/interface/web/dns/lib/lang/ar_dns_soa.lng +++ b/interface/web/dns/lib/lang/ar_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/bg_dns_soa.lng b/interface/web/dns/lib/lang/bg_dns_soa.lng index fa08521196..151e3ead11 100644 --- a/interface/web/dns/lib/lang/bg_dns_soa.lng +++ b/interface/web/dns/lib/lang/bg_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/br_dns_soa.lng b/interface/web/dns/lib/lang/br_dns_soa.lng index 34f71ba5ae..fcad62b44d 100644 --- a/interface/web/dns/lib/lang/br_dns_soa.lng +++ b/interface/web/dns/lib/lang/br_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'O ttl mínimo são 60 segundos.'; $wb['xfer_error_regex'] = 'Também notificar: Por favor, insira um endereço IP.'; $wb['dnssec_info_txt'] = 'Registro para DNSSEC (DS-Data)'; $wb['dnssec_wanted_txt'] = 'Zona assinada (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'Quando desabilitar o DNSSEC as chaves não são eliminadas mas a zona não será disponibilizada assinada.'; +$wb['dnssec_wanted_info'] = 'Quando desabilitar o DNSSEC as chaves não são eliminadas mas a zona não será disponibilizada assinada. Se você usar o PowerDNS, as chaves serão excluídas!'; $wb['error_not_allowed_server_id'] = 'O servidor selecionado não tem permissão para esta conta.'; $wb['soa_cannot_be_changed_txt'] = 'A zona SOA não pode ser modificada. Entre em contato com o administrador para alterar esta zona.'; $wb['configuration_error_txt'] = 'ERRO DE CONFIGURAÇÃO'; diff --git a/interface/web/dns/lib/lang/ca_dns_soa.lng b/interface/web/dns/lib/lang/ca_dns_soa.lng index 6ecc2762a3..aaf07a0b99 100644 --- a/interface/web/dns/lib/lang/ca_dns_soa.lng +++ b/interface/web/dns/lib/lang/ca_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'La TTL minimum est 60 secondes.'; $wb['xfer_error_regex'] = 'A noter également : Veuillez utiliser une adresse IP.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/cz_dns_soa.lng b/interface/web/dns/lib/lang/cz_dns_soa.lng index c3e75ca2ee..7dfbb0e91b 100644 --- a/interface/web/dns/lib/lang/cz_dns_soa.lng +++ b/interface/web/dns/lib/lang/cz_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL čas je 60 sekund.'; $wb['xfer_error_regex'] = 'Také oznámí: Prosím, použijte IP adresu.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Podepsat zónu (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'Když deaktivujete DNSSEC klíče nebudou odstraněny, ale DNS záznamy (zóna) již nebudou propagovány v podepsaném formátu.'; +$wb['dnssec_wanted_info'] = 'Když deaktivujete DNSSEC klíče nebudou odstraněny, ale DNS záznamy (zóna) již nebudou propagovány v podepsaném formátu. Pokud používáte PowerDNS, budou klíče WILL vymazány!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/de_dns_soa.lng b/interface/web/dns/lib/lang/de_dns_soa.lng index 719162e201..35d0e54ccd 100644 --- a/interface/web/dns/lib/lang/de_dns_soa.lng +++ b/interface/web/dns/lib/lang/de_dns_soa.lng @@ -13,7 +13,7 @@ $wb['xfer_txt'] = 'Zonentransfer zu diesen IP Adressen erlauben (mit Komma getre $wb['active_txt'] = 'Aktiv'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Daten für Registry'; $wb['dnssec_wanted_txt'] = 'Zone signieren (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'Wenn DNSSEC bereits aktiviert war und ein Key erstellt wurde, wird dieser durch deaktivieren nicht gelöscht. Die Zone wird dann jedoch nicht länger signiert ausgeliefert.'; +$wb['dnssec_wanted_info'] = 'Wenn DNSSEC bereits aktiviert war und ein Key erstellt wurde, wird dieser durch deaktivieren nicht gelöscht. Die Zone wird dann jedoch nicht länger signiert ausgeliefert. Wenn Sie PowerDNS verwenden, werden die Schlüssel gelöscht!'; $wb['limit_dns_zone_txt'] = 'Die maximale Anzahl an DNS Einträgen für Ihr Konto wurde erreicht.'; $wb['client_txt'] = 'Kunde'; $wb['no_zone_perm'] = 'Sie haben nicht die Berechtigung, einen Eintrag zu dieser DNS Zone hinzuzufügen.'; diff --git a/interface/web/dns/lib/lang/dk_dns_soa.lng b/interface/web/dns/lib/lang/dk_dns_soa.lng index 193dc9f4a2..1c8c5cc53c 100644 --- a/interface/web/dns/lib/lang/dk_dns_soa.lng +++ b/interface/web/dns/lib/lang/dk_dns_soa.lng @@ -37,7 +37,7 @@ $wb['minimum_range_error'] = 'Min. Minimum tid er 60 sekunder.'; $wb['ttl_range_error'] = 'Min. TTL tid er 60 sekunder.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'The Zone (SOA) can not be changed. Please contact your administrator to change the zone.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/el_dns_soa.lng b/interface/web/dns/lib/lang/el_dns_soa.lng index 773d25ab66..4d8c876d28 100644 --- a/interface/web/dns/lib/lang/el_dns_soa.lng +++ b/interface/web/dns/lib/lang/el_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/en_dns_soa.lng b/interface/web/dns/lib/lang/en_dns_soa.lng index af1f3db565..03dd6834c9 100644 --- a/interface/web/dns/lib/lang/en_dns_soa.lng +++ b/interface/web/dns/lib/lang/en_dns_soa.lng @@ -13,7 +13,7 @@ $wb["xfer_txt"] = 'Allow zone transfers to
these IPs (comma separated list $wb["active_txt"] = 'Active'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb["limit_dns_zone_txt"] = 'The max. number of DNS zones for your account is reached.'; $wb["client_txt"] = 'Client'; $wb["no_zone_perm"] = 'You do not have the permission to add a record to this DNS zone.'; diff --git a/interface/web/dns/lib/lang/es_dns_soa.lng b/interface/web/dns/lib/lang/es_dns_soa.lng index 189f8f5adf..23f4cc5ffc 100755 --- a/interface/web/dns/lib/lang/es_dns_soa.lng +++ b/interface/web/dns/lib/lang/es_dns_soa.lng @@ -4,7 +4,7 @@ $wb['also_notify_error_regex'] = 'También notificar a: Por favor use una direcc $wb['also_notify_txt'] = 'También notificar a'; $wb['client_txt'] = 'Cliente'; $wb['dnssec_info_txt'] = 'Datos DS para el registro DNSSEC'; -$wb['dnssec_wanted_info'] = 'Cuando se deshabilita, las claves DNSSEC no se borrarán si DNSSEC fué habilitado anteriormente y las claves fueron generadas, pero la zona no se entregará en formato firmado después de ello.'; +$wb['dnssec_wanted_info'] = 'Cuando se deshabilita, las claves DNSSEC no se borrarán si DNSSEC fué habilitado anteriormente y las claves fueron generadas, pero la zona no se entregará en formato firmado después de ello. Si usas PowerDNS, las claves serán borradas!'; $wb['dnssec_wanted_txt'] = 'Zona de firmado (DNSSEC)'; $wb['eg_domain_tld'] = 'eje. dominio.tld'; $wb['eg_ns1_domain_tld'] = 'eje. ns1.dominio.tld'; diff --git a/interface/web/dns/lib/lang/fi_dns_soa.lng b/interface/web/dns/lib/lang/fi_dns_soa.lng index a33b593e91..3e10625967 100755 --- a/interface/web/dns/lib/lang/fi_dns_soa.lng +++ b/interface/web/dns/lib/lang/fi_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/fr_dns_soa.lng b/interface/web/dns/lib/lang/fr_dns_soa.lng index c20afd3731..fa5a5202f6 100644 --- a/interface/web/dns/lib/lang/fr_dns_soa.lng +++ b/interface/web/dns/lib/lang/fr_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'La TTL minimum est 60 secondes.'; $wb['xfer_error_regex'] = 'A noter également : Veuillez utiliser une adresse IP.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/hr_dns_soa.lng b/interface/web/dns/lib/lang/hr_dns_soa.lng index 5789ace310..b4a9f2f9b0 100644 --- a/interface/web/dns/lib/lang/hr_dns_soa.lng +++ b/interface/web/dns/lib/lang/hr_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Minimalno TTL vrijeme je 60 sekundi.'; $wb['xfer_error_regex'] = 'Također obavijesti: Koristite IP adresu.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/hu_dns_soa.lng b/interface/web/dns/lib/lang/hu_dns_soa.lng index 8de33c83a4..80388e4056 100644 --- a/interface/web/dns/lib/lang/hu_dns_soa.lng +++ b/interface/web/dns/lib/lang/hu_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/id_dns_soa.lng b/interface/web/dns/lib/lang/id_dns_soa.lng index d1eee1c5f8..a8b9df0d59 100644 --- a/interface/web/dns/lib/lang/id_dns_soa.lng +++ b/interface/web/dns/lib/lang/id_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/it_dns_soa.lng b/interface/web/dns/lib/lang/it_dns_soa.lng index 9fd7a5aa01..48ba33d550 100644 --- a/interface/web/dns/lib/lang/it_dns_soa.lng +++ b/interface/web/dns/lib/lang/it_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time di 60 secondi.'; $wb['xfer_error_regex'] = 'Also notify: Per cortesia utilizzare un indirizzo IP.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/ja_dns_soa.lng b/interface/web/dns/lib/lang/ja_dns_soa.lng index f03be582f6..2e0fd5515f 100644 --- a/interface/web/dns/lib/lang/ja_dns_soa.lng +++ b/interface/web/dns/lib/lang/ja_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/nl_dns_soa.lng b/interface/web/dns/lib/lang/nl_dns_soa.lng index 1acf7bd456..b29c040df8 100644 --- a/interface/web/dns/lib/lang/nl_dns_soa.lng +++ b/interface/web/dns/lib/lang/nl_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/pl_dns_soa.lng b/interface/web/dns/lib/lang/pl_dns_soa.lng index dc2780f618..f2d7e1ad87 100644 --- a/interface/web/dns/lib/lang/pl_dns_soa.lng +++ b/interface/web/dns/lib/lang/pl_dns_soa.lng @@ -37,7 +37,7 @@ $wb['minimum_range_error'] = 'Min. czas minimalny wynosi 60 sekund'; $wb['ttl_range_error'] = 'Min. czas TTL wynosi 60 sekund'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/pt_dns_soa.lng b/interface/web/dns/lib/lang/pt_dns_soa.lng index dd443444de..61ff07f0cb 100644 --- a/interface/web/dns/lib/lang/pt_dns_soa.lng +++ b/interface/web/dns/lib/lang/pt_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/ro_dns_soa.lng b/interface/web/dns/lib/lang/ro_dns_soa.lng index 625281f268..134758f95e 100644 --- a/interface/web/dns/lib/lang/ro_dns_soa.lng +++ b/interface/web/dns/lib/lang/ro_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/ru_dns_soa.lng b/interface/web/dns/lib/lang/ru_dns_soa.lng index 9f9ea3126b..fe716cdc1b 100644 --- a/interface/web/dns/lib/lang/ru_dns_soa.lng +++ b/interface/web/dns/lib/lang/ru_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Мин. время TTL 60 секунд.'; $wb['xfer_error_regex'] = 'Also-notify: Пожалуйста, используйте IP-адрес.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'При отключении DNSSEC ключи не будут удалены, если DNSSEC был включен раньше, а ключи уже были созданы, но пояс не будет доставлен далее в подписанном формате.'; +$wb['dnssec_wanted_info'] = 'При отключении DNSSEC ключи не будут удалены, если DNSSEC был включен раньше, а ключи уже были созданы, но пояс не будет доставлен далее в подписанном формате. Если вы используете PowerDNS, ключи будут удалены!'; $wb['error_not_allowed_server_id'] = 'Выбранный сервер не доступен для этой учетной записи.'; $wb['soa_cannot_be_changed_txt'] = 'Зона (SOA) не может быть изменена. Пожалуйста, обратитесь к администратору, чтобы изменить зону.'; $wb['configuration_error_txt'] = 'ОШИБКА КОНФИГУРАЦИИ'; diff --git a/interface/web/dns/lib/lang/se_dns_soa.lng b/interface/web/dns/lib/lang/se_dns_soa.lng index 944c9c38f3..034d3235a7 100644 --- a/interface/web/dns/lib/lang/se_dns_soa.lng +++ b/interface/web/dns/lib/lang/se_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/sk_dns_soa.lng b/interface/web/dns/lib/lang/sk_dns_soa.lng index 176f001395..ac1f116243 100644 --- a/interface/web/dns/lib/lang/sk_dns_soa.lng +++ b/interface/web/dns/lib/lang/sk_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/tr_dns_soa.lng b/interface/web/dns/lib/lang/tr_dns_soa.lng index b406e274c5..02e325e427 100644 --- a/interface/web/dns/lib/lang/tr_dns_soa.lng +++ b/interface/web/dns/lib/lang/tr_dns_soa.lng @@ -37,7 +37,7 @@ $wb['minimum_range_error'] = 'En kısa en kısa süre 60 saniyedir.'; $wb['ttl_range_error'] = 'En düşük TTL süresi 60 saniyedir.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'The Zone (SOA) can not be changed. Please contact your administrator to change the zone.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/templates/dns_soa_edit.htm b/interface/web/dns/templates/dns_soa_edit.htm index 94faec4fa1..7a069cb3bf 100644 --- a/interface/web/dns/templates/dns_soa_edit.htm +++ b/interface/web/dns/templates/dns_soa_edit.htm @@ -179,4 +179,15 @@ searchFieldWatermark: '', resultBoxPosition: '' }); + jQuery('#dnssec_wanted').on('click', function(event) { + if ($(this).is(':checked')) { + return; + } + + if (window.confirm('{tmpl_var name="dnssec_wanted_info"}')) { + return; + } + + event.preventDefault(); + }); diff --git a/server/plugins-available/powerdns_plugin.inc.php b/server/plugins-available/powerdns_plugin.inc.php index 412050d009..f5f5158c44 100644 --- a/server/plugins-available/powerdns_plugin.inc.php +++ b/server/plugins-available/powerdns_plugin.inc.php @@ -151,6 +151,8 @@ class powerdns_plugin { //* tell pdns to rediscover zones in DB $this->zoneRediscover(); + //* handle dnssec + $this->handle_dnssec($data); //* tell pdns to use 'pdnssec rectify' on the new zone $this->rectifyZone($data); //* tell pdns to send notify to slave @@ -181,10 +183,6 @@ class powerdns_plugin { $ttl = $data["new"]["ttl"]; $app->db->query("UPDATE powerdns.records SET name = ?, content = ?, ttl = ?, change_date = UNIX_TIMESTAMP() WHERE ispconfig_id = ? AND type = 'SOA'", $origin, $content, $ttl, $data["new"]["id"]); - //* tell pdns to use 'pdnssec rectify' on the new zone - $this->rectifyZone($data); - //* tell pdns to send notify to slave - $this->notifySlave($data); } else { $this->soa_insert($event_name, $data); $ispconfig_id = $data["new"]["id"]; @@ -196,11 +194,14 @@ class powerdns_plugin { $this->rr_insert("dns_rr_insert", $data); } } - //* tell pdns to use 'pdnssec rectify' on the new zone - $this->rectifyZone($data); - //* tell pdns to send notify to slave - $this->notifySlave($data); } + + //* handle dnssec + $this->handle_dnssec($data); + //* tell pdns to use 'pdnssec rectify' on the new zone + $this->rectifyZone($data); + //* tell pdns to send notify to slave + $this->notifySlave($data); } } @@ -465,6 +466,199 @@ class powerdns_plugin { } } + function handle_dnssec($data) { + // If origin changed, delete keys first + if ($data['old']['origin'] != $data['new']['origin']) { + if (@$data['old']['dnssec_initialized'] == 'Y' && strlen(@$data['old']['origin']) > 3) { + $this->soa_dnssec_delete($data); + } + } + + // If DNSSEC is disabled, but was enabled before, just disable DNSSEC but leave the keys in dns_info + if ($data['new']['dnssec_wanted'] === 'N' && $data['old']['dnssec_initialized'] === 'Y') { + $this->soa_dnssec_disable($data); + + return; + } + + // If DNSSEC is wanted, enable it + if ($data['new']['dnssec_wanted'] === 'Y') { + $this->soa_dnssec_create($data); + } + } + + function soa_dnssec_create($data) { + global $app; + + if (!preg_match('/^3/',$this->get_pdns_version()) ) { + return; + } + + $pdns_pdnssec = $this->find_pdns_pdnssec(); + if ($pdns_pdnssec === false) { + return; + } + + $zone = rtrim($data['new']['origin'],'.'); + $log = array(); + + // We don't log the actual commands here, because having commands in the dnssec_info field will trigger + // the IDS if you try to save the record using the interface afterwards. + $cmd_secure_zone = sprintf('%s secure-zone %s 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running secure-zone command...'); + exec($cmd_secure_zone, $log); + + $cmd_set_nsec3 = sprintf('%s set-nsec3 %s "1 0 10 deadbeef" 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running set-nsec3 command...'); + exec($cmd_set_nsec3, $log); + + $pubkeys = []; + $cmd_show_zone = sprintf('%s show-zone %s 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running show-zone command...'); + exec($cmd_show_zone, $pubkeys); + + $log = array_merge($log, $pubkeys); + + $dnssec_info = array_merge($this->format_dnssec_pubkeys($pubkeys), ['', '== Raw log ============================'], $log); + $dnssec_info = implode("\r\n", $dnssec_info); + + if ($app->dbmaster !== $app->db) { + $app->dbmaster->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=? WHERE id=?', $dnssec_info, 'Y', intval($data['new']['id'])); + } + $app->db->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=? WHERE id=?', $dnssec_info, 'Y', intval($data['new']['id'])); + } + + function format_dnssec_pubkeys($lines) { + $formatted = []; + + // We don't care about the first two lines about presigning and NSEC + array_shift($lines); + array_shift($lines); + + foreach ($lines as $line) { + switch ($part = substr($line, 0, 3)) { + case 'ID ': + // Only process active keys + if (!strpos($line, 'Active: 1')) { + continue; + } + + // Determine key type (KSK or ZSK) + preg_match('/(KSK|ZSK)/', $line, $matches_key_type); + $key_type = $matches_key_type[1]; + + // We only care about the KSK + if ('ZSK' === $key_type) { + continue; + } + + // Determine key tag + preg_match('/ tag = (\d+),/', $line, $matches_key_tag); + $formatted[] = sprintf('%s key tag: %d', $key_type, $matches_key_tag[1]); + + // Determine algorithm + preg_match('/ algo = (\d+),/', $line, $matches_algo_id); + preg_match('/ \( (.*) \)$/', $line, $matches_algo_name); + $formatted[] = sprintf('Algo: %d (%s)', $matches_algo_id[1], $matches_algo_name[1]); + + // Determine bits + preg_match('/ bits = (\d+)/', $line, $matches_bits); + $formatted[] = sprintf('Bits: %d', $matches_bits[1]); + + break; + + case 'KSK': + // Determine DNSKEY + preg_match('/ IN DNSKEY \d+ \d+ \d+ (.*) ;/', $line, $matches_dnskey); + $formatted[] = sprintf('DNSKEY: %s', $matches_dnskey[1]); + + break; + + case 'DS ': + // Determine key tag + preg_match('/ IN DS (\d+) \d+ \d+ /', $line, $matches_ds_key_tag); + $formatted[] = sprintf(' - DS key tag: %d', $matches_ds_key_tag[1]); + + // Determine key tag + preg_match('/ IN DS \d+ (\d+) \d+ /', $line, $matches_ds_algo); + $formatted[] = sprintf(' Algo: %d', $matches_ds_algo[1]); + + // Determine digest + preg_match('/ IN DS \d+ \d+ (\d+) /', $line, $matches_ds_digest_id); + preg_match('/ \( (.*) \)$/', $line, $matches_ds_digest_name); + $formatted[] = sprintf(' Digest: %d (%s)', $matches_ds_digest_id[1], $matches_ds_digest_name[1]); + + // Determine public key + preg_match('/ IN DS \d+ \d+ \d+ (.*) ;/', $line, $matches_ds_key); + $formatted[] = sprintf(' Public key: %s', $matches_ds_key[1]); + break; + + default: + break; + } + } + + return $formatted; + } + + function soa_dnssec_disable($data) { + global $app; + + if (!preg_match('/^3/',$this->get_pdns_version()) ) { + return; + } + + $pdns_pdnssec = $this->find_pdns_pdnssec(); + if ($pdns_pdnssec === false) { + return; + } + + $zone = rtrim($data['new']['origin'],'.'); + $log = array(); + + // We don't log the actual commands here, because having commands in the dnssec_info field will trigger + // the IDS if you try to save the record using the interface afterwards. + $cmd_disable_dnssec = sprintf('%s disable-dnssec %s 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running disable-dnssec command...'); + exec($cmd_disable_dnssec, $log); + + if ($app->dbmaster !== $app->db) { + $app->dbmaster->query('UPDATE dns_soa SET dnssec_initialized=? WHERE id=?', 'N', intval($data['new']['id'])); + } + $app->db->query('UPDATE dns_soa SET dnssec_initialized=? WHERE id=?', 'N', intval($data['new']['id'])); + } + + function soa_dnssec_delete($data) { + global $app; + + if (!preg_match('/^3/',$this->get_pdns_version()) ) { + return; + } + + $pdns_pdnssec = $this->find_pdns_pdnssec(); + if ($pdns_pdnssec === false) { + return; + } + + $zone = rtrim($data['old']['origin'],'.'); + $log = array(); + + // We don't log the actual commands here, because having commands in the dnssec_info field will trigger + // the IDS if you try to save the record using the interface afterwards. + $cmd_disable_dnssec = sprintf('%s disable-dnssec %s 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running disable-dnssec command...'); + exec($cmd_disable_dnssec, $log); + + + $dnssec_info = array_merge(['== Raw log ============================'], $log); + $dnssec_info = implode("\r\n", $dnssec_info); + + if ($app->dbmaster !== $app->db) { + $app->dbmaster->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=? WHERE id=?', $dnssec_info, 'N', intval($data['new']['id'])); + } + $app->db->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=? WHERE id=?', $dnssec_info, 'N', intval($data['new']['id'])); + } + function rectifyZone($data) { global $app, $conf; if ( preg_match('/^3/',$this->get_pdns_version()) ) { -- GitLab From 355e7a9eb10a0184e36265c9e6a924a945157e39 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 15 Nov 2018 21:19:33 +0100 Subject: [PATCH 02/23] - fixed typo in resynctool (vservers not showing up if no db server present) --- interface/web/tools/resync.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/tools/resync.php b/interface/web/tools/resync.php index e5958c064e..ec947421b7 100644 --- a/interface/web/tools/resync.php +++ b/interface/web/tools/resync.php @@ -425,7 +425,7 @@ class page_action extends tform_actions { //* fetch vserver $v_server_rec = $app->db->queryAllRecords("SELECT server_id, server_name FROM server WHERE vserver_server = 1 AND active = 1 AND mirror_server_id = 0 ORDER BY active DESC, server_name"); - if (!empty($db_server_rec)) { + if (!empty($v_server_rec)) { $app->tpl->setVar('vserver_server_found', 1); $server_list = $this->create_list($v_server_rec, 'vserver', 'openvz_vm'); -- GitLab From ef8ba79ac7ad5ecc20a40c045385ae6bffb2897a Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Thu, 22 Nov 2018 12:00:13 +0100 Subject: [PATCH 03/23] Removed 3 unused - searchform - code files. --- interface/lib/classes/searchform.inc.php | 349 ------------------ .../lib/classes/searchform_actions.inc.php | 202 ---------- .../classes/searchform_tpl_generator.inc.php | 136 ------- 3 files changed, 687 deletions(-) delete mode 100644 interface/lib/classes/searchform.inc.php delete mode 100644 interface/lib/classes/searchform_actions.inc.php delete mode 100644 interface/lib/classes/searchform_tpl_generator.inc.php diff --git a/interface/lib/classes/searchform.inc.php b/interface/lib/classes/searchform.inc.php deleted file mode 100644 index 0a290c1d69..0000000000 --- a/interface/lib/classes/searchform.inc.php +++ /dev/null @@ -1,349 +0,0 @@ -listDef = $liste; - $this->module = $module; - - //* Fill datasources - foreach($this->listDef['item'] as $key => $field) { - if(is_array($field['datasource'])) { - $this->listDef['item'][$key]['value'] = $this->getDatasourceData($field); - } - } - return true; - } - - /** - * Get the key => value array of a form filed from a datasource definitiom - * - * @param field = array with field definition - * @param record = Dataset as array - * @return key => value array for the value field of a form - */ - - - public function getDatasourceData($field) - { - global $app; - $values = array(); - - if($field['datasource']['type'] == 'SQL') { - //* Preparing SQL string. We will replace some common placeholders - $querystring = $field['datasource']['querystring']; - $querystring = str_replace('{USERID}', $_SESSION['s']['user']['userid'], $querystring); - $querystring = str_replace('{GROUPID}', $_SESSION['s']['user']['default_group'], $querystring); - $querystring = str_replace('{GROUPS}', $_SESSION['s']['user']['groups'], $querystring); - $table_idx = $this->formDef['db_table_idx']; - //$querystring = str_replace('{RECORDID}',$record[$table_idx],$querystring); - $app->uses('tform'); - $querystring = str_replace('{AUTHSQL}', $app->tform->getAuthSQL('r'), $querystring); - - //* Getting the records - $tmp_records = $app->db->queryAllRecords($querystring); - if($app->db->errorMessage != ''){ - die($app->db->errorMessage); - } - if(is_array($tmp_records)) { - $key_field = $field['datasource']['keyfield']; - $value_field = $field['datasource']['valuefield']; - foreach($tmp_records as $tmp_rec) { - $values[$tmp_rec[$key_field]] = $tmp_rec[$value_field]; - } - } - } - if($field['datasource']['type'] == 'CUSTOM') { - //* Calls a custom class to validate this record - if($field['datasource']['class'] != '' and $field['datasource']['function'] != '') { - $datasource_class = $field['datasource']['class']; - $datasource_function = $field['datasource']['function']; - $app->uses($datasource_class); - $record = array(); - $values = $app->$datasource_class->$datasource_function($field, $record); - }else{ - $this->errorMessage .= "Custom datasource class or function is empty
\r\n"; - } - } - return $values; - } - - public function getSearchSQL($sql_where = '') - { - global $db; - - //* Config vars - $list_name = $this->listDef['name']; - $search_prefix = $this->listDef['search_prefix']; - - //* store retrieval query - foreach($this->listDef['item'] as $i) { - $field = $i['field']; - - //* TODO ? hat sich die suche ge�ndert - has itself search ? - $ki = $search_prefix.$field; - if(isset($_REQUEST) and $_REQUEST[$ki] != $_SESSION['search'][$list_name][$ki]){ - $this->searchChanged = 1; - } - - //* suchfield in session store. - if(isset($_REQUEST[$ki])){ - $_SESSION['search'][$list_name][$ki] = $_REQUEST[$ki]; - } - - if($i['formtype'] == 'SELECT'){ - if(is_array($i['value'])) { - $out = ''; - foreach($i['value'] as $k => $v) { - $selected = ($k == $_SESSION['search'][$list_name][$ki] && $_SESSION['search'][$list_name][$ki] != '') ? ' SELECTED' : ''; - $out .= "\r\n"; - } - } - $this->searchValues[$ki] = $out; - }else{ - $this->searchValues[$ki] = $_SESSION['search'][$list_name][$ki]; - } - } - - //* store variables in object. $this->searchValues = $_SESSION["search"][$list_name]; - foreach($this->listDef['item'] as $i) { - $field = $i['field']; - //if($_REQUEST[$search_prefix.$field] != '') $sql_where .= " $field ".$i["op"]." '".$i["prefix"].$_REQUEST[$search_prefix.$field].$i["suffix"]."' and"; - if($_SESSION['search'][$list_name][$ki] != ''){ - $sql_where .= " $field ".$i['op']." '".$i['prefix'].$_SESSION['search'][$list_name][$ki].$i['suffix']."' and"; - } - } - return ($sql_where != '') ? substr($sql_where, 0, -3) : '1'; - } - - public function getPagingSQL($sql_where = '1') { - global $app, $conf; - - $list_name = $this->listDef['name']; - $search_prefix = $this->listDef['search_prefix']; - $records_per_page = $this->listDef['records_per_page']; - $table = $this->listDef['table']; - - //* set page to seror id session not set - if($_SESSION['search'][$list_name]['page'] == '') $_SESSION['search'][$list_name]['page'] = 0; - - //* Set page size to request if set - if(isset($_REQUEST['page'])) $_SESSION['search'][$list_name]['page'] = $_REQUEST['page']; - - //* TODO PAGE to 0 set, if look for themselves ge?ndert. = page auf 0 setzen, wenn suche sich ge�ndert hat. - if($this->searchChanged == 1) $_SESSION['search'][$list_name]['page'] = 0; - - $sql_von = $_SESSION['search'][$list_name]['page'] * $records_per_page; - $record_count = $app->db->queryOneRecord("SELECT count(*) AS anzahl FROM ?? WHERE $sql_where", $table); - $pages = $app->functions->intval(($record_count['anzahl'] - 1) / $records_per_page); - - $vars['list_file'] = $this->listDef['file']; - $vars['page'] = $_SESSION['search'][$list_name]['page']; - $vars['last_page'] = $_SESSION['search'][$list_name]['page'] - 1; - $vars['next_page'] = $_SESSION['search'][$list_name]['page'] + 1; - $vars['pages'] = $pages; - $vars['max_pages'] = $pages + 1; - $vars['records_gesamt'] = $record_count['anzahl']; - $vars['page_params'] = $this->listDef['page_params']; - - if($_SESSION['search'][$list_name]['page'] > 0) $vars['show_page_back'] = 1; - if($_SESSION['search'][$list_name]['page'] <= $vars['pages'] - 1) $vars['show_page_next'] = 1; - - $this->pagingValues = $vars; - $this->pagingHTML = $this->getPagingHTML($vars); - - return "LIMIT $sql_von, $records_per_page"; - } - - public function getPagingHTML($vars) { - global $app; - $page_params = $vars['page_params']; - $list_file = $vars['list_file']; - $content = '   '; - if($vars['show_page_back'] == 1){ - $content .= ' '; - } - $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' '; - if($vars['show_page_next'] == 1){ - $content .= '   '; - } else{ - $content .= ' '; - } - $content .= ' '; - return $content; - } - - public function getPagingHTMLasTXT($vars) - { - global $app; - $page_params = $vars['page_params']; - $list_file = $vars['list_file']; - $content = '[|<< ]'; - if($vars['show_page_back'] == 1){ - $content .= '[<< '.$app->lng('Back').'] '; - } - $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' '; - if($vars['show_page_next'] == 1){ - $content .= '['.$app->lng('Next').' >>] '; - } - $content .= '[ >>|]'; - return $content; - } - - public function getSortSQL() - { - $sort_field = $this->listDef['sort_field']; - $sort_direction = $this->listDef['sort_direction']; - return ($sort_field != '' && $sort_direction != '') ? "ORDER BY $sort_field $sort_direction" : ''; - } - - public function saveSearchSettings($searchresult_name) - { - global $app, $conf; - - $list_name = $this->listDef['name']; - $settings = $_SESSION['search'][$list_name]; - unset($settings['page']); - $data = serialize($settings); - - $userid = $_SESSION['s']['user']['userid']; - $groupid = $_SESSION['s']['user']['default_group']; - $sys_perm_user = 'riud'; - $sys_perm_group = 'r'; - $sys_perm_other = ''; - $module = $_SESSION['s']['module']['name']; - $searchform = $this->listDef['name']; - $title = $searchresult_name; - - $sql = 'INSERT INTO `searchform` ( ' - .'`sys_userid` , `sys_groupid` , `sys_perm_user` , `sys_perm_group` , `sys_perm_other` , `module` , `searchform` , `title` , `data` ' - .')VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'; - $app->db->query($sql, $userid, $groupid, $sys_perm_user, $sys_perm_group, $sys_perm_other, $module, $searchform, $title, $data); - } - - public function decode($record) - { - global $app; - if(is_array($record)) { - foreach($this->listDef['item'] as $field) { - $key = $field['field']; - switch ($field['datatype']) - { - case 'DATE': - if($val > 0) { - $record[$key] = date($this->dateformat, $record[$key]); - } - break; - - case 'INTEGER': - $record[$key] = $app->functions->intval($record[$key]); - break; - - case 'DOUBLE': - $record[$key] = $record[$key]; - break; - - case 'CURRENCY': - $record[$key] = number_format($record[$key], 2, ',', ''); - break; - - - case 'VARCHAR': - case 'TEXT': - default: - $record[$key] = stripslashes($record[$key]); - break; - } - } - } - return $record; - } - - /* TODO: check for double quoting mysql value */ - public function encode($record) - { - global $app; - if(is_array($record)) { - foreach($this->listDef['item'] as $field) { - $key = $field['field']; - switch ($field['datatype']) - { - case 'VARCHAR': - case 'TEXT': - if(!is_array($record[$key])) { - $record[$key] = $app->db->quote($record[$key]); - } else { - $record[$key] = implode($this->tableDef[$key]['separator'], $record[$key]); - } - break; - - case 'DATE': - if($record[$key] > 0) { - list($tag, $monat, $jahr) = explode('.', $record[$key]); - $record[$key] = mktime(0, 0, 0, $monat, $tag, $jahr); - } - break; - - case 'INTEGER': - $record[$key] = $app->functions->intval($record[$key]); - break; - - case 'DOUBLE': - $record[$key] = $app->db->quote($record[$key]); - break; - - case 'CURRENCY': - $record[$key] = str_replace(',', '.', $record[$key]); - break; - } - } - } - return $record; - } - -} - -?> diff --git a/interface/lib/classes/searchform_actions.inc.php b/interface/lib/classes/searchform_actions.inc.php deleted file mode 100644 index c4372982c0..0000000000 --- a/interface/lib/classes/searchform_actions.inc.php +++ /dev/null @@ -1,202 +0,0 @@ -tpl)) $app->uses('tpl'); - if(!is_object($app->searchform)) $app->uses('searchform'); - if(!is_object($app->tform)) $app->uses('tform'); - - // Load list definition - $app->searchform->loadListDef($list_def_file); - - // Delete the search form contents, if requested - if($_REQUEST["empty_searchfields"] == 'yes') { - $list_name = $app->searchform->listDef["name"]; - unset($_SESSION["search"][$list_name]); - } - - // Save the search for later usage - if($_REQUEST["btn_submit_search_save"] && $_REQUEST["search_save_as"] != '') { - $app->searchform->saveSearchSettings($_REQUEST["search_save_as"]); - } - - // Set th returnto value for forms - $_SESSION["s"]["form"]["return_to_url"] = $app->searchform->listDef["file"]; - - if(!is_file('templates/'.$app->searchform->listDef["name"].'_search.htm')) { - $app->uses('searchform_tpl_generator'); - $app->searchform_tpl_generator->buildHTML($app->searchform->listDef); - } - - $app->tpl->newTemplate("searchpage.tpl.htm"); - $app->tpl->setInclude('content_tpl', 'templates/'.$app->searchform->listDef["name"].'_search.htm'); - - // Getting Datasets from DB - $records = $app->db->queryAllRecords($this->getQueryString()); - - - $this->DataRowColor = "#FFFFFF"; - if(is_array($records)) { - $this->idx_key = $app->searchform->listDef["table_idx"]; - foreach($records as $rec) { - $records_new[] = $this->prepareDataRow($rec); - } - } - - $app->tpl->setLoop('records', $records_new); - - //print_r($records_new); - - $this->onShow(); - - - } - - function prepareDataRow($rec) { - global $app; - - $rec = $app->searchform->decode($rec); - - // Alternating datarow colors - $this->DataRowColor = ($this->DataRowColor == "#FFFFFF")?"#EEEEEE":"#FFFFFF"; - $rec["bgcolor"] = $this->DataRowColor; - - // substitute value for select fields - foreach($app->searchform->listDef["item"] as $field) { - $key = $field["field"]; - if($field['formtype'] == "SELECT") { - if($rec[$key] == 'y' or $rec[$key] == 'n') { - // Set a additional image variable for bolean fields - $rec['_'.$key.'_'] = ($rec[$key] == 'y')?'list_icon_true.png':'list_icon_false.png'; - } - // substitute value for select field - $rec[$key] = $field['value'][$rec[$key]]; - } - } - - // The variable "id" contains always the index variable - $rec["id"] = $rec[$this->idx_key]; - - return $rec; - } - - function getQueryString() { - global $app; - - // Generate the search sql - if($app->searchform->listDef["auth"] != 'no') { - if($_SESSION["s"]["user"]["typ"] == "admin") { - $sql_where = ""; - } else { - $sql_where = $app->tform->getAuthSQL('r')." and"; - } - } - - if($this->SQLExtWhere != '') { - $sql_where .= " ".$this->SQLExtWhere." and"; - } - - $sql_where = $app->searchform->getSearchSQL($sql_where); - $app->tpl->setVar($app->searchform->searchValues); - - $order_by_sql = $this->SQLOrderBy; - - // Generate SQL for paging - $limit_sql = $app->searchform->getPagingSQL($sql_where); - $app->tpl->setVar("paging", $app->searchform->pagingHTML); - - return "SELECT * FROM ".$app->searchform->listDef["table"]." WHERE $sql_where $order_by_sql $limit_sql"; - - } - - - function onShow() { - global $app; - - // Language File setzen - $lng_file = ISPC_WEB_PATH.'/lang/lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_list.lng'; - if(!file_exists($lng_file)) $lng_file = ISPC_WEB_PATH.'/lang/lib/lang/en_'.'_list.lng'; - include $lng_file; - $lng_file = "lib/lang/".$app->functions->check_language($_SESSION["s"]["language"])."_".$app->searchform->listDef['name']."_search.lng"; - if(!file_exists($lng_file)) $lng_file = 'lib/lang/en_'.$app->searchform->listDef['name']."_search.lng"; - include $lng_file; - $app->tpl->setVar($wb); - $app->tpl->setVar("form_action", $app->searchform->listDef["file"]); - - // Parse the templates and send output to the browser - $this->onShowEnd(); - } - - function onShowEnd() { - global $app; - - if(count($_REQUEST) > 0) { - $app->tpl->setVar('searchresult_visible', 1); - if($_REQUEST['searchresult_visible'] == 'no') $app->tpl->setVar('searchresult_visible', 0); - - if($_REQUEST['searchform_visible'] == 'yes') { - $app->tpl->setVar('searchform_visible', 1); - } else { - $app->tpl->setVar('searchform_visible', 0); - } - } else { - $app->tpl->setVar('searchform_visible', 1); - if($_REQUEST['searchform_visible'] == 'no') $app->tpl->setVar('searchform_visible', 0); - - if($_REQUEST['searchresult_visible'] == 'yes') { - $app->tpl->setVar('searchresult_visible', 1); - } else { - $app->tpl->setVar('searchresult_visible', 0); - } - } - - // make columns visible - $visible_columns = explode(",", $app->searchform->listDef['default_columns']); - foreach($visible_columns as $col) { - $app->tpl->setVar($col.'_visible', 1); - } - - $app->tpl_defaults(); - $app->tpl->pparse(); - } - -} - -?> diff --git a/interface/lib/classes/searchform_tpl_generator.inc.php b/interface/lib/classes/searchform_tpl_generator.inc.php deleted file mode 100644 index 81e2f4ef1a..0000000000 --- a/interface/lib/classes/searchform_tpl_generator.inc.php +++ /dev/null @@ -1,136 +0,0 @@ - -

- -'; - - $lang["list_head_txt"] = $listDef["name"]; - foreach($listDef["item"] as $field) { - $key = $field["field"]; - - if($field["formtype"] == 'SELECT') { - $html .= " - - - - "; - } else { - $html .= " - - - - "; - } - } - - $html .= ' - - - -
:
:
-
- -

-[Neue Suche] -[Suchkriterien ändern] -Suche speichern unter: -

- - -'; - - $lang["list_head_txt"] = $listDef["name"]; - foreach($listDef["item"] as $field) { - $key = $field["field"]; - $html .= ""; - $html .= " \r\n"; - $html .= ""; - $lang[$key."_txt"] = $key; - } - - $html .= ' - - - -'; - - foreach($listDef["item"] as $field) { - $key = $field["field"]; - $html .= ""; - $html .= " \r\n"; - $html .= ""; - } - - $html .= " - - -"; - $html .= ' -
 
{tmpl_var name=\"".$key."\"}[{tmpl_var name='delete_txt'}]
- - - -
-
-'; - - if($module == '') { - $filename = 'templates/'.$listDef["name"].'_search.htm'; - } else { - $filename = '../'.$module.'/templates/'.$listDef["name"].'_search.htm'; - } - - - // speichere Template - if (!$handle = fopen($filename, 'w')) { - print "Cannot open file ($filename)"; - exit; - } - - if (!fwrite($handle, $html)) { - print "Cannot write to file ($filename)"; - exit; - } - fclose($handle); - - } - -} - -?> -- GitLab From 058903a31762902af78aac37e9ac949bbe8ac546 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Thu, 22 Nov 2018 12:08:02 +0100 Subject: [PATCH 04/23] Apply stricter language filename check in admin language file editor. --- interface/web/admin/language_edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/admin/language_edit.php b/interface/web/admin/language_edit.php index f17c4ae9a8..39baec55e3 100644 --- a/interface/web/admin/language_edit.php +++ b/interface/web/admin/language_edit.php @@ -49,7 +49,7 @@ $lang_file = $_REQUEST['lang_file']; if(!preg_match("/^[a-z]+$/i", $lang)) die('unallowed characters in language name.'); if(!preg_match("/^[a-z_]+$/i", $module)) die('unallowed characters in module name.'); -if(!preg_match("/^[a-z\._]+$/i", $lang_file)) die('unallowed characters in language file name.'); +if(!preg_match("/^[a-z\._]+$/i", $lang_file) || strpos($lang_file,'..') !== false || substr($lang_file,-4) != '.lng') die('unallowed characters in language file name.'); $msg = ''; -- GitLab From 1d0a8d1c662aa0330b8200606f3cb79f6a19e8c8 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 20 Nov 2018 22:38:43 +0100 Subject: [PATCH 05/23] First draft domains_domain_update --- interface/lib/classes/remote.d/domains.inc.php | 10 ++++++++++ interface/web/client/lib/remote.conf.php | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/interface/lib/classes/remote.d/domains.inc.php b/interface/lib/classes/remote.d/domains.inc.php index 33830335d8..ef768825b9 100644 --- a/interface/lib/classes/remote.d/domains.inc.php +++ b/interface/lib/classes/remote.d/domains.inc.php @@ -65,6 +65,16 @@ class remoting_domains extends remoting { return $this->insertQuery('../client/form/domain.tform.php', $client_id, $params); } + //* Update a record + public function domains_domain_update($session_id, $client_id, $params) + { + if(!$this->checkPerm($session_id, 'domains_domain_update')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + return $this->updateQuery('../client/form/domain.tform.php', $client_id, $params); + } + //* Delete a record public function domains_domain_delete($session_id, $primary_id) { diff --git a/interface/web/client/lib/remote.conf.php b/interface/web/client/lib/remote.conf.php index d58029e851..0c2449b939 100644 --- a/interface/web/client/lib/remote.conf.php +++ b/interface/web/client/lib/remote.conf.php @@ -1,7 +1,7 @@ Date: Tue, 27 Nov 2018 10:53:35 +0100 Subject: [PATCH 06/23] correct parameters --- interface/lib/classes/remote.d/domains.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/lib/classes/remote.d/domains.inc.php b/interface/lib/classes/remote.d/domains.inc.php index ef768825b9..05a639ad6e 100644 --- a/interface/lib/classes/remote.d/domains.inc.php +++ b/interface/lib/classes/remote.d/domains.inc.php @@ -66,13 +66,13 @@ class remoting_domains extends remoting { } //* Update a record - public function domains_domain_update($session_id, $client_id, $params) + public function domains_domain_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'domains_domain_update')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; } - return $this->updateQuery('../client/form/domain.tform.php', $client_id, $params); + return $this->updateQuery('../client/form/domain.tform.php', $client_id, $primary_id, $params); } //* Delete a record -- GitLab From e5ac9179520c1e51c99179e5f92c8e5fa667435e Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 27 Nov 2018 10:54:27 +0100 Subject: [PATCH 07/23] Add example for domains_domain_update --- .../examples/domains_domain_update.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 remoting_client/examples/domains_domain_update.php diff --git a/remoting_client/examples/domains_domain_update.php b/remoting_client/examples/domains_domain_update.php new file mode 100644 index 0000000000..4e868c2040 --- /dev/null +++ b/remoting_client/examples/domains_domain_update.php @@ -0,0 +1,38 @@ + $soap_location, + 'uri' => $soap_uri, + 'trace' => 1, + 'exceptions' => 1)); + + +try { + if($session_id = $client->login($username, $password)) { + echo 'Logged successfull. Session ID:'.$session_id.'
'; + } + + //* Set the function parameters. + $client_id = 1; + $primary_id = 42; // The domain_id + $params = array( + 'domain' => 'cellar.door' + ); + + $domain_id = $client->domains_domain_update($session_id, $client_id, $primary_id, $params); + + echo "Domain ID: ".$domain_id."
"; + + if($client->logout($session_id)) { + echo 'Logged out.
'; + } + + +} catch (SoapFault $e) { + echo $client->__getLastResponse(); + die('SOAP Error: '.$e->getMessage()); +} + +?> -- GitLab From cacfe8d3d6e0aa0815e618b0cad6e4e07a811da4 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 27 Nov 2018 10:57:13 +0100 Subject: [PATCH 08/23] Correct an obvious typo ... maybe remove as the code path below was unreachable --- interface/lib/classes/tform_base.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/lib/classes/tform_base.inc.php b/interface/lib/classes/tform_base.inc.php index 3dc9edacc1..36de1371ab 100644 --- a/interface/lib/classes/tform_base.inc.php +++ b/interface/lib/classes/tform_base.inc.php @@ -1384,7 +1384,7 @@ class tform_base { } else { if($this->formDef['auth'] == 'yes') { if($primary_id != 0) { - if($api == true && $_SESSION["s"]["user"]["client_id"] > 0 && $_SESSION["s"]["user"]["iserid"] > 0 && $_SESSION["s"]["user"]["default_group"] > 0) { + if($api == true && $_SESSION["s"]["user"]["client_id"] > 0 && $_SESSION["s"]["user"]["userid"] > 0 && $_SESSION["s"]["user"]["default_group"] > 0) { $sql_update .= '`sys_userid` = '.$this->sys_userid.', '; $sql_update .= '`sys_groupid` = '.$this->sys_default_group.', '; } -- GitLab From 54c38fc4a7f9c1cf34398097b16f183f965d8cec Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 27 Nov 2018 11:20:09 +0100 Subject: [PATCH 09/23] Add apidoc domains_domain_update --- .../API-docs/domains_domain_update.html | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 remoting_client/API-docs/domains_domain_update.html diff --git a/remoting_client/API-docs/domains_domain_update.html b/remoting_client/API-docs/domains_domain_update.html new file mode 100644 index 0000000000..bf3dd9c4bd --- /dev/null +++ b/remoting_client/API-docs/domains_domain_update.html @@ -0,0 +1,30 @@ + +ISPCOnfig 3 remote API documentation + + + + + + + + + + +
+

domains_domain_update($session_id, $client_id, $primary_id, $params);

+
+

Description:

+

Updates domain to move it to another client.


+

Input Variables:

+

$session_id, $client_id, $primary_id, $params

+

Parameters (in $params):

+

domain  (varchar(255))

+

client_id  (int(11))

+

Output:

+

Returns the number of affected rows.

+ +
+ + -- GitLab From e7f95dbe999e9ab73566237a2863bb97c0301f0c Mon Sep 17 00:00:00 2001 From: Kordian Bruck Date: Mon, 3 Dec 2018 18:53:20 +0100 Subject: [PATCH 10/23] Warn if the lockfile for system cron is older than a day We want to avoid deadlock situations and right now if there is a process running with the same PID that is not our process (e.g. after a reboot) we might be waiting forever to run the cron again. So to make this transparent to the user, we at least post a warning into the logfile. --- server/cron.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/server/cron.php b/server/cron.php index 261abd983b..6f74bd3570 100644 --- a/server/cron.php +++ b/server/cron.php @@ -32,9 +32,18 @@ define('SCRIPT_PATH', dirname($_SERVER["SCRIPT_FILENAME"])); require SCRIPT_PATH."/lib/config.inc.php"; // Check whether another instance of this script is already running -if (is_file($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock')) { +$lockFile = $conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock'; +if (is_file($lockFile)) { clearstatcache(); - $pid = trim(file_get_contents($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock')); + + // Maybe we hit a deadlock and the lock file is no longer relevant + if(filemtime($lockFile) > time() - 86400) { // 86400 seconds = 1 day + if($conf['log_priority'] <= LOGLEVEL_WARN) print @date('d.m.Y-H:i').' - WARNING - The cron lock file is older than one day.' . "\n"; + exit; + } + + // Check if the process id we have in the lock file is still present + $pid = trim(file_get_contents($lockFile)); if(preg_match('/^[0-9]+$/', $pid)) { if(file_exists('/proc/' . $pid)) { if($conf['log_priority'] <= LOGLEVEL_WARN) print @date('d.m.Y-H:i').' - WARNING - There is already an instance of server.php running with pid ' . $pid . '.' . "\n"; @@ -45,7 +54,7 @@ if (is_file($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock')) { } // Set Lockfile -@file_put_contents($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock', getmypid()); +@file_put_contents($lockFile, getmypid()); if($conf['log_priority'] <= LOGLEVEL_DEBUG) print 'Set Lock: ' . $conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock' . "\n"; -- GitLab From 03e39417a8250db0e698399c4a3ba9575eeb71bd Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 4 Dec 2018 16:26:11 +0100 Subject: [PATCH 11/23] Pass a client_id to getDataRecord() to not override a session in loadUserProfile() --- interface/lib/classes/remoting.inc.php | 2 +- interface/lib/classes/remoting_lib.inc.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/lib/classes/remoting.inc.php b/interface/lib/classes/remoting.inc.php index fe8b1694c4..6e551355a6 100644 --- a/interface/lib/classes/remoting.inc.php +++ b/interface/lib/classes/remoting.inc.php @@ -383,7 +383,7 @@ class remoting { $app->remoting_lib->loadFormDef($formdef_file); //* get old record and merge with params, so only new values have to be set in $params - $old_rec = $app->remoting_lib->getDataRecord($primary_id); + $old_rec = $app->remoting_lib->getDataRecord($primary_id, $client_id); foreach ($app->remoting_lib->formDef['fields'] as $fieldName => $fieldConf) { diff --git a/interface/lib/classes/remoting_lib.inc.php b/interface/lib/classes/remoting_lib.inc.php index a5a5d0c31c..ec04254dd3 100644 --- a/interface/lib/classes/remoting_lib.inc.php +++ b/interface/lib/classes/remoting_lib.inc.php @@ -225,10 +225,10 @@ class remoting_lib extends tform_base { return $sql; } - function getDataRecord($primary_id) { + function getDataRecord($primary_id, $client_id) { global $app; $escape = '`'; - $this->loadUserProfile(); + $this->loadUserProfile($client_id); if(@is_numeric($primary_id)) { if($primary_id > 0) { // Return a single record -- GitLab From 7bd740fa1e4c0f15d4b0b4ab46e330b8a43a645e Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Tue, 4 Dec 2018 18:58:15 +0100 Subject: [PATCH 12/23] Fixed #5168 Mail server settings can generate invalid main.cf --- interface/web/admin/lib/lang/ar_server_config.lng | 1 + interface/web/admin/lib/lang/bg_server_config.lng | 1 + interface/web/admin/lib/lang/br_server_config.lng | 1 + interface/web/admin/lib/lang/ca_server_config.lng | 1 + interface/web/admin/lib/lang/cz_server_config.lng | 1 + interface/web/admin/lib/lang/de_server_config.lng | 1 + interface/web/admin/lib/lang/dk_server_config.lng | 1 + interface/web/admin/lib/lang/el_server_config.lng | 1 + interface/web/admin/lib/lang/en_server_config.lng | 1 + interface/web/admin/lib/lang/es_server_config.lng | 1 + interface/web/admin/lib/lang/fi_server_config.lng | 1 + interface/web/admin/lib/lang/fr_server_config.lng | 1 + interface/web/admin/lib/lang/hr_server_config.lng | 1 + interface/web/admin/lib/lang/hu_server_config.lng | 1 + interface/web/admin/lib/lang/id_server_config.lng | 1 + interface/web/admin/lib/lang/it_server_config.lng | 1 + interface/web/admin/lib/lang/ja_server_config.lng | 1 + interface/web/admin/lib/lang/nl_server_config.lng | 1 + interface/web/admin/lib/lang/pl_server_config.lng | 1 + interface/web/admin/lib/lang/pt_server_config.lng | 1 + interface/web/admin/lib/lang/ro_server_config.lng | 1 + interface/web/admin/lib/lang/ru_server_config.lng | 1 + interface/web/admin/lib/lang/se_server_config.lng | 1 + interface/web/admin/lib/lang/sk_server_config.lng | 1 + interface/web/admin/lib/lang/tr_server_config.lng | 1 + interface/web/admin/server_config_edit.php | 9 +++++++++ 26 files changed, 34 insertions(+) diff --git a/interface/web/admin/lib/lang/ar_server_config.lng b/interface/web/admin/lib/lang/ar_server_config.lng index 55d4c4ffc0..b7e75ffd44 100644 --- a/interface/web/admin/lib/lang/ar_server_config.lng +++ b/interface/web/admin/lib/lang/ar_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/bg_server_config.lng b/interface/web/admin/lib/lang/bg_server_config.lng index 74e0405cd7..37f654d5a6 100644 --- a/interface/web/admin/lib/lang/bg_server_config.lng +++ b/interface/web/admin/lib/lang/bg_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/br_server_config.lng b/interface/web/admin/lib/lang/br_server_config.lng index 70512ea935..b016ad04c3 100644 --- a/interface/web/admin/lib/lang/br_server_config.lng +++ b/interface/web/admin/lib/lang/br_server_config.lng @@ -292,4 +292,5 @@ $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/ca_server_config.lng b/interface/web/admin/lib/lang/ca_server_config.lng index fbd3e1ea0a..a83144b334 100644 --- a/interface/web/admin/lib/lang/ca_server_config.lng +++ b/interface/web/admin/lib/lang/ca_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/cz_server_config.lng b/interface/web/admin/lib/lang/cz_server_config.lng index 54acda96fc..9a76563522 100644 --- a/interface/web/admin/lib/lang/cz_server_config.lng +++ b/interface/web/admin/lib/lang/cz_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng index f81bb279b3..1d8109e8e1 100644 --- a/interface/web/admin/lib/lang/de_server_config.lng +++ b/interface/web/admin/lib/lang/de_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Beschreibung Standard PHP'; $wb['php_default_name_error_empty'] = 'Beschreibung Standard PHP ist leer.'; +$wb['error_mailbox_message_size_txt'] = 'Mailboxgröße muss gleich oder größer als max. Nachrichtengröße sein.'; ?> diff --git a/interface/web/admin/lib/lang/dk_server_config.lng b/interface/web/admin/lib/lang/dk_server_config.lng index 61139aa544..26f953d5b4 100644 --- a/interface/web/admin/lib/lang/dk_server_config.lng +++ b/interface/web/admin/lib/lang/dk_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/el_server_config.lng b/interface/web/admin/lib/lang/el_server_config.lng index 38600769ce..1298ea71ae 100644 --- a/interface/web/admin/lib/lang/el_server_config.lng +++ b/interface/web/admin/lib/lang/el_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng index bcbf4ceea8..fe35d1c5ed 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -294,4 +294,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/es_server_config.lng b/interface/web/admin/lib/lang/es_server_config.lng index cb0fbf121a..5ce3381d98 100755 --- a/interface/web/admin/lib/lang/es_server_config.lng +++ b/interface/web/admin/lib/lang/es_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/fi_server_config.lng b/interface/web/admin/lib/lang/fi_server_config.lng index 6e08e98411..4609ce5b13 100755 --- a/interface/web/admin/lib/lang/fi_server_config.lng +++ b/interface/web/admin/lib/lang/fi_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/fr_server_config.lng b/interface/web/admin/lib/lang/fr_server_config.lng index 2045dbb8bd..e31d68383e 100644 --- a/interface/web/admin/lib/lang/fr_server_config.lng +++ b/interface/web/admin/lib/lang/fr_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/hr_server_config.lng b/interface/web/admin/lib/lang/hr_server_config.lng index 99d69fec0c..c54a67659d 100644 --- a/interface/web/admin/lib/lang/hr_server_config.lng +++ b/interface/web/admin/lib/lang/hr_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/hu_server_config.lng b/interface/web/admin/lib/lang/hu_server_config.lng index 24d2fcb054..1ac1cd2685 100644 --- a/interface/web/admin/lib/lang/hu_server_config.lng +++ b/interface/web/admin/lib/lang/hu_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/id_server_config.lng b/interface/web/admin/lib/lang/id_server_config.lng index 8abd5d6be0..a473891964 100644 --- a/interface/web/admin/lib/lang/id_server_config.lng +++ b/interface/web/admin/lib/lang/id_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/it_server_config.lng b/interface/web/admin/lib/lang/it_server_config.lng index a87f3129d5..8c563853c7 100644 --- a/interface/web/admin/lib/lang/it_server_config.lng +++ b/interface/web/admin/lib/lang/it_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/ja_server_config.lng b/interface/web/admin/lib/lang/ja_server_config.lng index f915e86070..76c400728b 100644 --- a/interface/web/admin/lib/lang/ja_server_config.lng +++ b/interface/web/admin/lib/lang/ja_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/nl_server_config.lng b/interface/web/admin/lib/lang/nl_server_config.lng index c8b320b8c5..350a06ba36 100644 --- a/interface/web/admin/lib/lang/nl_server_config.lng +++ b/interface/web/admin/lib/lang/nl_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/pl_server_config.lng b/interface/web/admin/lib/lang/pl_server_config.lng index 6f00d524e0..c052b7f373 100644 --- a/interface/web/admin/lib/lang/pl_server_config.lng +++ b/interface/web/admin/lib/lang/pl_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/pt_server_config.lng b/interface/web/admin/lib/lang/pt_server_config.lng index 62a8a34011..4767022e49 100644 --- a/interface/web/admin/lib/lang/pt_server_config.lng +++ b/interface/web/admin/lib/lang/pt_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/ro_server_config.lng b/interface/web/admin/lib/lang/ro_server_config.lng index f7c4c57038..41b967b735 100644 --- a/interface/web/admin/lib/lang/ro_server_config.lng +++ b/interface/web/admin/lib/lang/ro_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/ru_server_config.lng b/interface/web/admin/lib/lang/ru_server_config.lng index a95d6e70c9..0775ab7f88 100644 --- a/interface/web/admin/lib/lang/ru_server_config.lng +++ b/interface/web/admin/lib/lang/ru_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/se_server_config.lng b/interface/web/admin/lib/lang/se_server_config.lng index 97d3c9f802..5808fb2f5e 100644 --- a/interface/web/admin/lib/lang/se_server_config.lng +++ b/interface/web/admin/lib/lang/se_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/sk_server_config.lng b/interface/web/admin/lib/lang/sk_server_config.lng index cfc0b3ab7d..d5b1f92bf0 100644 --- a/interface/web/admin/lib/lang/sk_server_config.lng +++ b/interface/web/admin/lib/lang/sk_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/tr_server_config.lng b/interface/web/admin/lib/lang/tr_server_config.lng index ccf1ed5b9b..c7be379260 100644 --- a/interface/web/admin/lib/lang/tr_server_config.lng +++ b/interface/web/admin/lib/lang/tr_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/server_config_edit.php b/interface/web/admin/server_config_edit.php index e446bf3add..7eebb7f5b0 100644 --- a/interface/web/admin/server_config_edit.php +++ b/interface/web/admin/server_config_edit.php @@ -52,6 +52,15 @@ $app->load('tform_actions'); class page_action extends tform_actions { + function onSubmit() { + global $app, $conf; + + if(isset($this->dataRecord['mailbox_size_limit']) && $this->dataRecord['mailbox_size_limit'] != 0 && $this->dataRecord['mailbox_size_limit'] < $this->dataRecord['message_size_limit']) { + $app->tform->errorMessage .= $app->tform->lng("error_mailbox_message_size_txt").'
'; + } + parent::onSubmit(); + } + function onShowEdit() { global $app, $conf; -- GitLab From 33014e3beefef7e24021b0906da1ff1c20dba3f2 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 4 Dec 2018 16:50:00 +0100 Subject: [PATCH 13/23] Add a default value for client_id --- interface/lib/classes/remoting_lib.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/lib/classes/remoting_lib.inc.php b/interface/lib/classes/remoting_lib.inc.php index ec04254dd3..62ccd506c8 100644 --- a/interface/lib/classes/remoting_lib.inc.php +++ b/interface/lib/classes/remoting_lib.inc.php @@ -225,7 +225,7 @@ class remoting_lib extends tform_base { return $sql; } - function getDataRecord($primary_id, $client_id) { + function getDataRecord($primary_id, $client_id = 0) { global $app; $escape = '`'; $this->loadUserProfile($client_id); -- GitLab From c6320660dd20c14c9bc85e99853be6551c76690f Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Wed, 5 Dec 2018 09:35:36 +0100 Subject: [PATCH 14/23] Correct example code --- remoting_client/examples/domains_domain_update.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/remoting_client/examples/domains_domain_update.php b/remoting_client/examples/domains_domain_update.php index 4e868c2040..244222428c 100644 --- a/remoting_client/examples/domains_domain_update.php +++ b/remoting_client/examples/domains_domain_update.php @@ -21,11 +21,12 @@ try { 'domain' => 'cellar.door' ); - $domain_id = $client->domains_domain_update($session_id, $client_id, $primary_id, $params); + $result = $client->domains_domain_update($session_id, $client_id, $primary_id, $params); - echo "Domain ID: ".$domain_id."
"; - - if($client->logout($session_id)) { + if ($result) { + echo 'Domain updated.
'; + } + if ($client->logout($session_id)) { echo 'Logged out.
'; } -- GitLab From 79f6d0c842df9cd956452b0954cadc5b16b08d1e Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Wed, 5 Dec 2018 10:15:35 +0100 Subject: [PATCH 15/23] Limit rounding quota to 1 decimal 104.3 MB looks better to me then the current 104.3345 MB. (is that level of detail is desired then maybe we should force kB notation.) Maybe 2 or even three decimals ... but not 4. --- interface/lib/classes/quota_lib.inc.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/lib/classes/quota_lib.inc.php b/interface/lib/classes/quota_lib.inc.php index e5d55ff80c..3946b216dd 100644 --- a/interface/lib/classes/quota_lib.inc.php +++ b/interface/lib/classes/quota_lib.inc.php @@ -54,19 +54,19 @@ class quota_lib { if($used_ratio >= 1) $sites[$i]['display_colour'] = '#cc0000'; if($sites[$i]['used'] > 1024) { - $sites[$i]['used'] = round($sites[$i]['used'] / 1024, 2).' MB'; + $sites[$i]['used'] = round($sites[$i]['used'] / 1024, 1).' MB'; } else { if ($sites[$i]['used'] != '') $sites[$i]['used'] .= ' KB'; } if($sites[$i]['soft'] > 1024) { - $sites[$i]['soft'] = round($sites[$i]['soft'] / 1024, 2).' MB'; + $sites[$i]['soft'] = round($sites[$i]['soft'] / 1024, 1).' MB'; } else { $sites[$i]['soft'] .= ' KB'; } if($sites[$i]['hard'] > 1024) { - $sites[$i]['hard'] = round($sites[$i]['hard'] / 1024, 2).' MB'; + $sites[$i]['hard'] = round($sites[$i]['hard'] / 1024, 1).' MB'; } else { $sites[$i]['hard'] .= ' KB'; } @@ -268,14 +268,14 @@ class quota_lib { if($emails[$i]['quota'] == 0){ $emails[$i]['quota'] = $app->lng('unlimited'); } else { - $emails[$i]['quota'] = round($emails[$i]['quota'] / 1048576, 4).' MB'; + $emails[$i]['quota'] = round($emails[$i]['quota'] / 1048576, 1).' MB'; } if($emails[$i]['used'] < 1544000) { - $emails[$i]['used'] = round($emails[$i]['used'] / 1024, 4).' KB'; + $emails[$i]['used'] = round($emails[$i]['used'] / 1024, 1).' KB'; } else { - $emails[$i]['used'] = round($emails[$i]['used'] / 1048576, 4).' MB'; + $emails[$i]['used'] = round($emails[$i]['used'] / 1048576, 1).' MB'; } } } @@ -334,9 +334,9 @@ class quota_lib { if($databases[$i]['used'] < 1544000) { - $databases[$i]['used'] = round($databases[$i]['used'] / 1024, 4).' KB'; + $databases[$i]['used'] = round($databases[$i]['used'] / 1024, 1).' KB'; } else { - $databases[$i]['used'] = round($databases[$i]['used'] / 1048576, 4).' MB'; + $databases[$i]['used'] = round($databases[$i]['used'] / 1048576, 1).' MB'; } } } -- GitLab From e908814c1ca0402d55ba3ef1e2cf5cb3a0eb519d Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Sat, 20 Oct 2018 21:55:25 +0200 Subject: [PATCH 16/23] Make the debug log more specific --- server/plugins-available/shelluser_jailkit_plugin.inc.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/plugins-available/shelluser_jailkit_plugin.inc.php b/server/plugins-available/shelluser_jailkit_plugin.inc.php index 9a29a10a6f..147d39d571 100755 --- a/server/plugins-available/shelluser_jailkit_plugin.inc.php +++ b/server/plugins-available/shelluser_jailkit_plugin.inc.php @@ -131,10 +131,11 @@ class shelluser_jailkit_plugin { $this->_update_website_security_level(); $app->system->web_folder_protection($web['document_root'], true); + $app->log("Jailkit Plugin -> insert username:".$data['new']['username'], LOGLEVEL_DEBUG); + } else { + $app->log("Jailkit Plugin -> insert username:".$data['new']['username']. "skipped, Jailkit not selected", LOGLEVEL_DEBUG); } - $app->log("Jailkit Plugin -> insert username:".$data['new']['username'], LOGLEVEL_DEBUG); - } else { $app->log("Jailkit Plugin -> insert username:".$data['new']['username']." skipped, the user does not exist.", LOGLEVEL_WARN); } -- GitLab From c890a9f0f7dbca4db18bb0460f822aac6dfe28a7 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Mon, 3 Dec 2018 13:48:25 +0100 Subject: [PATCH 17/23] Add README to indicate where to override these templates --- install/tpl/README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 install/tpl/README.md diff --git a/install/tpl/README.md b/install/tpl/README.md new file mode 100644 index 0000000000..cf75d789d8 --- /dev/null +++ b/install/tpl/README.md @@ -0,0 +1,4 @@ +Overriding templates +-------------------- + +Manually altered versions have to be put into `server/conf-custom/install/`, e.g. `/usr/local/ispconfig/server/conf-custom/install/` -- GitLab From 1543ba74b27cc7aa63993ad9fd8c49915ea9b9ec Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 12 Dec 2018 14:02:24 +0100 Subject: [PATCH 18/23] - fixed autoresponder datetime validation in remote API --- interface/lib/classes/validate_autoresponder.inc.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/lib/classes/validate_autoresponder.inc.php b/interface/lib/classes/validate_autoresponder.inc.php index 98d49fdf6d..8fefa33b30 100755 --- a/interface/lib/classes/validate_autoresponder.inc.php +++ b/interface/lib/classes/validate_autoresponder.inc.php @@ -52,8 +52,9 @@ class validate_autoresponder extends validate_datetime //$start_date = $app->tform_actions->dataRecord['autoresponder_start_date']; // Parse date - $start_date_array = date_parse_from_format($app->lng('conf_format_datetime'),$start_date); - $end_date_array = date_parse_from_format($app->lng('conf_format_datetime'),$field_value); + $datetimeformat = (isset($app->remoting_lib) ? $app->remoting_lib->datetimeformat : $app->tform->datetimeformat); + $start_date_array = date_parse_from_format($datetimeformat,$start_date); + $end_date_array = date_parse_from_format($datetimeformat,$field_value); //calculate timestamps $start_date_tstamp = mktime($start_date_array['hour'], $start_date_array['minute'], $start_date_array['second'], $start_date_array['month'], $start_date_array['day'], $start_date_array['year']); -- GitLab From 68effaea315c9d1ef952b85071ee2db2eb388ad3 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Wed, 12 Dec 2018 17:55:33 +0100 Subject: [PATCH 19/23] Fixed #5167 DKIM public key for subdomain not saved in dns --- interface/web/mail/mail_domain_edit.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/interface/web/mail/mail_domain_edit.php b/interface/web/mail/mail_domain_edit.php index d7d6ea4c68..645d1fa037 100644 --- a/interface/web/mail/mail_domain_edit.php +++ b/interface/web/mail/mail_domain_edit.php @@ -312,7 +312,11 @@ class page_action extends tform_actions { //* create dns-record with dkim-values if the zone exists if ( $this->dataRecord['active'] == 'y' && $this->dataRecord['dkim'] == 'y' ) { - $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $this->dataRecord['domain'].'.'); + $soaDomain = $this->dataRecord['domain'].'.'; + while ((!isset($soa) && (substr_count($soaDomain,'.') > 1))) { + $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $soaDomain); + $soaDomain = preg_replace("/^\w+\./","",$soaDomain); + } if ( isset($soa) && !empty($soa) ) $this->update_dns($this->dataRecord, $soa); } @@ -437,7 +441,10 @@ class page_action extends tform_actions { $selector = @($this->dataRecord['dkim_selector'] != $this->oldDataRecord['dkim_selector']) ? true : false; $dkim_private = @($this->dataRecord['dkim_private'] != $this->oldDataRecord['dkim_private']) ? true : false; - $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $this->dataRecord['domain'].'.'); + while ((!isset($soa) && (substr_count($soaDomain,'.') > 1))) { + $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $soaDomain); + $soaDomain = preg_replace("/^\w+\./","",$soaDomain); + } if ( ($selector || $dkim_private || $dkim_active) && $dkim_active ) //* create a new record only if the dns-zone exists -- GitLab From 57b164e06074687838a422326fb844762f4ca7f2 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Wed, 12 Dec 2018 18:44:41 +0100 Subject: [PATCH 20/23] Fixed issue with creation of duplicate DKIM DNS records when mail domain is saved. --- interface/web/mail/mail_domain_edit.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/web/mail/mail_domain_edit.php b/interface/web/mail/mail_domain_edit.php index 645d1fa037..e39de91e0f 100644 --- a/interface/web/mail/mail_domain_edit.php +++ b/interface/web/mail/mail_domain_edit.php @@ -440,7 +440,8 @@ class page_action extends tform_actions { $dkim_active = @($this->dataRecord['dkim'] == 'y') ? true : false; $selector = @($this->dataRecord['dkim_selector'] != $this->oldDataRecord['dkim_selector']) ? true : false; $dkim_private = @($this->dataRecord['dkim_private'] != $this->oldDataRecord['dkim_private']) ? true : false; - + + $soaDomain = $this->dataRecord['domain'].'.'; while ((!isset($soa) && (substr_count($soaDomain,'.') > 1))) { $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $soaDomain); $soaDomain = preg_replace("/^\w+\./","",$soaDomain); @@ -474,10 +475,12 @@ class page_action extends tform_actions { // purge old rr-record(s) $sql = "SELECT * FROM dns_rr WHERE name LIKE ? AND data LIKE 'v=DKIM1%' AND " . $app->tform->getAuthSQL('r') . " ORDER BY serial DESC"; $rec = $app->db->queryAllRecords($sql, '%._domainkey.'.$dataRecord['domain'].'.'); - if (is_array($rec[1])) { - for ($i=1; $i < count($rec); ++$i) - $app->db->datalogDelete('dns_rr', 'id', $rec[$i]['id']); + if(is_array($rec)) { + foreach($rec as $r) { + $app->db->datalogDelete('dns_rr', 'id', $r['id']); + } } + // also delete a dsn-records with same selector $sql = "SELECT * from dns_rr WHERE name ? AND data LIKE 'v=DKIM1%' AND " . $app->tform->getAuthSQL('r'); $rec = $app->db->queryAllRecords($sql, '._domainkey.'.$dataRecord['dkim_selector'].'.', $dataRecord['domain']); -- GitLab From b25bf4f5389bcc0cef93b4f1dec7c9eb79911833 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 13:18:41 +0100 Subject: [PATCH 21/23] - backported datalog viewer from 3.2, contributed by Timme Hosting --- install/sql/incremental/upd_dev_collection.sql | 2 +- install/sql/ispconfig3.sql | 1 + interface/lib/classes/db_mysql.inc.php | 4 ++-- interface/web/login/index.php | 2 +- interface/web/monitor/lib/lang/de.lng | 1 + interface/web/monitor/lib/lang/en.lng | 1 + interface/web/monitor/lib/module.conf.php | 5 +++++ .../themes/default/assets/stylesheets/ispconfig.css | 13 +++++++++++++ 8 files changed, 25 insertions(+), 4 deletions(-) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 8b13789179..872ebfb465 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -1 +1 @@ - +ALTER TABLE `sys_datalog` ADD `session_id` varchar(64) NOT NULL DEFAULT '' AFTER `error`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index d3737a3ed9..aacd2ecdb6 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1631,6 +1631,7 @@ CREATE TABLE `sys_datalog` ( `data` longtext, `status` set('pending','ok','warning','error') NOT NULL default 'ok', `error` mediumtext, + `session_id` varchar(64) NOT NULL DEFAULT '', PRIMARY KEY (`datalog_id`), KEY `server_id` (`server_id`,`status`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index b03ad55676..8443d106b1 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -719,8 +719,8 @@ class db if($action == 'INSERT') $action = 'i'; if($action == 'UPDATE') $action = 'u'; if($action == 'DELETE') $action = 'd'; - $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data) VALUES (?, ?, ?, ?, ?, ?, ?)"; - $app->db->query($sql, $db_table, $dbidx, $server_id, $action, time(), $username, $diffstr); + $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data,session_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + $app->db->query($sql, $db_table, $dbidx, $server_id, $action, time(), $username, $diffstr, session_id()); } return true; diff --git a/interface/web/login/index.php b/interface/web/login/index.php index 558896acb7..47030e438d 100644 --- a/interface/web/login/index.php +++ b/interface/web/login/index.php @@ -262,7 +262,7 @@ if(count($_POST) > 0) { $app->plugin->raiseEvent('login', $username); //* Save successfull login message to var - $authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s'); + $authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s') . ' with session ID ' .session_id(); $authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a'); fwrite($authlog_handle, $authlog ."\n"); fclose($authlog_handle); diff --git a/interface/web/monitor/lib/lang/de.lng b/interface/web/monitor/lib/lang/de.lng index 78954daee6..f8fabe7990 100644 --- a/interface/web/monitor/lib/lang/de.lng +++ b/interface/web/monitor/lib/lang/de.lng @@ -40,6 +40,7 @@ $wb['Show Clamav-Log'] = 'ClamAV Protokoll anzeigen'; $wb['Show ISPConfig-Log'] = 'ISPConfig Protokoll anzeigen'; $wb['Show RKHunter-Log'] = 'RKHunter Protokoll anzeigen'; $wb['Show Jobqueue'] = 'Jobwarteschlange anzeigen'; +$wb['Show Data Log History'] = 'Datalog-History anzeigen'; $wb['Show ISPC Cron-Log'] = 'Cron Protokoll anzeigen'; $wb['no_data_updates_txt'] = 'Derzeit stehen keine Daten über Updates zur Verfügung. Bitte später erneut überprüfen.'; $wb['no_data_raid_txt'] = 'Derzeit stehen keine Daten über RAID zur Verfügung. Bitte später erneut überprüfen.'; diff --git a/interface/web/monitor/lib/lang/en.lng b/interface/web/monitor/lib/lang/en.lng index f4dbbeff9b..194bbc5030 100644 --- a/interface/web/monitor/lib/lang/en.lng +++ b/interface/web/monitor/lib/lang/en.lng @@ -46,6 +46,7 @@ $wb['Show Clamav-Log'] = 'Show Clamav-Log'; $wb['Show ISPConfig-Log'] = 'Show ISPConfig-Log'; $wb['Show RKHunter-Log'] = 'Show RKHunter-Log'; $wb['Show Jobqueue'] = 'Show Jobqueue'; +$wb['Show Data Log History'] = 'Show Data Log History'; $wb['Show fail2ban-Log'] = 'Show fail2ban-Log'; $wb['Show MongoDB-Log'] = 'Show MongoDB-Log'; $wb['Show IPTables'] = 'Show IPTables'; diff --git a/interface/web/monitor/lib/module.conf.php b/interface/web/monitor/lib/module.conf.php index cd84ff3b1a..ddb4972aae 100644 --- a/interface/web/monitor/lib/module.conf.php +++ b/interface/web/monitor/lib/module.conf.php @@ -26,6 +26,11 @@ $items[] = array( 'title' => 'Show Jobqueue', 'link' => 'monitor/datalog_list.php', 'html_id' => 'jobqueue'); +$items[] = array( 'title' => 'Show Data Log History', + 'target' => 'content', + 'link' => 'monitor/dataloghistory_list.php', + 'html_id' => 'dataloghistory'); + $module["nav"][] = array( 'title' => 'System State (All Servers)', 'open' => 1, 'items' => $items); diff --git a/interface/web/themes/default/assets/stylesheets/ispconfig.css b/interface/web/themes/default/assets/stylesheets/ispconfig.css index 5cd1bd1411..f5e8c46abf 100644 --- a/interface/web/themes/default/assets/stylesheets/ispconfig.css +++ b/interface/web/themes/default/assets/stylesheets/ispconfig.css @@ -782,3 +782,16 @@ span.notification_text { font-family: inherit; color: white; } +.finediff { + font-family: monospace; +} +.finediff ins { + color: green; + background: #dfd; + text-decoration: none; +} +.finediff del { + color: red; + background: #fdd; + text-decoration: none; +} \ No newline at end of file -- GitLab From 28bfeb97a4f75386a801ca8bcb7d0f1ddedca2b7 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 14:28:51 +0100 Subject: [PATCH 22/23] - datalog history view and restore added missing files --- interface/lib/classes/finediff.inc.php | 752 ++++++++++++++++++ interface/web/monitor/dataloghistory_list.php | 54 ++ interface/web/monitor/dataloghistory_undo.php | 70 ++ interface/web/monitor/dataloghistory_view.php | 130 +++ .../lib/lang/de_dataloghistory_list.lng | 8 + .../lib/lang/de_dataloghistory_undo.lng | 6 + .../lib/lang/de_dataloghistory_view.lng | 26 + .../lib/lang/en_dataloghistory_list.lng | 8 + .../lib/lang/en_dataloghistory_undo.lng | 6 + .../lib/lang/en_dataloghistory_view.lng | 26 + .../web/monitor/list/dataloghistory.list.php | 91 +++ .../monitor/templates/dataloghistory_list.htm | 54 ++ .../monitor/templates/dataloghistory_undo.htm | 17 + .../monitor/templates/dataloghistory_view.htm | 124 +++ 14 files changed, 1372 insertions(+) create mode 100644 interface/lib/classes/finediff.inc.php create mode 100644 interface/web/monitor/dataloghistory_list.php create mode 100644 interface/web/monitor/dataloghistory_undo.php create mode 100644 interface/web/monitor/dataloghistory_view.php create mode 100644 interface/web/monitor/lib/lang/de_dataloghistory_list.lng create mode 100644 interface/web/monitor/lib/lang/de_dataloghistory_undo.lng create mode 100644 interface/web/monitor/lib/lang/de_dataloghistory_view.lng create mode 100644 interface/web/monitor/lib/lang/en_dataloghistory_list.lng create mode 100644 interface/web/monitor/lib/lang/en_dataloghistory_undo.lng create mode 100644 interface/web/monitor/lib/lang/en_dataloghistory_view.lng create mode 100644 interface/web/monitor/list/dataloghistory.list.php create mode 100644 interface/web/monitor/templates/dataloghistory_list.htm create mode 100644 interface/web/monitor/templates/dataloghistory_undo.htm create mode 100644 interface/web/monitor/templates/dataloghistory_view.htm diff --git a/interface/lib/classes/finediff.inc.php b/interface/lib/classes/finediff.inc.php new file mode 100644 index 0000000000..43b542f362 --- /dev/null +++ b/interface/lib/classes/finediff.inc.php @@ -0,0 +1,752 @@ +copy->insert +* command (swap) for when the inserted segment is exactly the same +* as the deleted one, and with only a copy operation in between. +* TODO: How often this case occurs? Is it worth it? Can only +* be done as a postprocessing method (->optimize()?) +*/ +abstract class FineDiffOp { + abstract public function getFromLen(); + abstract public function getToLen(); + abstract public function getOpcode(); + } + +class FineDiffDeleteOp extends FineDiffOp { + public function __construct($len) { + $this->fromLen = $len; + } + public function getFromLen() { + return $this->fromLen; + } + public function getToLen() { + return 0; + } + public function getOpcode() { + if ( $this->fromLen === 1 ) { + return 'd'; + } + return "d{$this->fromLen}"; + } + } + +class FineDiffInsertOp extends FineDiffOp { + public function __construct($text) { + $this->text = $text; + } + public function getFromLen() { + return 0; + } + public function getToLen() { + return strlen($this->text); + } + public function getText() { + return $this->text; + } + public function getOpcode() { + $to_len = strlen($this->text); + if ( $to_len === 1 ) { + return "i:{$this->text}"; + } + return "i{$to_len}:{$this->text}"; + } + } + +class FineDiffReplaceOp extends FineDiffOp { + public function __construct($fromLen, $text) { + $this->fromLen = $fromLen; + $this->text = $text; + } + public function getFromLen() { + return $this->fromLen; + } + public function getToLen() { + return strlen($this->text); + } + public function getText() { + return $this->text; + } + public function getOpcode() { + if ( $this->fromLen === 1 ) { + $del_opcode = 'd'; + } + else { + $del_opcode = "d{$this->fromLen}"; + } + $to_len = strlen($this->text); + if ( $to_len === 1 ) { + return "{$del_opcode}i:{$this->text}"; + } + return "{$del_opcode}i{$to_len}:{$this->text}"; + } + } + +class FineDiffCopyOp extends FineDiffOp { + public function __construct($len) { + $this->len = $len; + } + public function getFromLen() { + return $this->len; + } + public function getToLen() { + return $this->len; + } + public function getOpcode() { + if ( $this->len === 1 ) { + return 'c'; + } + return "c{$this->len}"; + } + public function increase($size) { + return $this->len += $size; + } + } + +/** +* FineDiff ops +* +* Collection of ops +*/ +class FineDiffOps { + public function appendOpcode($opcode, $from, $from_offset, $from_len) { + if ( $opcode === 'c' ) { + $edits[] = new FineDiffCopyOp($from_len); + } + else if ( $opcode === 'd' ) { + $edits[] = new FineDiffDeleteOp($from_len); + } + else /* if ( $opcode === 'i' ) */ { + $edits[] = new FineDiffInsertOp(substr($from, $from_offset, $from_len)); + } + } + public $edits = array(); + } + +/** +* FineDiff class +* +* TODO: Document +* +*/ +class FineDiff { + + /**------------------------------------------------------------------------ + * + * Public section + * + */ + + /** + * Constructor + * ... + * The $granularityStack allows FineDiff to be configurable so that + * a particular stack tailored to the specific content of a document can + * be passed. + */ + public function __construct($from_text = '', $to_text = '', $granularityStack = null) { + // setup stack for generic text documents by default + $this->granularityStack = $granularityStack ? $granularityStack : FineDiff::$characterGranularity; + $this->edits = array(); + $this->from_text = $from_text; + $this->doDiff($from_text, $to_text); + } + + public function getOps() { + return $this->edits; + } + + public function getOpcodes() { + $opcodes = array(); + foreach ( $this->edits as $edit ) { + $opcodes[] = $edit->getOpcode(); + } + return implode('', $opcodes); + } + + public function renderDiffToHTML() { + $in_offset = 0; + ob_start(); + foreach ( $this->edits as $edit ) { + $n = $edit->getFromLen(); + if ( $edit instanceof FineDiffCopyOp ) { + FineDiff::renderDiffToHTMLFromOpcode('c', $this->from_text, $in_offset, $n); + } + else if ( $edit instanceof FineDiffDeleteOp ) { + FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n); + } + else if ( $edit instanceof FineDiffInsertOp ) { + FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen()); + } + else /* if ( $edit instanceof FineDiffReplaceOp ) */ { + FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n); + FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen()); + } + $in_offset += $n; + } + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Return an opcodes string describing the diff between a "From" and a + * "To" string + */ + public static function getDiffOpcodes($from, $to, $granularities = null) { + $diff = new FineDiff($from, $to, $granularities); + return $diff->getOpcodes(); + } + + /**------------------------------------------------------------------------ + * Return an iterable collection of diff ops from an opcodes string + */ + public static function getDiffOpsFromOpcodes($opcodes) { + $diffops = new FineDiffOps(); + FineDiff::renderFromOpcodes(null, $opcodes, array($diffops,'appendOpcode')); + return $diffops->edits; + } + + /**------------------------------------------------------------------------ + * Re-create the "To" string from the "From" string and an "Opcodes" string + */ + public static function renderToTextFromOpcodes($from, $opcodes) { + ob_start(); + FineDiff::renderFromOpcodes($from, $opcodes, array('FineDiff','renderToTextFromOpcode')); + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Render the diff to an HTML string -- UTF8 unsafe + */ + public static function renderDiffToHTMLFromOpcodes($from, $opcodes) { + ob_start(); + FineDiff::renderFromOpcodes($from, $opcodes, array('FineDiff','renderDiffToHTMLFromOpcode')); + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Render the diff to an HTML string -- UTF8 safe + */ + public static function renderUTF8DiffToHTMLFromOpcodes($from, $opcodes) { + ob_start(); + FineDiff::renderUTF8FromOpcode($from, $opcodes, array('FineDiff','renderDiffToHTMLFromOpcode')); + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Generic opcodes parser, user must supply callback for handling + * single opcode + */ + public static function renderFromOpcodes($from, $opcodes, $callback) { + if ( !is_callable($callback) ) { + return; + } + $opcodes_len = strlen($opcodes); + $from_offset = $opcodes_offset = 0; + while ( $opcodes_offset < $opcodes_len ) { + $opcode = substr($opcodes, $opcodes_offset, 1); + $opcodes_offset++; + $n = intval(substr($opcodes, $opcodes_offset)); + if ( $n ) { + $opcodes_offset += strlen(strval($n)); + } + else { + $n = 1; + } + if ( $opcode === 'c' ) { // copy n characters from source + call_user_func($callback, 'c', $from, $from_offset, $n, ''); + $from_offset += $n; + } + else if ( $opcode === 'd' ) { // delete n characters from source + call_user_func($callback, 'd', $from, $from_offset, $n, ''); + $from_offset += $n; + } + else /* if ( $opcode === 'i' ) */ { // insert n characters from opcodes + call_user_func($callback, 'i', $opcodes, $opcodes_offset + 1, $n); + $opcodes_offset += 1 + $n; + } + } + } + + /**------------------------------------------------------------------------ + * Generic opcodes parser, user must supply callback for handling + * single opcode + */ + private static function renderUTF8FromOpcode($from, $opcodes, $callback) { + if ( !is_callable($callback) ) { + return; + } + $from_len = strlen($from); + $opcodes_len = strlen($opcodes); + $from_offset = $opcodes_offset = 0; + $last_to_chars = ''; + while ( $opcodes_offset < $opcodes_len ) { + $opcode = substr($opcodes, $opcodes_offset, 1); + $opcodes_offset++; + $n = intval(substr($opcodes, $opcodes_offset)); + if ( $n ) { + $opcodes_offset += strlen(strval($n)); + } + else { + $n = 1; + } + if ( $opcode === 'c' || $opcode === 'd' ) { + $beg = $from_offset; + $end = $from_offset + $n; + while ( $beg > 0 && (ord($from[$beg]) & 0xC0) === 0x80 ) { $beg--; } + while ( $end < $from_len && (ord($from[$end]) & 0xC0) === 0x80 ) { $end++; } + if ( $opcode === 'c' ) { // copy n characters from source + call_user_func($callback, 'c', $from, $beg, $end - $beg, ''); + $last_to_chars = substr($from, $beg, $end - $beg); + } + else /* if ( $opcode === 'd' ) */ { // delete n characters from source + call_user_func($callback, 'd', $from, $beg, $end - $beg, ''); + } + $from_offset += $n; + } + else /* if ( $opcode === 'i' ) */ { // insert n characters from opcodes + $opcodes_offset += 1; + if ( strlen($last_to_chars) > 0 && (ord($opcodes[$opcodes_offset]) & 0xC0) === 0x80 ) { + $beg = strlen($last_to_chars) - 1; + while ( $beg > 0 && (ord($last_to_chars[$beg]) & 0xC0) === 0x80 ) { $beg--; } + $prefix = substr($last_to_chars, $beg); + } else { + $prefix = ''; + } + $end = $from_offset; + while ( $end < $from_len && (ord($from[$end]) & 0xC0) === 0x80 ) { $end++; } + $toInsert = $prefix . substr($opcodes, $opcodes_offset, $n) . substr($from, $end, $end - $from_offset); + call_user_func($callback, 'i', $toInsert, 0, strlen($toInsert)); + $opcodes_offset += $n; + $last_to_chars = $toInsert; + } + } + } + + /** + * Stock granularity stacks and delimiters + */ + + const paragraphDelimiters = "\n\r"; + public static $paragraphGranularity = array( + FineDiff::paragraphDelimiters + ); + const sentenceDelimiters = ".\n\r"; + public static $sentenceGranularity = array( + FineDiff::paragraphDelimiters, + FineDiff::sentenceDelimiters + ); + const wordDelimiters = " \t.\n\r"; + public static $wordGranularity = array( + FineDiff::paragraphDelimiters, + FineDiff::sentenceDelimiters, + FineDiff::wordDelimiters + ); + const characterDelimiters = ""; + public static $characterGranularity = array( + FineDiff::paragraphDelimiters, + FineDiff::sentenceDelimiters, + FineDiff::wordDelimiters, + FineDiff::characterDelimiters + ); + + public static $textStack = array( + ".", + " \t.\n\r", + "" + ); + + /**------------------------------------------------------------------------ + * + * Private section + * + */ + + /** + * Entry point to compute the diff. + */ + private function doDiff($from_text, $to_text) { + $this->last_edit = false; + $this->stackpointer = 0; + $this->from_text = $from_text; + $this->from_offset = 0; + // can't diff without at least one granularity specifier + if ( empty($this->granularityStack) ) { + return; + } + $this->_processGranularity($from_text, $to_text); + } + + /** + * This is the recursive function which is responsible for + * handling/increasing granularity. + * + * Incrementally increasing the granularity is key to compute the + * overall diff in a very efficient way. + */ + private function _processGranularity($from_segment, $to_segment) { + $delimiters = $this->granularityStack[$this->stackpointer++]; + $has_next_stage = $this->stackpointer < count($this->granularityStack); + foreach ( FineDiff::doFragmentDiff($from_segment, $to_segment, $delimiters) as $fragment_edit ) { + // increase granularity + if ( $fragment_edit instanceof FineDiffReplaceOp && $has_next_stage ) { + $this->_processGranularity( + substr($this->from_text, $this->from_offset, $fragment_edit->getFromLen()), + $fragment_edit->getText() + ); + } + // fuse copy ops whenever possible + else if ( $fragment_edit instanceof FineDiffCopyOp && $this->last_edit instanceof FineDiffCopyOp ) { + $this->edits[count($this->edits)-1]->increase($fragment_edit->getFromLen()); + $this->from_offset += $fragment_edit->getFromLen(); + } + else { + /* $fragment_edit instanceof FineDiffCopyOp */ + /* $fragment_edit instanceof FineDiffDeleteOp */ + /* $fragment_edit instanceof FineDiffInsertOp */ + $this->edits[] = $this->last_edit = $fragment_edit; + $this->from_offset += $fragment_edit->getFromLen(); + } + } + $this->stackpointer--; + } + + /** + * This is the core algorithm which actually perform the diff itself, + * fragmenting the strings as per specified delimiters. + * + * This function is naturally recursive, however for performance purpose + * a local job queue is used instead of outright recursivity. + */ + private static function doFragmentDiff($from_text, $to_text, $delimiters) { + // Empty delimiter means character-level diffing. + // In such case, use code path optimized for character-level + // diffing. + if ( empty($delimiters) ) { + return FineDiff::doCharDiff($from_text, $to_text); + } + + $result = array(); + + // fragment-level diffing + $from_text_len = strlen($from_text); + $to_text_len = strlen($to_text); + $from_fragments = FineDiff::extractFragments($from_text, $delimiters); + $to_fragments = FineDiff::extractFragments($to_text, $delimiters); + + $jobs = array(array(0, $from_text_len, 0, $to_text_len)); + + $cached_array_keys = array(); + + while ( $job = array_pop($jobs) ) { + + // get the segments which must be diff'ed + list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job; + + // catch easy cases first + $from_segment_length = $from_segment_end - $from_segment_start; + $to_segment_length = $to_segment_end - $to_segment_start; + if ( !$from_segment_length || !$to_segment_length ) { + if ( $from_segment_length ) { + $result[$from_segment_start * 4] = new FineDiffDeleteOp($from_segment_length); + } + else if ( $to_segment_length ) { + $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_length)); + } + continue; + } + + // find longest copy operation for the current segments + $best_copy_length = 0; + + $from_base_fragment_index = $from_segment_start; + + $cached_array_keys_for_current_segment = array(); + + while ( $from_base_fragment_index < $from_segment_end ) { + $from_base_fragment = $from_fragments[$from_base_fragment_index]; + $from_base_fragment_length = strlen($from_base_fragment); + // performance boost: cache array keys + if ( !isset($cached_array_keys_for_current_segment[$from_base_fragment]) ) { + if ( !isset($cached_array_keys[$from_base_fragment]) ) { + $to_all_fragment_indices = $cached_array_keys[$from_base_fragment] = array_keys($to_fragments, $from_base_fragment, true); + } + else { + $to_all_fragment_indices = $cached_array_keys[$from_base_fragment]; + } + // get only indices which falls within current segment + if ( $to_segment_start > 0 || $to_segment_end < $to_text_len ) { + $to_fragment_indices = array(); + foreach ( $to_all_fragment_indices as $to_fragment_index ) { + if ( $to_fragment_index < $to_segment_start ) { continue; } + if ( $to_fragment_index >= $to_segment_end ) { break; } + $to_fragment_indices[] = $to_fragment_index; + } + $cached_array_keys_for_current_segment[$from_base_fragment] = $to_fragment_indices; + } + else { + $to_fragment_indices = $to_all_fragment_indices; + } + } + else { + $to_fragment_indices = $cached_array_keys_for_current_segment[$from_base_fragment]; + } + // iterate through collected indices + foreach ( $to_fragment_indices as $to_base_fragment_index ) { + $fragment_index_offset = $from_base_fragment_length; + // iterate until no more match + for (;;) { + $fragment_from_index = $from_base_fragment_index + $fragment_index_offset; + if ( $fragment_from_index >= $from_segment_end ) { + break; + } + $fragment_to_index = $to_base_fragment_index + $fragment_index_offset; + if ( $fragment_to_index >= $to_segment_end ) { + break; + } + if ( $from_fragments[$fragment_from_index] !== $to_fragments[$fragment_to_index] ) { + break; + } + $fragment_length = strlen($from_fragments[$fragment_from_index]); + $fragment_index_offset += $fragment_length; + } + if ( $fragment_index_offset > $best_copy_length ) { + $best_copy_length = $fragment_index_offset; + $best_from_start = $from_base_fragment_index; + $best_to_start = $to_base_fragment_index; + } + } + $from_base_fragment_index += strlen($from_base_fragment); + // If match is larger than half segment size, no point trying to find better + // TODO: Really? + if ( $best_copy_length >= $from_segment_length / 2) { + break; + } + // no point to keep looking if what is left is less than + // current best match + if ( $from_base_fragment_index + $best_copy_length >= $from_segment_end ) { + break; + } + } + + if ( $best_copy_length ) { + $jobs[] = array($from_segment_start, $best_from_start, $to_segment_start, $best_to_start); + $result[$best_from_start * 4 + 2] = new FineDiffCopyOp($best_copy_length); + $jobs[] = array($best_from_start + $best_copy_length, $from_segment_end, $best_to_start + $best_copy_length, $to_segment_end); + } + else { + $result[$from_segment_start * 4 ] = new FineDiffReplaceOp($from_segment_length, substr($to_text, $to_segment_start, $to_segment_length)); + } + } + + ksort($result, SORT_NUMERIC); + return array_values($result); + } + + /** + * Perform a character-level diff. + * + * The algorithm is quite similar to doFragmentDiff(), except that + * the code path is optimized for character-level diff -- strpos() is + * used to find out the longest common subequence of characters. + * + * We try to find a match using the longest possible subsequence, which + * is at most the length of the shortest of the two strings, then incrementally + * reduce the size until a match is found. + * + * I still need to study more the performance of this function. It + * appears that for long strings, the generic doFragmentDiff() is more + * performant. For word-sized strings, doCharDiff() is somewhat more + * performant. + */ + private static function doCharDiff($from_text, $to_text) { + $result = array(); + $jobs = array(array(0, strlen($from_text), 0, strlen($to_text))); + while ( $job = array_pop($jobs) ) { + // get the segments which must be diff'ed + list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job; + $from_segment_len = $from_segment_end - $from_segment_start; + $to_segment_len = $to_segment_end - $to_segment_start; + + // catch easy cases first + if ( !$from_segment_len || !$to_segment_len ) { + if ( $from_segment_len ) { + $result[$from_segment_start * 4 + 0] = new FineDiffDeleteOp($from_segment_len); + } + else if ( $to_segment_len ) { + $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_len)); + } + continue; + } + if ( $from_segment_len >= $to_segment_len ) { + $copy_len = $to_segment_len; + while ( $copy_len ) { + $to_copy_start = $to_segment_start; + $to_copy_start_max = $to_segment_end - $copy_len; + while ( $to_copy_start <= $to_copy_start_max ) { + $from_copy_start = strpos(substr($from_text, $from_segment_start, $from_segment_len), substr($to_text, $to_copy_start, $copy_len)); + if ( $from_copy_start !== false ) { + $from_copy_start += $from_segment_start; + break 2; + } + $to_copy_start++; + } + $copy_len--; + } + } + else { + $copy_len = $from_segment_len; + while ( $copy_len ) { + $from_copy_start = $from_segment_start; + $from_copy_start_max = $from_segment_end - $copy_len; + while ( $from_copy_start <= $from_copy_start_max ) { + $to_copy_start = strpos(substr($to_text, $to_segment_start, $to_segment_len), substr($from_text, $from_copy_start, $copy_len)); + if ( $to_copy_start !== false ) { + $to_copy_start += $to_segment_start; + break 2; + } + $from_copy_start++; + } + $copy_len--; + } + } + // match found + if ( $copy_len ) { + $jobs[] = array($from_segment_start, $from_copy_start, $to_segment_start, $to_copy_start); + $result[$from_copy_start * 4 + 2] = new FineDiffCopyOp($copy_len); + $jobs[] = array($from_copy_start + $copy_len, $from_segment_end, $to_copy_start + $copy_len, $to_segment_end); + } + // no match, so delete all, insert all + else { + $result[$from_segment_start * 4] = new FineDiffReplaceOp($from_segment_len, substr($to_text, $to_segment_start, $to_segment_len)); + } + } + ksort($result, SORT_NUMERIC); + return array_values($result); + } + + /** + * Efficiently fragment the text into an array according to + * specified delimiters. + * No delimiters means fragment into single character. + * The array indices are the offset of the fragments into + * the input string. + * A sentinel empty fragment is always added at the end. + * Careful: No check is performed as to the validity of the + * delimiters. + */ + private static function extractFragments($text, $delimiters) { + // special case: split into characters + if ( empty($delimiters) ) { + $chars = str_split($text, 1); + $chars[strlen($text)] = ''; + return $chars; + } + $fragments = array(); + $start = $end = 0; + for (;;) { + $end += strcspn($text, $delimiters, $end); + $end += strspn($text, $delimiters, $end); + if ( $end === $start ) { + break; + } + $fragments[$start] = substr($text, $start, $end - $start); + $start = $end; + } + $fragments[$start] = ''; + return $fragments; + } + + /** + * Stock opcode renderers + */ + private static function renderToTextFromOpcode($opcode, $from, $from_offset, $from_len) { + if ( $opcode === 'c' || $opcode === 'i' ) { + echo substr($from, $from_offset, $from_len); + } + } + + private static function renderDiffToHTMLFromOpcode($opcode, $from, $from_offset, $from_len) { + if ( $opcode === 'c' ) { + echo htmlspecialchars(substr($from, $from_offset, $from_len)); + } + else if ( $opcode === 'd' ) { + $deletion = substr($from, $from_offset, $from_len); + if ( strcspn($deletion, " \n\r") === 0 ) { + $deletion = str_replace(array("\n","\r"), array('\n','\r'), $deletion); + } + echo '', htmlspecialchars($deletion), ''; + } + else /* if ( $opcode === 'i' ) */ { + echo '', htmlspecialchars(substr($from, $from_offset, $from_len)), ''; + } + } + } + diff --git a/interface/web/monitor/dataloghistory_list.php b/interface/web/monitor/dataloghistory_list.php new file mode 100644 index 0000000000..cab8da8a36 --- /dev/null +++ b/interface/web/monitor/dataloghistory_list.php @@ -0,0 +1,54 @@ +auth->check_module_permissions('monitor'); + +$app->uses('listform_actions'); + +$app->listform_actions->SQLOrderBy = "ORDER BY sys_datalog.tstamp DESC, sys_datalog.datalog_id DESC"; + +$app->listform_actions->onLoad(); + + +?> diff --git a/interface/web/monitor/dataloghistory_undo.php b/interface/web/monitor/dataloghistory_undo.php new file mode 100644 index 0000000000..5ff08faa0a --- /dev/null +++ b/interface/web/monitor/dataloghistory_undo.php @@ -0,0 +1,70 @@ +auth->check_module_permissions('monitor'); + +// Loading the template +$app->uses('tpl'); +$app->tpl->newTemplate("form.tpl.htm"); +$app->tpl->setInclude('content_tpl', 'templates/dataloghistory_undo.htm'); + +require('lib/lang/'.$_SESSION['s']['language'].'_dataloghistory_undo.lng'); +$app->tpl->setvar($wb); + +$id = intval($_GET['id']); + +$record = $app->db->queryOneRecord('SELECT * FROM sys_datalog WHERE datalog_id = ?', $id); + +$dbidx = explode(':', $record['dbidx']); + +$old_record = $app->db->queryOneRecord('SELECT * FROM ?? WHERE ??=?', $record['dbtable'], $dbidx[0], $dbidx[1]); + +if (is_array($old_record)) { + if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); + } + + $new_record = $data['old']; + + $app->db->datalogUpdate($record['dbtable'], $new_record, $dbidx[0], $dbidx[1]); + + $app->tpl->setVar('success', true); +} else { + $app->tpl->setVar('success', false); +} + +$app->tpl_defaults(); +$app->tpl->pparse(); + +?> diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php new file mode 100644 index 0000000000..e3b5e7b63c --- /dev/null +++ b/interface/web/monitor/dataloghistory_view.php @@ -0,0 +1,130 @@ +auth->check_module_permissions('monitor'); + +$app->load('finediff'); + +// Loading the template +$app->uses('tpl'); +$app->tpl->newTemplate("form.tpl.htm"); +$app->tpl->setInclude('content_tpl', 'templates/dataloghistory_view.htm'); + +$app->load_language_file('web/monitor/lib/lang/'.$_SESSION['s']['language'].'_dataloghistory_view.lng'); +require('lib/lang/'.$_SESSION['s']['language'].'_dataloghistory_view.lng'); +$app->tpl->setvar($wb); + +$id = intval($_GET['id']); + +$record = $app->db->queryOneRecord('SELECT * FROM sys_datalog WHERE datalog_id = ?', $id); + +$out['id'] = $id; + +$out['timestamp'] = date($app->lng('conf_format_datetime'), $record['tstamp']); +$out['table'] = $record['dbtable']; + +$out['action_char'] = $record['action']; +$out['action_name'] = $app->lng($record['action']); + +$out['session_id'] = $record['session_id']; + +if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); +} + +switch ($record['action']) { + case 'i': + $inserts = array(); + foreach ($data['new'] as $key=>$value) { + $inserts[] = array( + 'key' => $key, + 'value' => nl2br($value), + ); + } + $app->tpl->setLoop('inserts', $inserts); + break; + case 'u': + $updates = array(); + foreach ($data['new'] as $key=>$value) { + if ($value != $data['old'][$key]) { + $old = $data['old'][$key]; + $new = $value; + $changes = show_diff_if_needed($old, $new); + $updates[] = array( + 'key' => $key, + 'is_diff' => $changes['is_diff'], + 'old' => nl2br($changes['old']), + 'new' => nl2br($changes['new']), + 'diff' => nl2br($changes['diff']), + ); + } + } + if (count($updates) > 0) { + $app->tpl->setLoop('updates', $updates); + } else { + $out['no_changes'] = true; + } + break; + case 'd': + $deletes = array(); + foreach ($data['old'] as $key=>$value) { + $deletes[] = array( + 'key' => $key, + 'value' => nl2br($value), + ); + } + $app->tpl->setLoop('deletes', $deletes); + break; +} + +$app->tpl->setVar($out); + +$app->tpl_defaults(); +$app->tpl->pparse(); + +function show_diff_if_needed($old, $new) { + global $app; + + $diff_min_lines = 6; + + if (substr_count($old, "\n") >= $diff_min_lines || substr_count($new, "\n") >= $diff_min_lines) { + $opcodes = FineDiff::getDiffOpcodes($old, $new); + $html = FineDiff::renderUTF8DiffToHTMLFromOpcodes($old, $opcodes); + return array('is_diff'=>true, 'old'=>'', 'new'=>'', 'diff'=>$html); + } else { + return array('is_diff'=>false, 'old'=>$old, 'new'=>$new, 'diff'=>''); + } +} + +?> diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_list.lng b/interface/web/monitor/lib/lang/de_dataloghistory_list.lng new file mode 100644 index 0000000000..2c2b6c9fc2 --- /dev/null +++ b/interface/web/monitor/lib/lang/de_dataloghistory_list.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng new file mode 100644 index 0000000000..306f7c5eac --- /dev/null +++ b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng @@ -0,0 +1,6 @@ + diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng new file mode 100644 index 0000000000..81123a69c0 --- /dev/null +++ b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng @@ -0,0 +1,26 @@ + diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_list.lng b/interface/web/monitor/lib/lang/en_dataloghistory_list.lng new file mode 100644 index 0000000000..9f9afd6347 --- /dev/null +++ b/interface/web/monitor/lib/lang/en_dataloghistory_list.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng new file mode 100644 index 0000000000..258d886696 --- /dev/null +++ b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng @@ -0,0 +1,6 @@ + diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_view.lng b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng new file mode 100644 index 0000000000..df9ddd286f --- /dev/null +++ b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng @@ -0,0 +1,26 @@ + diff --git a/interface/web/monitor/list/dataloghistory.list.php b/interface/web/monitor/list/dataloghistory.list.php new file mode 100644 index 0000000000..1757125e8d --- /dev/null +++ b/interface/web/monitor/list/dataloghistory.list.php @@ -0,0 +1,91 @@ + "tstamp", + 'datatype' => "DATETIME", + 'formtype' => "TEXT", + 'op' => "like", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => ""); + + +$liste['item'][] = array( 'field' => 'server_id', + 'datatype' => 'INTEGER', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => 'SELECT server_id,server_name FROM server WHERE {AUTHSQL} ORDER BY server_name', + 'keyfield'=> 'server_id', + 'valuefield'=> 'server_name' + ), + 'width' => '', + 'value' => ''); + +$liste["item"][] = array( 'field' => "action", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => array('i' => "Insert", 'u' => "Update", 'd' => "Delete")); + + +$liste["item"][] = array( 'field' => "dbtable", + 'datatype' => "VARCHAR", + 'formtype' => "TEXT", + 'op' => "like", + 'prefix' => "%", + 'suffix' => "%", + 'width' => "", + 'value' => ""); + + +?> diff --git a/interface/web/monitor/templates/dataloghistory_list.htm b/interface/web/monitor/templates/dataloghistory_list.htm new file mode 100644 index 0000000000..0cd3c4f4d2 --- /dev/null +++ b/interface/web/monitor/templates/dataloghistory_list.htm @@ -0,0 +1,54 @@ + + + +

+ + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='search_limit'}
  + +
{tmpl_var name="tstamp"}{tmpl_var name="server_id"}{tmpl_var name="action"}{tmpl_var name="dbtable"}
{tmpl_var name='globalsearch_noresults_text_txt'}
+
+ + diff --git a/interface/web/monitor/templates/dataloghistory_undo.htm b/interface/web/monitor/templates/dataloghistory_undo.htm new file mode 100644 index 0000000000..997231a885 --- /dev/null +++ b/interface/web/monitor/templates/dataloghistory_undo.htm @@ -0,0 +1,17 @@ + + + + + + + + + + +
+
+ +
+
diff --git a/interface/web/monitor/templates/dataloghistory_view.htm b/interface/web/monitor/templates/dataloghistory_view.htm new file mode 100644 index 0000000000..0ce595e265 --- /dev/null +++ b/interface/web/monitor/templates/dataloghistory_view.htm @@ -0,0 +1,124 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +

+
+ +

+
+ +

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+
( / )
+
+
+
+ +
+
+ + {tmpl_var name='undo_txt'} + + +
+
-- GitLab From fcfeb80627ba486e48dc659a445ab9bf6473c1a5 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 16:25:13 +0100 Subject: [PATCH 23/23] - added datalog undelete to viewer --- interface/lib/classes/db_mysql.inc.php | 3 ++ interface/web/monitor/dataloghistory_undo.php | 34 ++++++++++++++----- interface/web/monitor/dataloghistory_view.php | 1 + .../lib/lang/de_dataloghistory_undo.lng | 1 + .../lib/lang/en_dataloghistory_undo.lng | 1 + .../monitor/templates/dataloghistory_view.htm | 2 +- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 8443d106b1..c4764cb555 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -759,6 +759,9 @@ class db $old_rec = array(); $index_value = $this->insertID(); + if(!$index_value && isset($insert_data[$index_field])) { + $index_value = $insert_data[$index_field]; + } $new_rec = $this->queryOneRecord("SELECT * FROM ?? WHERE ?? = ?", $tablename, $index_field, $index_value); $this->datalogSave($tablename, 'INSERT', $index_field, $index_value, $old_rec, $new_rec); diff --git a/interface/web/monitor/dataloghistory_undo.php b/interface/web/monitor/dataloghistory_undo.php index 5ff08faa0a..455f8c9d0d 100644 --- a/interface/web/monitor/dataloghistory_undo.php +++ b/interface/web/monitor/dataloghistory_undo.php @@ -50,18 +50,36 @@ $dbidx = explode(':', $record['dbidx']); $old_record = $app->db->queryOneRecord('SELECT * FROM ?? WHERE ??=?', $record['dbtable'], $dbidx[0], $dbidx[1]); -if (is_array($old_record)) { - if(!$data = unserialize(stripslashes($record['data']))) { - $data = unserialize($record['data']); +if($record['action'] === 'u') { + if (is_array($old_record)) { + if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); + } + + $new_record = $data['old']; + + $app->db->datalogUpdate($record['dbtable'], $new_record, $dbidx[0], $dbidx[1]); + + $app->tpl->setVar('success', true); + } else { + $app->tpl->setVar('success', false); } +} elseif($record['action'] === 'd') { + if(is_array($old_record)) { + $app->tpl->setVar('success', false); + $app->tpl->setVar('error_txt', $wb['error_undelete_txt']); + } else { + if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); + } - $new_record = $data['old']; + $new_record = $data['old']; + /* TODO: maybe check some data, e. g. server_id -> server still there?, sys_groupid -> sys_group/sys_user still there? */ - $app->db->datalogUpdate($record['dbtable'], $new_record, $dbidx[0], $dbidx[1]); + $app->db->datalogInsert($record['dbtable'], $new_record, $dbidx[0]); - $app->tpl->setVar('success', true); -} else { - $app->tpl->setVar('success', false); + $app->tpl->setVar('success', true); + } } $app->tpl_defaults(); diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php index e3b5e7b63c..2b5ea1e032 100644 --- a/interface/web/monitor/dataloghistory_view.php +++ b/interface/web/monitor/dataloghistory_view.php @@ -109,6 +109,7 @@ switch ($record['action']) { } $app->tpl->setVar($out); +$app->tpl->setVar('can_undo', ($out['action_char'] === 'u' || $out['action_char'] === 'd')); $app->tpl_defaults(); $app->tpl->pparse(); diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng index 306f7c5eac..9bae987d50 100644 --- a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng +++ b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng @@ -2,5 +2,6 @@ $wb['list_head_txt'] = 'Datalog-History-Eintrag'; $wb['success_txt'] = 'Erfolgreich zurückgesetzt'; $wb['error_txt'] = 'Fehler beim Zurücksetzen: Eintrag existiert nicht mehr'; +$wb['error_undelete_txt'] = 'Fehler beim Wiederherstellen: Eintrag mit dieser Id existiert bereits'; $wb['btn_cancel_txt'] = 'Zurück'; ?> diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng index 258d886696..0e040a3e77 100644 --- a/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng +++ b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng @@ -2,5 +2,6 @@ $wb['list_head_txt'] = 'Data Log History Entry'; $wb['success_txt'] = 'Undo successful'; $wb['error_txt'] = 'Error during undo: Record does not exist anymore'; +$wb['error_undelete_txt'] = 'Error during undelete: Record with primary id already existing.'; $wb['btn_cancel_txt'] = 'Back'; ?> diff --git a/interface/web/monitor/templates/dataloghistory_view.htm b/interface/web/monitor/templates/dataloghistory_view.htm index 0ce595e265..4ba82bbf05 100644 --- a/interface/web/monitor/templates/dataloghistory_view.htm +++ b/interface/web/monitor/templates/dataloghistory_view.htm @@ -116,7 +116,7 @@
- + {tmpl_var name='undo_txt'} -- GitLab