diff --git a/loginrec.c b/loginrec.c index af10d95..9e5c3aa 100644 --- a/loginrec.c +++ b/loginrec.c @@ -239,6 +239,13 @@ logininfo *login_alloc_entry(int pid, const char *username, newli = (struct logininfo *) m_malloc (sizeof(*newli)); (void)login_init_entry(newli, pid, username, hostname, line); +#ifdef HAVE_STRUCT_SOCKADDR_IN6 + if (inet_pton(AF_INET6, hostname, newli->hostaddr.sa_in6.sin6_addr.s6_addr) > 0) + newli->hostaddr.sa_in6.sin6_family = AF_INET6; + else +#endif + if (inet_pton(AF_INET, hostname, &newli->hostaddr.sa_in.sin_addr.s_addr) > 0) + newli->hostaddr.sa_in.sin_family = AF_INET; return newli; } @@ -473,9 +480,6 @@ void construct_utmp(struct logininfo *li, struct utmp *ut) { -# ifdef HAVE_ADDR_V6_IN_UTMP - struct sockaddr_in6 *sa6; -# endif memset(ut, '\0', sizeof(*ut)); /* First fill out fields used for both logins and logouts */ @@ -528,12 +532,11 @@ construct_utmp(struct logininfo *li, if (li->hostaddr.sa.sa_family == AF_INET) ut->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; # endif -# ifdef HAVE_ADDR_V6_IN_UTMP +# if defined(HAVE_STRUCT_UTMP_UT_ADDR_V6) && defined(HAVE_STRUCT_SOCKADDR_IN6) /* this is just a 128-bit IPv6 address */ if (li->hostaddr.sa.sa_family == AF_INET6) { - sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); - memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); - if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { + memcpy(ut->ut_addr_v6, li->hostaddr.sa_in6.sin6_addr.s6_addr, 16); + if (IN6_IS_ADDR_V4MAPPED(&li->hostaddr.sa_in6.sin6_addr)) { ut->ut_addr_v6[0] = ut->ut_addr_v6[3]; ut->ut_addr_v6[1] = 0; ut->ut_addr_v6[2] = 0; @@ -569,9 +572,6 @@ set_utmpx_time(struct logininfo *li, struct utmpx *utx) void construct_utmpx(struct logininfo *li, struct utmpx *utx) { -# ifdef HAVE_ADDR_V6_IN_UTMP - struct sockaddr_in6 *sa6; -# endif memset(utx, '\0', sizeof(*utx)); # ifdef HAVE_STRUCT_UTMPX_UT_ID line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); @@ -589,8 +589,6 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); set_utmpx_time(li, utx); utx->ut_pid = li->pid; - /* strncpy(): Don't necessarily want null termination */ - strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); if (li->type == LTYPE_LOGOUT) return; @@ -600,6 +598,9 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) * for logouts. */ + /* strncpy(): Don't necessarily want null termination */ + strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); + # ifdef HAVE_STRUCT_UTMPX_UT_HOST strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname)); # endif @@ -608,16 +609,15 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) if (li->hostaddr.sa.sa_family == AF_INET) utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; # endif -# ifdef HAVE_ADDR_V6_IN_UTMP +# if defined(HAVE_STRUCT_UTMPX_UT_ADDR_V6) && defined(HAVE_STRUCT_SOCKADDR_IN6) /* this is just a 128-bit IPv6 address */ if (li->hostaddr.sa.sa_family == AF_INET6) { - sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); - memcpy(ut->ut_addr_v6, sa6->sin6_addr.s6_addr, 16); - if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr)) { - ut->ut_addr_v6[0] = ut->ut_addr_v6[3]; - ut->ut_addr_v6[1] = 0; - ut->ut_addr_v6[2] = 0; - ut->ut_addr_v6[3] = 0; + memcpy(utx->ut_addr_v6, li->hostaddr.sa_in6.sin6_addr.s6_addr, 16); + if (IN6_IS_ADDR_V4MAPPED(&li->hostaddr.sa_in6.sin6_addr)) { + utx->ut_addr_v6[0] = utx->ut_addr_v6[3]; + utx->ut_addr_v6[1] = 0; + utx->ut_addr_v6[2] = 0; + utx->ut_addr_v6[3] = 0; } } # endif @@ -1047,30 +1047,12 @@ wtmp_get_entry(struct logininfo *li) **/ #ifdef USE_WTMPX -/* write a wtmpx entry direct to the end of the file */ -/* This is a slight modification of code in OpenBSD's logwtmp.c */ +/* write a wtmpx entry via updwtmpx() */ static int wtmpx_write(struct logininfo *li, struct utmpx *utx) { - struct stat buf; - int fd, ret = 1; - - if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { - dropbear_log(LOG_WARNING, "wtmpx_write: problem opening %s: %s", - WTMPX_FILE, strerror(errno)); - return 0; - } - - if (fstat(fd, &buf) == 0) - if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) { - ftruncate(fd, buf.st_size); - dropbear_log(LOG_WARNING, "wtmpx_write: problem writing %s: %s", - WTMPX_FILE, strerror(errno)); - ret = 0; - } - (void)close(fd); - - return ret; + updwtmpx(WTMPX_FILE, utx); + return 1; } diff --git a/loginrec.h b/loginrec.h index b2e3778..f594ad7 100644 --- a/loginrec.h +++ b/loginrec.h @@ -105,6 +105,9 @@ union login_netinfo { struct sockaddr sa; struct sockaddr_in sa_in; +#ifdef HAVE_STRUCT_SOCKADDR_IN6 + struct sockaddr_in6 sa_in6; +#endif #ifdef HAVE_STRUCT_SOCKADDR_STORAGE struct sockaddr_storage sa_storage; #endif diff --git a/svr-chansession.c b/svr-chansession.c index 656a968..bb4536c 100644 --- a/svr-chansession.c +++ b/svr-chansession.c @@ -850,6 +850,7 @@ static int ptycommand(struct Channel *channel, struct ChanSess *chansess) { * terminal used for stdout with the dup2 above, otherwise * the wtmp login will not be recorded */ li = chansess_login_alloc(chansess); + li->pid = getpid(); login_login(li); login_free_entry(li);