Home | History | Annotate | Download | only in in.ftpd
      1 #pragma ident	"%Z%%M%	%I%	%E% SMI"
      2 
      3 /****************************************************************************
      4   Copyright (c) 1999,2000 WU-FTPD Development Group.
      5   All rights reserved.
      6 
      7   Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994
      8     The Regents of the University of California.
      9   Portions Copyright (c) 1993, 1994 Washington University in Saint Louis.
     10   Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.
     11   Portions Copyright (c) 1989 Massachusetts Institute of Technology.
     12   Portions Copyright (c) 1998 Sendmail, Inc.
     13   Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P.  Allman.
     14   Portions Copyright (c) 1997 by Stan Barber.
     15   Portions Copyright (c) 1997 by Kent Landfield.
     16   Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
     17     Free Software Foundation, Inc.
     18 
     19   Use and distribution of this software and its source code are governed
     20   by the terms and conditions of the WU-FTPD Software License ("LICENSE").
     21 
     22   If you did not receive a copy of the license, it may be obtained online
     23   at http://www.wu-ftpd.org/license.html.
     24 
     25   $Id: logwtmp.c,v 1.16 2000/07/01 18:17:39 wuftpd Exp $
     26 
     27 ****************************************************************************/
     28 #include "config.h"
     29 
     30 #include <sys/types.h>
     31 #ifdef TIME_WITH_SYS_TIME
     32 #include <time.h>
     33 #include <sys/time.h>
     34 #else
     35 #ifdef HAVE_SYS_TIME_H
     36 #include <sys/time.h>
     37 #else
     38 #include <time.h>
     39 #endif
     40 #endif
     41 #include <sys/stat.h>
     42 #if defined(HAVE_FCNTL_H)
     43 #include <fcntl.h>
     44 #endif
     45 #include <utmp.h>
     46 #ifdef SVR4
     47 #ifndef NO_UTMPX
     48 #include <utmpx.h>
     49 #ifndef _SCO_DS
     50 #include <sac.h>
     51 #endif
     52 #endif
     53 #endif
     54 #ifdef BSD
     55 #include <strings.h>
     56 #else
     57 #include <string.h>
     58 #endif
     59 #ifdef HAVE_SYS_SYSLOG_H
     60 #include <sys/syslog.h>
     61 #endif
     62 #if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H))
     63 #include <syslog.h>
     64 #endif
     65 #ifdef __FreeBSD__
     66 #include <netinet/in.h>
     67 #include <arpa/inet.h>
     68 #include <netdb.h>
     69 #endif
     70 
     71 #include "pathnames.h"
     72 #include "proto.h"
     73 
     74 #ifndef NO_UTMP
     75 static int fd = -1;
     76 #endif
     77 #if defined(SVR4) && !defined(NO_UTMPX)
     78 static int fdx = -1;
     79 #endif
     80 
     81 /* Modified version of logwtmp that holds wtmp file open after first call,
     82  * for use with ftp (which may chroot after login, but before logout). */
     83 
     84 void wu_logwtmp(char *line, char *name, char *host, int login)
     85 {
     86     struct stat buf;
     87 #ifndef NO_UTMP
     88     struct utmp ut;
     89 #endif
     90 
     91 #if defined(SVR4) && !defined(NO_UTMPX)
     92     /*
     93      * Date: Tue, 09 Mar 1999 14:59:42 -0600
     94      * From: Chad Price <cprice (at) molbio.unmc.edu>
     95      * To: wu-ftpd (at) wugate.wustl.edu
     96      * Subject: Re: Problem w/ Solaris /var/adm/wtmpx and /usr/bin/last(1)
     97      *
     98      * I've been running Sol 2.4 since it came out, and the 'last' command
     99      * has never worked correctly, for ftpd or logins either one.  wtmpx
    100      * often fails to close out sessions when the user logs out.  As a
    101      * result, I only use last to see who logged in, not who/when the
    102      * logout occurred.
    103      *
    104      * When I first installed it, it was even worse, and they immediately
    105      * told me to patch the system.  This fixed it to semi-compus mentis,
    106      * but not to working order.  So I guess my conclusion is: ignore the
    107      * wtmpx / last log stuff on Solaris 2.4 (and other releases of Solaris
    108      * too from what I see in the comments), it's broken and always has
    109      * been.  I do of course stand ready to be corrected (in this case,
    110      * pointed to a patch which really does fix it.)
    111      *
    112      */
    113     struct utmpx utx;
    114 
    115     if (fdx < 0 && (fdx = open(WTMPX_FILE, O_WRONLY | O_APPEND, 0)) < 0) {
    116 	syslog(LOG_ERR, "wtmpx %s %m", WTMPX_FILE);
    117 	return;
    118     }
    119 
    120     if (fstat(fdx, &buf) == 0) {
    121 	memset((void *) &utx, '\0', sizeof(utx));
    122 	(void) strncpy(utx.ut_user, name, sizeof(utx.ut_user));
    123 	(void) strncpy(utx.ut_host, host, sizeof(utx.ut_host));
    124 	(void) strncpy(utx.ut_id, "ftp", sizeof(utx.ut_id));
    125 	(void) strncpy(utx.ut_line, line, sizeof(utx.ut_line));
    126 	utx.ut_syslen = strlen(utx.ut_host) + 1;
    127 	utx.ut_pid = getpid();
    128 	(void) time(&utx.ut_tv.tv_sec);
    129 	if (login /* name && *name */ ) {
    130 	    utx.ut_type = USER_PROCESS;
    131 	}
    132 	else {
    133 	    utx.ut_type = DEAD_PROCESS;
    134 	}
    135 	utx.ut_exit.e_termination = 0;
    136 	utx.ut_exit.e_exit = 0;
    137 	if (write(fdx, (char *) &utx, sizeof(struct utmpx)) !=
    138 	    sizeof(struct utmpx))
    139 	          (void) ftruncate(fdx, buf.st_size);
    140     }
    141 #endif /* defined(SVR4) && !defined(NO_UTMPX) */
    142 
    143 #ifndef NO_UTMP
    144 #ifdef __FreeBSD__
    145     if (strlen(host) > UT_HOSTSIZE) {
    146 	if ((host = inet_htop(host)) == NULL)
    147 	    host = "invalid hostname";
    148     }
    149 #endif
    150 
    151     if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY | O_APPEND, 0)) < 0) {
    152 	syslog(LOG_ERR, "wtmp %s %m", _PATH_WTMP);
    153 	return;
    154     }
    155     if (fstat(fd, &buf) == 0) {
    156 #ifdef UTMAXTYPE
    157 	memset((void *) &ut, 0, sizeof(ut));
    158 #ifdef LINUX
    159 	(void) strncpy(ut.ut_id, "", sizeof(ut.ut_id));
    160 #else
    161 	(void) strncpy(ut.ut_id, "ftp", sizeof(ut.ut_id));
    162 #endif
    163 	(void) strncpy(ut.ut_line, line, sizeof(ut.ut_line));
    164 	ut.ut_pid = getpid();
    165 	if (login /* name && *name */ ) {
    166 	    (void) strncpy(ut.ut_user, name, sizeof(ut.ut_user));
    167 	    ut.ut_type = USER_PROCESS;
    168 	}
    169 	else
    170 	    ut.ut_type = DEAD_PROCESS;
    171 #if defined(HAVE_UT_UT_EXIT_E_TERMINATION) || (!defined(AUTOCONF) && !defined(LINUX))
    172 	ut.ut_exit.e_termination = 0;
    173 	ut.ut_exit.e_exit = 0;
    174 #endif
    175 #else
    176 	(void) strncpy(ut.ut_line, line, sizeof(ut.ut_line));
    177 	if (login) {
    178 	    (void) strncpy(ut.ut_name, name, sizeof(ut.ut_name));
    179 	}
    180 	else {
    181 	    (void) strncpy(ut.ut_name, "", sizeof(ut.ut_name));
    182 	}
    183 #endif /* UTMAXTYPE */
    184 #ifdef HAVE_UT_UT_HOST		/* does have host in utmp */
    185 	if (login) {
    186 	    (void) strncpy(ut.ut_host, host, sizeof(ut.ut_host));
    187 	}
    188 	else {
    189 	    (void) strncpy(ut.ut_host, "", sizeof(ut.ut_host));
    190 	}
    191 #endif
    192 	(void) time(&ut.ut_time);
    193 	if (write(fd, (char *) &ut, sizeof(struct utmp)) !=
    194 	    sizeof(struct utmp))
    195 	         (void) ftruncate(fd, buf.st_size);
    196     }
    197 #endif /* NO_UTMP */
    198 }
    199