View | Details | Raw Unified | Return to bug 463 | Differences between
and this patch

Collapse All | Expand All

(-)monitor.c (-4 / +11 lines)
Lines 73-78 extern u_char session_id[]; Link Here
73
extern Buffer input, output;
73
extern Buffer input, output;
74
extern Buffer auth_debug;
74
extern Buffer auth_debug;
75
extern int auth_debug_init;
75
extern int auth_debug_init;
76
extern Buffer loginmsg;
76
77
77
/* State exported from the child */
78
/* State exported from the child */
78
79
Lines 1051-1060 mm_answer_pty(int sock, Buffer *m) Link Here
1051
1052
1052
	buffer_put_int(m, 1);
1053
	buffer_put_int(m, 1);
1053
	buffer_put_cstring(m, s->tty);
1054
	buffer_put_cstring(m, s->tty);
1054
	mm_request_send(sock, MONITOR_ANS_PTY, m);
1055
1056
	mm_send_fd(sock, s->ptyfd);
1057
	mm_send_fd(sock, s->ttyfd);
1058
1055
1059
	/* We need to trick ttyslot */
1056
	/* We need to trick ttyslot */
1060
	if (dup2(s->ttyfd, 0) == -1)
1057
	if (dup2(s->ttyfd, 0) == -1)
Lines 1064-1069 mm_answer_pty(int sock, Buffer *m) Link Here
1064
1061
1065
	/* Now we can close the file descriptor again */
1062
	/* Now we can close the file descriptor again */
1066
	close(0);
1063
	close(0);
1064
1065
	/* send messages generated by record_login */
1066
	buffer_append(&loginmsg, "\0", 1);
1067
	buffer_put_cstring(m, buffer_ptr(&loginmsg));
1068
	buffer_clear(&loginmsg);
1069
1070
	mm_request_send(sock, MONITOR_ANS_PTY, m);
1071
1072
	mm_send_fd(sock, s->ptyfd);
1073
	mm_send_fd(sock, s->ttyfd);
1067
1074
1068
	/* make sure nothing uses fd 0 */
1075
	/* make sure nothing uses fd 0 */
1069
	if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
1076
	if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
(-)monitor_wrap.c (-1 / +6 lines)
Lines 63-68 extern z_stream incoming_stream; Link Here
63
extern z_stream outgoing_stream;
63
extern z_stream outgoing_stream;
64
extern struct monitor *pmonitor;
64
extern struct monitor *pmonitor;
65
extern Buffer input, output;
65
extern Buffer input, output;
66
extern Buffer loginmsg;
66
67
67
int
68
int
68
mm_is_monitor(void)
69
mm_is_monitor(void)
Lines 632-638 int Link Here
632
mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
633
mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
633
{
634
{
634
	Buffer m;
635
	Buffer m;
635
	char *p;
636
	char *p, *msg;
636
	int success = 0;
637
	int success = 0;
637
638
638
	buffer_init(&m);
639
	buffer_init(&m);
Lines 648-657 mm_pty_allocate(int *ptyfd, int *ttyfd, Link Here
648
		return (0);
649
		return (0);
649
	}
650
	}
650
	p = buffer_get_string(&m, NULL);
651
	p = buffer_get_string(&m, NULL);
652
	msg = buffer_get_string(&m, NULL);
651
	buffer_free(&m);
653
	buffer_free(&m);
652
654
653
	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
655
	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
654
	xfree(p);
656
	xfree(p);
657
658
	buffer_append(&loginmsg, msg, strlen(msg));
659
	xfree(msg);
655
660
656
	*ptyfd = mm_receive_fd(pmonitor->m_recvfd);
661
	*ptyfd = mm_receive_fd(pmonitor->m_recvfd);
657
	*ttyfd = mm_receive_fd(pmonitor->m_recvfd);
662
	*ttyfd = mm_receive_fd(pmonitor->m_recvfd);
(-)session.c (-17 / +18 lines)
Lines 94-99 extern int debug_flag; Link Here
94
extern u_int utmp_len;
94
extern u_int utmp_len;
95
extern int startup_pipe;
95
extern int startup_pipe;
96
extern void destroy_sensitive_data(void);
96
extern void destroy_sensitive_data(void);
97
extern Buffer loginmsg;
97
98
98
/* original command from peer. */
99
/* original command from peer. */
99
const char *original_command = NULL;
100
const char *original_command = NULL;
Lines 189-194 auth_input_request_forwarding(struct pas Link Here
189
	return 1;
190
	return 1;
190
}
191
}
191
192
193
static void
194
display_loginmsg(void)
195
{
196
        if (buffer_len(&loginmsg) > 0) {
197
                buffer_append(&loginmsg, "\0", 1);
198
                printf("%s", (char *)buffer_ptr(&loginmsg));
199
                buffer_clear(&loginmsg);
200
        }
201
}
192
202
193
void
203
void
194
do_authenticated(Authctxt *authctxt)
204
do_authenticated(Authctxt *authctxt)
Lines 586-591 do_exec(Session *s, const char *command) Link Here
586
		do_exec_no_pty(s, command);
596
		do_exec_no_pty(s, command);
587
597
588
	original_command = NULL;
598
	original_command = NULL;
599
600
	/*
601
	 * Clear loginmsg: it's the child's responsibility to display
602
	 * it to the user, otherwise multiple sessions may accumulate
603
	 * multiple copies of the login messages.
604
	 */
605
	buffer_clear(&loginmsg);
589
}
606
}
590
607
591
608
Lines 593-599 do_exec(Session *s, const char *command) Link Here
593
void
610
void
594
do_login(Session *s, const char *command)
611
do_login(Session *s, const char *command)
595
{
612
{
596
	char *time_string;
597
	socklen_t fromlen;
613
	socklen_t fromlen;
598
	struct sockaddr_storage from;
614
	struct sockaddr_storage from;
599
	struct passwd * pw = s->pw;
615
	struct passwd * pw = s->pw;
Lines 623-638 do_login(Session *s, const char *command Link Here
623
	if (check_quietlogin(s, command))
639
	if (check_quietlogin(s, command))
624
		return;
640
		return;
625
641
626
	if (options.print_lastlog && s->last_login_time != 0) {
642
	display_loginmsg();
627
		time_string = ctime(&s->last_login_time);
628
		if (strchr(time_string, '\n'))
629
			*strchr(time_string, '\n') = 0;
630
		if (strcmp(s->hostname, "") == 0)
631
			printf("Last login: %s\r\n", time_string);
632
		else
633
			printf("Last login: %s from %s\r\n", time_string,
634
			    s->hostname);
635
	}
636
643
637
	do_motd();
644
	do_motd();
638
}
645
}
Lines 1377-1388 session_pty_req(Session *s) Link Here
1377
	if (s->ttyfd != -1) {
1384
	if (s->ttyfd != -1) {
1378
		packet_disconnect("Protocol error: you already have a pty.");
1385
		packet_disconnect("Protocol error: you already have a pty.");
1379
		return 0;
1386
		return 0;
1380
	}
1381
	/* Get the time and hostname when the user last logged in. */
1382
	if (options.print_lastlog) {
1383
		s->hostname[0] = '\0';
1384
		s->last_login_time = get_last_login_time(s->pw->pw_uid,
1385
		    s->pw->pw_name, s->hostname, sizeof(s->hostname));
1386
	}
1387
	}
1387
1388
1388
	s->term = packet_get_string(&len);
1389
	s->term = packet_get_string(&len);
(-)session.h (-3 lines)
Lines 39-47 struct Session { Link Here
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;
(-)sshd.c (+6 lines)
Lines 208-213 struct monitor *pmonitor = NULL; Link Here
208
/* global authentication context */
208
/* global authentication context */
209
Authctxt *the_authctxt = NULL;
209
Authctxt *the_authctxt = NULL;
210
210
211
/* message to be displayed after login */
212
Buffer loginmsg;
213
211
/* Prototypes for various functions defined later in this file. */
214
/* Prototypes for various functions defined later in this file. */
212
void destroy_sensitive_data(void);
215
void destroy_sensitive_data(void);
213
void demote_sensitive_data(void);
216
void demote_sensitive_data(void);
Lines 1603-1608 main(int ac, char **av) Link Here
1603
	if (use_privsep)
1606
	if (use_privsep)
1604
		if (privsep_preauth(authctxt) == 1)
1607
		if (privsep_preauth(authctxt) == 1)
1605
			goto authenticated;
1608
			goto authenticated;
1609
1610
	/* prepare buffer to collect messages to display to user after login */
1611
	buffer_init(&loginmsg);
1606
1612
1607
	/* perform the key exchange */
1613
	/* perform the key exchange */
1608
	/* authenticate user and start session */
1614
	/* authenticate user and start session */
(-)sshlogin.c (+38 lines)
Lines 45-50 RCSID("$OpenBSD: sshlogin.c,v 1.8 2004/0 Link Here
45
#include <utmp.h>
45
#include <utmp.h>
46
#include "sshlogin.h"
46
#include "sshlogin.h"
47
#include "log.h"
47
#include "log.h"
48
#include "buffer.h"
49
#include "servconf.h"
50
51
extern Buffer loginmsg;
52
extern ServerOptions options;
48
53
49
/*
54
/*
50
 * Returns the time when the user last logged in.  Returns 0 if the
55
 * Returns the time when the user last logged in.  Returns 0 if the
Lines 79-84 get_last_login_time(uid_t uid, const cha Link Here
79
}
84
}
80
85
81
/*
86
/*
87
 * Generate and store last login message.  This must be done before
88
 * login_login() is called and lastlog is updated.
89
 */
90
void
91
store_lastlog_message(const char *user, uid_t uid)
92
{
93
	char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512];
94
	time_t last_login_time;
95
96
	if (!options.print_lastlog)
97
		return;
98
99
	last_login_time = get_last_login_time(uid, user, hostname,
100
	    sizeof(hostname));
101
102
	if (last_login_time != 0) {
103
		time_string = ctime(&last_login_time);
104
		if (strchr(time_string, '\n'))
105
		    *strchr(time_string, '\n') = 0;
106
		if (strcmp(hostname, "") == 0)
107
			snprintf(buf, sizeof(buf), "Last login: %s\r\n",
108
			    time_string);
109
		else
110
			snprintf(buf, sizeof(buf), "Last login: %s from %s\r\n",
111
			    time_string, hostname);
112
		buffer_append(&loginmsg, buf, strlen(buf));
113
	}
114
}
115
116
/*
82
 * Records that the user has logged in.  I wish these parts of operating
117
 * Records that the user has logged in.  I wish these parts of operating
83
 * systems were more standardized.
118
 * systems were more standardized.
84
 */
119
 */
Lines 90-95 record_login(pid_t pid, const char *tty, Link Here
90
	struct lastlog ll;
125
	struct lastlog ll;
91
	char *lastlog;
126
	char *lastlog;
92
	struct utmp u;
127
	struct utmp u;
128
129
	/* save previous login details before writing new */
130
	store_lastlog_message(user, uid);
93
131
94
	/* Construct an utmp/wtmp entry. */
132
	/* Construct an utmp/wtmp entry. */
95
	memset(&u, 0, sizeof(u));
133
	memset(&u, 0, sizeof(u));

Return to bug 463