|
Lines 33-49
Link Here
|
| 33 |
#include "servconf.h" |
33 |
#include "servconf.h" |
| 34 |
#include "canohost.h" |
34 |
#include "canohost.h" |
| 35 |
#include "readpass.h" |
35 |
#include "readpass.h" |
|
|
36 |
#include "channels.h" |
| 37 |
#include "misc.h" |
| 36 |
|
38 |
|
| 37 |
extern char *__progname; |
39 |
extern char *__progname; |
| 38 |
|
40 |
|
| 39 |
extern int use_privsep; |
41 |
extern int use_privsep; |
|
|
42 |
extern ServerOptions options; |
| 40 |
|
43 |
|
| 41 |
RCSID("$Id: auth-pam.c,v 1.54 2002/07/28 20:24:08 stevesk Exp $"); |
44 |
RCSID("$Id: auth-pam.c,v 1.54 2002/07/28 20:24:08 stevesk Exp $"); |
| 42 |
|
45 |
|
| 43 |
#define NEW_AUTHTOK_MSG \ |
46 |
#define NEW_AUTHTOK_MSG \ |
| 44 |
"Warning: Your password has expired, please change it now." |
47 |
"Warning: Your password has expired, please change it now." |
| 45 |
#define NEW_AUTHTOK_MSG_PRIVSEP \ |
|
|
| 46 |
"Your password has expired, the session cannot proceed." |
| 47 |
|
48 |
|
| 48 |
static int do_pam_conversation(int num_msg, const struct pam_message **msg, |
49 |
static int do_pam_conversation(int num_msg, const struct pam_message **msg, |
| 49 |
struct pam_response **resp, void *appdata_ptr); |
50 |
struct pam_response **resp, void *appdata_ptr); |
|
Lines 204-210
Link Here
|
| 204 |
/* Attempt password authentation using PAM */ |
205 |
/* Attempt password authentation using PAM */ |
| 205 |
int auth_pam_password(Authctxt *authctxt, const char *password) |
206 |
int auth_pam_password(Authctxt *authctxt, const char *password) |
| 206 |
{ |
207 |
{ |
| 207 |
extern ServerOptions options; |
|
|
| 208 |
int pam_retval; |
208 |
int pam_retval; |
| 209 |
struct passwd *pw = authctxt->pw; |
209 |
struct passwd *pw = authctxt->pw; |
| 210 |
|
210 |
|
|
Lines 256-273
Link Here
|
| 256 |
case PAM_SUCCESS: |
256 |
case PAM_SUCCESS: |
| 257 |
/* This is what we want */ |
257 |
/* This is what we want */ |
| 258 |
break; |
258 |
break; |
| 259 |
#if 0 |
|
|
| 260 |
case PAM_NEW_AUTHTOK_REQD: |
259 |
case PAM_NEW_AUTHTOK_REQD: |
| 261 |
message_cat(&__pam_msg, use_privsep ? |
260 |
message_cat(&__pam_msg, NEW_AUTHTOK_MSG); |
| 262 |
NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG); |
|
|
| 263 |
/* flag that password change is necessary */ |
261 |
/* flag that password change is necessary */ |
| 264 |
password_change_required = 1; |
262 |
password_change_required = 1; |
| 265 |
/* disallow other functionality for now */ |
263 |
/* disallow other functionality for now */ |
| 266 |
no_port_forwarding_flag |= 2; |
264 |
no_port_forwarding_flag |= 2; |
| 267 |
no_agent_forwarding_flag |= 2; |
265 |
no_agent_forwarding_flag |= 2; |
| 268 |
no_x11_forwarding_flag |= 2; |
266 |
no_x11_forwarding_flag |= 2; |
|
|
267 |
/* set signal handler to restore flags */ |
| 268 |
mysignal(SIGUSR1, password_change_successful_handler); |
| 269 |
break; |
269 |
break; |
| 270 |
#endif |
|
|
| 271 |
default: |
270 |
default: |
| 272 |
log("PAM rejected by account configuration[%d]: " |
271 |
log("PAM rejected by account configuration[%d]: " |
| 273 |
"%.200s", pam_retval, PAM_STRERROR(__pamh, |
272 |
"%.200s", pam_retval, PAM_STRERROR(__pamh, |
|
Lines 344-369
Link Here
|
| 344 |
do_pam_set_conv(&conv); |
343 |
do_pam_set_conv(&conv); |
| 345 |
|
344 |
|
| 346 |
if (password_change_required) { |
345 |
if (password_change_required) { |
| 347 |
if (use_privsep) |
|
|
| 348 |
fatal("Password changing is currently unsupported" |
| 349 |
" with privilege separation"); |
| 350 |
pamstate = OTHER; |
346 |
pamstate = OTHER; |
| 351 |
pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK); |
347 |
pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK); |
| 352 |
if (pam_retval != PAM_SUCCESS) |
348 |
if (pam_retval != PAM_SUCCESS) |
| 353 |
fatal("PAM pam_chauthtok failed[%d]: %.200s", |
349 |
fatal("PAM pam_chauthtok failed[%d]: %.200s", |
| 354 |
pam_retval, PAM_STRERROR(__pamh, pam_retval)); |
350 |
pam_retval, PAM_STRERROR(__pamh, pam_retval)); |
| 355 |
#if 0 |
351 |
password_change_required = 0; |
| 356 |
/* XXX: This would need to be done in the parent process, |
|
|
| 357 |
* but there's currently no way to pass such request. */ |
| 358 |
no_port_forwarding_flag &= ~2; |
| 359 |
no_agent_forwarding_flag &= ~2; |
| 360 |
no_x11_forwarding_flag &= ~2; |
| 361 |
if (!no_port_forwarding_flag && options.allow_tcp_forwarding) |
| 362 |
channel_permit_all_opens(); |
| 363 |
#endif |
| 364 |
} |
352 |
} |
| 365 |
} |
353 |
} |
| 366 |
|
354 |
|
|
|
355 |
/* |
| 356 |
* Because do_pam_chauthtok is called after forking to exec the user's |
| 357 |
* shell, restoring the port forwarding flags is done by sending a |
| 358 |
* USR1 signal after the password is changed successfully. |
| 359 |
*/ |
| 360 |
void password_change_successful_handler(int sig) |
| 361 |
{ |
| 362 |
debug("%s: restoring port forwarding flags", __func__); |
| 363 |
mysignal(SIGUSR1, SIG_DFL); /* unset handler */ |
| 364 |
password_change_required = 0; |
| 365 |
no_port_forwarding_flag &= ~2; |
| 366 |
no_agent_forwarding_flag &= ~2; |
| 367 |
no_x11_forwarding_flag &= ~2; |
| 368 |
if (!no_port_forwarding_flag && options.allow_tcp_forwarding) |
| 369 |
channel_permit_all_opens(); |
| 370 |
} |
| 371 |
|
| 367 |
/* Cleanly shutdown PAM */ |
372 |
/* Cleanly shutdown PAM */ |
| 368 |
void finish_pam(void) |
373 |
void finish_pam(void) |
| 369 |
{ |
374 |
{ |
|
Lines 375-381
Link Here
|
| 375 |
void start_pam(const char *user) |
380 |
void start_pam(const char *user) |
| 376 |
{ |
381 |
{ |
| 377 |
int pam_retval; |
382 |
int pam_retval; |
| 378 |
extern ServerOptions options; |
|
|
| 379 |
extern u_int utmp_len; |
383 |
extern u_int utmp_len; |
| 380 |
const char *rhost; |
384 |
const char *rhost; |
| 381 |
|
385 |
|