summaryrefslogtreecommitdiff
path: root/auth-pam.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth-pam.c')
-rw-r--r--auth-pam.c63
1 files changed, 46 insertions, 17 deletions
diff --git a/auth-pam.c b/auth-pam.c
index 490990dec..99b03f45b 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -25,10 +25,10 @@
25#include "includes.h" 25#include "includes.h"
26 26
27#ifdef USE_PAM 27#ifdef USE_PAM
28#include "ssh.h"
29#include "xmalloc.h" 28#include "xmalloc.h"
30#include "log.h" 29#include "log.h"
31#include "auth.h" 30#include "auth.h"
31#include "auth-options.h"
32#include "auth-pam.h" 32#include "auth-pam.h"
33#include "servconf.h" 33#include "servconf.h"
34#include "canohost.h" 34#include "canohost.h"
@@ -36,17 +36,21 @@
36 36
37extern char *__progname; 37extern char *__progname;
38 38
39RCSID("$Id: auth-pam.c,v 1.46 2002/05/08 02:27:56 djm Exp $"); 39extern int use_privsep;
40
41RCSID("$Id: auth-pam.c,v 1.54 2002/07/28 20:24:08 stevesk Exp $");
40 42
41#define NEW_AUTHTOK_MSG \ 43#define NEW_AUTHTOK_MSG \
42 "Warning: Your password has expired, please change it now" 44 "Warning: Your password has expired, please change it now."
45#define NEW_AUTHTOK_MSG_PRIVSEP \
46 "Your password has expired, the session cannot proceed."
43 47
44static int do_pam_conversation(int num_msg, const struct pam_message **msg, 48static int do_pam_conversation(int num_msg, const struct pam_message **msg,
45 struct pam_response **resp, void *appdata_ptr); 49 struct pam_response **resp, void *appdata_ptr);
46 50
47/* module-local variables */ 51/* module-local variables */
48static struct pam_conv conv = { 52static struct pam_conv conv = {
49 do_pam_conversation, 53 (int (*)())do_pam_conversation,
50 NULL 54 NULL
51}; 55};
52static char *__pam_msg = NULL; 56static char *__pam_msg = NULL;
@@ -55,7 +59,7 @@ static const char *__pampasswd = NULL;
55 59
56/* states for do_pam_conversation() */ 60/* states for do_pam_conversation() */
57enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN; 61enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN;
58/* remember whether pam_acct_mgmt() returned PAM_NEWAUTHTOK_REQD */ 62/* remember whether pam_acct_mgmt() returned PAM_NEW_AUTHTOK_REQD */
59static int password_change_required = 0; 63static int password_change_required = 0;
60/* remember whether the last pam_authenticate() succeeded or not */ 64/* remember whether the last pam_authenticate() succeeded or not */
61static int was_authenticated = 0; 65static int was_authenticated = 0;
@@ -100,9 +104,7 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
100 char buf[1024]; 104 char buf[1024];
101 105
102 /* PAM will free this later */ 106 /* PAM will free this later */
103 reply = malloc(num_msg * sizeof(*reply)); 107 reply = xmalloc(num_msg * sizeof(*reply));
104 if (reply == NULL)
105 return PAM_CONV_ERR;
106 108
107 for (count = 0; count < num_msg; count++) { 109 for (count = 0; count < num_msg; count++) {
108 if (pamstate == INITIAL_LOGIN) { 110 if (pamstate == INITIAL_LOGIN) {
@@ -112,11 +114,11 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
112 */ 114 */
113 switch(PAM_MSG_MEMBER(msg, count, msg_style)) { 115 switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
114 case PAM_PROMPT_ECHO_ON: 116 case PAM_PROMPT_ECHO_ON:
115 free(reply); 117 xfree(reply);
116 return PAM_CONV_ERR; 118 return PAM_CONV_ERR;
117 case PAM_PROMPT_ECHO_OFF: 119 case PAM_PROMPT_ECHO_OFF:
118 if (__pampasswd == NULL) { 120 if (__pampasswd == NULL) {
119 free(reply); 121 xfree(reply);
120 return PAM_CONV_ERR; 122 return PAM_CONV_ERR;
121 } 123 }
122 reply[count].resp = xstrdup(__pampasswd); 124 reply[count].resp = xstrdup(__pampasswd);
@@ -124,7 +126,7 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
124 break; 126 break;
125 case PAM_ERROR_MSG: 127 case PAM_ERROR_MSG:
126 case PAM_TEXT_INFO: 128 case PAM_TEXT_INFO:
127 if ((*msg)[count].msg != NULL) { 129 if (PAM_MSG_MEMBER(msg, count, msg) != NULL) {
128 message_cat(&__pam_msg, 130 message_cat(&__pam_msg,
129 PAM_MSG_MEMBER(msg, count, msg)); 131 PAM_MSG_MEMBER(msg, count, msg));
130 } 132 }
@@ -132,7 +134,7 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
132 reply[count].resp_retcode = PAM_SUCCESS; 134 reply[count].resp_retcode = PAM_SUCCESS;
133 break; 135 break;
134 default: 136 default:
135 free(reply); 137 xfree(reply);
136 return PAM_CONV_ERR; 138 return PAM_CONV_ERR;
137 } 139 }
138 } else { 140 } else {
@@ -154,14 +156,14 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg,
154 break; 156 break;
155 case PAM_ERROR_MSG: 157 case PAM_ERROR_MSG:
156 case PAM_TEXT_INFO: 158 case PAM_TEXT_INFO:
157 if ((*msg)[count].msg != NULL) 159 if (PAM_MSG_MEMBER(msg, count, msg) != NULL)
158 fprintf(stderr, "%s\n", 160 fprintf(stderr, "%s\n",
159 PAM_MSG_MEMBER(msg, count, msg)); 161 PAM_MSG_MEMBER(msg, count, msg));
160 reply[count].resp = xstrdup(""); 162 reply[count].resp = xstrdup("");
161 reply[count].resp_retcode = PAM_SUCCESS; 163 reply[count].resp_retcode = PAM_SUCCESS;
162 break; 164 break;
163 default: 165 default:
164 free(reply); 166 xfree(reply);
165 return PAM_CONV_ERR; 167 return PAM_CONV_ERR;
166 } 168 }
167 } 169 }
@@ -256,9 +258,14 @@ int do_pam_account(char *username, char *remote_user)
256 break; 258 break;
257#if 0 259#if 0
258 case PAM_NEW_AUTHTOK_REQD: 260 case PAM_NEW_AUTHTOK_REQD:
259 message_cat(&__pam_msg, NEW_AUTHTOK_MSG); 261 message_cat(&__pam_msg, use_privsep ?
262 NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG);
260 /* flag that password change is necessary */ 263 /* flag that password change is necessary */
261 password_change_required = 1; 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;
262 break; 269 break;
263#endif 270#endif
264 default: 271 default:
@@ -328,7 +335,7 @@ int is_pam_password_change_required(void)
328 * Have user change authentication token if pam_acct_mgmt() indicated 335 * Have user change authentication token if pam_acct_mgmt() indicated
329 * it was expired. This needs to be called after an interactive 336 * it was expired. This needs to be called after an interactive
330 * session is established and the user's pty is connected to 337 * session is established and the user's pty is connected to
331 * stdin/stout/stderr. 338 * stdin/stdout/stderr.
332 */ 339 */
333void do_pam_chauthtok(void) 340void do_pam_chauthtok(void)
334{ 341{
@@ -337,11 +344,23 @@ void do_pam_chauthtok(void)
337 do_pam_set_conv(&conv); 344 do_pam_set_conv(&conv);
338 345
339 if (password_change_required) { 346 if (password_change_required) {
347 if (use_privsep)
348 fatal("Password changing is currently unsupported"
349 " with privilege separation");
340 pamstate = OTHER; 350 pamstate = OTHER;
341 pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK); 351 pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
342 if (pam_retval != PAM_SUCCESS) 352 if (pam_retval != PAM_SUCCESS)
343 fatal("PAM pam_chauthtok failed[%d]: %.200s", 353 fatal("PAM pam_chauthtok failed[%d]: %.200s",
344 pam_retval, PAM_STRERROR(__pamh, pam_retval)); 354 pam_retval, PAM_STRERROR(__pamh, pam_retval));
355#if 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
345 } 364 }
346} 365}
347 366
@@ -392,7 +411,7 @@ void start_pam(const char *user)
392 fatal_add_cleanup(&do_pam_cleanup_proc, NULL); 411 fatal_add_cleanup(&do_pam_cleanup_proc, NULL);
393} 412}
394 413
395/* Return list of PAM enviornment strings */ 414/* Return list of PAM environment strings */
396char **fetch_pam_environment(void) 415char **fetch_pam_environment(void)
397{ 416{
398#ifdef HAVE_PAM_GETENVLIST 417#ifdef HAVE_PAM_GETENVLIST
@@ -402,6 +421,16 @@ char **fetch_pam_environment(void)
402#endif /* HAVE_PAM_GETENVLIST */ 421#endif /* HAVE_PAM_GETENVLIST */
403} 422}
404 423
424void free_pam_environment(char **env)
425{
426 int i;
427
428 if (env != NULL) {
429 for (i = 0; env[i] != NULL; i++)
430 xfree(env[i]);
431 }
432}
433
405/* Print any messages that have been generated during authentication */ 434/* Print any messages that have been generated during authentication */
406/* or account checking to stderr */ 435/* or account checking to stderr */
407void print_pam_messages(void) 436void print_pam_messages(void)