#include #include #include #include #include #include #include #include #include #include int auth_pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { const struct pam_message **m; struct pam_response *r; if (!num_msg || !msg || !appdata_ptr) return PAM_CONV_ERR; *resp = (struct pam_response*)calloc(num_msg, sizeof(struct pam_response)); if (!*resp) return PAM_CONV_ERR; /* Assume that any prompt is asking for a password */ for (m = msg, r = *resp; m < msg + num_msg; ++m, ++r) { if ((*m)->msg_style == PAM_PROMPT_ECHO_OFF) { char *x; r->resp = (x = strdup((char*)appdata_ptr)); r->resp_retcode = 0; } } return PAM_SUCCESS; } int auth_pam_new_user_pass(const char *user, const char *pass) { pam_handle_t *pamh = NULL; struct passwd pw, *pw2; int r, n = PAM_SUCCESS; struct pam_conv conv = {0}; char *facility; int use_gid = 0; gid_t gid; pw2 = getpwnam(user); if (!pw2) { fprintf(stderr, "getpwnam(%s): unknown user (%s)", user, strerror(errno)); return 0; } else pw = *pw2; /* Obtain facility name. */ facility = "tpop3d"; conv.conv = auth_pam_conversation; conv.appdata_ptr = (void*)pass; r = pam_start(facility, user, &conv, &pamh); if (r != PAM_SUCCESS) { fprintf(stderr, "pam_start: %s\n", pam_strerror(pamh, r)); return 0; } /* Authenticate user. */ r = pam_authenticate(pamh, 0); if (r == PAM_SUCCESS) { /* OK, is the account presently allowed to log in? */ r = pam_acct_mgmt(pamh, 0); if (r == PAM_SUCCESS) fprintf(stderr, "."); else fprintf(stderr, "pam_acct_mgmt(%s): %s\n", user, pam_strerror(pamh, r)); } else fprintf(stderr, "pam_authenticate(%s): %s\n", user, pam_strerror(pamh, r)); r = pam_end(pamh, n); if (r != PAM_SUCCESS) fprintf(stderr, "pam_end: %s\n", pam_strerror(pamh, r)); return 1; } int main() { fprintf(stderr, "I am PID %d\n", (int)getpid()); while(1) auth_pam_new_user_pass("user", "password"); }