Подключаемые Модули Аутентификации (PAM)
Пред. |  | След.

# C. Пример функции взаимодействия PAM

Функция взаимодействия, приводимая ниже, является значительно упрощённой версией функции openpam_ttyconv(3) из OpenPAM. Она полнофункциональна, и должна послужить источником идей о том, как должна себя вести функция взаимодействия, однако она слишком проста для реальных приложений. Даже если вы не используете OpenPAM, можете сгрузить исходный код и использовать openpam_ttyconv(3) в своих целях; мы надеемся, что она достаточно надёжна в качестве функции для взаимодействия с терминальными устройствами.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>

    #include <security/pam_appl.h>

    int
    converse(int n, const struct pam_message **msg,
    	struct pam_response **resp, void *data)
    {
    	struct pam_response *aresp;
    	char buf[PAM_MAX_RESP_SIZE];
    	int i;

    	data = data;
    	if (n <= 0 || n > PAM_MAX_NUM_MSG)
    		return (PAM_CONV_ERR);
    	if ((aresp = calloc(n, sizeof *aresp)) == NULL)
    		return (PAM_BUF_ERR);
    	for (i = 0; i < n; ++i) {
    		aresp[i].resp_retcode = 0;
    		aresp[i].resp = NULL;
    		switch (msg[i]->msg_style) {
    		case PAM_PROMPT_ECHO_OFF:
    			aresp[i].resp = strdup(getpass(msg[i]->msg));
    			if (aresp[i].resp == NULL)
    				goto fail;
    			break;
    		case PAM_PROMPT_ECHO_ON:
    			fputs(msg[i]->msg, stderr);
    			if (fgets(buf, sizeof buf, stdin) == NULL)
    				goto fail;
    			aresp[i].resp = strdup(buf);
    			if (aresp[i].resp == NULL)
    				goto fail;
    			break;
    		case PAM_ERROR_MSG:
    			fputs(msg[i]->msg, stderr);
    			if (strlen(msg[i]->msg) > 0 &&
    			    msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
    				fputc('\n', stderr);
    			break;
    		case PAM_TEXT_INFO:
    			fputs(msg[i]->msg, stdout);
    			if (strlen(msg[i]->msg) > 0 &&
    			    msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
    				fputc('\n', stdout);
    			break;
    		default:
    			goto fail;
    		}
    	}
    	*resp = aresp;
    	return (PAM_SUCCESS);
     fail:
            for (i = 0; i < n; ++i) {
                    if (aresp[i].resp != NULL) {
                            memset(aresp[i].resp, 0, strlen(aresp[i].resp));
                            free(aresp[i].resp);
                    }
            }
            memset(aresp, 0, n * sizeof *aresp);
    	*resp = NULL;
    	return (PAM_CONV_ERR);
    }

Пред. | Начало | След.
Пример PAM-модуля |  | Дополнительная литература

Этот, и другие документы, могут быть скачаны с ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите <doc@FreeBSD.org>.
По вопросам, связанным с русским переводом документации, пишите в рассылку <frdp@FreeBSD.org.ua>.
Информация по подписке на эту рассылку находится на сайте проекта перевода.