117209Swollman/*	$NetBSD: logwtmp.c,v 1.24 2005/06/23 04:20:41 christos Exp $	*/
217209Swollman
3130461Sstefanf/*
417209Swollman * Copyright (c) 1988, 1993
515923Sscrappy *	The Regents of the University of California.  All rights reserved.
6111010Snectar *
72708Swollman * Redistribution and use in source and binary forms, with or without
82708Swollman * modification, are permitted provided that the following conditions
9130461Sstefanf * are met:
102708Swollman * 1. Redistributions of source code must retain the above copyright
112708Swollman *    notice, this list of conditions and the following disclaimer.
1292986Sobrien * 2. Redistributions in binary form must reproduce the above copyright
132708Swollman *    notice, this list of conditions and the following disclaimer in the
142708Swollman *    documentation and/or other materials provided with the distribution.
152708Swollman * 3. Neither the name of the University nor the names of its contributors
162708Swollman *    may be used to endorse or promote products derived from this software
172708Swollman *    without specific prior written permission.
182708Swollman *
192708Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
202708Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
212708Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2271579Sdeischen * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2318834Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2418834Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2571579Sdeischen * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2671579Sdeischen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2771579Sdeischen * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2871579Sdeischen * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2918834Swollman * SUCH DAMAGE.
302708Swollman *
312708Swollman */
3271579Sdeischen
3371579Sdeischen
3471579Sdeischen#include <sys/cdefs.h>
3571579Sdeischen#ifndef lint
3671579Sdeischen#if 0
37177824Sdavidxustatic char sccsid[] = "@(#)logwtmp.c	8.1 (Berkeley) 6/4/93";
38177824Sdavidxu#else
39177824Sdavidxu__RCSID("$NetBSD: logwtmp.c,v 1.24 2005/06/23 04:20:41 christos Exp $");
40177824Sdavidxu#endif
41177824Sdavidxu#endif /* not lint */
42177824Sdavidxu
43177824Sdavidxu#include <sys/types.h>
44177824Sdavidxu#include <sys/param.h>
45177824Sdavidxu#include <sys/time.h>
46177824Sdavidxu#include <sys/stat.h>
47177824Sdavidxu#include <sys/wait.h>
48177824Sdavidxu
49177824Sdavidxu#include <fcntl.h>
50177824Sdavidxu#include <signal.h>
51177824Sdavidxu#include <stdio.h>
529936Swollman#include <string.h>
539936Swollman#include <time.h>
549936Swollman#include <syslog.h>
552708Swollman#include <unistd.h>
562708Swollman#ifdef SUPPORT_UTMP
572708Swollman#include <utmp.h>
582708Swollman#endif
592708Swollman#ifdef SUPPORT_UTMPX
602708Swollman#include <utmpx.h>
612708Swollman#endif
622708Swollman#include <util.h>
632708Swollman
642708Swollman#ifdef KERBEROS5
652708Swollman#include <krb5/krb5.h>
662708Swollman#endif
679936Swollman
682708Swollman#include "extern.h"
699936Swollman
702708Swollman#ifdef SUPPORT_UTMP
712708Swollmanstatic int fd = -1;
722708Swollman
732708Swollmanvoid
742708Swollmanftpd_initwtmp(void)
752708Swollman{
762708Swollman	const char *wf = _PATH_WTMP;
772708Swollman	if ((fd = open(wf, O_WRONLY|O_APPEND, 0)) == -1)
782708Swollman		syslog(LOG_ERR, "Cannot open `%s' (%m)", wf);
792708Swollman}
802708Swollman
812708Swollman/*
822708Swollman * Modified version of logwtmp that holds wtmp file open
832708Swollman * after first call, for use with ftp (which may chroot
842708Swollman * after login, but before logout).
852708Swollman */
869936Swollmanvoid
872708Swollmanftpd_logwtmp(const char *line, const char *name, const char *host)
88130332Skensmith{
89130332Skensmith	struct utmp ut;
90130332Skensmith	struct stat buf;
91130332Skensmith
929936Swollman	if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
93130332Skensmith		return;
94130332Skensmith	if (fstat(fd, &buf) == 0) {
95130461Sstefanf		(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
96130461Sstefanf		(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
97130461Sstefanf		(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
98130461Sstefanf		(void)time(&ut.ut_time);
99130461Sstefanf		if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
100130461Sstefanf		    sizeof(struct utmp))
101130461Sstefanf			(void)ftruncate(fd, buf.st_size);
102130461Sstefanf	}
103130461Sstefanf}
104130461Sstefanf#endif
105130461Sstefanf
1062708Swollman#ifdef SUPPORT_UTMPX
107130461Sstefanfstatic int fdx = -1;
1082708Swollman
1092708Swollmanvoid
1102708Swollmanftpd_initwtmpx(void)
111130461Sstefanf{
1122708Swollman	const char *wf = _PATH_WTMPX;
1132708Swollman	if ((fd = open(wf, O_WRONLY|O_APPEND, 0)) == -1)
1142708Swollman		syslog(LOG_ERR, "Cannot open `%s' (%m)", wf);
1152708Swollman}
1162708Swollman
1172708Swollmanvoid
1182708Swollmanftpd_logwtmpx(const char *line, const char *name, const char *host,
1192708Swollman    struct sockinet *haddr, int status, int utx_type)
1202708Swollman{
1212708Swollman	struct utmpx ut;
1222708Swollman	struct stat buf;
1232708Swollman
1242708Swollman	if (fdx < 0)
1252708Swollman		return;
1262708Swollman	if (fstat(fdx, &buf) == 0) {
1272708Swollman		(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
1282708Swollman		(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
1292708Swollman		(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
1302708Swollman		if (haddr)
1312708Swollman			(void)memcpy(&ut.ut_ss, &haddr->si_su, haddr->su_len);
1322708Swollman		else
1332708Swollman			(void)memset(&ut.ut_ss, 0, sizeof(ut.ut_ss));
1342708Swollman		ut.ut_type = utx_type;
1352708Swollman		if (WIFEXITED(status))
1369936Swollman			ut.ut_exit.e_exit = (uint16_t)WEXITSTATUS(status);
1372708Swollman		if (WIFSIGNALED(status))
1382708Swollman		ut.ut_exit.e_termination = (uint16_t)WTERMSIG(status);
1392708Swollman		(void)gettimeofday(&ut.ut_tv, NULL);
1402708Swollman		if(write(fdx, (char *)&ut, sizeof(struct utmpx)) !=
1412708Swollman		    sizeof(struct utmpx))
1422708Swollman			(void)ftruncate(fdx, buf.st_size);
1432708Swollman	}
1442708Swollman}
1452708Swollman#endif
1462708Swollman