From 04966d045da6ae10a4fafccde2740f8c2aa03c29 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 21 Aug 2024 16:00:35 +0200
Subject: [PATCH 5/7] Introduce new log level [SEC] for audit trails
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Wires

This adds a new log level for security and audit trail related log
messages, see LOG_AUDIT defined in RFC5424.  E.g., nacm user applied
a change, copied a datastore, etc.

The new log level is added last to not affect the advertised command
line log levels.  A security notice has higher actual priorty than
DBG, of course, so we remap it to WRN.  The construct allows us to
have another [label] than [WRN], which might otherwise be read as
a bug/problem rather than just a high-priority-notification.

When logging to syslog() we let delegate labling and filtering to the
system log daemon, dropping any [SEVERITY] prefix.  Also, \n is most
often dropped by log daemons.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Mattias Walström <lazzer@gmail.com>
---
 src/log.c           | 18 +++++++++++++++++-
 src/log.h           |  1 +
 src/sysrepo_types.h |  3 ++-
 tests/tcommon.c     |  3 +++
 4 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/log.c b/src/log.c
index e15055ac..25eab8fa 100644
--- a/src/log.c
+++ b/src/log.c
@@ -30,6 +30,10 @@
 
 #include "config.h"
 
+#ifndef LOG_AUDIT
+#define LOG_AUDIT 	(13<<3)	/* Log audit, for audit trails */
+#endif
+
 sr_log_level_t sr_stderr_ll = SR_LL_NONE;   /**< stderr log level */
 sr_log_level_t sr_syslog_ll = SR_LL_NONE;   /**< syslog log level */
 int syslog_open;                            /**< Whether syslog was opened */
@@ -122,6 +126,11 @@ sr_log_msg(int plugin, sr_log_level_t ll, const char *msg)
         priority = LOG_INFO;
         severity = "INF";
         break;
+    case SR_LL_SEC:
+        priority = LOG_AUDIT | LOG_NOTICE;
+        severity = "SEC";
+        ll = SR_LL_WRN;         /* remap to higher level. */
+        break;
     case SR_LL_DBG:
         priority = LOG_DEBUG;
         severity = "DBG";
@@ -138,7 +147,14 @@ sr_log_msg(int plugin, sr_log_level_t ll, const char *msg)
 
     /* syslog logging */
     if (ll <= sr_syslog_ll) {
-        syslog(priority | (plugin ? LOG_DAEMON : 0), "[%s] %s\n", severity, msg);
+        int facility;
+
+        if (priority & ~LOG_PRIMASK)
+            facility = 0;       /* audit */
+        else
+            facility = plugin ? LOG_DAEMON : 0;
+
+        syslog(facility | priority, "%s", msg);
     }
 
     /* logging callback */
diff --git a/src/log.h b/src/log.h
index 9a60f1f6..acd7eead 100644
--- a/src/log.h
+++ b/src/log.h
@@ -31,6 +31,7 @@
 
 #define SR_LOG_WRN(...) sr_log(SR_LL_WRN, __VA_ARGS__)
 #define SR_LOG_INF(...) sr_log(SR_LL_INF, __VA_ARGS__)
+#define SR_LOG_SEC(...) sr_log(SR_LL_SEC, __VA_ARGS__)
 #define SR_LOG_DBG(...) sr_log(SR_LL_DBG, __VA_ARGS__)
 
 #define SR_CHECK_MEM_GOTO(cond, err_info, go) if (cond) { SR_ERRINFO_MEM(&(err_info)); goto go; }
diff --git a/src/sysrepo_types.h b/src/sysrepo_types.h
index 1fc7ed0b..b6540f77 100644
--- a/src/sysrepo_types.h
+++ b/src/sysrepo_types.h
@@ -65,7 +65,8 @@ typedef enum {
     SR_LL_ERR,       /**< Print only error messages. */
     SR_LL_WRN,       /**< Print error and warning messages. */
     SR_LL_INF,       /**< Besides errors and warnings, print some other informational messages. */
-    SR_LL_DBG        /**< Print all messages including some development debug messages. */
+    SR_LL_DBG,       /**< Print all messages including some development debug messages. */
+    SR_LL_SEC,       /**< Security, e.g., audit trail, high priority remapped to SR_LL_WRN */
 } sr_log_level_t;
 
 /**
diff --git a/tests/tcommon.c b/tests/tcommon.c
index 0dcdd0b4..49de738d 100644
--- a/tests/tcommon.c
+++ b/tests/tcommon.c
@@ -35,6 +35,9 @@ _test_log_msg(sr_log_level_t level, const char *message, const char *prefix)
     case SR_LL_WRN:
         severity = "WRN";
         break;
+    case SR_LL_SEC:
+        severity = "SEC";
+        break;
     case SR_LL_INF:
         severity = "INF";
         break;
-- 
2.43.0

