示例#1
0
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);
}
示例#2
0
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);
}
示例#3
0
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;

}