telnetd: fill hostname field in utmp/wtmp records

function                                             old     new   delta
get_lsa                                                -     109    +109
make_new_session                                     438     504     +66
get_peer_lsa                                           -      10     +10
ftpd_main                                           2340    2267     -73
get_sock_lsa                                         101      10     -91
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 1/2 up/down: 185/-164)           Total: 21 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2010-04-06 17:43:29 +02:00
parent fcad7681f8
commit f6916dbed4
4 changed files with 30 additions and 24 deletions

View File

@ -530,6 +530,8 @@ int create_and_connect_stream_or_die(const char *peer, int port) FAST_FUNC;
int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC; int xconnect_stream(const len_and_sockaddr *lsa) FAST_FUNC;
/* Get local address of bound or accepted socket */ /* Get local address of bound or accepted socket */
len_and_sockaddr *get_sock_lsa(int fd) FAST_FUNC RETURNS_MALLOC; len_and_sockaddr *get_sock_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
/* Get remote address of connected or accepted socket */
len_and_sockaddr *get_peer_lsa(int fd) FAST_FUNC RETURNS_MALLOC;
/* Return malloc'ed len_and_sockaddr with socket address of host:port /* Return malloc'ed len_and_sockaddr with socket address of host:port
* Currently will return IPv4 or IPv6 sockaddrs only * Currently will return IPv4 or IPv6 sockaddrs only
* (depending on host), but in theory nothing prevents e.g. * (depending on host), but in theory nothing prevents e.g.

View File

@ -47,25 +47,35 @@ int FAST_FUNC setsockopt_bindtodevice(int fd UNUSED_PARAM,
} }
#endif #endif
len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd) static len_and_sockaddr* get_lsa(int fd, int (*get_name)(int fd, struct sockaddr *addr, socklen_t *addrlen))
{ {
len_and_sockaddr lsa; len_and_sockaddr lsa;
len_and_sockaddr *lsa_ptr; len_and_sockaddr *lsa_ptr;
lsa.len = LSA_SIZEOF_SA; lsa.len = LSA_SIZEOF_SA;
if (getsockname(fd, &lsa.u.sa, &lsa.len) != 0) if (get_name(fd, &lsa.u.sa, &lsa.len) != 0)
return NULL; return NULL;
lsa_ptr = xzalloc(LSA_LEN_SIZE + lsa.len); lsa_ptr = xzalloc(LSA_LEN_SIZE + lsa.len);
if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */ if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */
lsa_ptr->len = lsa.len; lsa_ptr->len = lsa.len;
getsockname(fd, &lsa_ptr->u.sa, &lsa_ptr->len); get_name(fd, &lsa_ptr->u.sa, &lsa_ptr->len);
} else { } else {
memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len); memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len);
} }
return lsa_ptr; return lsa_ptr;
} }
len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd)
{
return get_lsa(fd, getsockname);
}
len_and_sockaddr* FAST_FUNC get_peer_lsa(int fd)
{
return get_lsa(fd, getpeername);
}
void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen)
{ {
if (connect(s, s_addr, addrlen) < 0) { if (connect(s, s_addr, addrlen) < 0) {

View File

@ -461,21 +461,6 @@ handle_epsv(void)
free(response); free(response);
} }
/* libbb candidate */
static
len_and_sockaddr* get_peer_lsa(int fd)
{
len_and_sockaddr *lsa;
socklen_t len = 0;
if (getpeername(fd, NULL, &len) != 0)
return NULL;
lsa = xzalloc(LSA_LEN_SIZE + len);
lsa->len = len;
getpeername(fd, &lsa->u.sa, &lsa->len);
return lsa;
}
static void static void
handle_port(void) handle_port(void)
{ {

View File

@ -226,6 +226,9 @@ make_new_session(
IF_FEATURE_TELNETD_STANDALONE(int sock) IF_FEATURE_TELNETD_STANDALONE(int sock)
IF_NOT_FEATURE_TELNETD_STANDALONE(void) IF_NOT_FEATURE_TELNETD_STANDALONE(void)
) { ) {
#if !ENABLE_FEATURE_TELNETD_STANDALONE
enum { sock = 0 );
#endif
const char *login_argv[2]; const char *login_argv[2];
struct termios termbuf; struct termios termbuf;
int fd, pid; int fd, pid;
@ -243,9 +246,9 @@ make_new_session(
ndelay_on(fd); ndelay_on(fd);
close_on_exec_on(fd); close_on_exec_on(fd);
#if ENABLE_FEATURE_TELNETD_STANDALONE
/* SO_KEEPALIVE by popular demand */ /* SO_KEEPALIVE by popular demand */
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
#if ENABLE_FEATURE_TELNETD_STANDALONE
ts->sockfd_read = sock; ts->sockfd_read = sock;
ndelay_on(sock); ndelay_on(sock);
if (sock == 0) { /* We are called with fd 0 - we are in inetd mode */ if (sock == 0) { /* We are called with fd 0 - we are in inetd mode */
@ -256,8 +259,6 @@ make_new_session(
if (sock > G.maxfd) if (sock > G.maxfd)
G.maxfd = sock; G.maxfd = sock;
#else #else
/* SO_KEEPALIVE by popular demand */
setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
/* ts->sockfd_read = 0; - done by xzalloc */ /* ts->sockfd_read = 0; - done by xzalloc */
ts->sockfd_write = 1; ts->sockfd_write = 1;
ndelay_on(0); ndelay_on(0);
@ -313,6 +314,17 @@ make_new_session(
/* Restore default signal handling ASAP */ /* Restore default signal handling ASAP */
bb_signals((1 << SIGCHLD) + (1 << SIGPIPE), SIG_DFL); bb_signals((1 << SIGCHLD) + (1 << SIGPIPE), SIG_DFL);
if (ENABLE_FEATURE_UTMP) {
len_and_sockaddr *lsa = get_peer_lsa(sock);
char *hostname = NULL;
if (lsa) {
hostname = xmalloc_sockaddr2dotted(&lsa->u.sa);
free(lsa);
}
write_new_utmp(pid, LOGIN_PROCESS, tty_name, /*username:*/ "LOGIN", hostname);
free(hostname);
}
/* Make new session and process group */ /* Make new session and process group */
setsid(); setsid();
@ -326,9 +338,6 @@ make_new_session(
pid = getpid(); pid = getpid();
tcsetpgrp(0, pid); /* switch this tty's process group to us */ tcsetpgrp(0, pid); /* switch this tty's process group to us */
//TODO: fetch remote addr via getpeername (see ftpd.c)
write_new_utmp(pid, LOGIN_PROCESS, tty_name, /*username:*/ "LOGIN", /*hostname:*/ NULL);
/* The pseudo-terminal allocated to the client is configured to operate /* The pseudo-terminal allocated to the client is configured to operate
* in cooked mode, and with XTABS CRMOD enabled (see tty(4)) */ * in cooked mode, and with XTABS CRMOD enabled (see tty(4)) */
tcgetattr(0, &termbuf); tcgetattr(0, &termbuf);