Question

I would like to authenticate users of my C network application with PAM and I have a found a nice PAM example here on Stack, which I attach at the bottom. The problem is that in my development machine I have a fingerprint reader which PAM is set up to use, as in /etc/pam.d/common-auth:

#%PAM-1.0                                                                                                                                                                                                                        
#                                                                                                                                                                                                                                
# This file is autogenerated by pam-config. All changes                                                                                                                                                                          
# will be overwritten.                                                                                                                                                                                                           
#                                                                                                                                                                                                                                
# Authentication-related modules common to all services                                                                                                                                                                          
#                                                                                                                                                                                                                                
# This file is included from other service-specific PAM config files,                                                                                                                                                            
# and should contain a list of the authentication modules that define                                                                                                                                                            
# the central authentication scheme for use on the system                                                                                                                                                                        
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the                                                                                                                                                           
# traditional Unix authentication mechanisms.                                                                                                                                                                                    
#                                                                                                                                                                                                                                
auth    required    pam_env.so                                                                                                                                                                                                 
auth    sufficient  pam_fprint.so                                                                                                                                                                                             
auth    optional    pam_gnome_keyring.so                                                                                                                                                                                         
auth    required    pam_unix2.so

pam_fprint.so is the fingerprint reader plugin. When you normally log in, the scan can fail and you are prompted for a password. However, sshd daemon does not initiate the fingerprint at all and I would like to understand how it skips it, because for example /etc/pam.d/sshd references the common-auth module so it must pull it ..

#%PAM-1.0
auth     requisite  pam_nologin.so
auth     include        common-auth
account  requisite      pam_nologin.so
account  include        common-account
password include        common-password
session  required   pam_loginuid.so
session  include        common-session
session  optional       pam_lastlog.so   silent noupdate showfailed

I have tried to reference the 'sshd' scheme from the C program but it still initiates the fingerprint reader. I want to skip the fingerprint reader somehow in C and retain my fingerprint reader default config.

    #include <stdlib.h>
    #include <iostream>
    #include <fstream>
    #include <security/pam_appl.h>
    #include <unistd.h>

// To build this:
// g++ test.cpp -lpam -o test

struct pam_response *reply;

//function used to get user input
int function_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
{
  *resp = reply;
  return PAM_SUCCESS;
}

int main(int argc, char** argv)
{
  if(argc != 2) {
      fprintf(stderr, "Usage: check_user <username>\n");
      exit(1);
  }
  const char *username;
  username = argv[1];

  const struct pam_conv local_conversation = { function_conversation, NULL };
  pam_handle_t *local_auth_handle = NULL; // this gets set by pam_start

  int retval;

  // local_auth_handle gets set based on the service
  retval = pam_start("common-auth", username, &local_conversation, &local_auth_handle);

  if (retval != PAM_SUCCESS)
  {
    std::cout << "pam_start returned " << retval << std::endl;
    exit(retval);
  }

  reply = (struct pam_response *)malloc(sizeof(struct pam_response));

  // *** Get the password by any method, or maybe it was passed into this function.
  reply[0].resp = getpass("Password: ");
  reply[0].resp_retcode = 0;

  retval = pam_authenticate(local_auth_handle, 0);

  if (retval != PAM_SUCCESS)
  {
    if (retval == PAM_AUTH_ERR)
    {
      std::cout << "Authentication failure." << std::endl;
    }
    else
    {
      std::cout << "pam_authenticate returned " << retval << std::endl;
    }
    exit(retval);
  }

  std::cout << "Authenticated." << std::endl;

  retval = pam_end(local_auth_handle, retval);

  if (retval != PAM_SUCCESS)
  {
    std::cout << "pam_end returned " << retval << std::endl;
    exit(retval);
  }

  return retval;
}
Was it helpful?

Solution

I doubt that sshd is actually skipping that module. Rather, I suspect that the fingerprint reader authentication module (sensibly) is checking whether the authenticating user appears to be on the local system or is coming over the network (which it can figure out from PAM data like rhost) and just silently does nothing if this is a network authentication. You could try looking at the source code to see if it has such a test, or try setting PAM_RHOST via pam_set_item and see if that changes the behavior.

To answer your actual question, I don't believe there is a way to tell PAM to run a particular PAM group except for one module. The expected way to do what you want to do is to create a new configuration file in /etc/pam.d that matches the application name you pass to pam_start that does not include common-auth but instead contains just the modules that you want to run.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top