Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum porta, diam at accumsan mollis, purus felis varius nibh, at bibendum nulla nisl eu libero. Aliquam erat volutpat. Quisque orci felis, pharetra vel, feugiat ut, eleifend vitae, sem. Nam adipiscing blandit tortor. Nulla dignissim tincidunt leo. Nulla scelerisque fermentum ipsum. Nunc at metus. In ac pede. Donec elit libero, vestibulum id, malesuada sed, cursus vitae, ligula. Praesent consequat, urna ut laoreet convallis, libero velit convallis quam, rhoncus cursus orci ipsum id mi. Quisque malesuada semper nunc. Nulla porttitor justo ut lacus. Fusce blandit tellus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas faucibus, quam at tristique facilisis, metus magna interdum arcu, vitae lobortis dui mauris ac risus.
Fusce quam. Aenean bibendum adipiscing metus. Etiam in felis. Vivamus sit amet erat eget velit bibendum sollicitudin. Donec molestie purus ac nibh. Ut dignissim, ligula id rhoncus consectetur, leo turpis dapibus tortor, nec hendrerit turpis velit a neque. Cras eu metus. Nullam sodales, tortor a molestie posuere, pede eros dictum lectus, nec sollicitudin lorem diam et velit. Maecenas dictum neque eget purus. Curabitur ac justo et odio congue euismod. Duis vitae felis ut nunc ultrices adipiscing. Vestibulum at tellus. Nunc in purus eget libero commodo posuere.
Coming soon: A Whole New Set of Tubes.
#include <stdio.h>
/* For getpass */
#include <unistd.h>
/* for malloc */
#include <stdlib.h>
/* For strdup */
#include <string.h>
#include <security/pam_appl.h>
int interact (int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr) {
struct pam_message *m = (struct pam_message*)*msg;
struct pam_response *r = (struct pam_response *)calloc(num_msg,sizeof(struct pam_response));
char *buf = (char *)calloc(1,PAM_MAX_RESP_SIZE);
*resp = r;
while (num_msg--) {
switch(m->msg_style) {
case PAM_PROMPT_ECHO_ON:
printf("%s",m->msg);
fgets(buf,PAM_MAX_RESP_SIZE-1,stdin);
r->resp = (char *)strndup(buf,PAM_MAX_RESP_SIZE-1);
m++;r++;
break;
case PAM_PROMPT_ECHO_OFF:
r->resp = (char *)strndup(getpass(m->msg),PAM_MAX_RESP_SIZE-1);
m++;r++;
break;
case PAM_ERROR_MSG:
printf("Error: ");
case PAM_TEXT_INFO:
printf("%s\n",m->msg);
m++;r++;
break;
default:
break;
}
}
free(buf);
return PAM_SUCCESS;
}
int main (int argc, char **argv) {
char *service = "system-auth";
char *user = argv[1];
int rval;
struct pam_conv callback;
pam_handle_t *hnd;
callback.conv = interact;
if (argc != 2) {
printf("Please provide a username, and no other arguments.\n");
return(1);
}
rval = pam_start(service,user,&callback,&hnd);
if(rval == PAM_SUCCESS) {
rval = pam_authenticate(hnd,0);
} else {
printf("%d: %s\n",rval,pam_strerror(hnd,rval));
}
if(rval == PAM_SUCCESS) {
rval = pam_acct_mgmt(hnd,0);
} else {
printf("%d: %s\n",rval,pam_strerror(hnd,rval));
}
/* It's a possible problem that PAM depends on the application to
report auth failures. */
if(rval == PAM_SUCCESS) {
printf("Success.\n");
pam_end(hnd,PAM_SUCCESS);
return(0);
} else {
printf("Failure: %s\n",pam_strerror(hnd,rval));
pam_end(hnd,PAM_AUTH_ERR);
return(1);
}
}