xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/logwtmp.c (revision 0:68f95e015346)
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