From 1e9def1efadb11a2ac56c8717cb354055a437eee Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 11 Mar 2011 15:54:12 -0500 Subject: [PATCH] Move utmp handling into utmp.c --- MANIFEST | 1 + src/Makefile.in | 2 + src/exec_pty.c | 161 ------------------------------------- src/sudo_exec.h | 4 + src/utmp.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 161 deletions(-) create mode 100644 src/utmp.c diff --git a/MANIFEST b/MANIFEST index 50998bb62..33b239902 100644 --- a/MANIFEST +++ b/MANIFEST @@ -222,6 +222,7 @@ src/sudo_plugin_int.h src/sudo_usage.h.in src/tgetpass.c src/ttysize.c +src/utmp.c sudo.pp zlib/Makefile.in zlib/adler32.c diff --git a/src/Makefile.in b/src/Makefile.in index 2c64249ce..340057920 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -138,6 +138,8 @@ tgetpass.o: $(srcdir)/tgetpass.c $(SUDODEP) $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/tgetpass.c ttysize.o: $(srcdir)/ttysize.c $(incdir)/missing.h $(top_builddir)/config.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/ttysize.c +utmp.o: $(srcdir)/utmp.c $(SUDODEP) + $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/utmp.c install: install-dirs install-binaries @INSTALL_NOEXEC@ diff --git a/src/exec_pty.c b/src/exec_pty.c index f41a7b67d..e02f72f26 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -52,14 +52,6 @@ #if TIME_WITH_SYS_TIME # include #endif -#if defined(HAVE_GETUTXID) -# include -#elif defined(HAVE_GETUTID) -# include -#elif defined(HAVE_UTIL_H) -# include -# include -#endif #include #include #include @@ -115,159 +107,6 @@ static void sync_ttysize(int src, int dst); static void deliver_signal(pid_t pid, int signo); static int safe_close(int fd); -#if defined(HAVE_GETUTXID) || defined(HAVE_GETUTID) -/* - * Create ut_id from tty line and the id from the entry we are cloning. - */ -static void -utmp_setid(const char *line, const char *old_id, char *new_id, size_t idsize) -{ - size_t idlen; - - /* Skip over "tty" in the id if old entry did too. */ - if (strncmp(line, "tty", 3) == 0 && - strncmp(old_id, "tty", idsize < 3 ? idsize : 3) != 0) - line += 3; - - /* Store as much as will fit, skipping parts of the beginning as needed. */ - idlen = strlen(line); - if (idlen > idsize) { - line += (idlen - idsize); - idlen = idsize; - } - strncpy(new_id, line, idlen); -} -#endif /* HAVE_GETUTXID || HAVE_GETUTID */ - -/* - * Clone a utmp entry, updating the line, id, pid and time. - * XXX - if no existing entry, make a new one - */ -static int -utmp_doclone(const char *from_line, const char *to_line) -{ - int rval = FALSE; -#ifdef HAVE_GETUTXID - struct utmpx *ut_old, ut_new; - - memset(&ut_new, 0, sizeof(ut_new)); - strncpy(ut_new.ut_line, from_line, sizeof(ut_new.ut_line)); - setutxent(); - if ((ut_old = getutxid(&ut_new)) != NULL) { - if (ut_old != &ut_new) - memcpy(&ut_new, ut_old, sizeof(ut_new)); - strncpy(ut_new.ut_line, to_line, sizeof(ut_new.ut_line)); - utmp_setid(to_line, ut_old->ut_id, ut_new.ut_id, sizeof(ut_new.ut_id)); - ut_new.ut_pid = getpid(); - gettimeofday(&ut_new.ut_tv, NULL); - ut_new.ut_type = USER_PROCESS; - - if (pututxline(&ut_new) != NULL) - rval = TRUE; - } - endutxent(); -#elif HAVE_GETUTID - struct utmp *ut_old, ut_new; - - memset(&ut_new, 0, sizeof(ut_new)); - strncpy(ut_new.ut_line, from_line, sizeof(ut_new.ut_line)); - setutent(); - if ((ut_old = getutid(&ut_new)) != NULL) { - if (ut_old != &ut_new) - memcpy(&ut_new, ut_old, sizeof(ut_new)); - strncpy(ut_new.ut_line, to_line, sizeof(ut_new.ut_line)); - utmp_setid(to_line, ut_old->ut_id, ut_new.ut_id, sizeof(ut_new.ut_id)); - ut_new.ut_pid = getpid(); - ut_new.ut_time = time(NULL); - ut_new.ut_type = USER_PROCESS; - - if (pututline(&ut_new) != NULL) - rval = TRUE; - } - endutent(); -#elif HAVE_LOGIN - FILE *fp; - struct utmp ut; - - /* Find existing entry, update line and add as new. */ - if ((fp = fopen(_PATH_UTMP, "r")) != NULL) { - while (fread(&ut, sizeof(ut), 1, fp) == 1) { - if (ut.ut_name[0] && - strncmp(ut.ut_line, from_line, sizeof(ut.ut_line)) == 0) { - strncpy(ut.ut_line, to_line, sizeof(ut.ut_line)); - login(&ut); - rval = TRUE; - break; - } - } - fclose(fp); - } -#endif - return rval; -} - -static int -utmp_clone(const char *from_line, const char *to_line) -{ - /* Strip off /dev/ prefix from to/from line as needed. */ - if (strncmp(from_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) - from_line += sizeof(_PATH_DEV) - 1; - if (strncmp(to_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) - to_line += sizeof(_PATH_DEV) - 1; - - return utmp_doclone(from_line, to_line); -} - -/* - * Remove (zero out) the utmp entry for a line. - */ -static int -utmp_doremove(const char *line) -{ - int rval = FALSE; -#ifdef HAVE_GETUTXID - struct utmpx *ut, key; - - memset(&key, 0, sizeof(key)); - strncpy(key.ut_line, line, sizeof(key.ut_line)); - setutxent(); - if ((ut = getutxid(&key)) != NULL) { - ut->ut_type = DEAD_PROCESS; - (void)gettimeofday(&ut->ut_tv, NULL); - if (pututxline(ut) != NULL) - rval = TRUE; - } - endutxent(); -#elif HAVE_GETUTID - struct utmp *ut, key; - - memset(&key, 0, sizeof(key)); - strncpy(key.ut_line, line, sizeof(key.ut_line)); - setutent(); - if ((ut = getutid(&key)) != NULL) { - ut->ut_type = DEAD_PROCESS; - ut->ut_time = time(NULL); - if (pututline(ut) != NULL) - rval = TRUE; - } - endutent(); -#elif HAVE_LOGIN - if (logout(line) != 0) - rval = TRUE; -#endif /* HAVE_GETUTXID */ - return rval; -} - -static int -utmp_remove(const char *line) -{ - /* Strip off /dev/ prefix from to/from line as needed. */ - if (strncmp(line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) - line += sizeof(_PATH_DEV) - 1; - - return utmp_doremove(line); -} - /* * Cleanup hook for error()/errorx() */ diff --git a/src/sudo_exec.h b/src/sudo_exec.h index 138bad41a..24bb5521c 100644 --- a/src/sudo_exec.h +++ b/src/sudo_exec.h @@ -42,4 +42,8 @@ void pty_setup(uid_t uid, const char *tty); void terminate_child(pid_t pid, int use_pgrp); extern int signal_pipe[2]; +/* utmp.c */ +int utmp_clone(const char *from_line, const char *to_line); +int utmp_remove(const char *line); + #endif /* _SUDO_EXEC_H */ diff --git a/src/utmp.c b/src/utmp.c new file mode 100644 index 000000000..f7a55de36 --- /dev/null +++ b/src/utmp.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2011 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif /* STDC_HEADERS */ +#ifdef HAVE_STRING_H +# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) +# include +# endif +# include +#endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include +#endif /* HAVE_STRINGS_H */ +#ifdef HAVE_UNISTD_H +# include +#endif /* HAVE_UNISTD_H */ +#if TIME_WITH_SYS_TIME +# include +#endif +#if defined(HAVE_GETUTXID) +# include +#elif defined(HAVE_GETUTID) +# include +#elif defined(HAVE_UTIL_H) +# include +# include +#endif + +#include "sudo.h" +#include "sudo_exec.h" + +#if defined(HAVE_GETUTXID) || defined(HAVE_GETUTID) +/* + * Create ut_id from tty line and the id from the entry we are cloning. + */ +static void +utmp_setid(const char *line, const char *old_id, char *new_id, size_t idsize) +{ + size_t idlen; + + /* Skip over "tty" in the id if old entry did too. */ + if (strncmp(line, "tty", 3) == 0 && + strncmp(old_id, "tty", idsize < 3 ? idsize : 3) != 0) + line += 3; + + /* Store as much as will fit, skipping parts of the beginning as needed. */ + idlen = strlen(line); + if (idlen > idsize) { + line += (idlen - idsize); + idlen = idsize; + } + strncpy(new_id, line, idlen); +} +#endif /* HAVE_GETUTXID || HAVE_GETUTID */ + +/* + * Clone a utmp entry, updating the line, id, pid and time. + * XXX - if no existing entry, make a new one + */ +static int +utmp_doclone(const char *from_line, const char *to_line) +{ + int rval = FALSE; +#ifdef HAVE_GETUTXID + struct utmpx *ut_old, ut_new; + + memset(&ut_new, 0, sizeof(ut_new)); + strncpy(ut_new.ut_line, from_line, sizeof(ut_new.ut_line)); + setutxent(); + if ((ut_old = getutxid(&ut_new)) != NULL) { + if (ut_old != &ut_new) + memcpy(&ut_new, ut_old, sizeof(ut_new)); + strncpy(ut_new.ut_line, to_line, sizeof(ut_new.ut_line)); + utmp_setid(to_line, ut_old->ut_id, ut_new.ut_id, sizeof(ut_new.ut_id)); + ut_new.ut_pid = getpid(); + gettimeofday(&ut_new.ut_tv, NULL); + ut_new.ut_type = USER_PROCESS; + + if (pututxline(&ut_new) != NULL) + rval = TRUE; + } + endutxent(); +#elif HAVE_GETUTID + struct utmp *ut_old, ut_new; + + memset(&ut_new, 0, sizeof(ut_new)); + strncpy(ut_new.ut_line, from_line, sizeof(ut_new.ut_line)); + setutent(); + if ((ut_old = getutid(&ut_new)) != NULL) { + if (ut_old != &ut_new) + memcpy(&ut_new, ut_old, sizeof(ut_new)); + strncpy(ut_new.ut_line, to_line, sizeof(ut_new.ut_line)); + utmp_setid(to_line, ut_old->ut_id, ut_new.ut_id, sizeof(ut_new.ut_id)); + ut_new.ut_pid = getpid(); + ut_new.ut_time = time(NULL); + ut_new.ut_type = USER_PROCESS; + + if (pututline(&ut_new) != NULL) + rval = TRUE; + } + endutent(); +#elif HAVE_LOGIN + FILE *fp; + struct utmp ut; + + /* Find existing entry, update line and add as new. */ + if ((fp = fopen(_PATH_UTMP, "r")) != NULL) { + while (fread(&ut, sizeof(ut), 1, fp) == 1) { + if (ut.ut_name[0] && + strncmp(ut.ut_line, from_line, sizeof(ut.ut_line)) == 0) { + strncpy(ut.ut_line, to_line, sizeof(ut.ut_line)); + login(&ut); + rval = TRUE; + break; + } + } + fclose(fp); + } +#endif + return rval; +} + +int +utmp_clone(const char *from_line, const char *to_line) +{ + /* Strip off /dev/ prefix from to/from line as needed. */ + if (strncmp(from_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) + from_line += sizeof(_PATH_DEV) - 1; + if (strncmp(to_line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) + to_line += sizeof(_PATH_DEV) - 1; + + return utmp_doclone(from_line, to_line); +} + +/* + * Remove (zero out) the utmp entry for a line. + */ +static int +utmp_doremove(const char *line) +{ + int rval = FALSE; +#ifdef HAVE_GETUTXID + struct utmpx *ut, key; + + memset(&key, 0, sizeof(key)); + strncpy(key.ut_line, line, sizeof(key.ut_line)); + setutxent(); + if ((ut = getutxid(&key)) != NULL) { + ut->ut_type = DEAD_PROCESS; + (void)gettimeofday(&ut->ut_tv, NULL); + if (pututxline(ut) != NULL) + rval = TRUE; + } + endutxent(); +#elif HAVE_GETUTID + struct utmp *ut, key; + + memset(&key, 0, sizeof(key)); + strncpy(key.ut_line, line, sizeof(key.ut_line)); + setutent(); + if ((ut = getutid(&key)) != NULL) { + ut->ut_type = DEAD_PROCESS; + ut->ut_time = time(NULL); + if (pututline(ut) != NULL) + rval = TRUE; + } + endutent(); +#elif HAVE_LOGIN + if (logout(line) != 0) + rval = TRUE; +#endif /* HAVE_GETUTXID */ + return rval; +} + +int +utmp_remove(const char *line) +{ + /* Strip off /dev/ prefix from to/from line as needed. */ + if (strncmp(line, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) + line += sizeof(_PATH_DEV) - 1; + + return utmp_doremove(line); +} -- 2.50.0