telnetd: fill hostname field in utmp/wtmp records
authorDenys Vlasenko <vda.linux@googlemail.com>
Tue, 6 Apr 2010 15:43:29 +0000 (17:43 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 6 Apr 2010 15:43:29 +0000 (17:43 +0200)
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>
include/libbb.h
libbb/xconnect.c
networking/ftpd.c
networking/telnetd.c

index f3121eb47f65a28c60447c10edbfbc80050e30d8..357571fd888b90b001c4993fc71e4591ea939900 100644 (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;
 /* Get local address of bound or accepted socket */
 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
  * Currently will return IPv4 or IPv6 sockaddrs only
  * (depending on host), but in theory nothing prevents e.g.
index d8c8d02d527c992c287ade0545225d358455a806..c3ee633e4c0d9e00187aa83534d5e54359404bf9 100644 (file)
@@ -47,25 +47,35 @@ int FAST_FUNC setsockopt_bindtodevice(int fd UNUSED_PARAM,
 }
 #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_ptr;
 
        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;
 
        lsa_ptr = xzalloc(LSA_LEN_SIZE + lsa.len);
        if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */
                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 {
                memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len);
        }
        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)
 {
        if (connect(s, s_addr, addrlen) < 0) {
index 375cc0ca53460b965b9860dd551e86a8ea53a0d8..9d43ea3a2d5d2a81ef4fb33fab00b94ecd94df38 100644 (file)
@@ -461,21 +461,6 @@ handle_epsv(void)
        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
 handle_port(void)
 {
index b3e66eb4b081012d8a89a5df88a3c0470c596d53..a8c86b62f7f3193c5c3ae3af5c4118b4802b2791 100644 (file)
@@ -226,6 +226,9 @@ make_new_session(
                IF_FEATURE_TELNETD_STANDALONE(int sock)
                IF_NOT_FEATURE_TELNETD_STANDALONE(void)
 ) {
+#if !ENABLE_FEATURE_TELNETD_STANDALONE
+       enum { sock = 0 );
+#endif
        const char *login_argv[2];
        struct termios termbuf;
        int fd, pid;
@@ -243,9 +246,9 @@ make_new_session(
        ndelay_on(fd);
        close_on_exec_on(fd);
 
-#if ENABLE_FEATURE_TELNETD_STANDALONE
        /* SO_KEEPALIVE by popular demand */
        setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
+#if ENABLE_FEATURE_TELNETD_STANDALONE
        ts->sockfd_read = sock;
        ndelay_on(sock);
        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)
                G.maxfd = sock;
 #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_write = 1;
        ndelay_on(0);
@@ -313,6 +314,17 @@ make_new_session(
        /* Restore default signal handling ASAP */
        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 */
        setsid();
 
@@ -326,9 +338,6 @@ make_new_session(
        pid = getpid();
        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
         * in cooked mode, and with XTABS CRMOD enabled (see tty(4)) */
        tcgetattr(0, &termbuf);