blob: 153dbc74fc0ee6671e92439bfc9a956ee287c6d5 [file] [log] [blame]
Ed Tanousf3d847c2017-06-12 16:01:42 -07001#include <security/pam_appl.h>
2
3// function used to get user input
4inline 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
26class 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};