예제 #1
0
/*
 * ngx_auth_pam_talker: supply authentication information to PAM when asked
 *
 * Assumptions:
 *   A password is asked for by requesting input without echoing
 *   A username is asked for by requesting input _with_ echoing
 */
static int
ngx_auth_pam_talker(int num_msg, const struct pam_message ** msg,
                    struct pam_response ** resp, void *appdata_ptr)
{
    int  i;
    ngx_pam_userinfo  *uinfo;
    struct pam_response  *response;

    uinfo = (ngx_pam_userinfo *) appdata_ptr;
    response = NULL;

    /* parameter sanity checking */
    if (!resp || !msg || !uinfo)
        return PAM_CONV_ERR;

    /* allocate memory to store response */
    response = malloc(num_msg * sizeof(struct pam_response));
    if (!response)
        return PAM_CONV_ERR;

    /* copy values */
    for (i = 0; i < num_msg; i++) {
        /* initialize to safe values */
        response[i].resp_retcode = 0;
        response[i].resp = 0;

        /* select response based on requested output style */
        switch (msg[i]->msg_style) {
        case PAM_PROMPT_ECHO_ON:
            /* on memory allocation failure, auth fails */
            response[i].resp = strdup((const char *)uinfo->username.data);
            break;
        case PAM_PROMPT_ECHO_OFF:
            response[i].resp = strdup((const char *)uinfo->password.data);
            break;
        default:
            free_resp(i, response);
            return PAM_CONV_ERR;
        }
    }
    /* everything okay, set PAM response values */
    *resp = response;
    return PAM_SUCCESS;
}
예제 #2
0
/* ARGSUSED */
int
pam_tty_conv(int num_msg, struct pam_message **mess,
    struct pam_response **resp, void *my_data)
{
	struct pam_message *m = *mess;
	struct pam_response *r = calloc(num_msg, sizeof (struct pam_response));
	int i;

	if (num_msg >= PAM_MAX_NUM_MSG) {
		(void) fprintf(stderr, "too many messages %d >= %d\n",
		    num_msg, PAM_MAX_NUM_MSG);
		free(r);
		*resp = NULL;
		return (PAM_CONV_ERR);
	}

	/* Talk it out */
	*resp = r;
	for (i = 0; i < num_msg; i++) {
		int echo_off;

		/* bad message from service module */
		if (m->msg == NULL) {
			(void) fprintf(stderr, "message[%d]: %d/NULL\n",
			    i, m->msg_style);
			goto err;
		}

		/*
		 * fix up final newline:
		 * 	removed for prompts
		 * 	added back for messages
		 */
		if (m->msg[strlen(m->msg)] == '\n')
			m->msg[strlen(m->msg)] = '\0';

		r->resp = NULL;
		r->resp_retcode = 0;
		echo_off = 0;
		switch (m->msg_style) {

		case PAM_PROMPT_ECHO_OFF:
			echo_off = 1;
			/*FALLTHROUGH*/

		case PAM_PROMPT_ECHO_ON:
			(void) fputs(m->msg, stdout);

			r->resp = getinput(echo_off);
			break;

		case PAM_ERROR_MSG:
			(void) fputs(m->msg, stderr);
			(void) fputc('\n', stderr);
			break;

		case PAM_TEXT_INFO:
			(void) fputs(m->msg, stdout);
			(void) fputc('\n', stdout);
			break;

		default:
			(void) fprintf(stderr, "message[%d]: unknown type "
			    "%d/val=\"%s\"\n",
			    i, m->msg_style, m->msg);
			/* error, service module won't clean up */
			goto err;
		}
		if (errno == EINTR)
			goto err;

		/* next message/response */
		m++;
		r++;
	}
	return (PAM_SUCCESS);

err:
	free_resp(i, r);
	*resp = NULL;
	return (PAM_CONV_ERR);
}