Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:favogt:symbolictw
rsyslog
0001-use-logind-instead-of-utmp-for-wall-messag...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-use-logind-instead-of-utmp-for-wall-messages-with-sy.patch of Package rsyslog
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
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor