xref: /openbmc/bmcweb/include/pam_authenticate.hpp (revision f3d847c9b91319220266695c726fdacbd1a860e8)
1  #include <security/pam_appl.h>
2  
3  // function used to get user input
4  inline int pam_function_conversation(int num_msg,
5                                       const struct pam_message** msg,
6                                       struct pam_response** resp,
7                                       void* appdata_ptr) {
8    char* pass = (char*)malloc(strlen((char*)appdata_ptr) + 1);
9    strcpy(pass, (char*)appdata_ptr);
10  
11    int i;
12  
13    *resp = (pam_response*)calloc(num_msg, sizeof(struct pam_response));
14  
15    for (i = 0; i < num_msg; ++i) {
16      /* Ignore all PAM messages except prompting for hidden input */
17      if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF) continue;
18  
19      /* Assume PAM is only prompting for the password as hidden input */
20      resp[i]->resp = pass;
21    }
22  
23    return PAM_SUCCESS;
24  }
25  
26  class PamAuthenticator {
27   public:
28    inline bool authenticate(const std::string& username,
29                             const std::string& password) {
30      const struct pam_conv local_conversation = {pam_function_conversation,
31                                                  (char*)password.c_str()};
32      pam_handle_t* local_auth_handle = NULL;  // this gets set by pam_start
33  
34      int retval;
35      retval = pam_start("su", username.c_str(), &local_conversation,
36                         &local_auth_handle);
37  
38      if (retval != PAM_SUCCESS) {
39        //printf("pam_start returned: %d\n ", retval);
40        return false;
41      }
42  
43      retval = pam_authenticate(local_auth_handle,
44                                PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
45  
46      if (retval != PAM_SUCCESS) {
47        if (retval == PAM_AUTH_ERR) {
48          //printf("Authentication failure.\n");
49        } else {
50          //printf("pam_authenticate returned %d\n", retval);
51        }
52        return false;
53      }
54  
55      //printf("Authenticated.\n");
56      retval = pam_end(local_auth_handle, retval);
57  
58      if (retval != PAM_SUCCESS) {
59        //printf("pam_end returned\n");
60        return false;
61      }
62  
63      return true;
64    }
65  };