#include #include #include #include #include static int converse(int n, const struct pam_message **msg, struct pam_response **resp, void *data) { struct pam_response *aresp; char buf[PAM_MAX_RESP_SIZE]; int i; if (n <= 0 || n > PAM_MAX_NUM_MSG) return (PAM_CONV_ERR); if ((aresp = calloc(n, sizeof *aresp)) == NULL) return (PAM_BUF_ERR); for (i = 0; i < n; ++i) { aresp[i].resp_retcode = 0; aresp[i].resp = NULL; switch (msg[i]->msg_style) { case PAM_PROMPT_ECHO_OFF: aresp[i].resp = strdup("root"); // getpass(msg[i]->msg)); if (aresp[i].resp == NULL) goto fail; break; case PAM_PROMPT_ECHO_ON: fputs(msg[i]->msg, stderr); if (fgets(buf, sizeof buf, stdin) == NULL) goto fail; aresp[i].resp = strdup(buf); if (aresp[i].resp == NULL) goto fail; break; case PAM_ERROR_MSG: fputs(msg[i]->msg, stderr); if (strlen(msg[i]->msg) > 0 && msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n') fputc('\n', stdout); break; case PAM_TEXT_INFO: fputs(msg[i]->msg, stdout); if (strlen(msg[i]->msg) > 0 && msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n') fputc('\n', stdout); break; default: goto fail; } } *resp = aresp; return (PAM_SUCCESS); fail: for (i = 0; i < n; ++i) { if (aresp[i].resp != NULL) { memset(aresp[i].resp, 0, strlen(aresp[i].resp)); free(aresp[i].resp); } } memset(aresp, 0, n * sizeof *aresp); *resp = NULL; return (PAM_CONV_ERR); } int main() { pam_handle_t *pamh; struct pam_conv pamc; pamc.conv = converse; int rc = pam_start("pamapp", "admin", &pamc, &pamh); if (rc != PAM_SUCCESS) { printf("Failed to init PAM (%s)\n", pam_strerror(pamh, rc)); return EXIT_FAILURE; } char buff[256]; gethostname(buff, sizeof(buff)); rc = pam_set_item(pamh, PAM_RUSER, "admin"); rc = pam_set_item(pamh, PAM_RHOST, strdup(buff)); if (rc != PAM_SUCCESS) printf("Failed to set items: %s (%d)\n", pam_strerror(pamh, rc), rc); rc = pam_authenticate(pamh, 0); if (rc != PAM_SUCCESS) { printf("Failed to authenticate: %s (%d)\n", pam_strerror(pamh, rc), rc); if (rc == PAM_MODULE_UNKNOWN) printf("Are 32 bit modules installed? (apt-get install libpam-modules:i386)"); } pam_end(pamh, rc); return rc != PAM_SUCCESS; }