PAM Authentication with program supplied username / password pair.
In cases like "login" and "sudo", the use of PAM involves asking user for password on the terminal. This is a feature provided by the pam-misc library. PAM will require calling program to supply an "conversasion" callback, and pam-misc library provided "misc_conv" to enable this askpass feature. As vsftpd, program could provide customized pam conversasion. Sample code (largly based on vsftpd code snippet so Thanks to VSFTPD)
- int
- pam_conv_func(int nmsg, const struct pam_message** p_msg,
- struct pam_response** p_reply, void* p_addata)
- {
- int i;
- struct pam_response* p_resps = 0;
- (void) p_addata;
- if (nmsg < 0)
- {
- fprintf(stderr, "dodgy nmsg in pam_conv_func");
- }
- p_resps = malloc(sizeof(struct pam_response) * nmsg);
- for (i=0; i<nmsg; i++)
- {
- switch (p_msg[i]->msg_style)
- {
- case PAM_PROMPT_ECHO_OFF:
- p_resps[i].resp_retcode = PAM_SUCCESS;
- p_resps[i].resp = (char*) strdup("PASSWORD_HERE"); // put the program supplied password here.
- break;
- case PAM_TEXT_INFO:
- case PAM_ERROR_MSG:
- p_resps[i].resp_retcode = PAM_SUCCESS;
- p_resps[i].resp = 0;
- break;
- case PAM_PROMPT_ECHO_ON:
- default:
- free(p_resps);
- return PAM_CONV_ERR;
- break;
- }
- }
- *p_reply = p_resps;
- return PAM_SUCCESS;
- }
- static struct pam_conv conv = {
- pam_conv_func,
- //misc_conv,
- NULL
- };
- pam_handle_t *pamh=NULL;
- pam_start(service, username, &conv, &pamh);
- pam_set_item(pamh, PAM_USER, "ryan"); // required in case "username" was NULL when calling pam_start
- retcode = pam_authenticate(pamh, 0); // will call "pam_conv" provided in pam_start. returns PAM_SUCCESS if auth passed.