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 };