diff --git a/admin_domains.php b/admin_domains.php
index 147f5319..6239035c 100644
--- a/admin_domains.php
+++ b/admin_domains.php
@@ -699,9 +699,14 @@ if ($page == 'domains' || $page == 'overview') {
} elseif ($page == 'domaindnseditor' && Settings::Get('system.dnsenabled') == '1') {
require_once __DIR__ . '/dns_editor.php';
+
} elseif ($page == 'sslcertificates') {
-
+
require_once __DIR__ . '/ssl_certificates.php';
+
+} elseif ($page == 'logfiles') {
+
+ require_once __DIR__.'/logfiles_viewer.php';
}
function formatDomainEntry(&$row, &$idna_convert)
diff --git a/customer_domains.php b/customer_domains.php
index 096a930f..ad6420f3 100644
--- a/customer_domains.php
+++ b/customer_domains.php
@@ -496,4 +496,7 @@ if ($page == 'overview') {
require_once __DIR__.'/ssl_certificates.php';
-}
\ No newline at end of file
+} elseif ($page == 'logfiles') {
+
+ require_once __DIR__.'/logfiles_viewer.php';
+}
diff --git a/install/froxlor.sql b/install/froxlor.sql
index 9801cfd5..c861cbd4 100644
--- a/install/froxlor.sql
+++ b/install/froxlor.sql
@@ -204,6 +204,7 @@ CREATE TABLE `panel_customers` (
`allowed_phpconfigs` varchar(500) NOT NULL default '',
`type_2fa` tinyint(1) NOT NULL default '0',
`data_2fa` varchar(500) NOT NULL default '',
+ `logviewenabled` tinyint(1) NOT NULL default '0',
PRIMARY KEY (`customerid`),
UNIQUE KEY `loginname` (`loginname`)
) ENGINE=MyISAM CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -693,7 +694,7 @@ opcache.interned_strings_buffer'),
('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'customer_hide_options', ''),
('panel', 'version', '0.10.0'),
- ('panel', 'db_version', '201811300');
+ ('panel', 'db_version', '201812010');
DROP TABLE IF EXISTS `panel_tasks`;
diff --git a/install/updates/froxlor/0.10/update_0.10.inc.php b/install/updates/froxlor/0.10/update_0.10.inc.php
index 7ff7a986..8bab98e7 100644
--- a/install/updates/froxlor/0.10/update_0.10.inc.php
+++ b/install/updates/froxlor/0.10/update_0.10.inc.php
@@ -96,3 +96,12 @@ if (isDatabaseVersion('201811180')) {
updateToDbVersion('201811300');
}
+
+if (isDatabaseVersion('201811300')) {
+
+ showUpdateStep("Adding new logview-flag to customers");
+ Database::query("ALTER TABLE `" . TABLE_PANEL_CUSTOMERS . "` ADD `logviewenabled` tinyint(1) NOT NULL default '0';");
+ lastStepStatus(0);
+
+ updateToDbVersion('201812010');
+}
diff --git a/lib/classes/api/commands/class.Customers.php b/lib/classes/api/commands/class.Customers.php
index 2b3d9b75..154b7655 100644
--- a/lib/classes/api/commands/class.Customers.php
+++ b/lib/classes/api/commands/class.Customers.php
@@ -197,10 +197,12 @@ class Customers extends ApiCommand implements ResourceEntity
* @param bool $perlenabled
* optional, whether to allow usage of Perl/CGI, default 0 (false)
* @param bool $dnsenabled
- * optional, ether to allow usage of the DNS editor (requires activated nameserver in settings)
+ * optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
+ * @param bool $logviewenabled
+ * optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
* @param bool $store_defaultindex
* optional, whether to store the default index file to customers homedir
- *
+ *
* @access admin
* @throws Exception
* @return array
@@ -248,6 +250,7 @@ class Customers extends ApiCommand implements ResourceEntity
$p_allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, array());
$perlenabled = $this->getParam('perlenabled', true, 0);
$dnsenabled = $this->getParam('dnsenabled', true, 0);
+ $logviewenabled = $this->getParam('logviewenabled', true, 0);
$store_defaultindex = $this->getParam('store_defaultindex', true, 0);
$loginname = $this->getParam('new_loginname', true, '');
@@ -375,6 +378,10 @@ class Customers extends ApiCommand implements ResourceEntity
$dnsenabled = '1';
}
+ if ($logviewenabled != '0') {
+ $logviewenabled = '1';
+ }
+
if ($password == '') {
$password = generatePassword();
}
@@ -415,6 +422,7 @@ class Customers extends ApiCommand implements ResourceEntity
'pop3' => $email_pop3,
'perlenabled' => $perlenabled,
'dnsenabled' => $dnsenabled,
+ 'logviewenabled' => $logviewenabled,
'theme' => $_theme,
'custom_notes' => $custom_notes,
'custom_notes_show' => $custom_notes_show
@@ -456,6 +464,7 @@ class Customers extends ApiCommand implements ResourceEntity
`pop3` = :pop3,
`perlenabled` = :perlenabled,
`dnsenabled` = :dnsenabled,
+ `logviewenabled` = :logviewenabled,
`theme` = :theme,
`custom_notes` = :custom_notes,
`custom_notes_show` = :custom_notes_show
@@ -828,7 +837,9 @@ class Customers extends ApiCommand implements ResourceEntity
* @param bool $perlenabled
* optional, whether to allow usage of Perl/CGI, default 0 (false)
* @param bool $dnsenabled
- * optional, ether to allow usage of the DNS editor (requires activated nameserver in settings)
+ * optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
+ * @param bool $logviewenabled
+ * optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
* @param string $theme
* optional, change theme
*
@@ -888,6 +899,7 @@ class Customers extends ApiCommand implements ResourceEntity
$allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, json_decode($result['allowed_phpconfigs'], true));
$perlenabled = $this->getParam('perlenabled', true, $result['perlenabled']);
$dnsenabled = $this->getParam('dnsenabled', true, $result['dnsenabled']);
+ $logviewenabled = $this->getParam('logviewenabled', true, $result['logviewenabled']);
$deactivated = $this->getParam('deactivated', true, $result['deactivated']);
$theme = $this->getParam('theme', true, $result['theme']);
} else {
@@ -1029,6 +1041,10 @@ class Customers extends ApiCommand implements ResourceEntity
inserttask('1');
}
+ if ($logviewenabled != '0') {
+ $logviewenabled = '1';
+ }
+
// activate/deactivate customer services
if ($deactivated != $result['deactivated']) {
@@ -1167,6 +1183,7 @@ class Customers extends ApiCommand implements ResourceEntity
'pop3' => $email_pop3,
'perlenabled' => $perlenabled,
'dnsenabled' => $dnsenabled,
+ 'logviewenabled' => $logviewenabled,
'custom_notes' => $custom_notes,
'custom_notes_show' => $custom_notes_show
);
@@ -1208,6 +1225,7 @@ class Customers extends ApiCommand implements ResourceEntity
`pop3` = :pop3,
`perlenabled` = :perlenabled,
`dnsenabled` = :dnsenabled,
+ `logviewenabled` = :logviewenabled,
`custom_notes` = :custom_notes,
`custom_notes_show` = :custom_notes_show";
$upd_query .= $admin_upd_query;
diff --git a/lib/formfields/admin/customer/formfield.customer_add.php b/lib/formfields/admin/customer/formfield.customer_add.php
index 862ecb9f..43a0808f 100644
--- a/lib/formfields/admin/customer/formfield.customer_add.php
+++ b/lib/formfields/admin/customer/formfield.customer_add.php
@@ -327,6 +327,16 @@ return array(
)
),
'visible' => (Settings::Get('system.dnsenabled') == '1' ? true : false)
+ ),
+ 'logviewenabled' => array(
+ 'label' => $lng['admin']['logviewenabled'] . '?',
+ 'type' => 'checkbox',
+ 'values' => array(
+ array(
+ 'label' => $lng['panel']['yes'],
+ 'value' => '1'
+ )
+ )
)
)
)
diff --git a/lib/formfields/admin/customer/formfield.customer_edit.php b/lib/formfields/admin/customer/formfield.customer_edit.php
index 86d8820c..22370ec8 100644
--- a/lib/formfields/admin/customer/formfield.customer_edit.php
+++ b/lib/formfields/admin/customer/formfield.customer_edit.php
@@ -297,6 +297,17 @@ return array(
'value' => array($result['dnsenabled']),
'visible' => (Settings::Get('system.dnsenabled') == '1' ? true : false)
),
+ 'logviewenabled' => array(
+ 'label' => $lng['admin']['logviewenabled'] . '?',
+ 'type' => 'checkbox',
+ 'values' => array(
+ array(
+ 'label' => $lng['panel']['yes'],
+ 'value' => '1'
+ )
+ ),
+ 'value' => array($result['logviewenabled'])
+ )
)
),
'section_d' => array(
diff --git a/lib/version.inc.php b/lib/version.inc.php
index 195f0938..142c0422 100644
--- a/lib/version.inc.php
+++ b/lib/version.inc.php
@@ -19,7 +19,7 @@
$version = '0.10.0';
// Database version (YYYYMMDDC where C is a daily counter)
-$dbversion = '201811300';
+$dbversion = '201812010';
// Distribution branding-tag (used for Debian etc.)
$branding = '';
diff --git a/lng/english.lng.php b/lng/english.lng.php
index 0e409461..0565eeaa 100644
--- a/lng/english.lng.php
+++ b/lng/english.lng.php
@@ -2165,3 +2165,5 @@ $lng['mails']['2fa']['subject'] = 'Froxlor - 2FA Code';
$lng['2fa']['2fa_overview_desc'] = 'Here you can activate a two-factor authentication for your account.
You can either use an authenticator-app (time-based one-time password / TOTP) or let froxlor send you an email to your account-address after each successful login with a one-time password.';
$lng['2fa']['2fa_email_desc'] = 'Your account is set up to use one-time passwords via e-mail. To deactivate, click on "'.$lng['2fa']['2fa_delete'].'"';
$lng['2fa']['2fa_ga_desc'] = 'Your account is set up to use time-based one-time passwords via authenticator-app. Please scan the QR code below with your desired authenticator app to generate the codes. To deactivate, click on "'.$lng['2fa']['2fa_delete'].'"';
+$lng['admin']['logviewenabled'] = 'Enable access to access/error-logs';
+$lng['panel']['viewlogs'] = 'View logfiles';
diff --git a/lng/german.lng.php b/lng/german.lng.php
index 5cb0ef52..3036fd22 100644
--- a/lng/german.lng.php
+++ b/lng/german.lng.php
@@ -1813,3 +1813,5 @@ $lng['mails']['2fa']['subject'] = 'Froxlor - 2FA Code';
$lng['2fa']['2fa_overview_desc'] = 'Hier kann für das Konto eine Zwei-Faktor-Authentisierung aktiviert werden.
Es kann entweder eine Authenticator-App (time-based one-time password / TOTP) genutzt werden oder ein Einmalpasswort, welches nach erfolgreichem Login an die hinterlegte E-Mail Adresse gesendet wird.';
$lng['2fa']['2fa_email_desc'] = 'Das Konto ist eingerichtet, um Einmalpasswörter per E-Mail zu erhalten. Zum Deaktivieren, klicke auf "'.$lng['2fa']['2fa_delete'].'"';
$lng['2fa']['2fa_ga_desc'] = 'Das Konto ist eingerichtet, um zeitbasierte Einmalpasswörter via Authenticator-App zu erhalten. Um die gewünschte Authenticator-App einzurichten, scanne bitte den untenstehenden QR-Code. Zum Deaktivieren, klicke auf "'.$lng['2fa']['2fa_delete'].'"';
+$lng['admin']['logviewenabled'] = 'Zugriff auf access/error-Logdateien';
+$lng['panel']['viewlogs'] = 'Logdateien einsehen';
diff --git a/logfiles_viewer.php b/logfiles_viewer.php
new file mode 100644
index 00000000..3226d25a
--- /dev/null
+++ b/logfiles_viewer.php
@@ -0,0 +1,85 @@
+ (2016-)
+ * @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
+ * @package Panel
+ *
+ */
+
+// This file is being included in admin_domains and customer_domains
+// and therefore does not need to require lib/init.php
+
+// TODO get domain related settings for logfile (speciallogfile)
+$domain_id = isset($_GET['domain_id']) ? (int) $_GET['domain_id'] : null;
+$last_n = isset($_GET['number_of_lines']) ? (int) $_GET['number_of_lines'] : 100;
+
+// user's with logviewenabled = false
+if (AREA != 'admin' && $userinfo['logviewenabled'] != '1') {
+ // back to domain overview
+ redirectTo($filename, array(
+ 'page' => 'domains',
+ 's' => $s
+ ));
+}
+
+if (function_exists('exec')) {
+
+ // get domain-info
+ try {
+ $json_result = SubDomains::getLocal($userinfo, array(
+ 'id' => $domain_id
+ ))->get();
+ } catch (Exception $e) {
+ dynamic_error($e->getMessage());
+ }
+ $domain = json_decode($json_result, true)['data'];
+
+ $speciallogfile = '';
+ if ($domain['speciallogfile'] == '1') {
+ if ($domain['parentdomainid'] == '0') {
+ $speciallogfile = '-' . $domain['domain'];
+ } else {
+ $speciallogfile = '-' . $domain['parentdomain'];
+ }
+ }
+ // The normal access/error - logging is enabled
+ $error_log = makeCorrectFile(Settings::Get('system.logfiles_directory') . getCustomerDetail($domain['customerid'], 'loginname') . $speciallogfile . '-error.log');
+ $access_log = makeCorrectFile(Settings::Get('system.logfiles_directory') . getCustomerDetail($domain['customerid'], 'loginname') . $speciallogfile . '-access.log');
+
+ // error log
+ if (file_exists($error_log)) {
+ $result = safe_exec('tail -n ' . $last_n . ' ' . escapeshellarg($error_log));
+ $error_log_content = implode("\n", $result) . "";
+ } else {
+ $error_log_content = "Error-Log" . (AREA == 'admin' ? " '" . $error_log . "'" : "") . " does not seem to exist";
+ }
+
+ // access log
+ if (file_exists($access_log)) {
+ $result = safe_exec('tail -n ' . $last_n . ' ' . escapeshellarg($access_log));
+ $access_log_content = implode("\n", $result);
+ } else {
+ $access_log_content = "Access-Log" . (AREA == 'admin' ? " '" . $access_log . "'" : "") . " does not seem to exist";
+ }
+
+ eval("echo \"" . getTemplate("logfiles_viewer/index", true) . "\";");
+} else {
+ if (AREA == 'admin') {
+ dynamic_error('You need to allow the exec() function in the froxlor-vhost php-config');
+ } else {
+ dynamic_error('Required function exec() is not allowed. Pllease contact the system administrator.');
+ }
+}
diff --git a/templates/Sparkle/admin/domains/domains_domain.tpl b/templates/Sparkle/admin/domains/domains_domain.tpl
index 8e9140c5..a00ecab6 100644
--- a/templates/Sparkle/admin/domains/domains_domain.tpl
+++ b/templates/Sparkle/admin/domains/domains_domain.tpl
@@ -20,6 +20,9 @@
+
+
+
diff --git a/templates/Sparkle/assets/css/main.css b/templates/Sparkle/assets/css/main.css
index 7783092c..c78c430d 100644
--- a/templates/Sparkle/assets/css/main.css
+++ b/templates/Sparkle/assets/css/main.css
@@ -1640,7 +1640,7 @@ table thead th.tablesorter-headerDesc {
margin-bottom: 20px;
}
-.shell, .filecontent {
+.shell, .filecontent .logcontent {
font-family: Consolas, Monaco, Lucida Console, Liberation Mono,
DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
border: 1px solid #d1d5d8;
diff --git a/templates/Sparkle/customer/domains/domains_domain.tpl b/templates/Sparkle/customer/domains/domains_domain.tpl
index 89ae2c60..e4e10181 100644
--- a/templates/Sparkle/customer/domains/domains_domain.tpl
+++ b/templates/Sparkle/customer/domains/domains_domain.tpl
@@ -20,6 +20,11 @@
+
+
+
+
+
diff --git a/templates/Sparkle/logfiles_viewer/index.tpl b/templates/Sparkle/logfiles_viewer/index.tpl
new file mode 100644
index 00000000..1fb819f7
--- /dev/null
+++ b/templates/Sparkle/logfiles_viewer/index.tpl
@@ -0,0 +1,19 @@
+$header
+
+
+
+
+ Error-Log
+
+ Access-Log
+
+
+
+
+
+$footer