Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Разработка совместимых с PAM приложений, часть 2

Оригинал: Writing PAM-Capable Applications, Part Two
Автор: Jennifer Vesperman
Дата публикации: 18 Апреля 2002 г.
Перевод: А.Панин
Дата перевода: 22 Февраля 2013 г.

Аббревиатура PAM расшифровывается как Pluggable Authentication Modules (система подключаемых модулей аутентификации) и используется для обозначения системы, позволяющей приложениям осуществлять независимую аутентификацию.

Если приложение осуществляет работу с PAM, системный администратор ответственен за указание используемых методов аутентификации в то время, как система PAM ответственна за реализацию самого процесса аутентификации. Это обстоятельство позволяет разработчику приложения концентрировать внимание на разработке основного кода приложения и быть уверенным в том, что приложение не устареет всего лишь из-за использования устаревшей схемы аутентификации.

Данная статья является второй частью серии статей о разработке совместимых с PAM приложений из двух частей. В первой части была приведена необходимая для разработки приложений информация и описаны механизмы работы, а также затронута тема механизма обмена данными, который должен быть реализован в рамках приложения для того, чтобы у модуля была возможность взаимодействия с пользователем.

В этой же части описываются функции для аутентификации средствами PAM, управления учетными записями, управления сессиями и смены аутентификационных данных. Также в этой части затрагиваются темы кодов ответов, установки паролей и составления стандартных файлов настроек для вашего приложения.

Если не указано обратное, описания функций и типов, рассматриваемых в данной статье, находятся в заголовочном файле <security/pam_appl.h>.

Функция pam_start()

Данная функция производит инициализацию системы PAM и возвращает приложению хэндл PAM, который используется в остальных функциях для уникальной идентификации экземпляра приложения.

Параметр service_name задает уникальное в рамках системы PAM имя приложения, которое используется в файлах настроек PAM.

В случае, если имя пользователя неизвестно, вместо него может использоваться значение NULL, но в такой ситуации модуль должен будет впоследствии использовать функцию обмена данными для его запроса.

Параметр pam_conversation является указателем на структуру обмена данными. Параметр pamh используется для сохранения хэндла PAM.

Функция возвращает код PAM_SUCCESS в случае удачного завершения и один из нескольких кодов ошибок в случае неудачного.
pam_handle_t *pamh=NULL;
extern int pam_start(const char *service_name, const char *user,
                     const struct pam_conv *pam_conversation,
                     pam_handle_t **pamh);

Аутентификация

Вызов данной функции сообщает системе PAM о необходимости использования методов аутентификации из соответствующих модулей. В случае успеха функция возвращает код PAM_SUCCESS. На неудачу при выполнении функции указывает любой другой код.

Модули для аутентификации обычно используются раньше модулей остальных типов.

Чаще всего функция вызывается с флагом PAM_DISALLOW_NULL_AUTHTOK. Если этот флаг установлен и база аутентификационных данных не содержит информации для заданного имени пользователя, аутентификация считается неудачной.
extern int pam_authenticate(pam_handle_t *pamh, int flags);

Учетные записи

Функция управления учетными записями проверяет работоспособность учетной записи и разрешение на открытие сессии в данное время для пользователя. Доступны модули PAM, позволяющие ограничивать действие учетных записей в зависимости от времени, количества пользователей системы, с использованием блокировок "nologin" Unix-подобных операционных систем и с помощью множества других различных методов.

Функции управления учетными записями обычно вызываются после функций аутентификации и до открытия сессий.

Модуль управления учетными записями вернет код PAM_NEW_AUTHTOK_REQD в случае истечения срока действия аутентификационных данных, что позволяет приложению потребовать от пользователя предоставления новых данных. Если вы получаете этот код после вызова функции, вы можете вызвать функцию pam_chauthtok(), после чего повторить попытку.

Функция возвращает код PAM_SUCCESS в случае корректной учетной записи и другие коды для указания на неудачное завершение.
extern int pam_acct_mgmt(pam_handle_t *pamh, int flags);

Установка дополнительных данных

После аутентификации пользователя и проверки его учетной записи на пригодность к использованию, многие методы аутентификации требуют от системы аутентифкации установки дополнительных данных. Эти данные могут отражать принадлежность пользователя к группе в Unix-системе или быть данными Kerberos.

Приложение должно вызвать эту функцию до открытия сессии.
extern int pam_setcred(pam_handle_t *pamh, int flags);

Сессия

Эти функции предназначены для открытия и закрытия аутентификационных сессий. Функция закрытия сессии может быть вызвана из другого приложения в том случае, если этому приложению будет доступен хэндл PAM.
extern int pam_open_session(pam_handle_t *pamh, int flags);
extern int pam_close_session(pam_handle_t *pamh, int flags);

Пароль

Функция pam_chauthtok изменяет аутентификационные данные, используя функцию обмена данными для взаимодействия с пользователем.

Вызов этой функции с флагом PAM_CHANGE_EXPIRED_AUTHTOK позволяет заменять данные только в случае истечения их срока действия. Рекомендую использовать этот флаг в случае вызова функции после возврата модулем управления учетными записями кода PAM_NEW_AUTHTOK_REQD.

Данный модуль обычно используется после открытия сессии, но он также может использоваться сразу после вызова модуля управления учетными записями для обновления аутентификационных данных.
extern int pam_chauthtok(pam_handle_t *pamh, const int flags);

Функция pam_end()

Эта функция завершает работу совместимого с PAM приложения. Вызывайте ее тогда, когда вам больше не требуется хэндл PAM для того, чтобы освободить ресурсы, зарезервированные вызываемыми модулями - освободить зарезервированные участки памяти, удалить из памяти данные структур и сделать неактивными внутренние аутентификационные данные.

Параметр pam_status позволяет указать было ли использование системы PAM успешным или нет, что в свою очередь влияет на ход процесса по освобождению зарезервированных модулями ресурсов. Полезно использовать одну переменную для получения возвращаемого значения вызовов PAM и использовать следующий условный переход после большинства вызовов: if (retval == PAM_SUCCESS). После этого вы можете вызвать функцию pam_end с возвращенным значением в качестве аргумента pam_status.
extern int pam_end(pam_handle_t *pamh, int pam_status);

Коды ошибок

Все функции PAM возвращают либо код PAM_SUCCESS, либо следующие коды ошибок. Стоит отметить, что мне пришлось столкнуться с функциями PAM, возвращающими не описанные в документации коды.

Функция PAM pam_strerror() возвращает текстовые строки, соответствующие каждому из кодов ошибок.
extern const char *pam_strerror(pam_handle_t *pamh, int errnum);
Коды ошибок:
PAM_ABORT
Обычно обозначает повреждение хэндла PAM.
PAM_ACCT_EXPIRED
Срок действия учетной записи пользователя истек, поэтому он или она не сможет получить доступ к системе.
PAM_AUTH_ERR
Ошибка аутентификации.
PAM_AUTHINFO_UNAVAIL
Один или большее количество модулей не могут получить доступ к аутентификационной информации, возможно из-за аппаратного сбоя.
PAM_AUTHTOK_DISABLE_AGING
Для одного или нескольких модулей отключен период действия внутренних аутентификационных данных.
PAM_AUTHTOK_ERR
Один или несколько модулей не могут прочитать новые внутренние аутентификационные данные.
PAM_AUTHTOK_LOCK_BUSY
Внутренние аутентификационные данные не могут быть изменены из-за блокировки.
PAM_AUTHTOK_RECOVERY_ERR
Предыдущие внутренние аутентификационные данные не могут быть получены.
PAM_BAD_ITEM
Переменная не может быть установлена/удалена, так как она не описана, недоступна или на данный момент не установлена.
PAM_BUF_ERR
Ошибка резервирования памяти.
PAM_CRED_ERR
Один или большее количество модулей не могут установить пользовательские аутентификационные данные.
PAM_CRED_EXPIRED
Период действия пользовательских аутентификационных данных истек.
PAM_CRED_INSUFFICIENT
Приложению не разрешено аутентифицировать пользователя из-за недостатка аутентификационных данных.
PAM_CRED_UNAVAIL
Один или большее количество модулей не могут прочитать пользовательские аутентификационные данные.
PAM_MAXTRIES
Один или большее количество модулей зафиксировали максимальное количество попыток аутентификации пользователя. Попытки аутентификации данного пользователя не будут продолжаться.
PAM_NEW_AUTHTOK_REQD
Срок действия внутренних аутентификационных данных пользователя истек и они должны быть обновлены.
PAM_PERM_DENIED
Обычно означает запрет доступа, но иногда возвращается в случае использования значения NULL в качестве требуемого параметра.
PAM_SYSTEM_ERR
Обычно означает некорректный хэндл PAM.
PAM_TRY_AGAIN
Один или несколько модулей не могут обновить данные аутентификации, поэтому не были обновлены никакие из аутентификационных записей.
PAM_USER_UNKNOWN
Пользователь неизвестен для одного или нескольких модулей (одного типа).

Дополнительные функции

Данные функции описаны в заголовочном файле <security/pam_misc.h>. Система Linux-PAM предоставляет функцию для безопасного дублирования строк. Функция возвращает копию переданной в качестве параметра строки. Если для дублирования строки недостаточно памяти, возвращается значение NULL.
extern char *x_strdup(const char *s)

Стандартный файл настройки

Проверяйте наличие файла с именем вашего приложения в директории /etc/pam.d с помощью сценария установки вашего приложения. Если его не существует, создайте файл с подходящей стандартной последовательностью PAM-модулей аутентификации для вашего приложения. Вы можете ознакомиться с подходящей стандартной настройкой PAM с описаниями модулей в файле /etc/pam.d/login из стандартной поставки большинства Linux-систем. Другим вариантом является использование следующего содержимого файла:
auth       requisite  pam_securetty.so
auth       required   pam_unix.so
account    required   pam_unix.so
session    required   pam_unix.so
password   required   pam_cracklib.so retry=3 minlen=6 difok=3
password   required   pam_unix.so use_authtok nullok md5

Если файл с названием вашего приложения существует, возможен конфликт имен с другим приложением или файл может быть установлен вместе с предыдущей версией вашего приложения.

Предостережения и советы

  • Прочитайте руководство разработчика приложений Linux-PAM.
  • Разрабатывайте безопасный код.
  • Функция xstrdup в документации является функцией x_strdup в коде (подтверждение получено от Andrew Morgan).
  • Константа PAM_AUTHTOKEN_REQD из документации, похоже, является константой PAM_NEW_AUTHTOK_REQD из кода.

Заключительные слова

В этой статье затронуты наиболее важные аспекты разработки работающих с PAM приложений. Для получения дополнительной информации, пожалуйста обратитесь к руководству разработчика приложений.

Дополнительные ресурсы