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
wu_logwtmp(char * line,char * name,char * host,int login)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 }
199