diff --git a/0001-use-logind-instead-of-utmp-for-wall-messages-with-sy.patch b/0001-use-logind-instead-of-utmp-for-wall-messages-with-sy.patch new file mode 100644 index 0000000..0d54ed1 --- /dev/null +++ b/0001-use-logind-instead-of-utmp-for-wall-messages-with-sy.patch @@ -0,0 +1,204 @@ +From 87c31b946d8d0a230f2db842328067eb5d8c5b08 Mon Sep 17 00:00:00 2001 +From: Thomas Blume +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 + #endif ++#ifdef HAVE_LIBSYSTEMD ++#include ++#include ++#include ++#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 -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 -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 + diff --git a/rsyslog.changes b/rsyslog.changes index fe95708..11fe815 100644 --- a/rsyslog.changes +++ b/rsyslog.changes @@ -1,3 +1,18 @@ +------------------------------------------------------------------- +Wed Oct 25 08:27:13 UTC 2023 - Thomas Blume + +- 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 diff --git a/rsyslog.spec b/rsyslog.spec index 39490a5..d7923df 100644 --- a/rsyslog.spec +++ b/rsyslog.spec @@ -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} \