]> andersk Git - openssh.git/blob - bsd-login.c
de49214c09538b1034ed8ae3c1246c62074d709d
[openssh.git] / bsd-login.c
1 /*
2  * This file has been modified from the original OpenBSD version 
3  */
4
5 /*      $OpenBSD: login.c,v 1.5 1998/07/13 02:11:12 millert Exp $       */
6 /*
7  * Copyright (c) 1988, 1993
8  *      The Regents of the University of California.  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
25  *
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
36  * SUCH DAMAGE.
37  */
38
39 #include "config.h"
40 #ifndef HAVE_LOGIN
41
42 #include <errno.h>
43
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 */
48
49 #include <sys/types.h>
50
51 #include <fcntl.h>
52 #include <unistd.h>
53 #include <stdlib.h>
54 #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
55 # include <utmpx.h>
56 #endif
57 #ifdef HAVE_UTMP_H
58 # include <utmp.h>
59 #endif
60 #include <stdio.h>
61 #include <string.h>
62
63 /*
64  * find first matching slot in utmp, or "-1" for none
65  *
66  * algorithm: for USER_PROCESS, check tty name
67  *            for DEAD_PROCESS, check PID and tty name
68  *
69  */
70 int find_tty_slot( utp )
71 struct utmp * utp;
72 {
73         int t = 0;
74         struct utmp * u;
75
76 #if defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX)
77         setutent();
78
79         while((u = getutent()) != NULL) {
80                 if (utp->ut_type == USER_PROCESS &&
81                     (strncmp(utp->ut_line, u->ut_line, sizeof(utp->ut_line)) == 0)) {
82                         endutent();
83                         return(t);
84                 }
85
86                 if ((utp->ut_type == DEAD_PROCESS) && (utp->ut_pid == u->ut_pid) &&
87                     (strncmp(utp->ut_line, u->ut_line, sizeof(utp->ut_line)) == 0 )) {
88                         endutent();
89                         return(t);
90                 }
91                 t++;
92         }
93
94         endutent();
95 #endif
96         return(-1);
97 }
98
99 #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
100 void
101 login(utp,utx)
102         struct utmp *utp;
103         struct utmpx *utx;
104 #else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
105 void
106 login(utp)
107         struct utmp *utp;
108 #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
109 {
110 #if defined(HAVE_HOST_IN_UTMP)
111         struct utmp old_ut;
112 #endif
113 #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
114         struct utmpx *old_utx;
115 #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
116         register int fd;
117         int tty;
118
119         /* can't use ttyslot here, as that will not work for logout
120          * (record_logout() is called from the master sshd, which does
121          * not have the correct tty on stdin/out, so ttyslot will return
122          * "-1" or (worse) a wrong number
123          */
124         tty = find_tty_slot(utp);
125
126 #ifdef USE_UTMPX
127         fd = open(_PATH_UTMPX, O_RDWR|O_CREAT, 0644);
128         if (fd == -1) {
129                 log("Couldn't open %s: %s", _PATH_UTMPX, strerror(errno));
130 #else /* USE_UTMPX */
131         fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644);
132         if (fd == -1) {
133                 log("Couldn't open %s: %s", _PATH_UTMP, strerror(errno));
134 #endif /* USE_UTMPX */
135         } else {
136                 /* If no tty was found... */
137                 if (tty == -1) {
138                         /* ... append it to utmp on login */
139 #if defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX)
140                         if (utp->ut_type == USER_PROCESS) {
141 #ifdef USE_UTMPX
142                                 if ((fd = open(_PATH_UTMPX, O_WRONLY|O_APPEND, 0)) >= 0) {
143 #else /* USE_UTMPX */
144                                 if ((fd = open(_PATH_UTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
145 #endif /* USE_UTMPX */
146                                         (void)write(fd, utp, sizeof(struct utmp));
147                                         (void)close(fd);
148                                 }
149                         } else {
150                                 /* Shouldn't get to here unless somthing happened to utmp */
151                                 /* Between login and logout */
152                                 log("No tty slot found at logout");
153                         }
154 #endif
155                 } else {
156                         /* Otherwise, tty was found - update at its location */
157 #if defined(HAVE_HOST_IN_UTMP)
158 # ifndef UT_LINESIZE
159 #  define UT_LINESIZE (sizeof(old_ut.ut_line))
160 #  define UT_NAMESIZE (sizeof(old_ut.ut_name))
161 #  define UT_HOSTSIZE (sizeof(old_ut.ut_host))
162 # endif
163                         (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
164                         /*
165                          * Prevent luser from zero'ing out ut_host.
166                          * If the new ut_line is empty but the old one is not
167                          * and ut_line and ut_name match, preserve the old ut_line.
168                          */
169                         if (read(fd, &old_ut, sizeof(struct utmp)) ==
170                          sizeof(struct utmp) && utp->ut_host[0] == '\0' &&
171                          old_ut.ut_host[0] != '\0' &&
172                          strncmp(old_ut.ut_line, utp->ut_line, UT_LINESIZE) == 0 &&
173                          strncmp(old_ut.ut_name, utp->ut_name, UT_NAMESIZE) == 0)
174                                 (void)memcpy(utp->ut_host, old_ut.ut_host, UT_HOSTSIZE);
175 #endif /* defined(HAVE_HOST_IN_UTMP) */
176                         (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
177                         (void)write(fd, utp, sizeof(struct utmp));
178                         (void)close(fd);
179                 }
180         }
181
182         if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
183                 (void)write(fd, utp, sizeof(struct utmp));
184                 (void)close(fd);
185         }
186 #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
187         old_utx = pututxline(utx);
188 # ifdef HAVE_UPDWTMPX
189         updwtmpx(_PATH_WTMPX, utx);
190 # endif /* HAVE_UPDWTMPX */
191         endutxent();
192 #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
193 }
194
195 #endif /* HAVE_LOGIN */
This page took 0.053379 seconds and 3 git commands to generate.