Accepting request 1120221 from home:tsaupe:branches:Base:System:rsyslog-no-utmp

use logind instead of utmp for wall messages with systemd

OBS-URL: https://build.opensuse.org/request/show/1120221
OBS-URL: https://build.opensuse.org/package/show/Base:System/rsyslog?expand=0&rev=362
This commit is contained in:
Thomas Blume 2023-11-13 14:05:33 +00:00 committed by Git OBS Bridge
parent 21ba6e0894
commit a7b17ceed2
3 changed files with 222 additions and 0 deletions

View File

@ -0,0 +1,204 @@
From 87c31b946d8d0a230f2db842328067eb5d8c5b08 Mon Sep 17 00:00:00 2001
From: Thomas Blume <Thomas.Blume@suse.com>
Date: Wed, 18 Oct 2023 16:22:45 +0200
Subject: [PATCH] use logind instead of utmp for wall messages with systemd
Future SUSE versions will get rid of utmp due to a 32bit time_t counter
overflow in 2038.
See details at:
https://github.com/thkukuk/utmpx/blob/main/Y2038.md
On systemd based systems logind is an alternative to utmp.
---
tools/omusrmsg.c | 142 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 110 insertions(+), 32 deletions(-)
diff --git a/tools/omusrmsg.c b/tools/omusrmsg.c
index 6086d2d6b..aaa36d9e5 100644
--- a/tools/omusrmsg.c
+++ b/tools/omusrmsg.c
@@ -56,6 +56,11 @@
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
+#ifdef HAVE_LIBSYSTEMD
+#include <systemd/sd-daemon.h>
+#include <systemd/sd-login.h>
+#include <pwd.h>
+#endif
#include "rsyslog.h"
#include "srUtils.h"
#include "stringbuf.h"
@@ -201,6 +206,42 @@ void endutent(void)
#endif /* #ifdef OS_BSD */
+static void sendwallmsg(const char *tty, uchar* pMsg)
+{
+ uchar szErr[512];
+ int errnoSave;
+ char p[sizeof(_PATH_DEV) + UNAMESZ];
+ int ttyf;
+ struct stat statb;
+ int wrRet;
+
+ /* compute the device name */
+ strcpy(p, _PATH_DEV);
+ strncat(p, tty, UNAMESZ);
+
+ /* we must be careful when writing to the terminal. A terminal may block
+ * (for example, a user has pressed <ctl>-s). In that case, we can not
+ * wait indefinitely. So we need to use non-blocking I/O. In case we would
+ * block, we simply do not send the message, because that's the best we can
+ * do. -- rgerhards, 2008-07-04
+ */
+
+ /* open the terminal */
+ if((ttyf = open(p, O_WRONLY|O_NOCTTY|O_NONBLOCK)) >= 0) {
+ if(fstat(ttyf, &statb) == 0 && (statb.st_mode & S_IWRITE)) {
+ wrRet = write(ttyf, pMsg, strlen((char*)pMsg));
+ if(Debug && wrRet == -1) {
+ /* we record the state to the debug log */
+ errnoSave = errno;
+ rs_strerror_r(errno, (char*)szErr, sizeof(szErr));
+ dbgprintf("write to terminal '%s' failed with [%d]:%s\n",
+ p, errnoSave, szErr);
+ }
+ }
+ close(ttyf);
+ }
+}
+
/* WALLMSG -- Write a message to the world at large
*
* Write the specified message to either the entire
@@ -215,20 +256,78 @@ void endutent(void)
*/
static rsRetVal wallmsg(uchar* pMsg, instanceData *pData)
{
-
- uchar szErr[512];
- char p[sizeof(_PATH_DEV) + UNAMESZ];
register int i;
- int errnoSave;
- int ttyf;
- int wrRet;
STRUCTUTMP ut;
STRUCTUTMP *uptr;
- struct stat statb;
DEFiRet;
assert(pMsg != NULL);
+#ifdef HAVE_LIBSYSTEMD
+ if (sd_booted() > 0) {
+ register int j;
+ int sdRet;
+ char **sessions_list;
+ int sessions = sd_get_sessions(&sessions_list);
+
+ for (j = 0; j < sessions; j++) {
+ uchar szErr[512];
+ char *user = NULL, *tty;
+ uid_t uid;
+ struct passwd *pws;
+
+ sdRet = sd_session_get_uid(sessions_list[j], &uid);
+ if (sdRet >= 0) {
+ pws = getpwuid(uid);
+ user = pws->pw_name;
+
+ if (user == NULL) {
+ dbgprintf("failed to get username for userid '%d'\n", uid);
+ continue;
+ }
+ } else {
+ /* we record the state to the debug log */
+ rs_strerror_r(-sdRet, (char*)szErr, sizeof(szErr));
+ dbgprintf("get userid for session '%s' failed with [%d]:%s\n",
+ sessions_list[j], -sdRet, szErr);
+ continue; /* try next session */
+ }
+ /* should we send the message to this user? */
+ if(pData->bIsWall == 0) {
+ for(i = 0; i < MAXUNAMES; i++) {
+ if(!pData->uname[i][0]) {
+ i = MAXUNAMES;
+ break;
+ }
+ if(strncmp(pData->uname[i], user, UNAMESZ) == 0)
+ break;
+ }
+ if(i == MAXUNAMES) { /* user not found? */
+ free(user);
+ free(sessions_list[j]);
+ continue; /* on to next user! */
+ }
+ }
+ if ((sdRet = sd_session_get_tty(sessions_list[j], &tty)) < 0) {
+ /* we record the state to the debug log */
+ rs_strerror_r(-sdRet, (char*)szErr, sizeof(szErr));
+ dbgprintf("get tty for session '%s' failed with [%d]:%s\n",
+ sessions_list[j], -sdRet, szErr);
+ free(user);
+ free(sessions_list[j]);
+ continue; /* try next session */
+ }
+
+ sendwallmsg(tty, pMsg);
+
+ free(user);
+ free(tty);
+ free(sessions_list[j]);
+ }
+ free(sessions_list);
+ } else {
+#endif
+
/* open the user login file */
setutent();
@@ -259,35 +358,14 @@ static rsRetVal wallmsg(uchar* pMsg, instanceData *pData)
continue; /* on to next user! */
}
- /* compute the device name */
- strcpy(p, _PATH_DEV);
- strncat(p, ut.ut_line, UNAMESZ);
-
- /* we must be careful when writing to the terminal. A terminal may block
- * (for example, a user has pressed <ctl>-s). In that case, we can not
- * wait indefinitely. So we need to use non-blocking I/O. In case we would
- * block, we simply do not send the message, because that's the best we can
- * do. -- rgerhards, 2008-07-04
- */
-
- /* open the terminal */
- if((ttyf = open(p, O_WRONLY|O_NOCTTY|O_NONBLOCK)) >= 0) {
- if(fstat(ttyf, &statb) == 0 && (statb.st_mode & S_IWRITE)) {
- wrRet = write(ttyf, pMsg, strlen((char*)pMsg));
- if(Debug && wrRet == -1) {
- /* we record the state to the debug log */
- errnoSave = errno;
- rs_strerror_r(errno, (char*)szErr, sizeof(szErr));
- dbgprintf("write to terminal '%s' failed with [%d]:%s\n",
- p, errnoSave, szErr);
- }
- }
- close(ttyf);
- }
+ sendwallmsg(ut.ut_line, pMsg);
}
/* close the user login file */
endutent();
+#ifdef HAVE_LIBSYSTEMD
+ }
+#endif
RETiRet;
}
--
2.42.0

View File

@ -1,3 +1,18 @@
-------------------------------------------------------------------
Wed Oct 25 08:27:13 UTC 2023 - Thomas Blume <thomas.blume@suse.com>
- use logind instead of utmp for wall messages with systemd
Future SUSE versions will get rid of utmp due to a 32bit time_t counter
overflow in 2038.
See details at:
https://github.com/thkukuk/utmpx/blob/main/Y2038.md
On systemd based systems logind is an alternative to utmp.
* add: 0001-use-logind-instead-of-utmp-for-wall-messages-with-sy.patch
-------------------------------------------------------------------
Tue Sep 5 12:43:28 UTC 2023 - Thomas Blume <thomas.blume@suse.com>

View File

@ -222,6 +222,8 @@ Source17: acpid.frule
Source18: firewall.frule
Source19: NetworkManager.frule
Patch1: 0001-use-logind-instead-of-utmp-for-wall-messages-with-sy.patch
# this is a dirty hack since % dir does only work for the specified directory and nothing above
# but I want to be able to switch this to /etc/apparmor.d once the profiles received more testing
%define APPARMOR_PROFILE_PATH /usr/share/apparmor/extra-profiles
@ -581,6 +583,7 @@ export CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -W -Wall -I../grammar -I../..
# for patch1
autoreconf -fiv
%autopatch -p1
%configure \
--with-moddirs=%{rsyslog_module_dir_withdeps} \