2 * This file has been heavily modified from the original OpenBSD version
5 /* $OpenBSD: login.c,v 1.5 1998/07/13 02:11:12 millert Exp $ */
7 * Copyright (c) 1988, 1993
8 * The Regents of the University of California. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 #if defined(LIBC_SCCS) && !defined(lint)
45 /* from: static char sccsid[] = "@(#)login.c 8.1 (Berkeley) 6/4/93"; */
46 static char *rcsid = "$OpenBSD: login.c,v 1.5 1998/07/13 02:11:12 millert Exp $";
47 #endif /* LIBC_SCCS and not lint */
49 #include <sys/types.h>
54 #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
65 * find first matching slot in utmp, or "-1" for none
67 * algorithm: for USER_PROCESS, check tty name
68 * for DEAD_PROCESS, check PID and tty name
71 int find_tty_slot( utp )
77 # if defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX)
80 while((u = getutent()) != NULL) {
81 if (utp->ut_type == USER_PROCESS &&
82 (strncmp(utp->ut_line, u->ut_line, sizeof(utp->ut_line)) == 0)) {
87 if ((utp->ut_type == DEAD_PROCESS) && (utp->ut_pid == u->ut_pid) &&
88 (strncmp(utp->ut_line, u->ut_line, sizeof(utp->ut_line)) == 0 )) {
96 # endif /* defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX) */
99 #else /* USER_PROCESS */
100 int find_tty_slot(struct utmp *utp)
104 #endif /* USER_PROCESS */
106 #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
107 void login(struct utmpx *utx)
108 #else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
109 void login(struct utmp *utp)
110 #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
112 /* Use proper API if we have it */
113 #if defined(USE_UTMPX)
114 # if defined(HAVE_PUTUTXLINE)
118 # endif /* defined(HAVE_PUTUTXLINE) */
119 # if defined(HAVE_UPDWTMPX)
120 updwtmpx(_PATH_WTMPX, utx);
121 # endif /* defined(HAVE_UPDWTMPX) */
122 #else /* defined(USE_UTMPX) */
123 # if defined(HAVE_PUTUTLINE)
127 # endif /* defined(HAVE_PUTUTLINE) */
128 # if defined(HAVE_UPDWTMPX)
129 updwtmp(_PATH_WTMP, utp);
130 # endif /* defined(HAVE_UPDWTMP) */
131 #endif /* defined(USE_UTMPX) */
134 #if (defined(USE_UTMPX) && !defined(HAVE_PUTUTXLINE)) || \
135 (!defined(USE_UTMPX) && !defined(HAVE_PUTUTLINE))
139 /* can't use ttyslot here, as that will not work for logout
140 * (record_logout() is called from the master sshd, which does
141 * not have the correct tty on stdin/out, so ttyslot will return
142 * "-1" or (worse) a wrong number
144 tty = find_tty_slot(utp);
147 /* If no tty was found, append it to utmpx */
149 if ((fd = open(_PATH_UTMPX, O_WRONLY|O_APPEND, 0)) >= 0) {
150 (void)write(fd, utp, sizeof(struct utmp));
155 /* Otherwise, tty was found - update at its location */
156 fd = open(_PATH_UTMPX, O_RDWR|O_CREAT, 0644);
158 log("Couldn't open %s: %s", _PATH_UTMPX, strerror(errno));
161 lseek(fd, (off_t)(tty * sizeof(struct utmpx)), SEEK_SET);
162 write(fd, utx, sizeof(struct utmpx));
164 if ((fd = open(_PATH_WTMPX, O_WRONLY|O_APPEND, 0)) >= 0) {
165 (void)write(fd, utx, sizeof(struct utmpx));
168 #else /* USE_UTMPX */
169 /* If no tty was found, append it to utmp */
171 if ((fd = open(_PATH_UTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
172 (void)write(fd, utp, sizeof(struct utmp));
177 /* Otherwise, tty was found - update at its location */
178 fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644);
180 log("Couldn't open %s: %s", _PATH_UTMP, strerror(errno));
183 lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
184 write(fd, utp, sizeof(struct utmp));
186 if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
187 (void)write(fd, utp, sizeof(struct utmp));
190 #endif /* USE_UTMPX */
191 #endif /* (defined(USE_UTMPX) && !defined(HAVE_PUTUTXLINE)) || \
192 (!defined(USE_UTMPX) && !defined(HAVE_PUTUTLINE)) */
195 #endif /* HAVE_LOGIN */