summaryrefslogtreecommitdiff
path: root/login.c
diff options
context:
space:
mode:
authorandre <andre>2000-06-03 14:57:40 +0000
committerandre <andre>2000-06-03 14:57:40 +0000
commit2ff7b5d02817eb74a3ac2bf02eadef127b09d77c (patch)
tree13273092785271978f00ba33f3b14519d5ca1409 /login.c
parente340f73b53aa3451f88fd9d41b652b659b0398f8 (diff)
Added new login recording code
Added test program for login code (make logintest)
Diffstat (limited to 'login.c')
-rw-r--r--login.c277
1 files changed, 19 insertions, 258 deletions
diff --git a/login.c b/login.c
index 09e73b3de..305b67cbc 100644
--- a/login.c
+++ b/login.c
@@ -18,30 +18,9 @@
18 */ 18 */
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: login.c,v 1.30 2000/05/31 03:57:19 damien Exp $"); 21RCSID("$Id: login.c,v 1.31 2000/06/03 14:57:40 andre Exp $");
22 22
23#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) 23#include "loginrec.h"
24# include <utmpx.h>
25#endif
26#ifdef HAVE_UTMP_H
27# include <utmp.h>
28#endif
29#include "ssh.h"
30
31#ifdef HAVE_UTIL_H
32# include <util.h>
33#endif
34#ifdef HAVE_LASTLOG_H
35# include <lastlog.h>
36#endif
37#ifdef HAVE_LOGIN_H
38# include <login.h>
39#endif
40
41#ifdef WITH_AIXAUTHENTICATE
42/* This is done in do_authentication */
43# define DISABLE_LASTLOG
44#endif /* WITH_AIXAUTHENTICATE */
45 24
46/* 25/*
47 * Returns the time when the user last logged in. Returns 0 if the 26 * Returns the time when the user last logged in. Returns 0 if the
@@ -49,248 +28,32 @@ RCSID("$Id: login.c,v 1.30 2000/05/31 03:57:19 damien Exp $");
49 * The host the user logged in from will be returned in buf. 28 * The host the user logged in from will be returned in buf.
50 */ 29 */
51 30
52/*
53 * Returns the time when the user last logged in (or 0 if no previous login
54 * is found). The name of the host used last time is returned in buf.
55 */
56
57unsigned long 31unsigned long
58get_last_login_time(uid_t uid, const char *logname, 32get_last_login_time(uid_t uid, const char *logname,
59 char *buf, unsigned int bufsize) 33 char *buf, unsigned int bufsize)
60{ 34{
61#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) 35 struct logininfo li;
62 struct lastlog ll;
63 int fd;
64# ifdef LASTLOG_IS_DIR
65 char lbuf[1024];
66
67 snprintf(lbuf, sizeof(buf), "%s/%s", _PATH_LASTLOG, logname);
68 if ((fd = open(lbuf, O_RDONLY)) < 0)
69 return 0;
70# else /* LASTLOG_IS_DIR */
71 buf[0] = '\0';
72
73 if ((fd = open(_PATH_LASTLOG, O_RDONLY)) < 0)
74 return 0;
75
76 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
77# endif /* LASTLOG_IS_DIR */
78 if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) {
79 close(fd);
80 return 0;
81 }
82
83 close(fd);
84
85 if (bufsize > sizeof(ll.ll_host) + 1)
86 bufsize = sizeof(ll.ll_host) + 1;
87 strncpy(buf, ll.ll_host, bufsize - 1);
88 buf[bufsize - 1] = 0;
89
90 return ll.ll_time;
91#else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
92# ifdef HAVE_TYPE_IN_UTMP
93 /* Look in wtmp for the last login */
94 struct utmp wt;
95 int fd1;
96 unsigned long t = 0;
97
98 if ((fd1 = open(_PATH_WTMP, O_RDONLY)) < 0) {
99 error("Couldn't open %.100s to find last login time.", _PATH_WTMP);
100 return 0;
101 }
102
103 /* seek to last record of file */
104 lseek(fd1, (off_t)(0 - sizeof(struct utmp)), SEEK_END);
105
106 /* loop through wtmp for our last user login record */
107 do {
108 if (read(fd1, &wt, sizeof(wt)) != sizeof(wt)) {
109 close(fd1);
110 return 0;
111 }
112
113 if (wt.ut_type == USER_PROCESS) {
114 if (!strncmp(logname, wt.ut_user, 8)) {
115 t = (unsigned long)wt.ut_time;
116# ifdef HAVE_HOST_IN_UTMP
117 if (bufsize > sizeof(wt.ut_host) + 1)
118 bufsize = sizeof(wt.ut_host) + 1;
119 strncpy(buf, wt.ut_host, bufsize - 1);
120 buf[bufsize - 1] = 0;
121# else /* HAVE_HOST_IN_UTMP */
122 buf[0] = 0;
123# endif /* HAVE_HOST_IN_UTMP */
124 }
125 }
126 36
127 if (lseek(fd1, (off_t)(0 - (2 * sizeof(struct utmp))), SEEK_CUR) < 0) 37 login_getlastentry_uid(&li, uid);
128 break; 38 strncpy(buf, li.hostname, bufsize);
129 } while (t == 0); 39 return li.tv_sec;
130
131 return t;
132# else /* HAVE_TYPE_IN_UTMP */
133 return 0;
134# endif /* HAVE_TYPE_IN_UTMP */
135#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
136} 40}
137 41
138/* 42/*
139 * Records that the user has logged in. I wish these parts of operating 43 * Records that the user has logged in. I these parts of operating systems
140 * systems were more standardized. 44 * were more standardized.
141 */ 45 */
46
142void 47void
143record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, 48record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
144 const char *host, struct sockaddr * addr) 49 const char *host, struct sockaddr * addr)
145{ 50{
146#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) 51 struct logininfo *li;
147 struct lastlog ll;
148# ifdef LASTLOG_IS_DIR
149 char buf[1024];
150# endif /* LASTLOG_IS_DIR */
151#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
152 struct utmp u;
153#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
154 struct utmpx utx;
155#endif
156
157 /* Construct an utmp/wtmp entry. */
158 memset(&u, 0, sizeof(u));
159 strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
160
161#if defined(HAVE_ID_IN_UTMP)
162# ifdef _AIX
163 strncpy(u.ut_id, ttyname + 5, sizeof(u.ut_id));
164# else /* !AIX */
165 strncpy(u.ut_id, ttyname + 8, sizeof(u.ut_id));
166# endif
167#endif /* defined(HAVE_ID_IN_UTMP) */
168
169 strncpy(u.ut_name, user, sizeof(u.ut_name));
170
171#if defined(HAVE_TV_IN_UTMP)
172 (void)gettimeofday(&u.ut_tv, NULL);
173#else /* defined(HAVE_TV_IN_UTMP) */
174 u.ut_time = time(NULL);
175#endif /* defined(HAVE_TV_IN_UTMP) */
176
177#if defined(HAVE_PID_IN_UTMP)
178 u.ut_pid = (pid_t)pid;
179#endif /* HAVE_PID_IN_UTMP */
180
181#if defined(HAVE_TYPE_IN_UTMP)
182 u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS;
183#endif /* HAVE_TYPE_IN_UTMP */
184
185#if defined(HAVE_HOST_IN_UTMP)
186 strncpy(u.ut_host, host, sizeof(u.ut_host));
187#endif
188
189#if defined(HAVE_ADDR_IN_UTMP)
190 if (addr) {
191 switch (addr->sa_family) {
192 case AF_INET: {
193 struct sockaddr_in *in = (struct sockaddr_in*)addr;
194 memcpy(&(u.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr)));
195 break;
196 }
197# if defined(HAVE_ADDR_V6_IN_UTMP)
198 case AF_INET6: {
199 struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
200 memcpy(u.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr)));
201 break;
202 }
203# endif /* defined(HAVE_ADDR_V6_IN_UTMP) */
204 default:
205 break;
206 }
207 }
208#endif /* defined(HAVE_ADDR_IN_UTMP) */
209 52
210#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) 53 li = login_alloc_entry(pid, user, host, ttyname);
211 memset(&utx, 0, sizeof(utx)); 54 login_set_ip4(li, (struct sockaddr_in *)addr);
212 55 login_login(li);
213 strncpy(utx.ut_user, user, sizeof(utx.ut_name)); 56 login_free_entry(li);
214 strncpy(utx.ut_line, ttyname + 5, sizeof(utx.ut_line));
215 strncpy(utx.ut_id, ttyname + 8, sizeof(utx.ut_id));
216
217 utx.ut_pid = (pid_t)pid;
218 (void)gettimeofday(&utx.ut_tv, NULL);
219
220 utx.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS;
221# ifdef HAVE_HOST_IN_UTMPX
222# ifdef HAVE_SYSLEN_IN_UTMPX
223 utx.ut_syslen = strlen(host);
224 if (utx.ut_syslen + 1 > sizeof(utx.ut_host))
225 utx.ut_syslen = sizeof(utx.ut_host);
226 strncpy(utx.ut_host, host, utx.ut_syslen);
227# else
228 strncpy(utx.ut_host, host, sizeof(utx.ut_host));
229# endif /* HAVE_SYSLEN_IN_UTMPX */
230 utx.ut_host[sizeof(utx.ut_host)-1] = '\0';
231# endif
232
233# if defined(HAVE_ADDR_IN_UTMPX)
234 if (addr) {
235 switch (addr->sa_family) {
236 case AF_INET: {
237 struct sockaddr_in *in = (struct sockaddr_in*)addr;
238 memcpy(&(utx.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr)));
239 break;
240 }
241# if defined(HAVE_ADDR_V6_IN_UTMPX)
242 case AF_INET6: {
243 struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
244 memcpy(utx.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr)));
245 break;
246 }
247# endif /* defined(HAVE_ADDR_V6_IN_UTMPX) */
248 default:
249 break;
250 }
251 }
252# endif /* defined(HAVE_ADDR_IN_UTMPX) */
253#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
254
255#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
256 login(&utx);
257#else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
258 login(&u);
259#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
260
261#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
262 /* Update lastlog unless actually recording a logout. */
263 if (strcmp(user, "") != 0) {
264 int fd;
265 /*
266 * It is safer to bzero the lastlog structure first because
267 * some systems might have some extra fields in it (e.g. SGI)
268 */
269 memset(&ll, 0, sizeof(ll));
270
271 /* Update lastlog. */
272 ll.ll_time = time(NULL);
273 strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
274 strncpy(ll.ll_host, host, sizeof(ll.ll_host));
275# ifdef LASTLOG_IS_DIR
276 snprintf(buf, sizeof(buf), "%s/%s", _PATH_LASTLOG, user);
277 if ((fd = open(buf, O_RDWR)) >= 0) {
278 if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
279 log("Could not write %.100s: %.100s", buf, strerror(errno));
280 close(fd);
281 }
282# else /* LASTLOG_IS_DIR */
283 if ((fd = open(_PATH_LASTLOG, O_RDWR)) >= 0) {
284 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
285 if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) {
286 log("Could not write %.100s: %.100s", _PATH_LASTLOG,
287 strerror(errno));
288 }
289 close(fd);
290 }
291# endif /* LASTLOG_IS_DIR */
292 }
293#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
294} 57}
295 58
296/* Records that the user has logged out. */ 59/* Records that the user has logged out. */
@@ -298,11 +61,9 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
298void 61void
299record_logout(pid_t pid, const char *ttyname) 62record_logout(pid_t pid, const char *ttyname)
300{ 63{
301#ifdef HAVE_LIBUTIL_LOGIN 64 struct logininfo *li;
302 const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */ 65
303 if (logout(line)) 66 li = login_alloc_entry(pid, NULL, NULL, ttyname);
304 logwtmp(line, "", ""); 67 login_logout(li);
305#else /* HAVE_LIBUTIL_LOGIN */ 68 login_free_entry(li);
306 record_login(pid, ttyname, "", -1, "", NULL);
307#endif /* HAVE_LIBUTIL_LOGIN */
308} 69}