#include <security/pam_appl.h>
struct pam_conv {
int (*conv) (int num_msg, const struct pam_message ** msg,
struct pam_response ** resp, void * appdata_ptr);
void * appdata_ptr;
};
Член conv()
является указателем на функцию диалога, которая принимает сообщения для передачи пользователю в структуру struct pam_message
и возвращает введенную пользователем информацию в структуру struct pam_response
. Библиотека libpam_misc
предлагает функцию диалога misc_conv
, которая отвечает за работу с текстовыми консольными приложениями. Чтобы использовать ее (мы рекомендуем вам делать это по мере возможности), вам нужно будет включить заголовочный файл <security/pam_misc.h>
и присвоить члену conv
значение misc_conv
. Этот простой механизм использован в программе pamexample
, представленной в конце этой главы.
Как вариант, вам будет необходимо реализовать свою собственную функцию диалога. Для этого вы должны разобраться еще с двумя структурами данных.
struct pam_message {
int msg_style;
const char * msg;
};
struct pam_response {
char * resp;
int resp_retcode; /*пока что не используется, ожидается нулевое значение*/
};
Функции диалога передается массив указателей на структуры pam_message
и массив указателей на структуры pam_response, каждый из которых имеет длину num_msg
. При получении отклика его необходимо передавать каждой структуре pam_message
в структуре pam_response
с одним и тем же индексом массива, msg_style
может принимать одно из перечисленных ниже значений.
PAM_PROMPT_ECHO_OFF | Выводит текст, определенный в msg как информационный (например, в стандартном дескрипторе выходного файла), просит пользователя об отклике, не отображая введенные символы (например, пароль), и возвращает текст в новую сформированную строку символов, хранящуюся в соответствующей структуре resp pam_response . |
PAM_PROMPT_ECHO_ON | Выводит текст, определенный в msg как информационный (например, в стандартном дескрипторе выходного файла), просит пользователя об отклике, отображая введенные символы (например, имя пользователя), и возвращает текст в новую сформированную строку символов, хранящуюся в соответствующей структуре resp pam_response . |
PAM_ERROR_MSG | Выводит текст, определенный в msg как текст ошибки (например, стандартный дескриптор файла ошибок), присваивает соответствующей структуре resp pam_response значение NULL . |
PAM_TEXT_INFO | Выводит текст, определенный в msg как информационный (например, стандартный дескриптор выходного файла), присваивает структуре resp pam_response значение NULL . |
Остальные значения могут быть определены как расширения стандарта; ваша функция диалога должна игнорировать их, если они не записываются для последующей их обработки, и должна просто передавать им NULL
-отклик. РАМ (вернее, модуль РАМ, производящий запрос) отвечает за освобождение каждой строки resp
, не содержащей NULL
, а также массивов структур pam_message
и pam_response
.
Член appdate_ptr
, который задается в структуре диалога, передается функции диалога. Это будет полезно в тех случаях, когда вы используете одну функцию диалога в нескольких контекстах, или если вы хотите передать контекстную информацию функции диалога. Эта информация может включать спецификацию дисплея X, внутреннюю структуру данных, в которой хранятся описатели файлов для соединения, или любые другие данные, которые могут быть полезны для вашего приложения. В любом случае, эта информация не интерпретируется библиотекой РАМ.
Функция диалога должна вернуть PAM_CONVERR
, если во время выполнения возникнет ошибка, в противном случае — PAM_SUCCESS
.
28.2.2. Действия РАМ
РАМ не хранит никакой статической информации в библиотеке между вызовами, а хранит всю постоянную информацию с использованием непрозрачной структуры данных, передаваемой всем вызовам. Этот непрозрачный объект, pam_handle
, управляется РАМ, однако хранится в вызывающем приложении. Он инициализируется с помощью функции pam_start()
и освобождается функцией pam_end()
.
#include <security/pam_appl.h>
int pam_start (const char * service_name, const char * user,
const struct pam_conv * pam_conversation,
pam_handle_t ** pamh);
int pam_end(pam_handle_t * pamh, int pam_status);
Аргумент service_name
должен представлять уникальное имя для вашего приложения. Это уникальное имя позволяет администратору системы конфигурировать защиту применительно к вашему приложению; два приложения, использующие одно и то же имя service name
, разделяют одну и ту же конфигурацию. Аргумент user
представляет имя аутентифицированного пользователя. Аргумент pam_conversation
представляет структуру диалога, о которой мы уже говорили. Аргумент pamh
представляет непрозрачный объект, который следит за внутренним состоянием. Функция pam_start()
показана в строке 97 кода.
Функция pam_end()
, показанная в строке 137 кода pamexample.с
, очищает каждое; состояние, хранящееся в непрозрачном объекте pamh
, и информирует