diff --git a/src/etc/inc/plugins.inc.d/core.inc b/src/etc/inc/plugins.inc.d/core.inc
index 5016a0203..cc68e8d4f 100644
--- a/src/etc/inc/plugins.inc.d/core.inc
+++ b/src/etc/inc/plugins.inc.d/core.inc
@@ -244,6 +244,7 @@ function core_syslog()
{
$logfacilities = array();
+ $logfacilities['audit'] = array('facility' => array('audit'));
$logfacilities['configd'] = array('facility' => array('configd.py'));
$logfacilities['dhcpd'] = array('facility' => array('dhcpd', 'dhcrelay'));
$logfacilities['filter'] = array('facility' => array('filterlog'));
diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php b/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php
index 34d075641..998cdb2d6 100644
--- a/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php
+++ b/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php
@@ -187,6 +187,7 @@ class AuthenticationFactory
*/
public function authenticate($service_name, $username, $password)
{
+ openlog("audit", LOG_ODELAY, LOG_AUTH);
$service = $this->getService($service_name);
if ($service !== null) {
$service->setUserName($username);
@@ -203,6 +204,7 @@ class AuthenticationFactory
get_class($service),
get_class($authenticator)
));
+ closelog();
return true;
} else {
// since checkConstraints() is defined on the service, who doesn't know about the
@@ -214,6 +216,7 @@ class AuthenticationFactory
get_class($service),
get_class($authenticator)
));
+ closelog();
return false;
}
} else {
@@ -229,12 +232,13 @@ class AuthenticationFactory
}
}
syslog(LOG_WARNING, sprintf(
- "user %s could not authenticate for %s. [using %s + %s]\n",
+ "user %s could not authenticate for %s. [using %s + %s]",
$username,
$service_name,
!empty($service) ? get_class($service) : '-',
!empty($authenticator) ? get_class($authenticator) : '-'
));
+ closelog();
return false;
}
diff --git a/src/opnsense/mvc/app/library/OPNsense/Core/Config.php b/src/opnsense/mvc/app/library/OPNsense/Core/Config.php
index b2be0139c..7fbfffaf4 100644
--- a/src/opnsense/mvc/app/library/OPNsense/Core/Config.php
+++ b/src/opnsense/mvc/app/library/OPNsense/Core/Config.php
@@ -463,6 +463,27 @@ class Config extends Singleton
}
}
+ /**
+ * send config change to audit log including the context we currently know of.
+ */
+ private function auditLogChange($backup_filename, $revision=null)
+ {
+ openlog("audit", LOG_ODELAY, LOG_AUTH);
+ $append_message = "";
+ if (is_array($revision) && !empty($revision['description'])) {
+ $append_message = sprintf(" [%s]", $revision['description']);
+ }
+ syslog(LOG_NOTICE, sprintf(
+ "user %s%s changed configuration to %s in %s%s",
+ !empty($_SESSION["Username"]) ? $_SESSION["Username"] : "(system)",
+ !empty($_SERVER['REMOTE_ADDR']) ? "@" . $_SERVER['REMOTE_ADDR'] : "",
+ $backup_filename,
+ !empty($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $_SERVER['SCRIPT_NAME'],
+ $append_message
+ ));
+ closelog();
+ }
+
/**
* backup current config
* @return string target filename
@@ -626,6 +647,7 @@ class Config extends Singleton
fflush($this->config_file_handle);
$backup_filename = $backup ? $this->backup() : null;
if ($backup_filename) {
+ $this->auditLogChange($backup_filename, $revision);
// use syslog to trigger a new configd event, which should signal a syshook config (in batch).
// Althought we include the backup filename, the event handler is responsible to determine the
// last processed event itself. (it's merely added for debug purposes)
diff --git a/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml b/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml
index b9faf99d1..50428bb6b 100644
--- a/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml
+++ b/src/opnsense/mvc/app/models/OPNsense/Core/Menu/Menu.xml
@@ -90,6 +90,7 @@
+
diff --git a/src/opnsense/service/templates/OPNsense/Syslog/local/audit.conf b/src/opnsense/service/templates/OPNsense/Syslog/local/audit.conf
new file mode 100644
index 000000000..ffb6a3f5b
--- /dev/null
+++ b/src/opnsense/service/templates/OPNsense/Syslog/local/audit.conf
@@ -0,0 +1,6 @@
+###################################################################
+# Local syslog-ng configuration filter definition [audit].
+###################################################################
+filter f_local_audit {
+ program("audit") or facility(auth);
+};
diff --git a/src/www/system_groupmanager.php b/src/www/system_groupmanager.php
index 6ad199cd5..132c029ff 100644
--- a/src/www/system_groupmanager.php
+++ b/src/www/system_groupmanager.php
@@ -155,8 +155,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
}
}
}
-
- write_config();
+ if (isset($id) && $a_group[$id]) {
+ $audit_msg = sprintf("group \"%s\" changed", $group['name']);
+ } else {
+ $audit_msg = sprintf("group \"%s\" created", $group['name']);
+ }
+ write_config($audit_msg);
// XXX: signal backend which users have changed.
// core_user_changed_groups() would change local group assignments in that case as well.
$new_members = !empty($group['member']) ? $group['member'] : array();
diff --git a/src/www/system_usermanager.php b/src/www/system_usermanager.php
index c5bcfe63b..200da25f6 100644
--- a/src/www/system_usermanager.php
+++ b/src/www/system_usermanager.php
@@ -181,7 +181,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
local_user_del($a_user[$id]);
$userdeleted = $a_user[$id]['name'];
unset($a_user[$id]);
- write_config();
+ write_config(sprintf('The user "%s" was successfully removed.', $userdeleted));
$savemsg = sprintf(gettext('The user "%s" was successfully removed.'), $userdeleted);
header(url_safe('Location: /system_usermanager.php?savemsg=%s', array($savemsg)));
exit;
@@ -191,7 +191,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$certdeleted = lookup_cert($a_user[$id]['cert'][$pconfig['certid']]);
$certdeleted = $certdeleted['descr'];
unset($a_user[$id]['cert'][$pconfig['certid']]);
- write_config();
+ write_config(sprintf('The certificate association "%s" was successfully removed.', $certdeleted));
$savemsg = sprintf(gettext('The certificate association "%s" was successfully removed.'), $certdeleted);
header(url_safe('Location: /system_usermanager.php?savemsg=%s&act=edit&userid=%d', array($savemsg, $id)));
exit;
@@ -385,7 +385,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
local_user_set_groups($userent, $pconfig['groups']);
local_user_set($userent);
- write_config();
+ if (isset($id)) {
+ $audit_msg = sprintf("user \"%s\" changed", $userent['name']);
+ } else {
+ $audit_msg = sprintf("user \"%s\" created", $userent['name']);
+ }
+ write_config($audit_msg);
// XXX: signal backend that the user has changed.
configdp_run('auth user changed', [$userent['name']]);