|
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 205-210
static int sshpam_authenticated = 0;
Link Here
|
| 205 |
static int sshpam_session_open = 0; |
205 |
static int sshpam_session_open = 0; |
| 206 |
static int sshpam_cred_established = 0; |
206 |
static int sshpam_cred_established = 0; |
| 207 |
static int sshpam_account_status = -1; |
207 |
static int sshpam_account_status = -1; |
|
|
208 |
static int sshpam_faked_user = 0; |
| 208 |
static char **sshpam_env = NULL; |
209 |
static char **sshpam_env = NULL; |
| 209 |
static Authctxt *sshpam_authctxt = NULL; |
210 |
static Authctxt *sshpam_authctxt = NULL; |
| 210 |
static const char *sshpam_password = NULL; |
211 |
static const char *sshpam_password = NULL; |
|
Lines 249-254
sshpam_chauthtok_ruid(pam_handle_t *pamh
Link Here
|
| 249 |
# define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) |
250 |
# define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) |
| 250 |
#endif |
251 |
#endif |
| 251 |
|
252 |
|
|
|
253 |
struct passwd * |
| 254 |
sshpam_getpw(const char *user) |
| 255 |
{ |
| 256 |
struct passwd *pw; |
| 257 |
|
| 258 |
if ((pw = getpwnam(user)) != NULL) |
| 259 |
return(pw); |
| 260 |
|
| 261 |
debug("PAM: faking passwd struct for user '%.100s'", user); |
| 262 |
sshpam_faked_user = 1; |
| 263 |
if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) |
| 264 |
return NULL; |
| 265 |
pw->pw_name = xstrdup(user); /* XXX leak */ |
| 266 |
pw->pw_shell = "/bin/true"; |
| 267 |
pw->pw_gecos = "sshd fake PAM user"; |
| 268 |
return (pw); |
| 269 |
} |
| 270 |
|
| 271 |
void |
| 272 |
sshpam_check_userchanged(void) |
| 273 |
{ |
| 274 |
int sshpam_err; |
| 275 |
struct passwd *pw; |
| 276 |
const char *user; |
| 277 |
|
| 278 |
debug("sshpam_check_userchanged"); |
| 279 |
sshpam_err = pam_get_item(sshpam_handle, PAM_USER, &user); |
| 280 |
if (sshpam_err != PAM_SUCCESS) |
| 281 |
fatal("PAM: could not get PAM_USER: %s", |
| 282 |
pam_strerror(sshpam_handle, sshpam_err)); |
| 283 |
if (strcmp(user, sshpam_authctxt->pw->pw_name) != 0) { |
| 284 |
debug("PAM: user mapped from '%.100s' to '%.100s'", |
| 285 |
sshpam_authctxt->pw->pw_name, user); |
| 286 |
if ((pw = getpwnam(user)) == NULL) |
| 287 |
fatal("PAM: could not get passwd entry for user " |
| 288 |
"'%.100s' provided by PAM_USER", user); |
| 289 |
sshpam_authctxt->pw = pw; /* XXX leak */ |
| 290 |
sshpam_authctxt->valid = allowed_user(pw); |
| 291 |
sshpam_faked_user = 0; |
| 292 |
debug("PAM: user '%.100s' now %svalid", user, |
| 293 |
sshpam_authctxt->valid ? "" : "in"); |
| 294 |
} |
| 295 |
} |
| 296 |
|
| 252 |
void |
297 |
void |
| 253 |
sshpam_password_change_required(int reqd) |
298 |
sshpam_password_change_required(int reqd) |
| 254 |
{ |
299 |
{ |
|
Lines 271-277
sshpam_password_change_required(int reqd
Link Here
|
| 271 |
static void |
316 |
static void |
| 272 |
import_environments(Buffer *b) |
317 |
import_environments(Buffer *b) |
| 273 |
{ |
318 |
{ |
| 274 |
char *env; |
319 |
char *env, *user; |
| 275 |
u_int i, num_env; |
320 |
u_int i, num_env; |
| 276 |
int err; |
321 |
int err; |
| 277 |
|
322 |
|
|
Lines 281-286
import_environments(Buffer *b)
Link Here
|
| 281 |
/* Import variables set by do_pam_account */ |
326 |
/* Import variables set by do_pam_account */ |
| 282 |
sshpam_account_status = buffer_get_int(b); |
327 |
sshpam_account_status = buffer_get_int(b); |
| 283 |
sshpam_password_change_required(buffer_get_int(b)); |
328 |
sshpam_password_change_required(buffer_get_int(b)); |
|
|
329 |
user = buffer_get_string(b, NULL); |
| 330 |
debug("PAM: got username '%.100s' from thread", user); |
| 331 |
if ((err = pam_set_item(sshpam_handle, PAM_USER, user)) != PAM_SUCCESS) |
| 332 |
fatal("PAM: failed to set PAM_USER: %s", |
| 333 |
pam_strerror(sshpam_handle, err)); |
| 334 |
sshpam_authctxt-> pw = sshpam_getpw(user); |
| 284 |
|
335 |
|
| 285 |
/* Import environment from subprocess */ |
336 |
/* Import environment from subprocess */ |
| 286 |
num_env = buffer_get_int(b); |
337 |
num_env = buffer_get_int(b); |
|
Lines 438-443
sshpam_thread(void *ctxtp)
Link Here
|
| 438 |
if (sshpam_err != PAM_SUCCESS) |
489 |
if (sshpam_err != PAM_SUCCESS) |
| 439 |
goto auth_fail; |
490 |
goto auth_fail; |
| 440 |
|
491 |
|
|
|
492 |
sshpam_check_userchanged(); |
| 441 |
if (compat20) { |
493 |
if (compat20) { |
| 442 |
if (!do_pam_account()) |
494 |
if (!do_pam_account()) |
| 443 |
goto auth_fail; |
495 |
goto auth_fail; |
|
Lines 456-461
sshpam_thread(void *ctxtp)
Link Here
|
| 456 |
/* Export variables set by do_pam_account */ |
508 |
/* Export variables set by do_pam_account */ |
| 457 |
buffer_put_int(&buffer, sshpam_account_status); |
509 |
buffer_put_int(&buffer, sshpam_account_status); |
| 458 |
buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); |
510 |
buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); |
|
|
511 |
buffer_put_cstring(&buffer, sshpam_authctxt->pw->pw_name); |
| 459 |
|
512 |
|
| 460 |
/* Export any environment strings set in child */ |
513 |
/* Export any environment strings set in child */ |
| 461 |
for(i = 0; environ[i] != NULL; i++) |
514 |
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, |
917 |
debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, |
| 865 |
pam_strerror(sshpam_handle, sshpam_err)); |
918 |
pam_strerror(sshpam_handle, sshpam_err)); |
| 866 |
|
919 |
|
|
|
920 |
sshpam_check_userchanged(); |
| 921 |
if (sshpam_faked_user) |
| 922 |
fatal("PAM: completed authentication but PAM account invalid"); |
| 923 |
|
| 867 |
if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { |
924 |
if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { |
| 868 |
sshpam_account_status = 0; |
925 |
sshpam_account_status = 0; |
| 869 |
return (sshpam_account_status); |
926 |
return (sshpam_account_status); |
|
Lines 1164-1169
sshpam_auth_passwd(Authctxt *authctxt, c
Link Here
|
| 1164 |
pam_strerror(sshpam_handle, sshpam_err)); |
1221 |
pam_strerror(sshpam_handle, sshpam_err)); |
| 1165 |
|
1222 |
|
| 1166 |
sshpam_err = pam_authenticate(sshpam_handle, flags); |
1223 |
sshpam_err = pam_authenticate(sshpam_handle, flags); |
|
|
1224 |
sshpam_check_userchanged(); |
| 1167 |
sshpam_password = NULL; |
1225 |
sshpam_password = NULL; |
| 1168 |
if (sshpam_err == PAM_SUCCESS && authctxt->valid) { |
1226 |
if (sshpam_err == PAM_SUCCESS && authctxt->valid) { |
| 1169 |
debug("PAM: password authentication accepted for %.100s", |
1227 |
debug("PAM: password authentication accepted for %.100s", |