Interacting with PAM issues

From: Mikhail Zakharov <zmey20000_at_yahoo.com>
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