]> andersk Git - openssh.git/blob - bsd-login.c
- Several patches from SAKAI Kiyotaka <ksakai@kso.netwk.ntt-at.co.jp>
[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 #ifdef HAVE_TYPE_IN_UTMP
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         fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644);
127         if (fd == -1) {
128                 log("Couldn't open %s: %s", _PATH_UTMP, strerror(errno));
129         } else {
130                 /* If no tty was found... */
131                 if (tty == -1) {
132                         /* ... append it to utmp on login */
133 #ifdef HAVE_TYPE_IN_UTMP
134                         if (utp->ut_type == USER_PROCESS) {
135                                 if ((fd = open(_PATH_UTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
136                                         (void)write(fd, utp, sizeof(struct utmp));
137                                         (void)close(fd);
138                                 }
139                         } else {
140                                 /* Shouldn't get to here unless somthing happened to utmp */
141                                 /* Between login and logout */
142                                 log("No tty slot found at logout");
143                         }
144 #endif
145                 } else {
146                         /* Otherwise, tty was found - update at its location */
147 #if defined(HAVE_HOST_IN_UTMP)
148 # ifndef UT_LINESIZE
149 #  define UT_LINESIZE (sizeof(old_ut.ut_line))
150 #  define UT_NAMESIZE (sizeof(old_ut.ut_name))
151 #  define UT_HOSTSIZE (sizeof(old_ut.ut_host))
152 # endif
153                         (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
154                         /*
155                          * Prevent luser from zero'ing out ut_host.
156                          * If the new ut_line is empty but the old one is not
157                          * and ut_line and ut_name match, preserve the old ut_line.
158                          */
159                         if (read(fd, &old_ut, sizeof(struct utmp)) ==
160                          sizeof(struct utmp) && utp->ut_host[0] == '\0' &&
161                          old_ut.ut_host[0] != '\0' &&
162                          strncmp(old_ut.ut_line, utp->ut_line, UT_LINESIZE) == 0 &&
163                          strncmp(old_ut.ut_name, utp->ut_name, UT_NAMESIZE) == 0)
164                                 (void)memcpy(utp->ut_host, old_ut.ut_host, UT_HOSTSIZE);
165 #endif /* defined(HAVE_HOST_IN_UTMP) */
166                         (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
167                         (void)write(fd, utp, sizeof(struct utmp));
168                         (void)close(fd);
169                 }
170         }
171
172         if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
173                 (void)write(fd, utp, sizeof(struct utmp));
174                 (void)close(fd);
175         }
176 #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
177         old_utx = pututxline(utx);
178 # ifdef HAVE_UPDWTMPX
179         updwtmpx(_PATH_WTMPX, utx);
180 # endif /* HAVE_UPDWTMPX */
181         endutxent();
182 #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
183 }
184
185 #endif /* HAVE_LOGIN */
This page took 0.04765 seconds and 5 git commands to generate.