Fwd: Interacting with PAM issues

From: Mikhail Zakharov <zmey20000_at_yahoo.com>
Date: Wed, 26 Apr 2023 06:25:57 UTC
FWD to record the solution in the history of the maillist.

Exactly what is required, for the exact mentioned purpose of a terminal 
screenlocker application: https://github.com/mezantrop/sclocka. Thank 
you again!

Best,
M

On 4/25/2023 9:20 PM, Jesper Schmitz Mouridsen wrote:
> Hi
>
> Yes for pam_unix.so root is always required.
>
> The following gives some background info and might help you
>
> https://github.com/Zirias/unix-selfauth-helper
>
> ported in security/unix-selfauth-helper
>
> On 25.04.2023 20.50, Mikhail Zakharov wrote:
>> Wow! Thanks Jesper, it really works as root!
>>
>> But, I'd like to avoid running as root. The goal is to re-check the 
>> user's password to ensure, this is still the same user working on. I 
>> looked through https://docs.freebsd.org/en/articles/pam/ and 
>> unfortunately didn't see anything appropriate except pam_unix. So, am 
>> I doomed to SUID?
>>
>> Best,
>>
>> M
>>
>> On 4/25/2023 8:12 PM, Jesper Schmitz Mouridsen wrote:
>>> Hi
>>>
>>> If I am not mistaken pam_unix.so requires root so try to run your 
>>> program as root.
>>>
>>> On 25.04.2023 20.05, Mikhail Zakharov wrote:
>>>> No, just a common user, id 1001
>>>>
>>>> On 4/25/2023 8:01 PM, Jesper Schmitz Mouridsen wrote:
>>>>>
>>>>>
>>>>> On 25.04.2023 19.26, Mikhail Zakharov wrote:
>>>>>> 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
>>>>>>
>>>>>>
>>>>> Hi
>>>>> Do you run it as root?
>>>>>
>>>>>