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

Collapse All | Expand All

(-)loginrec.c (+8 lines)
Lines 157-162 Link Here
157
#include "loginrec.h"
157
#include "loginrec.h"
158
#include "log.h"
158
#include "log.h"
159
#include "atomicio.h"
159
#include "atomicio.h"
160
#include "buffer.h"
160
161
161
RCSID("$Id: loginrec.c,v 1.56 2004/04/08 06:16:06 dtucker Exp $");
162
RCSID("$Id: loginrec.c,v 1.56 2004/04/08 06:16:06 dtucker Exp $");
162
163
Lines 197-202 int wtmpx_get_entry(struct logininfo *li Link Here
197
/* pick the shortest string */
198
/* pick the shortest string */
198
#define MIN_SIZEOF(s1,s2) ( sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2) )
199
#define MIN_SIZEOF(s1,s2) ( sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2) )
199
200
201
extern Buffer loginmsg;
202
200
/**
203
/**
201
 ** platform-independent login functions
204
 ** platform-independent login functions
202
 **/
205
 **/
Lines 434-439 login_write (struct logininfo *li) Link Here
434
#endif
437
#endif
435
#ifdef USE_WTMPX
438
#ifdef USE_WTMPX
436
	wtmpx_write_entry(li);
439
	wtmpx_write_entry(li);
440
#endif
441
#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN
442
	if (li->type == LTYPE_LOGIN && 
443
	   !sys_auth_record_login(li->username,li->hostname,li->line))
444
		logit("Writing login record failed for %s", li->username);
437
#endif
445
#endif
438
	return 0;
446
	return 0;
439
}
447
}
(-)monitor.c (-4 / +11 lines)
Lines 79-84 extern u_char session_id[]; Link Here
79
extern Buffer input, output;
79
extern Buffer input, output;
80
extern Buffer auth_debug;
80
extern Buffer auth_debug;
81
extern int auth_debug_init;
81
extern int auth_debug_init;
82
extern Buffer loginmsg;
82
83
83
/* State exported from the child */
84
/* State exported from the child */
84
85
Lines 1230-1239 mm_answer_pty(int sock, Buffer *m) Link Here
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)
Lines 1243-1248 mm_answer_pty(int sock, Buffer *m) Link Here
1243
1240
1244
	/* Now we can close the file descriptor again */
1241
	/* Now we can close the file descriptor again */
1245
	close(0);
1242
	close(0);
1243
1244
	/* send messages generated by record_login */
1245
	buffer_append(&loginmsg, "\0", 1);
1246
	buffer_put_cstring(m, buffer_ptr(&loginmsg));
1247
	buffer_clear(&loginmsg);
1248
1249
	mm_request_send(sock, MONITOR_ANS_PTY, m);
1250
1251
	mm_send_fd(sock, s->ptyfd);
1252
	mm_send_fd(sock, s->ttyfd);
1246
1253
1247
	/* make sure nothing uses fd 0 */
1254
	/* make sure nothing uses fd 0 */
1248
	if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
1255
	if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
(-)monitor_wrap.c (-1 / +6 lines)
Lines 70-75 extern z_stream incoming_stream; Link Here
70
extern z_stream outgoing_stream;
70
extern z_stream outgoing_stream;
71
extern struct monitor *pmonitor;
71
extern struct monitor *pmonitor;
72
extern Buffer input, output;
72
extern Buffer input, output;
73
extern Buffer loginmsg;
73
extern ServerOptions options;
74
extern ServerOptions options;
74
75
75
int
76
int
Lines 642-648 int Link Here
642
mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
643
mm_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);
Lines 658-667 mm_pty_allocate(int *ptyfd, int *ttyfd, Link Here
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);
667
668
	buffer_append(&loginmsg, msg, strlen(msg));
669
	xfree(msg);
665
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);
(-)session.c (-31 / +16 lines)
Lines 193-209 auth_input_request_forwarding(struct pas Link Here
193
	return 1;
193
	return 1;
194
}
194
}
195
195
196
static void
197
display_loginmsg(void)
198
{
199
	if (buffer_len(&loginmsg) > 0) {
200
		buffer_append(&loginmsg, "\0", 1);
201
		printf("%s\n", (char *)buffer_ptr(&loginmsg));
202
		buffer_clear(&loginmsg);
203
	}
204
	fflush(stdout);
205
}
206
207
void
196
void
208
do_authenticated(Authctxt *authctxt)
197
do_authenticated(Authctxt *authctxt)
209
{
198
{
Lines 676-689 do_exec(Session *s, const char *command) Link Here
676
		do_exec_no_pty(s, command);
665
		do_exec_no_pty(s, command);
677
666
678
	original_command = NULL;
667
	original_command = NULL;
668
669
	/*
670
	 * Clear loginmsg: it's the child's responsibility to display
671
	 * it to the user, otherwise multiple sessions may accumulate
672
	 * multiple copies of the login messages.
673
	 */
674
	buffer_clear(&loginmsg);
679
}
675
}
680
676
677
static void
678
display_loginmsg(void)
679
{
680
        if (buffer_len(&loginmsg) > 0) {
681
                buffer_append(&loginmsg, "\0", 1);
682
                printf("%s", (char *)buffer_ptr(&loginmsg));
683
                buffer_clear(&loginmsg);
684
        }
685
}
681
686
682
/* administrative, login(1)-like work */
687
/* administrative, login(1)-like work */
683
void
688
void
684
do_login(Session *s, const char *command)
689
do_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;
Lines 728-746 do_login(Session *s, const char *command Link Here
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
Lines 1702-1713 session_pty_req(Session *s) Link Here
1702
	if (s->ttyfd != -1) {
1693
	if (s->ttyfd != -1) {
1703
		packet_disconnect("Protocol error: you already have a pty.");
1694
		packet_disconnect("Protocol error: you already have a pty.");
1704
		return 0;
1695
		return 0;
1705
	}
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
	}
1696
	}
1712
1697
1713
	s->term = packet_get_string(&len);
1698
	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 220-225 Buffer loginmsg; Link Here
220
/* global authentication context */
220
/* global authentication context */
221
Authctxt *the_authctxt = NULL;
221
Authctxt *the_authctxt = NULL;
222
222
223
/* message to be displayed after login */
224
Buffer loginmsg;
225
223
/* Prototypes for various functions defined later in this file. */
226
/* Prototypes for various functions defined later in this file. */
224
void destroy_sensitive_data(void);
227
void destroy_sensitive_data(void);
225
void demote_sensitive_data(void);
228
void demote_sensitive_data(void);
Lines 1683-1688 main(int ac, char **av) Link Here
1683
	if (use_privsep)
1686
	if (use_privsep)
1684
		if (privsep_preauth(authctxt) == 1)
1687
		if (privsep_preauth(authctxt) == 1)
1685
			goto authenticated;
1688
			goto authenticated;
1689
1690
	/* prepare buffer to collect messages to display to user after login */
1691
	buffer_init(&loginmsg);
1686
1692
1687
	/* perform the key exchange */
1693
	/* perform the key exchange */
1688
	/* authenticate user and start session */
1694
	/* authenticate user and start session */
(-)sshlogin.c (+41 lines)
Lines 42-47 Link Here
42
RCSID("$OpenBSD: sshlogin.c,v 1.8 2004/06/21 17:36:31 avsm Exp $");
42
RCSID("$OpenBSD: sshlogin.c,v 1.8 2004/06/21 17:36:31 avsm Exp $");
43
43
44
#include "loginrec.h"
44
#include "loginrec.h"
45
#include "log.h"
46
#include "buffer.h"
47
#include "servconf.h"
48
49
extern Buffer loginmsg;
50
extern 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
Lines 60-65 get_last_login_time(uid_t uid, const cha Link Here
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
 */
72
void
73
store_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
 */
Lines 68-73 record_login(pid_t pid, const char *tty, Link Here
68
    const char *host, struct sockaddr * addr, socklen_t addrlen)
106
    const char *host, struct sockaddr * addr, socklen_t addrlen)
69
{
107
{
70
	struct logininfo *li;
108
	struct logininfo *li;
109
110
	/* save previous login details before writing new */
111
	store_lastlog_message(user, uid);
71
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);
(-)openbsd-compat/port-aix.c (-10 / +20 lines)
Lines 101-107 aix_remove_embedded_newlines(char *p) Link Here
101
int
101
int
102
sys_auth_passwd(Authctxt *ctxt, const char *password)
102
sys_auth_passwd(Authctxt *ctxt, const char *password)
103
{
103
{
104
	char *authmsg = NULL, *host, *msg, *name = ctxt->pw->pw_name;
104
	char *authmsg = NULL, *msg, *name = ctxt->pw->pw_name;
105
	int authsuccess = 0, expired, reenter, result;
105
	int authsuccess = 0, expired, reenter, result;
106
106
107
	do {
107
	do {
Lines 115-134 sys_auth_passwd(Authctxt *ctxt, const ch Link Here
115
	if (result == 0) {
115
	if (result == 0) {
116
		authsuccess = 1;
116
		authsuccess = 1;
117
117
118
		host = (char *)get_canonical_hostname(options.use_dns);
119
120
	       	/*
118
	       	/*
121
		 * Record successful login.  We don't have a pty yet, so just
119
		 * Record successful login.  We don't have a pty yet, so just
122
		 * label the line as "ssh"
120
		 * label the line as "ssh"
123
		 */
121
		 */
124
		aix_setauthdb(name);
122
		aix_setauthdb(name);
125
	       	if (loginsuccess((char *)name, (char *)host, "ssh", &msg) == 0) {
126
			if (msg != NULL) {
127
				debug("%s: msg %s", __func__, msg);
128
				buffer_append(&loginmsg, msg, strlen(msg));
129
				xfree(msg);
130
			}
131
		}
132
123
133
		/*
124
		/*
134
		 * Check if the user's password is expired.
125
		 * Check if the user's password is expired.
Lines 206-211 sys_auth_allowed_user(struct passwd *pw) Link Here
206
		logit("Login restricted for %s: %.100s", pw->pw_name, msg);
197
		logit("Login restricted for %s: %.100s", pw->pw_name, msg);
207
	xfree(msg);
198
	xfree(msg);
208
	return permitted;
199
	return permitted;
200
}
201
202
int
203
sys_auth_record_login(const char *user, const char *host, const char *ttynm)
204
{
205
	char *msg;
206
	int success = 0;
207
208
	aix_setauthdb(user);
209
       	if (loginsuccess((char *)user, host, ttynm, &msg) == 0) {
210
		success = 1;
211
		if (msg != NULL) {
212
			debug("AIX/loginsuccess: msg %s", __func__, msg);
213
			buffer_append(&loginmsg, msg, strlen(msg));
214
			xfree(msg);
215
		}
216
	}
217
	aix_restoreauthdb();
218
	return (success);
209
}
219
}
210
220
211
#  ifdef CUSTOM_FAILED_LOGIN
221
#  ifdef CUSTOM_FAILED_LOGIN
(-)openbsd-compat/port-aix.h (+2 lines)
Lines 65-70 void aix_usrinfo(struct passwd *); Link Here
65
# define CUSTOM_SYS_AUTH_PASSWD 1
65
# define CUSTOM_SYS_AUTH_PASSWD 1
66
# define CUSTOM_SYS_AUTH_ALLOWED_USER 1
66
# define CUSTOM_SYS_AUTH_ALLOWED_USER 1
67
int sys_auth_allowed_user(struct passwd *);
67
int sys_auth_allowed_user(struct passwd *);
68
# define CUSTOM_SYS_AUTH_RECORD_LOGIN 1
69
int sys_auth_record_login(const char *, const char *, const char *);
68
# define CUSTOM_FAILED_LOGIN 1
70
# define CUSTOM_FAILED_LOGIN 1
69
void record_failed_login(const char *, const char *);
71
void record_failed_login(const char *, const char *);
70
#endif
72
#endif

Return to bug 463