#include <security/_pam_macros.h>
#include <security/pam_modules.h>
#include "pam_mount.h"

/* adapted from pam_unix/support.c */
static int converse(pam_handle_t * pamh, int ctrl, int nargs,
		    struct pam_message **message,
		    struct pam_response **response)
{
    int retval;
    struct pam_conv *conv;

    w4rn("%s", "pam_mount: enter converse");

    retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
    if (retval == PAM_SUCCESS) {

	retval = conv->conv(nargs, (const struct pam_message **) message,
			    response, conv->appdata_ptr);

	w4rn("%s", "pam_mount: returned from app's conversation fn");
    }

    w4rn("%s", "pam_mount: leave converse");

    return retval;		/* propagate error status */
}

/* adapted from pam_unix/support.c (_unix_read_password) */
int read_password(pam_handle_t * pamh, const char *prompt1, char **pass)
{
    int retval;
    char *token;

    w4rn("%s", "enter read_password");

    /*
     * make sure nothing inappropriate gets returned
     */

    *pass = token = NULL;

    {
	struct pam_message msg, *pmsg;
	struct pam_response *resp;

	pmsg = &msg;
	msg.msg_style = PAM_PROMPT_ECHO_OFF;
	msg.msg = prompt1;

	/* so call the conversation */
	resp = NULL;
	retval = converse(pamh, 0, 1, &pmsg, &resp);

	/* w4rn ("pam_mount: read_password got: %s\n", resp->resp); */

	if (resp != NULL) {
	    if (retval == PAM_SUCCESS) {	/* a good conversation */
		token = x_strdup(resp->resp);
	    }

	    _pam_drop_reply(resp, 1);
	} else {
	    retval = (retval == PAM_SUCCESS)
		? PAM_AUTHTOK_RECOVER_ERR : retval;
	}
    }

    if (retval != PAM_SUCCESS) {
	return retval;
    }

    *pass = token;

    w4rn("%s", "pam_mount: leave read_password");
    return PAM_SUCCESS;
}
