aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2021-04-22 18:26:04 -0700
committerRob Landley <rob@landley.net>2021-04-24 04:50:19 -0500
commit35c484489b06134fb1ac56801c621020b935b2a7 (patch)
treea3d360b00f2a54a62e482126c45c0cee722b721c
parentc366525850cfdfd2884ab9a214be21a4f66505bd (diff)
downloadtoybox-35c484489b06134fb1ac56801c621020b935b2a7.tar.gz
telnetd: pass `-h hostname` to login(1).
Handling utmp is login's job: telnetd should just pass the appropriate option to login. (I was investigating a different bug that caused telnetd to take 100% CPU after a network outage and noticed an unexpected utmp fd. It turned out to not be relevant to my actual problem, but it did remind me that this utmp code isn't right in small details like that, but also in the bigger picture: it's writing the wrong information, and only on logout, not login. But rather than try to fix it, let's just let login do its job.)
-rw-r--r--toys/pending/telnetd.c32
1 files changed, 10 insertions, 22 deletions
diff --git a/toys/pending/telnetd.c b/toys/pending/telnetd.c
index c82ff61e..7bfbf316 100644
--- a/toys/pending/telnetd.c
+++ b/toys/pending/telnetd.c
@@ -25,7 +25,6 @@ config TELNETD
#define FOR_telnetd
#include "toys.h"
#include <arpa/telnet.h>
-#include <utmp.h>
GLOBALS(
char *login_path;
@@ -97,23 +96,6 @@ static void get_sockaddr(char *host, void *buf)
else ((struct sockaddr_in6*)buf)->sin6_port = port_num;
}
-static void utmp_entry(void)
-{
- struct utmp entry;
- struct utmp *utp_ptr;
- pid_t pid = getpid();
-
- utmpname(_PATH_UTMP);
- setutent(); //start from start
- while ((utp_ptr = getutent()) != NULL) {
- if (utp_ptr->ut_pid == pid && utp_ptr->ut_type >= INIT_PROCESS) break;
- }
- if (!utp_ptr) entry.ut_type = DEAD_PROCESS;
- entry.ut_time = time(0);
- setutent();
- pututline(&entry);
-}
-
static int listen_socket(void)
{
int s, af = AF_INET, yes = 1;
@@ -165,11 +147,13 @@ static void write_issue(char *tty)
static int new_session(int sockfd)
{
- char *argv_login[2]; //arguments for execvp cmd, NULL
+ char *argv_login[] = {NULL, "-h", NULL, NULL};
char tty_name[30]; //tty name length.
int fd, flags, i = 1;
char intial_iacs[] = {IAC, DO, TELOPT_ECHO, IAC, DO, TELOPT_NAWS,
IAC, WILL, TELOPT_ECHO, IAC, WILL, TELOPT_SGA };
+ struct sockaddr_storage sa;
+ socklen_t sl = sizeof(sa);
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i));
flags = fcntl(sockfd, F_GETFL);
@@ -183,9 +167,14 @@ static int new_session(int sockfd)
return fd;
}
if (TT.fork_pid < 0) perror_exit("fork");
+
+ if (getpeername(sockfd, (void *)&sa, &sl)) perror_exit("getpeername");
+ if (getnameinfo((void *)&sa, sl, toybuf, sizeof(toybuf), NULL, 0, 0))
+ perror_exit("getnameinfo");
+
write_issue(tty_name);
- argv_login[0] = strdup(TT.login_path);
- argv_login[1] = NULL;
+ argv_login[0] = TT.login_path;
+ argv_login[2] = toybuf;
execvp(argv_login[0], argv_login);
exit(EXIT_FAILURE);
}
@@ -418,7 +407,6 @@ void telnetd_main(void)
if (FLAG(i)) exit(EXIT_SUCCESS);
if (!prev) session_list = session_list->next;
else prev->next = tm->next;
- utmp_entry();
xclose(tm->pty_fd);
xclose(tm->new_fd);
free(tm);