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@molbio.unmc.edu> 95 * To: wu-ftpd@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 }