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

Collapse All | Expand All

(-)auth-pam.c (-2 / +59 lines)
Lines 30-36 Link Here
30
 */
30
 */
31
/*
31
/*
32
 * Copyright (c) 2003,2004 Damien Miller <djm@mindrot.org>
32
 * Copyright (c) 2003,2004 Damien Miller <djm@mindrot.org>
33
 * Copyright (c) 2003,2004 Darren Tucker <dtucker@zip.com.au>
33
 * Copyright (c) 2003,2004,2006 Darren Tucker <dtucker@zip.com.au>
34
 *
34
 *
35
 * Permission to use, copy, modify, and distribute this software for any
35
 * Permission to use, copy, modify, and distribute this software for any
36
 * purpose with or without fee is hereby granted, provided that the above
36
 * purpose with or without fee is hereby granted, provided that the above
Lines 249-254 sshpam_chauthtok_ruid(pam_handle_t *pamh Link Here
249
# define pam_chauthtok(a,b)	(sshpam_chauthtok_ruid((a), (b)))
249
# define pam_chauthtok(a,b)	(sshpam_chauthtok_ruid((a), (b)))
250
#endif
250
#endif
251
251
252
struct passwd *
253
sshpam_getpw(const char *user)
254
{
255
	struct passwd *pw;
256
257
	if ((pw = getpwnam(user)) != NULL)
258
		return(pw);
259
260
	debug("PAM: faking passwd struct for user '%.100s'", user);
261
	if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL)
262
		return NULL;
263
	pw->pw_name = xstrdup(user);	/* XXX leak */
264
	pw->pw_shell = "/bin/true";
265
	pw->pw_gecos = "sshd fake PAM user";
266
	return (pw);
267
}
268
269
void
270
sshpam_check_userchanged(void)
271
{
272
	int sshpam_err;
273
	struct passwd *pw;
274
	const char *user;
275
276
	debug("sshpam_check_userchanged");
277
	sshpam_err = pam_get_item(sshpam_handle, PAM_USER, &user);
278
	if (sshpam_err != PAM_SUCCESS)
279
		fatal("PAM: could not get PAM_USER: %s",
280
		    pam_strerror(sshpam_handle, sshpam_err));
281
	if (strcmp(user, sshpam_authctxt->pw->pw_name) != 0) {
282
		debug("PAM: user mapped from '%.100s' to '%.100s'",
283
		    sshpam_authctxt->pw->pw_name, user);
284
		if ((pw = getpwnam(user)) == NULL)
285
			fatal("PAM: could not get passwd entry for user "
286
			    "'%.100s' provided by PAM_USER", user);
287
		pwfree(sshpam_authctxt->pw);
288
		sshpam_authctxt->pw = pw;
289
		sshpam_authctxt->valid = allowed_user(pw);
290
		debug("PAM: user '%.100s' now %svalid", user,
291
		    sshpam_authctxt->valid ? "" : "in");
292
	}
293
}
294
252
void
295
void
253
sshpam_password_change_required(int reqd)
296
sshpam_password_change_required(int reqd)
254
{
297
{
Lines 271-277 sshpam_password_change_required(int reqd Link Here
271
static void
314
static void
272
import_environments(Buffer *b)
315
import_environments(Buffer *b)
273
{
316
{
274
	char *env;
317
	char *env, *user;
275
	u_int i, num_env;
318
	u_int i, num_env;
276
	int err;
319
	int err;
277
320
Lines 281-286 import_environments(Buffer *b) Link Here
281
	/* Import variables set by do_pam_account */
324
	/* Import variables set by do_pam_account */
282
	sshpam_account_status = buffer_get_int(b);
325
	sshpam_account_status = buffer_get_int(b);
283
	sshpam_password_change_required(buffer_get_int(b));
326
	sshpam_password_change_required(buffer_get_int(b));
327
	user = buffer_get_string(b, NULL);
328
	debug("PAM: got username '%.100s' from thread", user);
329
	if ((err = pam_set_item(sshpam_handle, PAM_USER, user)) != PAM_SUCCESS)
330
		fatal("PAM: failed to set PAM_USER: %s",
331
		    pam_strerror(sshpam_handle, err));
332
	pwfree(sshpam_authctxt->pw);
333
	sshpam_authctxt->pw = pwcopy(sshpam_getpw(user));
284
334
285
	/* Import environment from subprocess */
335
	/* Import environment from subprocess */
286
	num_env = buffer_get_int(b);
336
	num_env = buffer_get_int(b);
Lines 438-443 sshpam_thread(void *ctxtp) Link Here
438
	if (sshpam_err != PAM_SUCCESS)
488
	if (sshpam_err != PAM_SUCCESS)
439
		goto auth_fail;
489
		goto auth_fail;
440
490
491
	sshpam_check_userchanged();
441
	if (compat20) {
492
	if (compat20) {
442
		if (!do_pam_account())
493
		if (!do_pam_account())
443
			goto auth_fail;
494
			goto auth_fail;
Lines 456-461 sshpam_thread(void *ctxtp) Link Here
456
	/* Export variables set by do_pam_account */
507
	/* Export variables set by do_pam_account */
457
	buffer_put_int(&buffer, sshpam_account_status);
508
	buffer_put_int(&buffer, sshpam_account_status);
458
	buffer_put_int(&buffer, sshpam_authctxt->force_pwchange);
509
	buffer_put_int(&buffer, sshpam_authctxt->force_pwchange);
510
	buffer_put_cstring(&buffer, sshpam_authctxt->pw->pw_name);
459
511
460
	/* Export any environment strings set in child */
512
	/* Export any environment strings set in child */
461
	for(i = 0; environ[i] != NULL; i++)
513
	for(i = 0; environ[i] != NULL; i++)
Lines 864-869 do_pam_account(void) Link Here
864
	debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
916
	debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
865
	    pam_strerror(sshpam_handle, sshpam_err));
917
	    pam_strerror(sshpam_handle, sshpam_err));
866
918
919
	sshpam_check_userchanged();
920
	if (getpwnam(sshpam_authctxt->pw->pw_name) == NULL)
921
		fatal("PAM: completed authentication but PAM account invalid");
922
867
	if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
923
	if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
868
		sshpam_account_status = 0;
924
		sshpam_account_status = 0;
869
		return (sshpam_account_status);
925
		return (sshpam_account_status);
Lines 1164-1169 sshpam_auth_passwd(Authctxt *authctxt, c Link Here
1164
		    pam_strerror(sshpam_handle, sshpam_err));
1220
		    pam_strerror(sshpam_handle, sshpam_err));
1165
1221
1166
	sshpam_err = pam_authenticate(sshpam_handle, flags);
1222
	sshpam_err = pam_authenticate(sshpam_handle, flags);
1223
	sshpam_check_userchanged();
1167
	sshpam_password = NULL;
1224
	sshpam_password = NULL;
1168
	if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
1225
	if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
1169
		debug("PAM: password authentication accepted for %.100s",
1226
		debug("PAM: password authentication accepted for %.100s",
(-)auth-pam.h (+2 lines)
Lines 46-50 void sshpam_thread_cleanup(void); Link Here
46
void sshpam_cleanup(void);
46
void sshpam_cleanup(void);
47
int sshpam_auth_passwd(Authctxt *, const char *);
47
int sshpam_auth_passwd(Authctxt *, const char *);
48
int is_pam_session_open(void);
48
int is_pam_session_open(void);
49
void sshpam_invalid_user(void);
50
struct passwd *sshpam_getpw(const char *);
49
51
50
#endif /* USE_PAM */
52
#endif /* USE_PAM */
(-)auth.c (+4 lines)
Lines 493-498 getpwnamallow(const char *user) Link Here
493
	struct passwd *pw;
493
	struct passwd *pw;
494
494
495
	pw = getpwnam(user);
495
	pw = getpwnam(user);
496
#ifdef USE_PAM
497
	if (options.use_pam && pw == NULL)
498
		pw = sshpam_getpw(user);
499
#endif
496
	if (pw == NULL) {
500
	if (pw == NULL) {
497
		logit("Invalid user %.100s from %.100s",
501
		logit("Invalid user %.100s from %.100s",
498
		    user, get_remote_ipaddr());
502
		    user, get_remote_ipaddr());
(-)misc.c (+14 lines)
Lines 177-182 pwcopy(struct passwd *pw) Link Here
177
	return copy;
177
	return copy;
178
}
178
}
179
179
180
void
181
pwfree(struct passwd *pw)
182
{
183
	xfree(pw->pw_name);
184
	xfree(pw->pw_passwd);
185
	xfree(pw->pw_gecos);
186
#ifdef HAVE_PW_CLASS_IN_PASSWD
187
	xfree(pw->pw_class);
188
#endif
189
	xfree(pw->pw_dir);
190
	xfree(pw->pw_shell);
191
	xfree(pw);
192
}
193
180
/*
194
/*
181
 * Convert ASCII string to TCP/IP port number.
195
 * Convert ASCII string to TCP/IP port number.
182
 * Port must be >0 and <=65535.
196
 * Port must be >0 and <=65535.
(-)misc.h (+1 lines)
Lines 31-36 char *tohex(const u_char *, u_int); Link Here
31
void	 sanitise_stdfd(void);
31
void	 sanitise_stdfd(void);
32
32
33
struct passwd *pwcopy(struct passwd *);
33
struct passwd *pwcopy(struct passwd *);
34
void	 pwfree(struct passwd *);
34
35
35
typedef struct arglist arglist;
36
typedef struct arglist arglist;
36
struct arglist {
37
struct arglist {

Return to bug 1215