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

Collapse All | Expand All

(-)TODO (-2 lines)
Lines 15-22 Link Here
15
15
16
- Replacement for setproctitle() - HP-UX support only currently
16
- Replacement for setproctitle() - HP-UX support only currently
17
17
18
- Handle changing passwords for the non-PAM expired password case
19
20
- Improve PAM support (a pam_lastlog module will cause sshd to exit)
18
- Improve PAM support (a pam_lastlog module will cause sshd to exit)
21
  and maybe support alternate forms of authentications like OPIE via
19
  and maybe support alternate forms of authentications like OPIE via
22
  pam?
20
  pam?
(-)acconfig.h (+3 lines)
Lines 25-30 Link Here
25
/* from environment and PATH */
25
/* from environment and PATH */
26
#undef LOGIN_PROGRAM_FALLBACK
26
#undef LOGIN_PROGRAM_FALLBACK
27
27
28
/* Path to passwd program */
29
#undef PASSWD_PROGRAM_PATH
30
28
/* Define if your password has a pw_class field */
31
/* Define if your password has a pw_class field */
29
#undef HAVE_PW_CLASS_IN_PASSWD
32
#undef HAVE_PW_CLASS_IN_PASSWD
30
33
(-)auth-pam.c (-7 / +2 lines)
Lines 60-66 Link Here
60
/* states for do_pam_conversation() */
60
/* states for do_pam_conversation() */
61
enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
61
enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
62
/* remember whether pam_acct_mgmt() returned PAM_NEW_AUTHTOK_REQD */
62
/* remember whether pam_acct_mgmt() returned PAM_NEW_AUTHTOK_REQD */
63
static int password_change_required = 0;
63
extern int password_change_required;
64
/* remember whether the last pam_authenticate() succeeded or not */
64
/* remember whether the last pam_authenticate() succeeded or not */
65
static int was_authenticated = 0;
65
static int was_authenticated = 0;
66
66
Lines 260-271 Link Here
260
		case PAM_NEW_AUTHTOK_REQD:
260
		case PAM_NEW_AUTHTOK_REQD:
261
			message_cat(&__pam_msg, use_privsep ?
261
			message_cat(&__pam_msg, use_privsep ?
262
			    NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG);
262
			    NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG);
263
			/* flag that password change is necessary */
263
			flag_password_change_required();
264
			password_change_required = 1;
265
			/* disallow other functionality for now */
266
			no_port_forwarding_flag |= 2;
267
			no_agent_forwarding_flag |= 2;
268
			no_x11_forwarding_flag |= 2;
269
			break;
264
			break;
270
#endif
265
#endif
271
		default:
266
		default:
(-)auth-passwd.c (-7 / +130 lines)
Lines 42-47 Link Here
42
#include "log.h"
42
#include "log.h"
43
#include "servconf.h"
43
#include "servconf.h"
44
#include "auth.h"
44
#include "auth.h"
45
#include "buffer.h"
46
#include "misc.h"
47
#include "channels.h"
48
#include "monitor_wrap.h"
49
#include "auth-options.h"
45
50
46
#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
51
#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
47
/* Don't need any of these headers for the PAM or SIA cases */
52
/* Don't need any of these headers for the PAM or SIA cases */
Lines 81-89 Link Here
81
#endif /* !USE_PAM && !HAVE_OSF_SIA */
86
#endif /* !USE_PAM && !HAVE_OSF_SIA */
82
87
83
extern ServerOptions options;
88
extern ServerOptions options;
84
#ifdef WITH_AIXAUTHENTICATE
89
extern Buffer login_message;
85
extern char *aixloginmsg;
90
extern int password_change_required;
86
#endif
91
pid_t password_change_pid;	/* pid used to reset forwarding flags */
87
92
88
/*
93
/*
89
 * Tries to authenticate the user using password.  Returns true if
94
 * Tries to authenticate the user using password.  Returns true if
Lines 123-128 Link Here
123
	/* deny if no user. */
128
	/* deny if no user. */
124
	if (pw == NULL)
129
	if (pw == NULL)
125
		return 0;
130
		return 0;
131
	buffer_init(&login_message);
126
#ifndef HAVE_CYGWIN
132
#ifndef HAVE_CYGWIN
127
       if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
133
       if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
128
		return 0;
134
		return 0;
Lines 149-161 Link Here
149
#endif
155
#endif
150
#ifdef WITH_AIXAUTHENTICATE
156
#ifdef WITH_AIXAUTHENTICATE
151
	authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);
157
	authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);
158
	aix_remove_embedded_newlines(authmsg);
152
159
153
	if (authsuccess)
160
	if (authsuccess) {
161
		char *msg;
162
163
		debug("authenticate() succeeded for user %s: %.100s",
164
		    pw->pw_name, authmsg);
154
	        /* We don't have a pty yet, so just label the line as "ssh" */
165
	        /* We don't have a pty yet, so just label the line as "ssh" */
155
	        if (loginsuccess(authctxt->user,
166
	        if (loginsuccess(authctxt->user,
156
			get_canonical_hostname(options.verify_reverse_mapping),
167
		    get_canonical_hostname(options.verify_reverse_mapping),
157
			"ssh", &aixloginmsg) < 0)
168
		    "ssh", &msg) < 0)
158
				aixloginmsg = NULL;
169
			msg = NULL;
170
		buffer_append(&login_message, msg, strlen(msg));
171
	} else {
172
		debug("AIX authenticate() failed for user %s: %.100s",
173
		    pw->pw_name, authmsg);
174
	}
175
	if (authmsg)
176
		xfree(authmsg);
159
177
160
	return(authsuccess);
178
	return(authsuccess);
161
#endif
179
#endif
Lines 232-235 Link Here
232
	/* Authentication is accepted if the encrypted passwords are identical. */
250
	/* Authentication is accepted if the encrypted passwords are identical. */
233
	return (strcmp(encrypted_password, pw_password) == 0);
251
	return (strcmp(encrypted_password, pw_password) == 0);
234
#endif /* !USE_PAM && !HAVE_OSF_SIA */
252
#endif /* !USE_PAM && !HAVE_OSF_SIA */
253
}
254
255
/*
256
 * Perform generic password change via tty. Like do_pam_chauthtok(),
257
 * it throws a fatal error if the password can't be changed.
258
 */
259
int
260
do_tty_change_password(struct passwd *pw)
261
{
262
	pid_t pid;
263
	int status;
264
	mysig_t old_signal;
265
266
	old_signal = mysignal(SIGCHLD, SIG_DFL);
267
268
	if ((pid = fork()) == -1)
269
		fatal("Couldn't fork: %s", strerror(errno));
270
271
	if (pid == 0) {
272
		setuid(pw->pw_uid);
273
		if (geteuid() == 0) 
274
			execl(PASSWD_PROGRAM_PATH, "passwd", pw->pw_name,
275
			    (char *)NULL);
276
		else
277
			execl(PASSWD_PROGRAM_PATH, "passwd", (char *)NULL);
278
			
279
		/* execl shouldn't return */
280
		fatal("Couldn't exec %s", PASSWD_PROGRAM_PATH);
281
		exit(1);
282
	}
283
284
	if (waitpid(pid, &status, 0) == -1)
285
		fatal("Couldn't wait for child: %s", strerror(errno));
286
	mysignal(SIGCHLD, old_signal);
287
288
	/*
289
	 * passwd sometimes returns 0 when the password has not been changed
290
	 * so we re-test via getpwnamallow
291
	 */
292
	if (WIFEXITED(status) && (WEXITSTATUS(status) == 0) &&
293
	    PRIVSEP(getpwnamallow(pw->pw_name)) != NULL) {
294
		debug("password changed sucessfully");
295
		flag_password_change_successful();
296
		return 1;
297
	} else {
298
		fatal("Failed to change password for %s, passwd returned %d",
299
		    pw->pw_name, status);
300
		return 0;
301
	}
302
}
303
304
/*
305
 * Because an expired password is changed after forking to exec the user's
306
 * shell, restoring the port forwarding flags is done by sending a
307
 * USR1 signal to the parent after the password is changed successfully.
308
 */
309
void
310
flag_password_change_required(void)
311
{
312
	debug("%s disabling forwarding flags", __func__);
313
	/* flag that password change is necessary */
314
	password_change_required = 1;
315
316
	/* disallow other functionality for now */
317
	no_port_forwarding_flag |= 2;
318
	no_agent_forwarding_flag |= 2;
319
	no_x11_forwarding_flag |= 2;
320
321
	/* set handler to reset flags */
322
	password_change_pid = getpid();
323
	mysignal(SIGUSR1, password_change_successful_handler);
324
}
325
326
/*
327
 * password change successful, tell parent to restore port
328
 * forwarding flags
329
 */
330
void
331
flag_password_change_successful(void)
332
{
333
	debug("%s signalling parent to reset forwarding flags", __func__);
334
	kill(password_change_pid, SIGUSR1);
335
336
	/* reset flags in local process too */
337
	password_change_required = 0;
338
	no_port_forwarding_flag &= ~2;
339
	no_agent_forwarding_flag &= ~2;
340
	no_x11_forwarding_flag &= ~2;
341
}
342
343
/*
344
 * signal handler to reset change flags
345
 */
346
void
347
password_change_successful_handler(int sig)
348
{
349
	debug("%s restoring port forwarding flags", __func__);
350
	mysignal(SIGUSR1, SIG_DFL);     /* unset handler */
351
352
	password_change_required = 0;
353
	no_port_forwarding_flag &= ~2;
354
	no_agent_forwarding_flag &= ~2;
355
	no_x11_forwarding_flag &= ~2;
356
	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
357
		channel_permit_all_opens();
235
}
358
}
(-)auth.c (-20 / +51 lines)
Lines 58-63 Link Here
58
/* Debugging messages */
58
/* Debugging messages */
59
Buffer auth_debug;
59
Buffer auth_debug;
60
int auth_debug_init;
60
int auth_debug_init;
61
extern int password_change_required;
62
extern Buffer expire_message;
61
63
62
/*
64
/*
63
 * Check if the user is allowed to log in via ssh. If user is listed
65
 * Check if the user is allowed to log in via ssh. If user is listed
Lines 75-83 Link Here
75
	const char *hostname = NULL, *ipaddr = NULL, *passwd;
77
	const char *hostname = NULL, *ipaddr = NULL, *passwd;
76
	char *shell;
78
	char *shell;
77
	int i;
79
	int i;
78
#ifdef WITH_AIXAUTHENTICATE
79
	char *loginmsg;
80
#endif /* WITH_AIXAUTHENTICATE */
81
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
80
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
82
	struct spwd *spw;
81
	struct spwd *spw;
83
#if !defined(USE_PAM) && defined(HAS_SHADOW_EXPIRE)
82
#if !defined(USE_PAM) && defined(HAS_SHADOW_EXPIRE)
Lines 222-248 Link Here
222
	 * PermitRootLogin to control logins via ssh), or if running as
221
	 * PermitRootLogin to control logins via ssh), or if running as
223
	 * non-root user (since loginrestrictions will always fail).
222
	 * non-root user (since loginrestrictions will always fail).
224
	 */
223
	 */
225
	if ( (pw->pw_uid != 0) && (geteuid() == 0) &&
224
	if ( (pw->pw_uid != 0) && (geteuid() == 0) ) {
226
	    loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) {
227
		int loginrestrict_errno = errno;
225
		int loginrestrict_errno = errno;
226
		char *msg;
228
227
229
		if (loginmsg && *loginmsg) {
228
		/* check for AIX account restrictions */
230
			/* Remove embedded newlines (if any) */
229
		if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) {
231
			char *p;
230
			if (msg && *msg) {
232
			for (p = loginmsg; *p; p++) {
231
				aix_remove_embedded_newlines(msg);
233
				if (*p == '\n')
232
				log("Login restricted for %s: %.100s",
234
					*p = ' ';
233
				    pw->pw_name, msg);
234
				xfree(msg);
235
			}
235
			}
236
			/* Remove trailing newline */
236
237
			*--p = '\0';
237
			/* Don't fail if /etc/nologin  set */
238
			log("Login restricted for %s: %.100s", pw->pw_name, 
238
	   	 	if (!(loginrestrict_errno == EPERM && 
239
			    loginmsg);
239
			    stat(_PATH_NOLOGIN, &st) == 0))
240
		}
240
				return 0;
241
		/* Don't fail if /etc/nologin  set */
241
		}
242
	    	if (!(loginrestrict_errno == EPERM && 
243
		    stat(_PATH_NOLOGIN, &st) == 0))
244
			return 0;
245
	}
242
	}
243
244
	/*
245
	 * Check AIX password expiry.  Only check when running as root.
246
	 * Unpriv'ed users can't access /etc/security/passwd or
247
	 * /etc/security/user so passwdexpired will always fail.
248
	 */
249
	if (geteuid() == 0) {
250
		char *msg;
251
		int passexpcode;
252
253
		passexpcode = passwdexpired(pw->pw_name, &msg);
254
		buffer_append(&expire_message, msg, strlen(msg));
255
		if (msg && *msg)
256
			aix_remove_embedded_newlines(msg);
257
		debug("AIX passwdexpired returned %d, msg %.100s",
258
		    passexpcode, msg);
259
260
		switch (passexpcode) {
261
			case 0:	/* success, password not expired */
262
				break;
263
			case 1:	/* expired, password change required */
264
				flag_password_change_required();
265
				break;
266
			default: /* only admin can change (2) or other error (-1) */
267
				log("Password can't be changed for user %s: %.100s",
268
				    pw->pw_name, msg);
269
				if (msg)
270
					xfree(msg);
271
				return 0;
272
  		}
273
		if (msg)
274
			xfree(msg);
275
  	}
246
#endif /* WITH_AIXAUTHENTICATE */
276
#endif /* WITH_AIXAUTHENTICATE */
247
277
248
	/* We found no reason not to let this user try to log on... */
278
	/* We found no reason not to let this user try to log on... */
Lines 508-513 Link Here
508
#endif
538
#endif
509
	struct passwd *pw;
539
	struct passwd *pw;
510
540
541
	buffer_init(&expire_message);
511
	pw = getpwnam(user);
542
	pw = getpwnam(user);
512
	if (pw == NULL) {
543
	if (pw == NULL) {
513
		log("Illegal user %.100s from %.100s",
544
		log("Illegal user %.100s from %.100s",
(-)auth.h (+3 lines)
Lines 101-106 Link Here
101
101
102
int	 auth_rhosts_rsa(struct passwd *, char *, Key *);
102
int	 auth_rhosts_rsa(struct passwd *, char *, Key *);
103
int      auth_password(Authctxt *, const char *);
103
int      auth_password(Authctxt *, const char *);
104
int	 do_tty_change_password(struct passwd *pw);
104
int      auth_rsa(struct passwd *, BIGNUM *);
105
int      auth_rsa(struct passwd *, BIGNUM *);
105
int      auth_rsa_challenge_dialog(Key *);
106
int      auth_rsa_challenge_dialog(Key *);
106
BIGNUM	*auth_rsa_generate_challenge(Key *);
107
BIGNUM	*auth_rsa_generate_challenge(Key *);
Lines 183-188 Link Here
183
void	 auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
184
void	 auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2)));
184
void	 auth_debug_send(void);
185
void	 auth_debug_send(void);
185
void	 auth_debug_reset(void);
186
void	 auth_debug_reset(void);
187
188
void	password_change_successful_handler(int);
186
189
187
#define AUTH_FAIL_MAX 6
190
#define AUTH_FAIL_MAX 6
188
#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
191
#define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
(-)configure.ac (+7 lines)
Lines 41-46 Link Here
41
	fi
41
	fi
42
fi
42
fi
43
43
44
AC_PATH_PROG(PASSWD_PROGRAM_PATH, passwd)
45
if test ! -z "$PASSWD_PROGRAM_PATH" ; then
46
	AC_DEFINE_UNQUOTED(PASSWD_PROGRAM_PATH, "$PASSWD_PROGRAM_PATH")
47
else
48
	AC_MSG_ERROR([*** passwd command not found - check config.log ***])
49
fi
50
44
if test -z "$LD" ; then
51
if test -z "$LD" ; then
45
	LD=$CC
52
	LD=$CC
46
fi
53
fi
(-)servconf.c (+17 lines)
Lines 123-128 Link Here
123
	options->client_alive_count_max = -1;
123
	options->client_alive_count_max = -1;
124
	options->authorized_keys_file = NULL;
124
	options->authorized_keys_file = NULL;
125
	options->authorized_keys_file2 = NULL;
125
	options->authorized_keys_file2 = NULL;
126
	options->passwd_expire_warn_days = -1;
127
	options->forced_passwd_change = -1;
126
128
127
	/* Needs to be accessable in many places */
129
	/* Needs to be accessable in many places */
128
	use_privsep = -1;
130
	use_privsep = -1;
Lines 255-260 Link Here
255
	}
257
	}
256
	if (options->authorized_keys_file == NULL)
258
	if (options->authorized_keys_file == NULL)
257
		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
259
		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
260
	if (options->passwd_expire_warn_days == -1)
261
		options->passwd_expire_warn_days = 14;
262
	if (options->forced_passwd_change == -1)
263
		options->forced_passwd_change = 1;
258
264
259
	/* Turn privilege separation on by default */
265
	/* Turn privilege separation on by default */
260
	if (use_privsep == -1)
266
	if (use_privsep == -1)
Lines 302-307 Link Here
302
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
308
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
303
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
309
	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
304
	sUsePrivilegeSeparation,
310
	sUsePrivilegeSeparation,
311
	sPasswordExpireWarningDays, sForcedPasswdChange,
305
	sDeprecated
312
	sDeprecated
306
} ServerOpCodes;
313
} ServerOpCodes;
307
314
Lines 380-385 Link Here
380
	{ "authorizedkeysfile", sAuthorizedKeysFile },
387
	{ "authorizedkeysfile", sAuthorizedKeysFile },
381
	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
388
	{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
382
	{ "useprivilegeseparation", sUsePrivilegeSeparation},
389
	{ "useprivilegeseparation", sUsePrivilegeSeparation},
390
	{ "passwordexpirewarningdays", sPasswordExpireWarningDays},
391
	{ "forcedpasswdchange", sForcedPasswdChange},
383
	{ NULL, sBadOption }
392
	{ NULL, sBadOption }
384
};
393
};
385
394
Lines 908-913 Link Here
908
	case sClientAliveCountMax:
917
	case sClientAliveCountMax:
909
		intptr = &options->client_alive_count_max;
918
		intptr = &options->client_alive_count_max;
910
		goto parse_int;
919
		goto parse_int;
920
921
        case sPasswordExpireWarningDays:
922
                intptr = &options->passwd_expire_warn_days;
923
                goto parse_int;
924
925
        case sForcedPasswdChange:
926
                intptr = &options->forced_passwd_change;
927
                goto parse_flag;
911
928
912
	case sDeprecated:
929
	case sDeprecated:
913
		log("%s line %d: Deprecated option %s",
930
		log("%s line %d: Deprecated option %s",
(-)servconf.h (+3 lines)
Lines 132-137 Link Here
132
	char   *authorized_keys_file;	/* File containing public keys */
132
	char   *authorized_keys_file;	/* File containing public keys */
133
	char   *authorized_keys_file2;
133
	char   *authorized_keys_file2;
134
	int	pam_authentication_via_kbd_int;
134
	int	pam_authentication_via_kbd_int;
135
	int	passwd_expire_warn_days;
136
	int	acct_expire_warn_days;
137
	int	forced_passwd_change;
135
}       ServerOptions;
138
}       ServerOptions;
136
139
137
void	 initialize_server_options(ServerOptions *);
140
void	 initialize_server_options(ServerOptions *);
(-)session.c (-12 / +22 lines)
Lines 102-111 Link Here
102
/* data */
102
/* data */
103
#define MAX_SESSIONS 10
103
#define MAX_SESSIONS 10
104
Session	sessions[MAX_SESSIONS];
104
Session	sessions[MAX_SESSIONS];
105
105
Buffer expire_message;	/* "password will expire/has expired" messages */
106
#ifdef WITH_AIXAUTHENTICATE
106
Buffer login_message;	/* message to be displayed after login */
107
char *aixloginmsg;
107
int password_change_required = 0;
108
#endif /* WITH_AIXAUTHENTICATE */
109
108
110
#ifdef HAVE_LOGIN_CAP
109
#ifdef HAVE_LOGIN_CAP
111
login_cap_t *lc;
110
login_cap_t *lc;
Lines 456-465 Link Here
456
#if defined(USE_PAM)
455
#if defined(USE_PAM)
457
	do_pam_session(s->pw->pw_name, NULL);
456
	do_pam_session(s->pw->pw_name, NULL);
458
	do_pam_setcred(1);
457
	do_pam_setcred(1);
459
	if (is_pam_password_change_required())
458
#endif /* USE_PAM */
459
460
	if (password_change_required)
460
		packet_disconnect("Password change required but no "
461
		packet_disconnect("Password change required but no "
461
		    "TTY available");
462
		    "TTY available");
462
#endif /* USE_PAM */
463
463
464
	/* Fork the child. */
464
	/* Fork the child. */
465
	if ((pid = fork()) == 0) {
465
	if ((pid = fork()) == 0) {
Lines 723-728 Link Here
723
	socklen_t fromlen;
723
	socklen_t fromlen;
724
	struct sockaddr_storage from;
724
	struct sockaddr_storage from;
725
	struct passwd * pw = s->pw;
725
	struct passwd * pw = s->pw;
726
	int password_changed = 0;
726
	pid_t pid = getpid();
727
	pid_t pid = getpid();
727
728
728
	/*
729
	/*
Lines 746-761 Link Here
746
		    options.verify_reverse_mapping),
747
		    options.verify_reverse_mapping),
747
		    (struct sockaddr *)&from, fromlen);
748
		    (struct sockaddr *)&from, fromlen);
748
749
749
#ifdef USE_PAM
750
	/*
750
	/*
751
	 * If password change is needed, do it now.
751
	 * If password change is needed, do it now.
752
	 * This needs to occur before the ~/.hushlogin check.
752
	 * This needs to occur before the ~/.hushlogin check.
753
	 */
753
	 */
754
#ifdef USE_PAM
754
	if (is_pam_password_change_required()) {
755
	if (is_pam_password_change_required()) {
755
		print_pam_messages();
756
		print_pam_messages();
756
		do_pam_chauthtok();
757
		if (!use_privsep)
758
			do_pam_chauthtok();
757
	}
759
	}
758
#endif
760
#endif
761
	buffer_append(&expire_message, "\0", 1);
762
	if (options.forced_passwd_change && password_change_required) {
763
		puts((char *)buffer_ptr(&expire_message));
764
		do_tty_change_password(pw);
765
		password_changed = 1;
766
	}
759
767
760
	if (check_quietlogin(s, command))
768
	if (check_quietlogin(s, command))
761
		return;
769
		return;
Lines 764-773 Link Here
764
	if (!is_pam_password_change_required())
772
	if (!is_pam_password_change_required())
765
		print_pam_messages();
773
		print_pam_messages();
766
#endif /* USE_PAM */
774
#endif /* USE_PAM */
767
#ifdef WITH_AIXAUTHENTICATE
775
	if (!password_changed)
768
	if (aixloginmsg && *aixloginmsg)
776
		printf("%s", (char *)buffer_ptr(&expire_message));
769
		printf("%s\n", aixloginmsg);
777
770
#endif /* WITH_AIXAUTHENTICATE */
778
	/* display post-login message */
779
	buffer_append(&login_message, "\0", 1);
780
	puts((char *)buffer_ptr(&login_message));
771
781
772
#ifndef NO_SSH_LASTLOG
782
#ifndef NO_SSH_LASTLOG
773
	if (options.print_lastlog && s->last_login_time != 0) {
783
	if (options.print_lastlog && s->last_login_time != 0) {
(-)sshd_config (+2 lines)
Lines 55-60 Link Here
55
# To disable tunneled clear text passwords, change to no here!
55
# To disable tunneled clear text passwords, change to no here!
56
#PasswordAuthentication yes
56
#PasswordAuthentication yes
57
#PermitEmptyPasswords no
57
#PermitEmptyPasswords no
58
#ForcedPasswdChange yes
59
#PasswordExpireWarningDays 14
58
60
59
# Change to no to disable s/key passwords
61
# Change to no to disable s/key passwords
60
#ChallengeResponseAuthentication yes
62
#ChallengeResponseAuthentication yes
(-)sshd_config.5 (+10 lines)
Lines 206-211 Link Here
206
If the pattern takes the form USER@HOST then USER and HOST
206
If the pattern takes the form USER@HOST then USER and HOST
207
are separately checked, restricting logins to particular
207
are separately checked, restricting logins to particular
208
users from particular hosts.
208
users from particular hosts.
209
.It Cm ForcedPasswdChange
210
Specifies whether or not a password change will be forced when the
211
password is expired.  The default is
212
.Dq yes .
209
.It Cm GatewayPorts
213
.It Cm GatewayPorts
210
Specifies whether remote hosts are allowed to connect to ports
214
Specifies whether remote hosts are allowed to connect to ports
211
forwarded for the client.
215
forwarded for the client.
Lines 431-436 Link Here
431
Specifies whether password authentication is allowed.
435
Specifies whether password authentication is allowed.
432
The default is
436
The default is
433
.Dq yes .
437
.Dq yes .
438
.It Cm PasswordExpireWarningDays
439
If the password will expire in less than the specified number of days, a
440
warning will be printed at login.  Note that on some platforms (eg AIX)
441
this specified by the operating system and this parameter is ignored.
442
The default is
443
.Dq 14 .
434
.It Cm PermitEmptyPasswords
444
.It Cm PermitEmptyPasswords
435
When password authentication is allowed, it specifies whether the
445
When password authentication is allowed, it specifies whether the
436
server allows login to accounts with empty password strings.
446
server allows login to accounts with empty password strings.
(-)openbsd-compat/port-aix.c (-1 / +21 lines)
Lines 52-56 Link Here
52
	xfree(cp);
52
	xfree(cp);
53
}
53
}
54
54
55
#endif /* _AIX */
55
#ifdef WITH_AIXAUTHENTICATE
56
/*
57
 * Remove embedded newlines in string (if any).
58
 * Used before logging messages returned by AIX authentication functions
59
 * so the message is logged on one line.
60
 */
61
void
62
aix_remove_embedded_newlines(char *p)
63
{
64
	if (p == NULL)
65
		return;
66
67
	for (; *p; p++) {
68
		if (*p == '\n')
69
			*p = ' ';
70
	}
71
	/* Remove trailing newline */
72
	*--p = '\0';
73
}
74
#endif /* WITH_AIXAUTHENTICATE */
56
75
76
#endif /* _AIX */
(-)openbsd-compat/port-aix.h (+1 lines)
Lines 26-29 Link Here
26
26
27
#ifdef _AIX
27
#ifdef _AIX
28
void aix_usrinfo(struct passwd *pw);
28
void aix_usrinfo(struct passwd *pw);
29
void aix_remove_embedded_newlines(char *);
29
#endif /* _AIX */
30
#endif /* _AIX */

Return to bug 14