Interacting with PAM issues
- Reply: Jesper Schmitz Mouridsen : "Re: Interacting with PAM issues"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 25 Apr 2023 17:26:16 UTC
Hi,
I'm trying to write a custom PAM conversation function and perform
authentication (re-check password) for my already logged in user. Below
is the function:
int pam_conv(int n, const struct pam_message **msg, struct pam_response
**resp, void *data) {
struct pam_response *pr;
int i;
if (n <= 0 || n > PAM_MAX_NUM_MSG) return PAM_CONV_ERR;
if ((pr = calloc(n, sizeof(*pr))) == NULL) return PAM_BUF_ERR;
for (i = 0; i < n; i++) {
pr[i].resp = NULL;
pr[i].resp_retcode = 0;
switch (msg[i]->msg_style) {
case PAM_PROMPT_ECHO_OFF:
case PAM_PROMPT_ECHO_ON:
pr[i].resp = strdup(passwd);
break;
case PAM_ERROR_MSG: /* Do we need this? */
case PAM_TEXT_INFO:
fprintf(stderr, "\n\r%s\n", msg[i]->msg);
break;
default:
/* Clear possible passwords in responces; then free
memory */
for (i = 0; i < n; i++)
if (pr[i].resp) {
memset(pr[i].resp, 0, strlen(pr[i].resp));
free(pr[i].resp);
}
free(pr);
*resp = NULL;
return PAM_CONV_ERR;
}
}
*resp = pr;
return PAM_SUCCESS;
}
And that's how I call it:
int pam_auth(char *user) {
static pam_handle_t *pamh;
static struct pam_conv pamc;
int rval;
char *tty_name;
pamc.conv = &pam_conv;
/* Pretend we want login service */
rval = pam_start("login", user, &pamc, &pamh);
tty_name = ttyname(STDIN_FILENO);
if (rval == PAM_SUCCESS) rval = pam_set_item(pamh, PAM_TTY, tty_name);
if (rval == PAM_SUCCESS) rval = pam_authenticate(pamh, 0);
if (pam_end(pamh, rval) != PAM_SUCCESS) pamh = NULL;
return rval == PAM_SUCCESS ? 0 : 1;
}
Well, PAM login, allows to login as the same user without checking a
password:
# auth
auth sufficient pam_self.so no_warn
auth include system
When trying other services e.g. "system", "ssh", "other"
pam_authenticate() return Authentication error, PAM error 9.
What do I do wrong? Surprisingly, I do not see the same issue on Mac and
Centos.
Best, Mikhail Zakharov