summaryrefslogtreecommitdiffstats
path: root/modules-available/syslog
diff options
context:
space:
mode:
authorroot2019-02-19 18:53:50 +0100
committerroot2019-02-19 18:53:50 +0100
commit0ad4c0f8196b61699754762aacbaab0223478ab9 (patch)
treede434c4aea8d07ecd01cd3badd48d057d62c2d1b /modules-available/syslog
parent[usb-lock-off] Edit rule cleanup and fix of the dropdown boxes. (diff)
parent[statistics] Fix RAM change warning to handle increase too (diff)
downloadslx-admin-usb-lock-off.tar.gz
slx-admin-usb-lock-off.tar.xz
slx-admin-usb-lock-off.zip
Merge branch 'master' into usb-lock-offusb-lock-off
Diffstat (limited to 'modules-available/syslog')
-rw-r--r--modules-available/syslog/api.inc.php39
-rw-r--r--modules-available/syslog/config.json8
-rw-r--r--modules-available/syslog/hooks/cron.inc.php21
-rw-r--r--modules-available/syslog/lang/de/messages.json4
-rw-r--r--modules-available/syslog/lang/de/permissions.json4
-rw-r--r--modules-available/syslog/lang/de/template-tags.json11
-rw-r--r--modules-available/syslog/lang/en/messages.json4
-rw-r--r--modules-available/syslog/lang/en/permissions.json4
-rw-r--r--modules-available/syslog/lang/en/template-tags.json11
-rw-r--r--modules-available/syslog/page.inc.php41
-rw-r--r--modules-available/syslog/permissions/permissions.json11
-rw-r--r--modules-available/syslog/templates/heading.html68
-rw-r--r--modules-available/syslog/templates/page-syslog.html1
13 files changed, 215 insertions, 12 deletions
diff --git a/modules-available/syslog/api.inc.php b/modules-available/syslog/api.inc.php
index 18c42c31..945f9d09 100644
--- a/modules-available/syslog/api.inc.php
+++ b/modules-available/syslog/api.inc.php
@@ -1,5 +1,44 @@
<?php
+// Check for user data export
+if (($user = Request::post('export-user', false, 'string')) !== false) {
+ User::load();
+ User::assertPermission('export-user-data', null, '?do=syslog');
+ if (!Util::verifyToken()) {
+ die('Invalid Token');
+ }
+ $puser = preg_quote($user);
+ $exp = "$puser logged|^\[$puser\]";
+ Header('Content-Type: text/plain; charset=utf-8');
+ Header('Content-Disposition: attachment; filename=bwlehrpool-export-' .Util::sanitizeFilename($user) . '-' . date('Y-m-d') . '.txt');
+ $srcs = [];
+ $srcs[] = ['res' => Database::simpleQuery("SELECT dateline, logtypeid AS typeid, clientip, description FROM clientlog
+ WHERE description REGEXP :exp
+ ORDER BY dateline ASC", ['exp' => $exp])];
+ if (Module::get('statistics') !== false) {
+ $srcs[] = ['res' => Database::simpleQuery("SELECT dateline, typeid, clientip, data AS description FROM statistic
+ WHERE username = :user
+ ORDER BY dateline ASC", ['user' => $user])];
+ }
+ echo "# Begin log\n";
+ for (;;) {
+ unset($best);
+ foreach ($srcs as &$src) {
+ if (!isset($src['row'])) {
+ $src['row'] = $src['res']->fetch(PDO::FETCH_ASSOC);
+ }
+ if ($src['row'] !== false && (!isset($best) || $src['row']['dateline'] < $best['dateline'])) {
+ $best =& $src['row'];
+ }
+ }
+ if (!isset($best))
+ break;
+ echo date('Y-m-d H:i:s', $best['dateline']), "\t", $best['typeid'], "\t", $best['clientip'], "\t", $best['description'], "\n";
+ $best = null; // so we repopulate on next iteration
+ }
+ die("# End log\n");
+}
+
if (empty($_POST['type'])) die('Missing options.');
$type = mb_strtolower($_POST['type']);
diff --git a/modules-available/syslog/config.json b/modules-available/syslog/config.json
index 2b718a8e..691bd4df 100644
--- a/modules-available/syslog/config.json
+++ b/modules-available/syslog/config.json
@@ -1,4 +1,6 @@
{
- "category":"main.status",
- "dependencies":["js_selectize"]
-}
+ "category": "main.status",
+ "dependencies": [
+ "js_selectize"
+ ]
+} \ No newline at end of file
diff --git a/modules-available/syslog/hooks/cron.inc.php b/modules-available/syslog/hooks/cron.inc.php
index bae882a9..62516648 100644
--- a/modules-available/syslog/hooks/cron.inc.php
+++ b/modules-available/syslog/hooks/cron.inc.php
@@ -1,7 +1,28 @@
<?php
if (mt_rand(1, 10) === 1) {
+ // Prune old entries
Database::exec("DELETE FROM clientlog WHERE (UNIX_TIMESTAMP() - 86400 * 190) > dateline");
+ // Anonymize if requested
+ $days = Property::get('syslog.anon-days', 0);
+ if ($days > 0) {
+ $cutoff = time() - ($days * 86400);
+ Database::exec("UPDATE clientlog SET description = '[root] User logged in'
+ WHERE $cutoff > dateline AND logtypeid = 'session-open' AND description NOT LIKE '[root] User %'");
+ Database::exec("UPDATE clientlog SET description = '[root] User logged out'
+ WHERE $cutoff > dateline AND logtypeid = 'session-close' AND description NOT LIKE '[root] User %'");
+ Database::exec("UPDATE clientlog SET description = '-', extra = ''
+ WHERE $cutoff > dateline AND description NOT LIKE '-'
+ AND logtypeid NOT IN ('session-open', 'session-close', 'idleaction-busy', 'partition-temp',
+ 'partition-swap', 'smartctl-realloc', 'vmware-netifup', 'vmware-insmod', 'firewall-script-apply',
+ 'mount-vm-tmp-fail')");
+ if (Module::get('statistics') !== false) {
+ Database::exec("UPDATE statistic SET username = 'anonymous'
+ WHERE $cutoff > dateline AND username NOT LIKE 'anonymous' AND username NOT LIKE ''");
+ Database::exec("UPDATE machine SET currentuser = NULL
+ WHERE $cutoff > lastseen AND currentuser IS NOT NULL");
+ }
+ }
if (mt_rand(1, 100) === 1) {
Database::exec("OPTIMIZE TABLE clientlog");
}
diff --git a/modules-available/syslog/lang/de/messages.json b/modules-available/syslog/lang/de/messages.json
new file mode 100644
index 00000000..eec31c2f
--- /dev/null
+++ b/modules-available/syslog/lang/de/messages.json
@@ -0,0 +1,4 @@
+{
+ "anon-days-out-of-range": "Tage muss zwischen 0 und 180 liegen (war {{0}})",
+ "anon-days-saved": "Anonymisierungszeitraum gespeichert"
+} \ No newline at end of file
diff --git a/modules-available/syslog/lang/de/permissions.json b/modules-available/syslog/lang/de/permissions.json
new file mode 100644
index 00000000..dcd96ae1
--- /dev/null
+++ b/modules-available/syslog/lang/de/permissions.json
@@ -0,0 +1,4 @@
+{
+ "configure-anonymization": "Einstellen, nach wie vielen Tagen die Nutzernamen in den Logs entfernt werden.",
+ "view": "Client Log anschauen."
+} \ No newline at end of file
diff --git a/modules-available/syslog/lang/de/template-tags.json b/modules-available/syslog/lang/de/template-tags.json
index c8b2bb45..c00d619a 100644
--- a/modules-available/syslog/lang/de/template-tags.json
+++ b/modules-available/syslog/lang/de/template-tags.json
@@ -1,11 +1,16 @@
{
+ "lang_anonDaysDescription": "Nach wie vielen Tagen sollen Logeintr\u00e4ge anonymisiert werden? Auf 0 setzen, um Funktion zu deaktivieren.",
+ "lang_applyFilter": "Filter anwenden",
"lang_client": "Client",
"lang_clientLog": "Client Log",
"lang_details": "Details",
"lang_event": "Ereignis",
+ "lang_export": "Exportieren",
+ "lang_exportUserDesc": "Mit dieser Funktion k\u00f6nnen Sie alle in der Datenbank vorhandenen Datens\u00e4tze zu einem bestimmten Benutzer exportieren. Bitte geben Sie den Benutzernamen genau so ein, wie ihn der Nutzer beim Login am Client angeben muss.",
"lang_filter": "Filter",
- "lang_go": "Go",
"lang_not": "not",
- "lang_when": "Wann",
- "lang_applyFilter": "Filter anwenden"
+ "lang_settings": "Einstellungen",
+ "lang_userExport": "Nutzer-Export",
+ "lang_userLogin": "Benutzer-Login",
+ "lang_when": "Wann"
} \ No newline at end of file
diff --git a/modules-available/syslog/lang/en/messages.json b/modules-available/syslog/lang/en/messages.json
new file mode 100644
index 00000000..5578d7b9
--- /dev/null
+++ b/modules-available/syslog/lang/en/messages.json
@@ -0,0 +1,4 @@
+{
+ "anon-days-out-of-range": "Days have to be between 0 and 180 (was {{0}})",
+ "anon-days-saved": "Anonymization delay saved"
+} \ No newline at end of file
diff --git a/modules-available/syslog/lang/en/permissions.json b/modules-available/syslog/lang/en/permissions.json
new file mode 100644
index 00000000..26ea4448
--- /dev/null
+++ b/modules-available/syslog/lang/en/permissions.json
@@ -0,0 +1,4 @@
+{
+ "configure-anonymization": "Configure after how many days any usernames will be removed from log files.",
+ "view": "View client log."
+} \ No newline at end of file
diff --git a/modules-available/syslog/lang/en/template-tags.json b/modules-available/syslog/lang/en/template-tags.json
index 7dae52d9..24e9aaa1 100644
--- a/modules-available/syslog/lang/en/template-tags.json
+++ b/modules-available/syslog/lang/en/template-tags.json
@@ -1,11 +1,16 @@
{
+ "lang_anonDaysDescription": "After how many days should log messages be anonymized? Set to 0 to disable this feature.",
+ "lang_applyFilter": "Apply Filter",
"lang_client": "Client",
"lang_clientLog": "Client Log",
"lang_details": "Details",
"lang_event": "Event",
+ "lang_export": "Export",
+ "lang_exportUserDesc": "This exports all data from the database relating to the given user login. Please specify the user name exactly the way they would provide it when logging in on a client.",
"lang_filter": "Filter",
- "lang_go": "Go",
"lang_not": "not",
- "lang_when": "When",
- "lang_applyFilter": "Apply Filter"
+ "lang_settings": "Settings",
+ "lang_userExport": "User export",
+ "lang_userLogin": "User login",
+ "lang_when": "When"
} \ No newline at end of file
diff --git a/modules-available/syslog/page.inc.php b/modules-available/syslog/page.inc.php
index 153b591f..6c1a0a16 100644
--- a/modules-available/syslog/page.inc.php
+++ b/modules-available/syslog/page.inc.php
@@ -3,6 +3,9 @@
class Page_SysLog extends Page
{
+ const PROP_ANON_DAYS = 'syslog.anon-days'; // Copy in cronjob
+
+
protected function doPreprocess()
{
User::load();
@@ -11,10 +14,31 @@ class Page_SysLog extends Page
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
+
+ if (($days = Request::post('anondays', false, 'int')) !== false) {
+ User::assertPermission('configure-anonymization', NULL,'?do=syslog');
+ if ($days < 0 || $days > 180) {
+ Message::addError('anon-days-out-of-range', $days);
+ } else {
+ Property::set(self::PROP_ANON_DAYS, $days);
+ Message::addSuccess('anon-days-saved');
+ }
+ Util::redirect('?do=syslog');
+ }
+ User::assertPermission('*');
}
protected function doRender()
{
+ $data = ['anondays' => Property::get(self::PROP_ANON_DAYS, 0)];
+ Permission::addGlobalTags($data['perms'], NULL, ['configure-anonymization', 'export-user-data']);
+ Render::addTemplate("heading", $data);
+
+ if (!User::hasPermission("view")) {
+ Message::addError('main.no-permission');
+ return;
+ }
+
$cutoff = strtotime('-1 month');
$res = Database::simpleQuery("SELECT logtypeid, Count(*) AS counter FROM clientlog WHERE dateline > $cutoff GROUP BY logtypeid ORDER BY counter ASC");
$types = array();
@@ -57,9 +81,22 @@ class Page_SysLog extends Page
$whereClause .= "machineuuid='" . preg_replace('/[^0-9a-zA-Z\-]/', '', Request::get('machineuuid', '', 'string')) . "'";
}
+
+ $allowedLocations = User::getAllowedLocations("view");
+ $joinClause = "";
+ if (!in_array(0, $allowedLocations)) {
+ $joinClause = "INNER JOIN machine USING (machineuuid)";
+ if (empty($whereClause))
+ $whereClause .= ' WHERE ';
+ else
+ $whereClause .= ' AND ';
+
+ $whereClause .= 'locationid IN (:allowedLocations)';
+ }
+
$lines = array();
- $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientip, machineuuid, description, extra FROM clientlog $whereClause ORDER BY logid DESC", 50);
- $res = $paginate->exec();
+ $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientlog.clientip, clientlog.machineuuid, description, extra FROM clientlog $joinClause $whereClause ORDER BY logid DESC", 50);
+ $res = $paginate->exec(array("allowedLocations" => $allowedLocations));
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$row['date'] = Util::prettyTime($row['dateline']);
$row['icon'] = $this->eventToIconName($row['logtypeid']);
diff --git a/modules-available/syslog/permissions/permissions.json b/modules-available/syslog/permissions/permissions.json
new file mode 100644
index 00000000..1f2373d4
--- /dev/null
+++ b/modules-available/syslog/permissions/permissions.json
@@ -0,0 +1,11 @@
+{
+ "view": {
+ "location-aware": true
+ },
+ "configure-anonymization": {
+ "location-aware": false
+ },
+ "export-user-data": {
+ "location-aware": false
+ }
+} \ No newline at end of file
diff --git a/modules-available/syslog/templates/heading.html b/modules-available/syslog/templates/heading.html
new file mode 100644
index 00000000..8dd3d440
--- /dev/null
+++ b/modules-available/syslog/templates/heading.html
@@ -0,0 +1,68 @@
+<div class="page-header">
+ <span class="buttonbar pull-right">
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#modal-export" {{perms.export-user-data.disabled}}>
+ <span class="glyphicon glyphicon-export"></span>
+ {{lang_userExport}}
+ </button>
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#modal-settings">
+ <span class="glyphicon glyphicon-cog"></span> {{lang_settings}}
+ </button>
+ </span>
+
+ <div id="modal-settings" class="modal fade" role="dialog">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <form method="post" action="?do=syslog">
+ <input type="hidden" name="token" value="{{token}}">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">&times;</button>
+ <h4 class="modal-title"><b>{{lang_settings}}</b></h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_anonDaysDescription}}</p>
+ <input {{perms.configure-anonymization.disabled}} class="form-control" type="number" name="anondays"
+ value="{{anondays}}" min="0" max="180">
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button {{perms.configure-anonymization.disabled}} type="submit"
+ class="btn btn-primary">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+ </form>
+ </div>
+
+ </div>
+ </div>
+
+ <div id="modal-export" class="modal fade" role="dialog">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <form method="post" action="api.php?do=syslog">
+ <input type="hidden" name="token" value="{{token}}">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">&times;</button>
+ <h4 class="modal-title"><b>{{lang_userExport}}</b></h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_exportUserDesc}}</p>
+ <label for="export-user-name">{{lang_userLogin}}</label>
+ <input id="export-user-name" type="text" name="export-user" class="form-control" style="width:100%">
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" class="btn btn-primary">
+ <span class="glyphicon glyphicon-export"></span>
+ {{lang_export}}
+ </button>
+ </div>
+ </form>
+ </div>
+
+ </div>
+ </div>
+
+ <h1>{{lang_clientLog}}</h1>
+</div> \ No newline at end of file
diff --git a/modules-available/syslog/templates/page-syslog.html b/modules-available/syslog/templates/page-syslog.html
index d4709456..9d05d434 100644
--- a/modules-available/syslog/templates/page-syslog.html
+++ b/modules-available/syslog/templates/page-syslog.html
@@ -1,4 +1,3 @@
-<h1>{{lang_clientLog}}</h1>
<style type="text/css">
.selectize-dropdown {
max-width: 500px;