Hi,
Hit by the same problem. I think there are 2 issues at play here.
First, it doesn't make sense that failing to retrieve "ssh_agent_pid"
returns an error, as the agent wasn't started at all. We should return
PAM_SUCCESS, like we do when $HOME/.ssh doesn't exist at session
opening.
So the code I use in pam_ssh.c in function pam_sm_close_session is:
/* retrieve the agent's process id */
- if ((retval = pam_get_data(pamh, "ssh_agent_pid",
+ if ((pam_get_data(pamh, "ssh_agent_pid",
(const void **)(void *)&ssh_agent_pid)) != PAM_SUCCESS) {
openpam_restore_cred(pamh);
- return retval;
+ return PAM_SUCCESS;
}
Secondly, I discovered while debugging the issue that my logs
contained the message "inexistent configuration directory", when I was
performing a su to root, where /root/.ssh existed. So that directory
wasn't detected. The existence test is done in function
pam_sm_open_session with the access() system call, which man page
states:
"The check is done using the calling process's real UID and GID,
rather than the effective IDs as is done when actually attempting an
operation"
And su which is using libpam_ssh is suid... So you can never start an
ssh_agent (it's the main task of the pam_ssh session module) when you
su from an unpriviledged user to root!
Notice that the pam_ssh authentication module is fine, it doesn't use
access().
Here my patch was to use opendir() instead:
openpam_restore_cred(pamh);
return PAM_SERVICE_ERR;
}
- if ((access(dotdir,F_OK)) == -1) {
- pam_ssh_log(LOG_DEBUG, "inexistent configuration directory");
- free(dotdir);
- openpam_restore_cred(pamh);
- return PAM_SUCCESS;
+ {
+ DIR *dirs;
+ if (dirs = opendir(dotdir)) {
+ closedir(dirs);
+ } else {
+ pam_ssh_log(LOG_DEBUG, "inexistent configuration directory");
+ free(dotdir);
+ openpam_restore_cred(pamh);
+ return PAM_SUCCESS;
+ }
}
Regards.
--
Bernard