summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--monitor.c16
-rw-r--r--monitor_wrap.c9
-rw-r--r--session.c42
-rw-r--r--session.h5
-rw-r--r--sshd.c8
-rw-r--r--sshlogin.c43
7 files changed, 89 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index a70a1fac1..8255b3e59 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,12 @@
15 Fix incorrect macro, .I -> .Em 15 Fix incorrect macro, .I -> .Em
16 From: Eric S. Raymond <esr at thyrsus dot com> 16 From: Eric S. Raymond <esr at thyrsus dot com>
17 ok jmc@ 17 ok jmc@
18 - dtucker@cvs.openbsd.org 2004/07/17 05:31:41
19 [monitor.c monitor_wrap.c session.c session.h sshd.c sshlogin.c]
20 Move "Last logged in at.." message generation to the monitor, right
21 before recording the new login. Fixes missing lastlog message when
22 /var/log/lastlog is not world-readable and incorrect datestamp when
23 multiple sessions are used (bz #463); much assistance & ok markus@
18 24
1920040711 2520040711
20 - (dtucker) [auth-pam.c] Check for zero from waitpid() too, which allows 26 - (dtucker) [auth-pam.c] Check for zero from waitpid() too, which allows
@@ -1521,4 +1527,4 @@
1521 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 1527 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
1522 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 1528 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
1523 1529
1524$Id: ChangeLog,v 1.3476 2004/07/17 06:13:15 dtucker Exp $ 1530$Id: ChangeLog,v 1.3477 2004/07/17 07:05:14 dtucker Exp $
diff --git a/monitor.c b/monitor.c
index 3f468dfff..b7463400e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "includes.h" 27#include "includes.h"
28RCSID("$OpenBSD: monitor.c,v 1.60 2004/06/22 05:05:45 dtucker Exp $"); 28RCSID("$OpenBSD: monitor.c,v 1.61 2004/07/17 05:31:41 dtucker Exp $");
29 29
30#include <openssl/dh.h> 30#include <openssl/dh.h>
31 31
@@ -79,6 +79,7 @@ extern u_char session_id[];
79extern Buffer input, output; 79extern Buffer input, output;
80extern Buffer auth_debug; 80extern Buffer auth_debug;
81extern int auth_debug_init; 81extern int auth_debug_init;
82extern Buffer loginmsg;
82 83
83/* State exported from the child */ 84/* State exported from the child */
84 85
@@ -1230,10 +1231,6 @@ mm_answer_pty(int sock, Buffer *m)
1230 1231
1231 buffer_put_int(m, 1); 1232 buffer_put_int(m, 1);
1232 buffer_put_cstring(m, s->tty); 1233 buffer_put_cstring(m, s->tty);
1233 mm_request_send(sock, MONITOR_ANS_PTY, m);
1234
1235 mm_send_fd(sock, s->ptyfd);
1236 mm_send_fd(sock, s->ttyfd);
1237 1234
1238 /* We need to trick ttyslot */ 1235 /* We need to trick ttyslot */
1239 if (dup2(s->ttyfd, 0) == -1) 1236 if (dup2(s->ttyfd, 0) == -1)
@@ -1244,6 +1241,15 @@ mm_answer_pty(int sock, Buffer *m)
1244 /* Now we can close the file descriptor again */ 1241 /* Now we can close the file descriptor again */
1245 close(0); 1242 close(0);
1246 1243
1244 /* send messages generated by record_login */
1245 buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg));
1246 buffer_clear(&loginmsg);
1247
1248 mm_request_send(sock, MONITOR_ANS_PTY, m);
1249
1250 mm_send_fd(sock, s->ptyfd);
1251 mm_send_fd(sock, s->ttyfd);
1252
1247 /* make sure nothing uses fd 0 */ 1253 /* make sure nothing uses fd 0 */
1248 if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) 1254 if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
1249 fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); 1255 fatal("%s: open(/dev/null): %s", __func__, strerror(errno));
diff --git a/monitor_wrap.c b/monitor_wrap.c
index f6bc34ec8..0d7a0e3bd 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "includes.h" 27#include "includes.h"
28RCSID("$OpenBSD: monitor_wrap.c,v 1.38 2004/07/03 11:02:25 dtucker Exp $"); 28RCSID("$OpenBSD: monitor_wrap.c,v 1.39 2004/07/17 05:31:41 dtucker Exp $");
29 29
30#include <openssl/bn.h> 30#include <openssl/bn.h>
31#include <openssl/dh.h> 31#include <openssl/dh.h>
@@ -70,6 +70,7 @@ extern z_stream incoming_stream;
70extern z_stream outgoing_stream; 70extern z_stream outgoing_stream;
71extern struct monitor *pmonitor; 71extern struct monitor *pmonitor;
72extern Buffer input, output; 72extern Buffer input, output;
73extern Buffer loginmsg;
73extern ServerOptions options; 74extern ServerOptions options;
74 75
75int 76int
@@ -642,7 +643,7 @@ int
642mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) 643mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
643{ 644{
644 Buffer m; 645 Buffer m;
645 char *p; 646 char *p, *msg;
646 int success = 0; 647 int success = 0;
647 648
648 buffer_init(&m); 649 buffer_init(&m);
@@ -658,11 +659,15 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
658 return (0); 659 return (0);
659 } 660 }
660 p = buffer_get_string(&m, NULL); 661 p = buffer_get_string(&m, NULL);
662 msg = buffer_get_string(&m, NULL);
661 buffer_free(&m); 663 buffer_free(&m);
662 664
663 strlcpy(namebuf, p, namebuflen); /* Possible truncation */ 665 strlcpy(namebuf, p, namebuflen); /* Possible truncation */
664 xfree(p); 666 xfree(p);
665 667
668 buffer_append(&loginmsg, msg, strlen(msg));
669 xfree(msg);
670
666 *ptyfd = mm_receive_fd(pmonitor->m_recvfd); 671 *ptyfd = mm_receive_fd(pmonitor->m_recvfd);
667 *ttyfd = mm_receive_fd(pmonitor->m_recvfd); 672 *ttyfd = mm_receive_fd(pmonitor->m_recvfd);
668 673
diff --git a/session.c b/session.c
index 7c8fe5faf..99b84394e 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
33 */ 33 */
34 34
35#include "includes.h" 35#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.178 2004/07/11 17:48:47 deraadt Exp $"); 36RCSID("$OpenBSD: session.c,v 1.179 2004/07/17 05:31:41 dtucker Exp $");
37 37
38#include "ssh.h" 38#include "ssh.h"
39#include "ssh1.h" 39#include "ssh1.h"
@@ -196,12 +196,11 @@ auth_input_request_forwarding(struct passwd * pw)
196static void 196static void
197display_loginmsg(void) 197display_loginmsg(void)
198{ 198{
199 if (buffer_len(&loginmsg) > 0) { 199 if (buffer_len(&loginmsg) > 0) {
200 buffer_append(&loginmsg, "\0", 1); 200 buffer_append(&loginmsg, "\0", 1);
201 printf("%s\n", (char *)buffer_ptr(&loginmsg)); 201 printf("%s", (char *)buffer_ptr(&loginmsg));
202 buffer_clear(&loginmsg); 202 buffer_clear(&loginmsg);
203 } 203 }
204 fflush(stdout);
205} 204}
206 205
207void 206void
@@ -676,14 +675,19 @@ do_exec(Session *s, const char *command)
676 do_exec_no_pty(s, command); 675 do_exec_no_pty(s, command);
677 676
678 original_command = NULL; 677 original_command = NULL;
679}
680 678
679 /*
680 * Clear loginmsg: it's the child's responsibility to display
681 * it to the user, otherwise multiple sessions may accumulate
682 * multiple copies of the login messages.
683 */
684 buffer_clear(&loginmsg);
685}
681 686
682/* administrative, login(1)-like work */ 687/* administrative, login(1)-like work */
683void 688void
684do_login(Session *s, const char *command) 689do_login(Session *s, const char *command)
685{ 690{
686 char *time_string;
687 socklen_t fromlen; 691 socklen_t fromlen;
688 struct sockaddr_storage from; 692 struct sockaddr_storage from;
689 struct passwd * pw = s->pw; 693 struct passwd * pw = s->pw;
@@ -728,19 +732,6 @@ do_login(Session *s, const char *command)
728 732
729 display_loginmsg(); 733 display_loginmsg();
730 734
731#ifndef NO_SSH_LASTLOG
732 if (options.print_lastlog && s->last_login_time != 0) {
733 time_string = ctime(&s->last_login_time);
734 if (strchr(time_string, '\n'))
735 *strchr(time_string, '\n') = 0;
736 if (strcmp(s->hostname, "") == 0)
737 printf("Last login: %s\r\n", time_string);
738 else
739 printf("Last login: %s from %s\r\n", time_string,
740 s->hostname);
741 }
742#endif /* NO_SSH_LASTLOG */
743
744 do_motd(); 735 do_motd();
745} 736}
746 737
@@ -1318,6 +1309,7 @@ do_setusercontext(struct passwd *pw)
1318static void 1309static void
1319do_pwchange(Session *s) 1310do_pwchange(Session *s)
1320{ 1311{
1312 fflush(NULL);
1321 fprintf(stderr, "WARNING: Your password has expired.\n"); 1313 fprintf(stderr, "WARNING: Your password has expired.\n");
1322 if (s->ttyfd != -1) { 1314 if (s->ttyfd != -1) {
1323 fprintf(stderr, 1315 fprintf(stderr,
@@ -1703,12 +1695,6 @@ session_pty_req(Session *s)
1703 packet_disconnect("Protocol error: you already have a pty."); 1695 packet_disconnect("Protocol error: you already have a pty.");
1704 return 0; 1696 return 0;
1705 } 1697 }
1706 /* Get the time and hostname when the user last logged in. */
1707 if (options.print_lastlog) {
1708 s->hostname[0] = '\0';
1709 s->last_login_time = get_last_login_time(s->pw->pw_uid,
1710 s->pw->pw_name, s->hostname, sizeof(s->hostname));
1711 }
1712 1698
1713 s->term = packet_get_string(&len); 1699 s->term = packet_get_string(&len);
1714 1700
diff --git a/session.h b/session.h
index e52506652..48be5070c 100644
--- a/session.h
+++ b/session.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.h,v 1.22 2004/04/27 09:46:37 djm Exp $ */ 1/* $OpenBSD: session.h,v 1.23 2004/07/17 05:31:41 dtucker Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -39,9 +39,6 @@ struct Session {
39 int ptyfd, ttyfd, ptymaster; 39 int ptyfd, ttyfd, ptymaster;
40 u_int row, col, xpixel, ypixel; 40 u_int row, col, xpixel, ypixel;
41 char tty[TTYSZ]; 41 char tty[TTYSZ];
42 /* last login */
43 char hostname[MAXHOSTNAMELEN];
44 time_t last_login_time;
45 /* X11 */ 42 /* X11 */
46 u_int display_number; 43 u_int display_number;
47 char *display; 44 char *display;
diff --git a/sshd.c b/sshd.c
index ac62cb506..a9e7ccb31 100644
--- a/sshd.c
+++ b/sshd.c
@@ -42,7 +42,7 @@
42 */ 42 */
43 43
44#include "includes.h" 44#include "includes.h"
45RCSID("$OpenBSD: sshd.c,v 1.298 2004/07/11 17:48:47 deraadt Exp $"); 45RCSID("$OpenBSD: sshd.c,v 1.299 2004/07/17 05:31:41 dtucker Exp $");
46 46
47#include <openssl/dh.h> 47#include <openssl/dh.h>
48#include <openssl/bn.h> 48#include <openssl/bn.h>
@@ -216,6 +216,9 @@ Buffer loginmsg;
216/* global authentication context */ 216/* global authentication context */
217Authctxt *the_authctxt = NULL; 217Authctxt *the_authctxt = NULL;
218 218
219/* message to be displayed after login */
220Buffer loginmsg;
221
219/* Prototypes for various functions defined later in this file. */ 222/* Prototypes for various functions defined later in this file. */
220void destroy_sensitive_data(void); 223void destroy_sensitive_data(void);
221void demote_sensitive_data(void); 224void demote_sensitive_data(void);
@@ -1680,6 +1683,9 @@ main(int ac, char **av)
1680 if (privsep_preauth(authctxt) == 1) 1683 if (privsep_preauth(authctxt) == 1)
1681 goto authenticated; 1684 goto authenticated;
1682 1685
1686 /* prepare buffer to collect messages to display to user after login */
1687 buffer_init(&loginmsg);
1688
1683 /* perform the key exchange */ 1689 /* perform the key exchange */
1684 /* authenticate user and start session */ 1690 /* authenticate user and start session */
1685 if (compat20) { 1691 if (compat20) {
diff --git a/sshlogin.c b/sshlogin.c
index 75446f9eb..41817ec96 100644
--- a/sshlogin.c
+++ b/sshlogin.c
@@ -39,9 +39,15 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: sshlogin.c,v 1.9 2004/07/03 05:11:33 dtucker Exp $"); 42RCSID("$OpenBSD: sshlogin.c,v 1.10 2004/07/17 05:31:41 dtucker Exp $");
43 43
44#include "loginrec.h" 44#include "loginrec.h"
45#include "log.h"
46#include "buffer.h"
47#include "servconf.h"
48
49extern Buffer loginmsg;
50extern ServerOptions options;
45 51
46/* 52/*
47 * Returns the time when the user last logged in. Returns 0 if the 53 * Returns the time when the user last logged in. Returns 0 if the
@@ -60,6 +66,38 @@ get_last_login_time(uid_t uid, const char *logname,
60} 66}
61 67
62/* 68/*
69 * Generate and store last login message. This must be done before
70 * login_login() is called and lastlog is updated.
71 */
72void
73store_lastlog_message(const char *user, uid_t uid)
74{
75 char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512];
76 time_t last_login_time;
77
78#ifndef NO_SSH_LASTLOG
79 if (!options.print_lastlog)
80 return;
81
82 last_login_time = get_last_login_time(uid, user, hostname,
83 sizeof(hostname));
84
85 if (last_login_time != 0) {
86 time_string = ctime(&last_login_time);
87 if (strchr(time_string, '\n'))
88 *strchr(time_string, '\n') = '\0';
89 if (strcmp(hostname, "") == 0)
90 snprintf(buf, sizeof(buf), "Last login: %s\r\n",
91 time_string);
92 else
93 snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n",
94 time_string, hostname);
95 buffer_append(&loginmsg, buf, strlen(buf));
96 }
97#endif /* NO_SSH_LASTLOG */
98}
99
100/*
63 * Records that the user has logged in. I wish these parts of operating 101 * Records that the user has logged in. I wish these parts of operating
64 * systems were more standardized. 102 * systems were more standardized.
65 */ 103 */
@@ -69,6 +107,9 @@ record_login(pid_t pid, const char *tty, const char *user, uid_t uid,
69{ 107{
70 struct logininfo *li; 108 struct logininfo *li;
71 109
110 /* save previous login details before writing new */
111 store_lastlog_message(user, uid);
112
72 li = login_alloc_entry(pid, user, host, tty); 113 li = login_alloc_entry(pid, user, host, tty);
73 login_set_addr(li, addr, addrlen); 114 login_set_addr(li, addr, addrlen);
74 login_login(li); 115 login_login(li);