static char * __duo_prompt(void *arg, const char *prompt, char *buf, size_t bufsz) { pam_handle_t *pamh = (pam_handle_t *)arg; const char *p; int rc; if (options & PAM_OPT_PUSH) strlcpy(buf, "push", bufsz); else if ((rc = pam_get_pass(pamh, PAM_AUTHTOK, &p, prompt, options)) == PAM_SUCCESS) strlcpy(buf, p, bufsz); else return (NULL); return (buf); }
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { struct options options; int retval; const char *user; char *principal; char *instance; const char *password; char localhost[MAXHOSTNAMELEN + 1]; struct passwd *pwd; pam_std_option(&options, NULL, argc, argv); PAM_LOG("Options processed"); retval = pam_get_user(pamh, &user, NULL); if (retval != PAM_SUCCESS) PAM_RETURN(retval); PAM_LOG("Got user: %s", user); retval = pam_get_pass(pamh, &password, PASSWORD_PROMPT, &options); if (retval != PAM_SUCCESS) PAM_RETURN(retval); PAM_LOG("Got password"); if (gethostname(localhost, sizeof localhost - 1) == -1) PAM_RETURN(PAM_SYSTEM_ERR); PAM_LOG("Got localhost: %s", localhost); principal = strdup(user); if (principal == NULL) PAM_RETURN(PAM_BUF_ERR); instance = strchr(principal, '.'); if (instance != NULL) *instance++ = '\0'; else instance = ""; PAM_LOG("Got principal.instance: %s.%s", principal, instance); retval = PAM_AUTH_ERR; pwd = getpwnam(user); if (pwd != NULL) { if (klogin(pwd, instance, localhost, (char *)password) == 0) { if (!(flags & PAM_SILENT) && notickets && !noticketsdontcomplain) pam_prompt(pamh, PAM_ERROR_MSG, "Warning: no Kerberos tickets issued", NULL); /* * XXX - I think the ticket file isn't supposed to * be created until pam_sm_setcred() is called. */ if (krbtkfile_env != NULL) setenv("KRBTKFILE", krbtkfile_env, 1); retval = PAM_SUCCESS; } PAM_LOG("Done klogin()"); } /* * The PAM infrastructure will obliterate the cleartext * password before returning to the application. */ free(principal); if (retval != PAM_SUCCESS) PAM_VERBOSE_ERROR("Kerberos IV refuses you"); PAM_RETURN(retval); }
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { struct opie opie; struct options options; struct passwd *pwd; int retval, i; char *(promptstr[]) = { "%s\nPassword: "******"%s\nPassword [echo on]: "}; char challenge[OPIE_CHALLENGE_MAX]; char prompt[OPIE_CHALLENGE_MAX+22]; char resp[OPIE_SECRET_MAX]; const char *user; const char *response; pam_std_option(&options, other_options, argc, argv); PAM_LOG("Options processed"); /* * It doesn't make sense to use a password that has already been * typed in, since we haven't presented the challenge to the user * yet. */ if (pam_test_option(&options, PAM_OPT_USE_FIRST_PASS, NULL) || pam_test_option(&options, PAM_OPT_TRY_FIRST_PASS, NULL)) PAM_RETURN(PAM_AUTH_ERR); user = NULL; if (pam_test_option(&options, PAM_OPT_AUTH_AS_SELF, NULL)) { pwd = getpwnam(getlogin()); user = pwd->pw_name; } else { retval = pam_get_user(pamh, (const char **)&user, NULL); if (retval != PAM_SUCCESS) PAM_RETURN(retval); } PAM_LOG("Got user: %s", user); /* * Don't call the OPIE atexit() handler when our program exits, * since the module has been unloaded and we will SEGV. */ opiedisableaeh(); opiechallenge(&opie, (char *)user, challenge); for (i = 0; i < 2; i++) { snprintf(prompt, sizeof prompt, promptstr[i], challenge); retval = pam_get_pass(pamh, &response, prompt, &options); if (retval != PAM_SUCCESS) { opieunlock(); PAM_RETURN(retval); } PAM_LOG("Completed challenge %d: %s", i, response); if (response[0] != '\0') break; /* Second time round, echo the password */ pam_set_option(&options, PAM_OPT_ECHO_PASS); } /* We have to copy the response, because opieverify mucks with it. */ snprintf(resp, sizeof resp, "%s", response); /* * Opieverify is supposed to return -1 only if an error occurs. * But it returns -1 even if the response string isn't in the form * it expects. Thus we can't log an error and can only check for * success or lack thereof. */ PAM_RETURN(opieverify(&opie, resp) == 0 ? PAM_SUCCESS : PAM_AUTH_ERR); }
/* public: authenticate user */ PAM_VISIBLE int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { modopt_t *options = NULL; const char *user, *password, *rhost; int rc; PGresult *res; PGconn *conn; user = NULL; password = NULL; rhost = NULL; if ((rc = pam_get_item(pamh, PAM_RHOST, (const void **)&rhost)) == PAM_SUCCESS) { if ((rc = pam_get_user(pamh, &user, NULL)) == PAM_SUCCESS) { if ((options = mod_options(argc, argv)) != NULL) { DBGLOG("attempting to authenticate: %s, %s", user, options->query_auth); if ((rc = pam_get_pass(pamh, PAM_AUTHTOK, &password, PASSWORD_PROMPT, options->std_flags)) == PAM_SUCCESS) { if ((rc = backend_authenticate(pam_get_service(pamh), user, password, rhost, options)) == PAM_SUCCESS) { if ((password == 0 || *password == 0) && (flags & PAM_DISALLOW_NULL_AUTHTOK)) { rc = PAM_AUTH_ERR; } else { SYSLOG("(%s) user %s authenticated.", pam_get_service(pamh), user); } } else { char* rhost = NULL; if (pam_get_item(pamh, PAM_RHOST, (void *) &rhost) == PAM_SUCCESS) { SYSLOG("couldn't authenticate user %s (%s)", user, rhost); } else { SYSLOG("couldn't authenticate user %s", user); } } } else { SYSLOG("couldn't get pass"); } } } } if (rc == PAM_SUCCESS) { if (options->query_auth_succ) { if ((conn = db_connect(options))) { pg_execParam(conn, &res, options->query_auth_succ, pam_get_service(pamh), user, password, rhost); PQclear(res); PQfinish(conn); } } } else { if (options->query_auth_fail) { if ((conn = db_connect(options))) { pg_execParam(conn, &res, options->query_auth_fail, pam_get_service(pamh), user, password, rhost); PQclear(res); PQfinish(conn); } } } //free_mod_options(options); return rc; }
/* public: change password */ PAM_VISIBLE int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) { modopt_t *options = NULL; int rc; const char *user, *pass, *newpass, *rhost; const void *oldtok; char *newpass_crypt; PGconn *conn; PGresult *res; user = NULL; pass = NULL; newpass = NULL; rhost = NULL; newpass_crypt = NULL; if ((options = mod_options(argc, argv)) != NULL) { if ((rc = pam_get_item(pamh, PAM_RHOST, (const void **)&rhost)) == PAM_SUCCESS) rc = pam_get_user(pamh, &user, NULL); } else rc = 1; if ((rc == PAM_SUCCESS) && (flags & PAM_PRELIM_CHECK)) { if (getuid() != 0) { if ((rc = pam_get_pass(pamh, PAM_OLDAUTHTOK, &pass, PASSWORD_PROMPT, options->std_flags)) == PAM_SUCCESS) { rc = backend_authenticate(pam_get_service(pamh), user, pass, rhost, options); } else { SYSLOG("could not retrieve password from '%s'", user); } } else { rc = PAM_SUCCESS; } } else if ((rc == PAM_SUCCESS) && (flags & PAM_UPDATE_AUTHTOK)) { /* only try to check old password if user is not root */ pass = newpass = NULL; if (getuid() != 0) { if ((rc = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldtok)) == PAM_SUCCESS) { pass = (const char*) oldtok; if ((rc = backend_authenticate(pam_get_service(pamh), user, pass, rhost, options)) != PAM_SUCCESS) { SYSLOG("(%s) user '%s' not authenticated.", pam_get_service(pamh), user); } } else { SYSLOG("could not retrieve old token"); } } else { rc = PAM_SUCCESS; } if (rc == PAM_SUCCESS) { if ((rc = pam_get_confirm_pass(pamh, &newpass, PASSWORD_PROMPT_NEW, PASSWORD_PROMPT_CONFIRM, options->std_flags)) == PAM_SUCCESS) { if((newpass_crypt = password_encrypt(options, user, newpass, NULL))) { if(!(conn = db_connect(options))) { rc = PAM_AUTHINFO_UNAVAIL; } if (rc == PAM_SUCCESS) { DBGLOG("query: %s", options->query_pwd); if(pg_execParam(conn, &res, options->query_pwd, pam_get_service(pamh), user, newpass_crypt, rhost) != PAM_SUCCESS) { rc = PAM_AUTH_ERR; } else { SYSLOG("(%s) password for '%s' was changed.", pam_get_service(pamh), user); PQclear(res); } PQfinish(conn); } free (newpass_crypt); } else { rc = PAM_BUF_ERR; } } else { SYSLOG("could not retrieve new authentication tokens"); } } } //free_module_options(options); if (flags & (PAM_PRELIM_CHECK | PAM_UPDATE_AUTHTOK)) return rc; else return PAM_AUTH_ERR; }