|
Lines 117-122
Link Here
|
| 117 |
static int sshpam_new_authtok_reqd = 0; |
117 |
static int sshpam_new_authtok_reqd = 0; |
| 118 |
static int sshpam_session_open = 0; |
118 |
static int sshpam_session_open = 0; |
| 119 |
static int sshpam_cred_established = 0; |
119 |
static int sshpam_cred_established = 0; |
|
|
120 |
static char **sshpam_env = NULL; |
| 120 |
|
121 |
|
| 121 |
struct pam_ctxt { |
122 |
struct pam_ctxt { |
| 122 |
sp_pthread_t pam_thread; |
123 |
sp_pthread_t pam_thread; |
|
Lines 127-132
Link Here
|
| 127 |
|
128 |
|
| 128 |
static void sshpam_free_ctx(void *); |
129 |
static void sshpam_free_ctx(void *); |
| 129 |
|
130 |
|
|
|
131 |
/* Some PAM implementations don't implement this */ |
| 132 |
#ifndef HAVE_PAM_GETENVLIST |
| 133 |
static char ** |
| 134 |
pam_getenvlist(pam_handle_t *pamh) |
| 135 |
{ |
| 136 |
/* |
| 137 |
* XXX - If necessary, we can still support envrionment passing |
| 138 |
* for platforms without pam_getenvlist by searching for known |
| 139 |
* env vars (e.g. KRB5CCNAME) from the PAM environment. |
| 140 |
*/ |
| 141 |
return NULL; |
| 142 |
} |
| 143 |
#endif |
| 144 |
|
| 145 |
/* Import regular and PAM environment from subprocess */ |
| 146 |
static void |
| 147 |
import_environments(Buffer *b) |
| 148 |
{ |
| 149 |
char *env; |
| 150 |
u_int i, num_env; |
| 151 |
int err; |
| 152 |
|
| 153 |
/* Import environment from subprocess */ |
| 154 |
num_env = buffer_get_int(b); |
| 155 |
sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env)); |
| 156 |
debug("XXX PAM: num env strings %d", num_env); |
| 157 |
for(i = 0; i < num_env; i++) { |
| 158 |
sshpam_env[i] = buffer_get_string(b, NULL); |
| 159 |
debug("XXX PAM: env %d: %s", i, sshpam_env[i]); |
| 160 |
} |
| 161 |
sshpam_env[num_env] = NULL; |
| 162 |
|
| 163 |
/* Import PAM environment from subprocess */ |
| 164 |
num_env = buffer_get_int(b); |
| 165 |
debug("XXX PAM: num PAM env strings %d", num_env); |
| 166 |
for(i = 0; i < num_env; i++) { |
| 167 |
env = buffer_get_string(b, NULL); |
| 168 |
debug("XXX PAM: PAM env %d: %s", i, env); |
| 169 |
|
| 170 |
/* Errors are not fatal here */ |
| 171 |
if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) { |
| 172 |
error("PAM: pam_putenv: %s", |
| 173 |
pam_strerror(sshpam_handle, sshpam_err)); |
| 174 |
} |
| 175 |
} |
| 176 |
} |
| 177 |
|
| 130 |
/* |
178 |
/* |
| 131 |
* Conversation function for authentication thread. |
179 |
* Conversation function for authentication thread. |
| 132 |
*/ |
180 |
*/ |
|
Lines 213-222
Link Here
|
| 213 |
Buffer buffer; |
261 |
Buffer buffer; |
| 214 |
struct pam_conv sshpam_conv; |
262 |
struct pam_conv sshpam_conv; |
| 215 |
#ifndef USE_POSIX_THREADS |
263 |
#ifndef USE_POSIX_THREADS |
|
|
264 |
extern char **environ; |
| 265 |
char **env_from_pam; |
| 266 |
u_int i; |
| 216 |
const char *pam_user; |
267 |
const char *pam_user; |
| 217 |
|
268 |
|
| 218 |
pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user); |
269 |
pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user); |
| 219 |
setproctitle("%s [pam]", pam_user); |
270 |
setproctitle("%s [pam]", pam_user); |
|
|
271 |
environ[0] = NULL; |
| 220 |
#endif |
272 |
#endif |
| 221 |
|
273 |
|
| 222 |
sshpam_conv.conv = sshpam_thread_conv; |
274 |
sshpam_conv.conv = sshpam_thread_conv; |
|
Lines 231-236
Link Here
|
| 231 |
if (sshpam_err != PAM_SUCCESS) |
283 |
if (sshpam_err != PAM_SUCCESS) |
| 232 |
goto auth_fail; |
284 |
goto auth_fail; |
| 233 |
buffer_put_cstring(&buffer, "OK"); |
285 |
buffer_put_cstring(&buffer, "OK"); |
|
|
286 |
|
| 287 |
#ifndef USE_POSIX_THREADS |
| 288 |
/* Export any environment strings set in child */ |
| 289 |
for(i = 0; environ[i] != NULL; i++) |
| 290 |
; /* Count */ |
| 291 |
buffer_put_int(&buffer, i); |
| 292 |
for(i = 0; environ[i] != NULL; i++) |
| 293 |
buffer_put_cstring(&buffer, environ[i]); |
| 294 |
|
| 295 |
/* Export any environment strings set by PAM in child */ |
| 296 |
env_from_pam = pam_getenvlist(sshpam_handle); |
| 297 |
for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) |
| 298 |
; /* Count */ |
| 299 |
buffer_put_int(&buffer, i); |
| 300 |
for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) |
| 301 |
buffer_put_cstring(&buffer, env_from_pam[i]); |
| 302 |
#endif /* USE_POSIX_THREADS */ |
| 303 |
|
| 234 |
ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); |
304 |
ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); |
| 235 |
buffer_free(&buffer); |
305 |
buffer_free(&buffer); |
| 236 |
pthread_exit(NULL); |
306 |
pthread_exit(NULL); |
|
Lines 430-435
Link Here
|
| 430 |
**prompts = NULL; |
500 |
**prompts = NULL; |
| 431 |
} |
501 |
} |
| 432 |
if (type == PAM_SUCCESS) { |
502 |
if (type == PAM_SUCCESS) { |
|
|
503 |
import_environments(&buffer); |
| 433 |
*num = 0; |
504 |
*num = 0; |
| 434 |
**echo_on = 0; |
505 |
**echo_on = 0; |
| 435 |
ctxt->pam_done = 1; |
506 |
ctxt->pam_done = 1; |
|
Lines 692-698
Link Here
|
| 692 |
* modules can handle things like Kerberos/GSI credentials that appear |
763 |
* modules can handle things like Kerberos/GSI credentials that appear |
| 693 |
* during the ssh authentication process. |
764 |
* during the ssh authentication process. |
| 694 |
*/ |
765 |
*/ |
| 695 |
|
|
|
| 696 |
int |
766 |
int |
| 697 |
do_pam_putenv(char *name, char *value) |
767 |
do_pam_putenv(char *name, char *value) |
| 698 |
{ |
768 |
{ |
|
Lines 719-732
Link Here
|
| 719 |
} |
789 |
} |
| 720 |
|
790 |
|
| 721 |
char ** |
791 |
char ** |
|
|
792 |
fetch_pam_child_environment(void) |
| 793 |
{ |
| 794 |
return sshpam_env; |
| 795 |
} |
| 796 |
|
| 797 |
char ** |
| 722 |
fetch_pam_environment(void) |
798 |
fetch_pam_environment(void) |
| 723 |
{ |
799 |
{ |
| 724 |
#ifdef HAVE_PAM_GETENVLIST |
|
|
| 725 |
debug("PAM: retrieving environment"); |
| 726 |
return (pam_getenvlist(sshpam_handle)); |
800 |
return (pam_getenvlist(sshpam_handle)); |
| 727 |
#else |
|
|
| 728 |
return (NULL); |
| 729 |
#endif |
| 730 |
} |
801 |
} |
| 731 |
|
802 |
|
| 732 |
void |
803 |
void |