]> andersk Git - openssh.git/blob - bsd-login.c
a6f4acca345719067d9ef4578189c09eb221773f
[openssh.git] / bsd-login.c
1 /*
2  * This file has been heavily 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 #ifdef USER_PROCESS
64 /*
65  * find first matching slot in utmp, or "-1" for none
66  *
67  * algorithm: for USER_PROCESS, check tty name
68  *            for DEAD_PROCESS, check PID and tty name
69  *
70  */
71 int find_tty_slot( utp )
72 struct utmp * utp;
73 {
74         int t = 0;
75         struct utmp * u;
76
77 # if defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX)
78         setutent();
79
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)) {
83                         endutent();
84                         return(t);
85                 }
86
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 )) {
89                         endutent();
90                         return(t);
91                 }
92                 t++;
93         }
94
95         endutent();
96 # endif /* defined(HAVE_TYPE_IN_UTMP) || defined(HAVE_TYPE_IN_UTMPX) */
97         return(-1);
98 }
99 #else /* USER_PROCESS */
100 int find_tty_slot(struct utmp *utp)
101 {
102         return(ttyslot());
103 }
104 #endif /* USER_PROCESS */
105
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) */
111 {
112         /* Use proper API if we have it */
113 #if defined(USE_UTMPX)
114 # if defined(HAVE_PUTUTXLINE)
115         setutxent();
116         pututxline(utx);
117         endutxent();    
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)
124         setutent();
125         pututline(utp);
126         endutent();     
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) */
132
133         /* Otherwise DIY */
134 #if (defined(USE_UTMPX) && !defined(HAVE_PUTUTXLINE)) || \
135         (!defined(USE_UTMPX) && !defined(HAVE_PUTUTLINE)) 
136         int fd;
137         int tty;
138
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
143          */
144         tty = find_tty_slot(utp);
145
146 #ifdef USE_UTMPX
147         /* If no tty was found, append it to utmpx */
148         if (tty == -1) {
149                 if ((fd = open(_PATH_UTMPX, O_WRONLY|O_APPEND, 0)) >= 0) {
150                         (void)write(fd, utp, sizeof(struct utmp));
151                         (void)close(fd);
152                         return;
153                 }
154         }
155         /* Otherwise, tty was found - update at its location */
156         fd = open(_PATH_UTMPX, O_RDWR|O_CREAT, 0644);
157         if (fd == -1) {
158                 log("Couldn't open %s: %s", _PATH_UTMPX, strerror(errno));
159                 return;
160         }
161         lseek(fd, (off_t)(tty * sizeof(struct utmpx)), SEEK_SET);
162         write(fd, utx, sizeof(struct utmpx));
163         close(fd);
164         if ((fd = open(_PATH_WTMPX, O_WRONLY|O_APPEND, 0)) >= 0) {
165                 (void)write(fd, utx, sizeof(struct utmpx));
166                 (void)close(fd);
167         }
168 #else /* USE_UTMPX */
169         /* If no tty was found, append it to utmp */
170         if (tty == -1) {
171                 if ((fd = open(_PATH_UTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
172                         (void)write(fd, utp, sizeof(struct utmp));
173                         (void)close(fd);
174                         return;
175                 }
176         }
177         /* Otherwise, tty was found - update at its location */
178         fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644);
179         if (fd == -1) {
180                 log("Couldn't open %s: %s", _PATH_UTMP, strerror(errno));
181                 return;
182         }
183         lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET);
184         write(fd, utp, sizeof(struct utmp));
185         close(fd);
186         if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
187                 (void)write(fd, utp, sizeof(struct utmp));
188                 (void)close(fd);
189         }
190 #endif /* USE_UTMPX */
191 #endif /* (defined(USE_UTMPX) && !defined(HAVE_PUTUTXLINE)) || \
192                         (!defined(USE_UTMPX) && !defined(HAVE_PUTUTLINE)) */
193 }
194
195 #endif /* HAVE_LOGIN */
This page took 0.04981 seconds and 3 git commands to generate.