Skip to content

Commit

Permalink
write: query logind for list of users with tty (#2088)
Browse files Browse the repository at this point in the history
  • Loading branch information
thkukuk committed Mar 6, 2023
1 parent 4b81a80 commit 963eee4
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 3 deletions.
1 change: 1 addition & 0 deletions meson.build
Expand Up @@ -2386,6 +2386,7 @@ exe = executable(
write_sources,
include_directories : includes,
link_with : [lib_common],
dependencies : [lib_systemd],
install_dir : usrbin_exec_dir,
install : opt,
build_by_default : opt)
Expand Down
4 changes: 4 additions & 0 deletions term-utils/Makemodule.am
Expand Up @@ -126,6 +126,10 @@ write_SOURCES = term-utils/write.c
write_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS)
write_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
write_LDADD = $(LDADD) libcommon.la
if HAVE_SYSTEMD
write_LDADD += $(SYSTEMD_LIBS)
write_CFLAGS += $(SYSTEMD_CFLAGS)
endif

if USE_TTY_GROUP
if MAKEINSTALL_DO_CHOWN
Expand Down
107 changes: 104 additions & 3 deletions term-utils/write.c
Expand Up @@ -57,7 +57,12 @@
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <utmpx.h>

#if defined(HAVE_LIBSYSTEMD) && HAVE_DECL_SD_SESSION_GET_USERNAME == 1
# include <systemd/sd-login.h>
#else
# include <utmpx.h>
#endif

#include "c.h"
#include "carefulputc.h"
Expand Down Expand Up @@ -129,8 +134,41 @@ static int check_tty(const char *tty, int *tty_writeable, time_t *tty_atime, int
*/
static int check_utmp(const struct write_control *ctl)
{
struct utmpx *u;
int res = 1;
#if defined(HAVE_LIBSYSTEMD) && HAVE_DECL_SD_SESSION_GET_USERNAME == 1
char **sessions_list;
int sessions = sd_get_sessions(&sessions_list);
if (sessions < 0)
errx(EXIT_FAILURE, _("error getting sessions: %s"),
strerror(-sessions));

for (int i = 0; i < sessions; i++) {
char *name, *tty;
int r;

if ((r = sd_session_get_username(sessions_list[i], &name)) < 0)
errx(EXIT_FAILURE, _("get user name failed: %s"), strerror (-r));
if (sd_session_get_tty(sessions_list[i], &tty) < 0) {
free(name);
continue;
}

if (strcmp(ctl->dst_login, name) == 0 &&
strcmp(ctl->dst_tty_name, tty) == 0) {
free(name);
free(tty);
res = 0;
break;
}
free(name);
free(tty);
}
for (int i = 0; i < sessions; i++)
free(sessions_list[i]);
free(sessions_list);

#else
struct utmpx *u;

utmpxname(_PATH_UTMP);
setutxent();
Expand All @@ -144,6 +182,7 @@ static int check_utmp(const struct write_control *ctl)
}

endutxent();
#endif
return res;
}

Expand All @@ -160,9 +199,70 @@ static int check_utmp(const struct write_control *ctl)
*/
static void search_utmp(struct write_control *ctl)
{
struct utmpx *u;
time_t best_atime = 0, tty_atime;
int num_ttys = 0, valid_ttys = 0, tty_writeable = 0, user_is_me = 0;

#if defined(HAVE_LIBSYSTEMD) && HAVE_DECL_SD_SESSION_GET_USERNAME == 1
char path[256];
char **sessions_list;
int sessions = sd_get_sessions(&sessions_list);
if (sessions < 0)
errx(EXIT_FAILURE, _("error getting sessions: %s"),
strerror(-sessions));

for (int i = 0; i < sessions; i++) {
char *name, *tty;
int r;

if ((r = sd_session_get_username(sessions_list[i], &name)) < 0)
errx(EXIT_FAILURE, _("get user name failed: %s"), strerror (-r));

if (strcmp(ctl->dst_login, name) != 0) {
free(name);
continue;
}

if (sd_session_get_tty(sessions_list[i], &tty) < 0) {
free(name);
continue;
}

num_ttys++;
snprintf(path, sizeof(path), "/dev/%s", tty);
if (check_tty(path, &tty_writeable, &tty_atime, 0)) {
/* bad term? skip */
free(name);
free(tty);
continue;
}
if (ctl->src_uid && !tty_writeable) {
/* skip ttys with msgs off */
free(name);
free(tty);
continue;
}
if (strcmp(tty, ctl->src_tty_name) == 0) {
user_is_me = 1;
free(name);
free(tty);
/* don't write to yourself */
continue;
}
valid_ttys++;
if (best_atime < tty_atime) {
best_atime = tty_atime;
free(ctl->dst_tty_path);
ctl->dst_tty_path = xstrdup(path);
ctl->dst_tty_name = ctl->dst_tty_path + 5;
}
free(name);
free(tty);
}
for (int i = 0; i < sessions; i++)
free(sessions_list[i]);
free(sessions_list);
#else
struct utmpx *u;
char path[sizeof(u->ut_line) + 6];

utmpxname(_PATH_UTMP);
Expand Down Expand Up @@ -197,6 +297,7 @@ static void search_utmp(struct write_control *ctl)
}

endutxent();
#endif
if (num_ttys == 0)
errx(EXIT_FAILURE, _("%s is not logged in"), ctl->dst_login);
if (valid_ttys == 0) {
Expand Down

0 comments on commit 963eee4

Please sign in to comment.