1 | /* |
---|
2 | |
---|
3 | login.c |
---|
4 | |
---|
5 | Author: Tatu Ylonen <ylo@cs.hut.fi> |
---|
6 | |
---|
7 | Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
---|
8 | All rights reserved |
---|
9 | |
---|
10 | Created: Fri Mar 24 14:51:08 1995 ylo |
---|
11 | |
---|
12 | This file performs some of the things login(1) normally does. We cannot |
---|
13 | easily use something like login -p -h host -f user, because there are |
---|
14 | several different logins around, and it is hard to determined what kind of |
---|
15 | login the current system has. Also, we want to be able to execute commands |
---|
16 | on a tty. |
---|
17 | |
---|
18 | */ |
---|
19 | |
---|
20 | /* |
---|
21 | * $Id: login.c,v 1.1.1.3 1999-03-08 17:43:07 danw Exp $ |
---|
22 | * $Log: not supported by cvs2svn $ |
---|
23 | * Revision 1.10 1998/07/08 00:44:01 kivinen |
---|
24 | * Added better hpux TCB auth support. Added ut_syslen support. |
---|
25 | * |
---|
26 | * Revision 1.9 1998/04/30 01:52:43 kivinen |
---|
27 | * Moved copying of user name to utmp structure to be done only |
---|
28 | * in login. |
---|
29 | * |
---|
30 | * Revision 1.8 1998/04/17 00:38:38 kivinen |
---|
31 | * Fixed ttyslot code. |
---|
32 | * |
---|
33 | * Revision 1.7 1997/03/26 07:09:49 kivinen |
---|
34 | * Added HAVE_NO_TZ_IN_GETTIMEOFDAY support. |
---|
35 | * |
---|
36 | * Revision 1.6 1997/01/10 16:15:19 ttsalo |
---|
37 | * Merged ttyslot patch for SunOS/Solaris from Scott Schwartz |
---|
38 | * |
---|
39 | * Revision 1.5 1996/10/29 22:38:58 kivinen |
---|
40 | * log -> log_msg. |
---|
41 | * |
---|
42 | * Revision 1.4 1996/07/12 07:20:49 ttsalo |
---|
43 | * utmp fix for cray (handled like sgi) |
---|
44 | * |
---|
45 | * Revision 1.3 1996/06/27 12:44:08 ttsalo |
---|
46 | * FreeBSD with long hostnames in utmp fixed (again). |
---|
47 | * |
---|
48 | * Revision 1.2 1996/06/27 12:30:32 ttsalo |
---|
49 | * FreeBSD with long hostnames in utmp fixed. |
---|
50 | * Also small changes for SCO. |
---|
51 | * |
---|
52 | * Revision 1.1.1.1 1996/02/18 21:38:12 ylo |
---|
53 | * Imported ssh-1.2.13. |
---|
54 | * |
---|
55 | * Revision 1.7 1995/09/21 17:11:52 ylo |
---|
56 | * Added NULL second argument to gettimeofday. |
---|
57 | * |
---|
58 | * Revision 1.6 1995/09/09 21:26:43 ylo |
---|
59 | * /m/shadows/u2/users/ylo/ssh/README |
---|
60 | * |
---|
61 | * Revision 1.5 1995/07/27 00:38:43 ylo |
---|
62 | * Use SSH_{WTMP,UTMP,LASTLOG} instead of hard-coded default |
---|
63 | * values if path not defined in header. |
---|
64 | * |
---|
65 | * Revision 1.4 1995/07/16 01:03:11 ylo |
---|
66 | * Clear host name field in record_logout. |
---|
67 | * Test DEAD_PROCESS instead of LOGIN_PROCESS in ifdef. |
---|
68 | * |
---|
69 | * Revision 1.3 1995/07/15 13:25:17 ylo |
---|
70 | * NEXTSTEP patches from Ray Spalding. |
---|
71 | * |
---|
72 | * Revision 1.2 1995/07/13 01:26:29 ylo |
---|
73 | * Removed "Last modified" header. |
---|
74 | * Added cvs log. |
---|
75 | * |
---|
76 | * $Endlog$ |
---|
77 | */ |
---|
78 | |
---|
79 | #include "includes.h" |
---|
80 | #ifdef HAVE_UTMP_H |
---|
81 | #include <utmp.h> |
---|
82 | #ifdef HAVE_LASTLOG_H |
---|
83 | #include <lastlog.h> /* Some have the definitions in utmp.h. */ |
---|
84 | #endif /* HAVE_LASTLOG_H */ |
---|
85 | #endif /* HAVE_UTMP_H */ |
---|
86 | #ifdef HAVE_UTMPX_H |
---|
87 | #include <utmpx.h> |
---|
88 | #ifndef SCO |
---|
89 | #ifdef MAJOR_IN_MKDEV |
---|
90 | #include <sys/mkdev.h> /* for minor() */ |
---|
91 | #endif /* MAJOR_IN_MKDEV */ |
---|
92 | #ifdef MAJOR_IN_SYSMACROS |
---|
93 | #include <sys/sysmacros.h> /* for minor() */ |
---|
94 | #endif /* MAJOR_IN_SYSMACROS */ |
---|
95 | #endif /* SCO */ |
---|
96 | #endif /* HAVE_UTMPX_H */ |
---|
97 | #ifdef HAVE_USERSEC_H |
---|
98 | #include <usersec.h> |
---|
99 | #endif /* HAVE_USERSEC_H */ |
---|
100 | #ifdef HAVE_HPUX_TCB_AUTH |
---|
101 | #include <sys/types.h> |
---|
102 | #include <hpsecurity.h> |
---|
103 | #include <prot.h> |
---|
104 | #endif /* HAVE_HPUX_TCB_AUTH */ |
---|
105 | #include "ssh.h" |
---|
106 | |
---|
107 | /* Returns the time when the user last logged in. Returns 0 if the |
---|
108 | information is not available. This must be called before record_login. |
---|
109 | The host the user logged in from will be returned in buf. */ |
---|
110 | |
---|
111 | #ifdef LASTLOG_IS_DIR |
---|
112 | unsigned long get_last_login_time(uid_t uid, const char *name, |
---|
113 | char *buf, unsigned int bufsize) |
---|
114 | { |
---|
115 | #if defined(HAVE_LASTLOG_H) || defined(HAVE_LASTLOG) |
---|
116 | struct lastlog ll; |
---|
117 | char lastlogfile[500]; |
---|
118 | int fd; |
---|
119 | |
---|
120 | #ifdef _PATH_LASTLOG |
---|
121 | sprintf(lastlogfile, "%.200s/%.200s", _PATH_LASTLOG, name); |
---|
122 | #else |
---|
123 | #ifdef LASTLOG_FILE |
---|
124 | sprintf(lastlogfile, "%.200s/%.200s", LASTLOG_FILE, name); |
---|
125 | #else |
---|
126 | sprintf(lastlogfile, "%.200s/%.200s", SSH_LASTLOG, name); |
---|
127 | #endif |
---|
128 | #endif |
---|
129 | |
---|
130 | strcpy(buf, ""); |
---|
131 | |
---|
132 | fd = open(lastlogfile, O_RDONLY); |
---|
133 | if (fd < 0) |
---|
134 | return 0; |
---|
135 | if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) |
---|
136 | { |
---|
137 | close(fd); |
---|
138 | return 0; |
---|
139 | } |
---|
140 | close(fd); |
---|
141 | if (bufsize > sizeof(ll.ll_host) + 1) |
---|
142 | bufsize = sizeof(ll.ll_host) + 1; |
---|
143 | strncpy(buf, ll.ll_host, bufsize - 1); |
---|
144 | buf[bufsize - 1] = 0; |
---|
145 | return ll.ll_time; |
---|
146 | |
---|
147 | #else /* HAVE_LASTLOG_H || HAVE_LASTLOG */ |
---|
148 | |
---|
149 | return 0; |
---|
150 | |
---|
151 | #endif /* HAVE_LASTLOG_H || HAVE_LASTLOG */ |
---|
152 | } |
---|
153 | |
---|
154 | #else /* LASTLOG_IS_DIR */ |
---|
155 | |
---|
156 | /* Returns the time when the user last logged in (or 0 if no previous login |
---|
157 | is found). The name of the host used last time is returned in buf. */ |
---|
158 | |
---|
159 | unsigned long get_last_login_time(uid_t uid, const char *logname, |
---|
160 | char *buf, unsigned int bufsize) |
---|
161 | { |
---|
162 | #if defined(HAVE_LASTLOG_H) || defined(HAVE_LASTLOG) |
---|
163 | |
---|
164 | struct lastlog ll; |
---|
165 | char *lastlog; |
---|
166 | int fd; |
---|
167 | |
---|
168 | #ifdef _PATH_LASTLOG |
---|
169 | lastlog = _PATH_LASTLOG; |
---|
170 | #else |
---|
171 | #ifdef LASTLOG_FILE |
---|
172 | lastlog = LASTLOG_FILE; |
---|
173 | #else |
---|
174 | lastlog = SSH_LASTLOG; |
---|
175 | #endif |
---|
176 | #endif |
---|
177 | |
---|
178 | strcpy(buf, ""); |
---|
179 | |
---|
180 | fd = open(lastlog, O_RDONLY); |
---|
181 | if (fd < 0) |
---|
182 | return 0; |
---|
183 | lseek(fd, (off_t)((long)uid * sizeof(ll)), 0); |
---|
184 | if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) |
---|
185 | { |
---|
186 | close(fd); |
---|
187 | return 0; |
---|
188 | } |
---|
189 | close(fd); |
---|
190 | if (bufsize > sizeof(ll.ll_host) + 1) |
---|
191 | bufsize = sizeof(ll.ll_host) + 1; |
---|
192 | strncpy(buf, ll.ll_host, bufsize - 1); |
---|
193 | buf[bufsize - 1] = 0; |
---|
194 | return ll.ll_time; |
---|
195 | |
---|
196 | #else /* HAVE_LASTLOG_H || HAVE_LASTLOG */ |
---|
197 | |
---|
198 | #ifdef HAVE_USERSEC_H |
---|
199 | |
---|
200 | char *lasthost; |
---|
201 | int lasttime; |
---|
202 | if (setuserdb(S_READ) < 0) |
---|
203 | return 0; |
---|
204 | if (getuserattr((char *)logname, S_LASTTIME, &lasttime, SEC_INT) < 0) |
---|
205 | { |
---|
206 | enduserdb(); |
---|
207 | return 0; |
---|
208 | } |
---|
209 | if (getuserattr((char *)logname, S_LASTHOST, &lasthost, SEC_CHAR) < 0) |
---|
210 | { |
---|
211 | enduserdb(); |
---|
212 | return 0; |
---|
213 | } |
---|
214 | strncpy(buf, lasthost, bufsize); |
---|
215 | buf[bufsize - 1] = 0; |
---|
216 | if (enduserdb() < 0) |
---|
217 | return 0; |
---|
218 | return lasttime; |
---|
219 | |
---|
220 | #else /* HAVE_USERSEC_H */ |
---|
221 | #ifdef HAVE_HPUX_TCB_AUTH |
---|
222 | { |
---|
223 | struct pr_passwd *pr; |
---|
224 | |
---|
225 | pr = getprpwnam(logname); |
---|
226 | if (pr) |
---|
227 | if (pr->uflg.fg_slogin) |
---|
228 | return pr->ufld.fd_slogin; |
---|
229 | } |
---|
230 | #endif /* HAVE_HPUX_TCB_AUTH */ |
---|
231 | |
---|
232 | return 0; |
---|
233 | |
---|
234 | #endif /* HAVE_USERSEC_H */ |
---|
235 | |
---|
236 | #endif /* HAVE_LASTLOG_H || HAVE_LASTLOG */ |
---|
237 | } |
---|
238 | #endif /* LASTLOG_IS_DIR */ |
---|
239 | |
---|
240 | /* Records that the user has logged in. I these parts of operating systems |
---|
241 | were more standardized. */ |
---|
242 | |
---|
243 | void record_login(int pid, const char *ttyname, const char *user, uid_t uid, |
---|
244 | const char *host, struct sockaddr_in *addr) |
---|
245 | { |
---|
246 | int fd; |
---|
247 | |
---|
248 | #if defined(HAVE_LASTLOG_H) || defined(HAVE_LASTLOG) |
---|
249 | struct lastlog ll; |
---|
250 | char *lastlog; |
---|
251 | #ifdef LASTLOG_IS_DIR |
---|
252 | char lastlogfile[100]; |
---|
253 | #endif /* LASTLOG_IS_DIR */ |
---|
254 | #endif /* HAVE_LASTLOG_H || HAVE_LASTLOG */ |
---|
255 | |
---|
256 | #if defined(HAVE_UTMP_H) && !defined(HAVE_UTMPX_H) |
---|
257 | struct utmp u, u2; |
---|
258 | off_t offset; |
---|
259 | const char *utmp, *wtmp; |
---|
260 | |
---|
261 | /* Construct an utmp/wtmp entry. */ |
---|
262 | memset(&u, 0, sizeof(u)); |
---|
263 | #ifdef DEAD_PROCESS |
---|
264 | if (strcmp(user, "") == 0) |
---|
265 | u.ut_type = DEAD_PROCESS; /* logout */ |
---|
266 | else |
---|
267 | u.ut_type = USER_PROCESS; |
---|
268 | #endif /* LOGIN_PROCESS */ |
---|
269 | #ifdef HAVE_PID_IN_UTMP |
---|
270 | u.ut_pid = pid; |
---|
271 | #endif /* PID_IN_UTMP */ |
---|
272 | #ifdef HAVE_ID_IN_UTMP |
---|
273 | #if defined(__sgi) || defined(CRAY) |
---|
274 | strncpy(u.ut_id, ttyname + 8, sizeof(u.ut_id)); /* /dev/ttyq99 -> q99 */ |
---|
275 | #else /* __sgi */ |
---|
276 | if (sizeof(u.ut_id) > 4) |
---|
277 | strncpy(u.ut_id, ttyname + 5, sizeof(u.ut_id)); |
---|
278 | else |
---|
279 | strncpy(u.ut_id, ttyname + strlen(ttyname) - 2, sizeof(u.ut_id)); |
---|
280 | #endif /* __sgi */ |
---|
281 | #endif /* HAVE_ID_IN_UTMP */ |
---|
282 | strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line)); |
---|
283 | u.ut_time = time(NULL); |
---|
284 | #ifdef HAVE_NAME_IN_UTMP |
---|
285 | strncpy(u.ut_name, user, sizeof(u.ut_name)); |
---|
286 | #else /* HAVE_NAME_IN_UTMP */ |
---|
287 | strncpy(u.ut_user, user, sizeof(u.ut_user)); |
---|
288 | #endif /* HAVE_NAME_IN_UTMP */ |
---|
289 | #ifdef HAVE_HOST_IN_UTMP |
---|
290 | strncpy(u.ut_host, host, sizeof(u.ut_host)); |
---|
291 | #ifdef __FreeBSD__ |
---|
292 | if (strlen(host) > sizeof(u.ut_host)) { |
---|
293 | strncpy(u.ut_host, get_remote_ipaddr(), sizeof(u.ut_host)); |
---|
294 | } |
---|
295 | #endif /* __FreeBSD__ */ |
---|
296 | #endif /* HAVE_HOST_IN_UTMP */ |
---|
297 | #ifdef HAVE_ADDR_IN_UTMP |
---|
298 | if (addr) |
---|
299 | memcpy(&u.ut_addr, &addr->sin_addr, sizeof(u.ut_addr)); |
---|
300 | else |
---|
301 | memset(&u.ut_addr, 0, sizeof(u.ut_addr)); |
---|
302 | #endif |
---|
303 | |
---|
304 | /* Figure out the file names. */ |
---|
305 | #ifdef _PATH_UTMP |
---|
306 | utmp = _PATH_UTMP; |
---|
307 | wtmp = _PATH_WTMP; |
---|
308 | #else |
---|
309 | #ifdef UTMP_FILE |
---|
310 | utmp = UTMP_FILE; |
---|
311 | wtmp = WTMP_FILE; |
---|
312 | #else |
---|
313 | utmp = SSH_UTMP; |
---|
314 | wtmp = SSH_WTMP; |
---|
315 | #endif |
---|
316 | #endif |
---|
317 | |
---|
318 | #ifdef HAVE_LIBUTIL_LOGIN |
---|
319 | login(&u); |
---|
320 | #else /* HAVE_LIBUTIL_LOGIN */ |
---|
321 | /* Append an entry to wtmp. */ |
---|
322 | fd = open(wtmp, O_WRONLY|O_APPEND); |
---|
323 | if (fd >= 0) |
---|
324 | { |
---|
325 | if (write(fd, &u, sizeof(u)) != sizeof(u)) |
---|
326 | log_msg("Could not write %.100s: %.100s", wtmp, strerror(errno)); |
---|
327 | close(fd); |
---|
328 | } |
---|
329 | |
---|
330 | /* Replace the proper entry in utmp, as identified by ut_line. Append a |
---|
331 | new entry if the line could not be found. */ |
---|
332 | fd = open(utmp, O_RDWR); |
---|
333 | if (fd >= 0) |
---|
334 | { |
---|
335 | #ifdef HAVE_TTYSLOT |
---|
336 | int n = ttyslot(); |
---|
337 | #if defined(ultrix) || defined(NeXT) |
---|
338 | /* |
---|
339 | * the problem is that Berkeley unix uses ttyslot() to determine where in |
---|
340 | * the utmp file to write and it is correct at login time because the |
---|
341 | * controlling tty is correct. At logout time, I think a different process |
---|
342 | * runs this code and may have a different (or no) controlling tty so |
---|
343 | * we must search for the right record to clobber. -- corey 5/7/97 |
---|
344 | */ |
---|
345 | if (n > 0 && *user) { |
---|
346 | #else |
---|
347 | if (n > 0) { |
---|
348 | #endif |
---|
349 | lseek(fd, (off_t)(n*sizeof(u)), 0); |
---|
350 | if (write(fd, &u, sizeof(u)) != sizeof(u)) |
---|
351 | log_msg("Could not write to %.100s: %.100s", |
---|
352 | utmp, strerror(errno)); |
---|
353 | } else |
---|
354 | #endif |
---|
355 | while (1) |
---|
356 | { |
---|
357 | offset = lseek(fd, (off_t)0L, 1); |
---|
358 | if (read(fd, &u2, sizeof(u2)) != sizeof(u2)) |
---|
359 | { |
---|
360 | lseek(fd, offset, 0); |
---|
361 | if (write(fd, &u, sizeof(u)) != sizeof(u)) |
---|
362 | log_msg("Could not append to %.100s: %.100s", |
---|
363 | utmp, strerror(errno)); |
---|
364 | break; |
---|
365 | } |
---|
366 | #if defined(ultrix) || defined(NeXT) /* corey */ |
---|
367 | if (strcmp(u2.ut_line, ttyname + 5) == 0 && *u2.ut_name) |
---|
368 | #else /* ultrix || NeXT */ |
---|
369 | if (strncmp(u2.ut_line, ttyname + 5, sizeof(u2.ut_line)) == 0) |
---|
370 | #endif /* ultrix || NeXT */ |
---|
371 | { |
---|
372 | lseek(fd, offset, 0); |
---|
373 | if (write(fd, &u, sizeof(u)) != sizeof(u)) |
---|
374 | log_msg("Could not write to %.100s: %.100s", |
---|
375 | utmp, strerror(errno)); |
---|
376 | break; |
---|
377 | } |
---|
378 | } |
---|
379 | close(fd); |
---|
380 | } |
---|
381 | #endif /* HAVE_LIBUTIL_LOGIN */ |
---|
382 | #endif /* HAVE_UTMP_H && !HAVE_UTMPX_H */ |
---|
383 | |
---|
384 | #ifdef HAVE_UTMPX_H |
---|
385 | { |
---|
386 | struct utmpx ux, *uxp; |
---|
387 | memset(&ux, 0, sizeof(ux)); |
---|
388 | strncpy(ux.ut_line, ttyname + 5, sizeof(ux.ut_line)); |
---|
389 | if (strcmp(user, "") == 0) { |
---|
390 | /* logout; find previous entry for pid and zonk it */ |
---|
391 | setutxent(); |
---|
392 | while ( (uxp = getutxent()) ) { |
---|
393 | if (uxp->ut_pid != (pid_t)pid) |
---|
394 | continue; |
---|
395 | ux = *uxp; |
---|
396 | break; |
---|
397 | } |
---|
398 | endutxent(); |
---|
399 | } |
---|
400 | else { |
---|
401 | /* login: find appropriate slot for this tty */ |
---|
402 | uxp = getutxline(&ux); |
---|
403 | if (uxp) |
---|
404 | ux = *uxp; |
---|
405 | strncpy(ux.ut_user, user, sizeof(ux.ut_user)); |
---|
406 | } |
---|
407 | #if defined(__sgi) || defined(SCO) |
---|
408 | strncpy(ux.ut_id, ttyname + 8, sizeof(ux.ut_id)); /* /dev/ttyq99 -> q99 */ |
---|
409 | #else /* __sgi */ |
---|
410 | if (sizeof(ux.ut_id) > 4) |
---|
411 | strncpy(ux.ut_id, ttyname + 5, sizeof(ux.ut_id)); |
---|
412 | else { |
---|
413 | struct stat st; |
---|
414 | char buf[20]; |
---|
415 | |
---|
416 | buf[0] = 0; |
---|
417 | if (stat(ttyname, &st) == 0) { |
---|
418 | /* allow for 1000 /dev/pts devices */ |
---|
419 | sprintf(buf, "P%03d", (int)minor(st.st_rdev)); |
---|
420 | } |
---|
421 | strncpy(ux.ut_id, buf, sizeof(ux.ut_id)); |
---|
422 | } |
---|
423 | #endif /* __sgi */ |
---|
424 | ux.ut_pid = pid; |
---|
425 | if (strcmp(user, "") == 0) |
---|
426 | ux.ut_type = DEAD_PROCESS; |
---|
427 | else |
---|
428 | ux.ut_type = USER_PROCESS; |
---|
429 | #ifdef HAVE_NO_TZ_IN_GETTIMEOFDAY |
---|
430 | gettimeofday(&ux.ut_tv); |
---|
431 | #else |
---|
432 | gettimeofday(&ux.ut_tv, NULL); |
---|
433 | #endif |
---|
434 | ux.ut_session = pid; |
---|
435 | strncpy(ux.ut_host, host, sizeof(ux.ut_host)); |
---|
436 | ux.ut_host[sizeof(ux.ut_host) - 1] = 0; |
---|
437 | ux.ut_syslen = strlen(ux.ut_host); |
---|
438 | #ifdef HAVE_SYSLEN_IN_UTMPX |
---|
439 | ux.ut_syslen = strlen(ux.ut_host); |
---|
440 | #endif |
---|
441 | ux.ut_exit.e_termination = 0; |
---|
442 | ux.ut_exit.e_exit = 0; |
---|
443 | #ifdef HAVE_MAKEUTX |
---|
444 | /* |
---|
445 | * modutx/makeutx notify init(1) to clean up utmpx for this pid |
---|
446 | * automatically if we don't manage to, for some odd reason |
---|
447 | */ |
---|
448 | if (strcmp(user, "") == 0) |
---|
449 | modutx(&ux); |
---|
450 | else |
---|
451 | makeutx(&ux); |
---|
452 | #else |
---|
453 | pututxline(&ux); |
---|
454 | updwtmpx(WTMPX_FILE, &ux); |
---|
455 | #endif |
---|
456 | endutxent(); |
---|
457 | } |
---|
458 | #endif /* HAVE_UTMPX_H */ |
---|
459 | |
---|
460 | #if defined(HAVE_LASTLOG_H) || defined(HAVE_LASTLOG) |
---|
461 | |
---|
462 | #ifdef _PATH_LASTLOG |
---|
463 | lastlog = _PATH_LASTLOG; |
---|
464 | #else |
---|
465 | #ifdef LASTLOG_FILE |
---|
466 | lastlog = LASTLOG_FILE; |
---|
467 | #else |
---|
468 | lastlog = SSH_LASTLOG; |
---|
469 | #endif |
---|
470 | #endif |
---|
471 | |
---|
472 | /* Update lastlog unless actually recording a logout. */ |
---|
473 | if (strcmp(user, "") != 0) |
---|
474 | { |
---|
475 | /* It is safer to bzero the lastlog structure first because some |
---|
476 | systems might have some extra fields in it (e.g. SGI) */ |
---|
477 | memset(&ll, 0, sizeof(ll)); |
---|
478 | |
---|
479 | /* Update lastlog. */ |
---|
480 | ll.ll_time = time(NULL); |
---|
481 | strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line)); |
---|
482 | strncpy(ll.ll_host, host, sizeof(ll.ll_host)); |
---|
483 | #ifdef LASTLOG_IS_DIR |
---|
484 | sprintf(lastlogfile, "%.100s/%.100s", lastlog, user); |
---|
485 | fd = open(lastlogfile, O_WRONLY | O_CREAT, 0644); |
---|
486 | if (fd >= 0) |
---|
487 | { |
---|
488 | if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) |
---|
489 | log_msg("Could not write %.100s: %.100s", |
---|
490 | lastlogfile, strerror(errno)); |
---|
491 | close(fd); |
---|
492 | } |
---|
493 | else |
---|
494 | { |
---|
495 | log_msg("Could not open %.100s: %.100s", lastlogfile, strerror(errno)); |
---|
496 | } |
---|
497 | #else /* LASTLOG_IS_DIR */ |
---|
498 | fd = open(lastlog, O_RDWR); |
---|
499 | if (fd >= 0) |
---|
500 | { |
---|
501 | lseek(fd, (off_t)((long)uid * sizeof(ll)), 0); |
---|
502 | if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) |
---|
503 | log_msg("Could not write %.100s: %.100s", lastlog, strerror(errno)); |
---|
504 | close(fd); |
---|
505 | } |
---|
506 | #endif /* LASTLOG_IS_DIR */ |
---|
507 | } |
---|
508 | #endif /* HAVE_LASTLOG_H || HAVE_LASTLOG */ |
---|
509 | |
---|
510 | #ifdef HAVE_HPUX_TCB_AUTH |
---|
511 | { |
---|
512 | struct pr_passwd *pr; |
---|
513 | |
---|
514 | pr = getprpwnam(user); |
---|
515 | if (pr) |
---|
516 | { |
---|
517 | pr->ufld.fd_slogin = time(NULL); |
---|
518 | pr->uflg.fg_slogin = 1; pr->uflg.fg_suctty = 1; |
---|
519 | pr->ufld.fd_nlogins = 0; |
---|
520 | strncpy(pr->ufld.fd_suctty, ttyname + 5, sizeof(pr->ufld.fd_suctty)); |
---|
521 | if (putprpwnam(user, pr) == 0) |
---|
522 | log_msg("putprpwnam failed for %.100s",user); |
---|
523 | } |
---|
524 | } |
---|
525 | #endif /* HAVE_HPUX_TCB_AUTH */ |
---|
526 | |
---|
527 | #ifdef HAVE_USERSEC_H |
---|
528 | |
---|
529 | if (strcmp(user, "") != 0) |
---|
530 | { |
---|
531 | int lasttime = time(NULL); |
---|
532 | if (setuserdb(S_WRITE) < 0) |
---|
533 | log_msg("setuserdb S_WRITE failed: %.100s", strerror(errno)); |
---|
534 | if (putuserattr((char *)user, S_LASTTIME, (void *)lasttime, SEC_INT) < 0) |
---|
535 | log_msg("putuserattr S_LASTTIME failed: %.100s", strerror(errno)); |
---|
536 | if (putuserattr((char *)user, S_LASTTTY, (void *)(ttyname + 5), |
---|
537 | SEC_CHAR) < 0) |
---|
538 | log_msg("putuserattr S_LASTTTY %.900s failed: %.100s", |
---|
539 | ttyname, strerror(errno)); |
---|
540 | if (putuserattr((char *)user, S_LASTHOST, (void *)host, SEC_CHAR) < 0) |
---|
541 | log_msg("putuserattr S_LASTHOST %.900s failed: %.100s", |
---|
542 | host, strerror(errno)); |
---|
543 | if (putuserattr((char *)user, 0, NULL, SEC_COMMIT) < 0) |
---|
544 | log_msg("putuserattr SEC_COMMIT failed: %.100s", strerror(errno)); |
---|
545 | if (enduserdb() < 0) |
---|
546 | log_msg("enduserdb failed: %.100s", strerror(errno)); |
---|
547 | } |
---|
548 | #endif |
---|
549 | } |
---|
550 | |
---|
551 | /* Records that the user has logged out. */ |
---|
552 | |
---|
553 | void record_logout(int pid, const char *ttyname) |
---|
554 | { |
---|
555 | #ifdef HAVE_LIBUTIL_LOGIN |
---|
556 | const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */ |
---|
557 | if (logout(line)) |
---|
558 | logwtmp(line, "", ""); |
---|
559 | #else /* HAVE_LIBUTIL_LOGIN */ |
---|
560 | record_login(pid, ttyname, "", -1, "", NULL); |
---|
561 | #endif /* HAVE_LIBUTIL_LOGIN */ |
---|
562 | } |
---|