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

UnixForum





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

Разработка модулей PAM, часть 3

Оригинал: Writing PAM Modules, Part Three
Автор: Jennifer Vesperman
Дата публикации: 30 Мая 2002 г.
Перевод: А.Панин
Дата перевода: 21 Февраля 2013 г.

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

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

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

Требуемые функции

Модуль должен в полной мере удовлетворять требованиям, предъявляемым как минимум к одному из типов модулей. Он должен, но не обязан, отвечать на запросы, отправляемые к модулям других типов с использованием статусов PAM_SERVICE_ERR или PAM_IGNORE.

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

Все функции модулей имеют параметр flag. Флаг PAM_SILENT является корректным флагом для всех функций и сообщает модулю о том, что он не должен передавать какие-либо текстовые сообщения с ошибками или предупреждениями приложению. Флаги могут комбинироваться с помощью логической операции "ИЛИ".

Модули для работы с учетными записями

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

Флаг PAM_DISALLOW_NULL_AUTHTOK сообщает модулю о том, что он должен проверить, имеют ли данные аутентификации из базы данных значение NULL и в случае такой ситуации вернуть статус PAM_AUTH_ERR.
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv);
В случае успешного выполнения операций модуль должен возвращать статус PAM_SUCCESS. Другие допустимые значения статуса:
  • PAM_ACCT_EXPIRED
  • PAM_AUTH_ERR
  • PAM_NEW_AUTHTOK_REQD
  • PAM_USER_UNKNOWN

Модули аутентификации

Проверка существования пользователя

Первым этапом работы модуля аутентификации является проверка наличия информации о данном пользователе.

Флаг PAM_DISALLOW_NULL_AUTHTOK сообщает модулю о том, что он должен проверить, не представлена ли информация из базы данных для аутентификации пользователя значением NULL. Если это так, модуль должен вернуть статус PAM_AUTH_ERR. Без этого флага в данной ситуации модуль может вернуть статус PAM_SUCCESS без запроса данных для аутентификации у пользователя.
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv);
В случае успешного выполнения функций модуля должен быть возвращен статус PAM_SUCCESS. Другие допустимые значения статуса:
  • PAM_AUTH_ERR
  • PAM_AUTHINFO_UNAVAIL
  • PAM_CRED_INSUFFICIENT
  • PAM_MAXTRIES
  • PAM_USER_UNKNOWN

Установка внутренних аутентификационных данных

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

Допустимые флаги:
PAM_DELETE_CRED
Удалить внутренние аутентификационные данные, ассоциированные с системой аутентификации.
PAM_ESTABLISH_CRED
Установить внутренние атентификационные данные, ассоциировав их системой аутентификации.
PAM_REFRESH_CRED
Увеличить срок действия внутренних аутентификационных данных.
PAM_REINITIALIZE_CRED
Провести повторную инициализацию внутренних аутентификационных данных, связанных с системой аутентификации.
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv);
В случае успешного выполнения функций модуля он должен вернуть статус PAM_SUCCESS. Другие допустимые значения статуса:
  • PAM_CRED_ERR
  • PAM_CRED_EXPIRED
  • PAM_CRED_UNAVAIL
  • PAM_USER_UNKNOWN

Модули для работы с паролями

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

Допустимые флаги:
PAM_CHANGE_EXPIRED_AUTHTOK
Аутентификационные данные пользователя могут быть только изменены, так как их срок действия истек.
PAM_PRELIM_CHECK
С помощью данного флага может быть запрошена степень готовности модуля к обновлению аутентификационных данных пользователя. В том случае, если модуль не готов к данным действиям, он должен вернуть статус PAM_TRY_AGAIN.
PAM_UPDATE_AUTHTOK
Указание на то, что модуль должен заменить аутентификационные данные пользователя.
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv);
В случае успешного выполнения функций модуля должен быть возвращен статус PAM_SUCCESS. Другие допустимые значения статуса:
  • PAM_AUTHTOK_DISABLE_AGING
  • PAM_AUTHTOK_ERR
  • PAM_AUTHTOK_LOCK_BUSY
  • PAM_AUTHTOK_RECOVERY_ERR
  • PAM_PERM_DENIED
  • PAM_TRY_AGAIN
  • PAM_USER_UNKNOWN

Модули для работы с сессиями

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

Функция завершения сессии может быть вызвана приложением, не вызывавшим функцию открытия сессии, поэтому данные должны сохраняться с помощью системы PAM или в другом постоянно действующем хранилище.
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv);
PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv);

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

Другие функции

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

Функция pam_fail_delay предназначена для выбора периода времени задержки после неудачной попытки аутентификации. При неудачном вызове функции pam_authenticate(), система PAM задерживает возврат контроля приложению, выбирая случайный период времени с ориентировкой на максимальный период, выбранный с помощью приведенной выше функции для данной сессии PAM. Приложение также может предложить период времени задержки.
extern const char *pam_strerror(pam_handle_t *pamh, int errnum);
extern int pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec);

Значения статусов

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

Статусы успешного выполнения функций
PAM_SUCCESS
Все прошло хорошо, модуль успешно выполнил свою функцию, а также (если осуществлялась аутентификация) пользователь является тем, кем он представился системе.
Статусы неудачного выполнения функций
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_IGNORE
Результат работы данного модуля может быть проигнорирован.
PAM_MAXTRIES
Достигнуто максимальное количество попыток аутентификации пользователя с помощью данного модуля. Процесс аутентификации пользователя не будет продолжен.
PAM_NEW_AUTHTOK_REQD
Срок действия внутренних данных аутентификации истек и данные должны быть обновлены.
PAM_PERM_DENIED
Отказано в доступе или требуемый параметр имеет значение NULL.
PAM_SERVICE_ERR
Данный модуль не может обработать заданный тип запроса.
PAM_SYSTEM_ERR
Обычно означает ошибку использования некорректного хэндла PAM.
PAM_TRY_AGAIN
Модуль не может обновить данные аутентификации, поэтому ни один из идентификаторов не обновлен.
PAM_USER_UNKNOWN
Модуль не может определить пользователя.

Вопросы безопасности

Системы аутентификации должны разрабатываться с использованием техник безопасного программирования. Несколько примеров приведено в данной серии статей, а для того, чтобы узнать о других приемах, следует обратиться к руководству разработчика модулей Linux-PAM (Linux-PAM Module Developer's Guide). Ознакомьтесь с информацией из двух описанных выше источников и проявите осторожность, попросив кого-либо знакомого с безопасным программированием проверить корректность вашего кода перед его промышленным использованием.
  • Будьте осторожны и аутентифицируйте корректного пользователя. Имя пользователя, возвращаемое функцией pam_get_user(), является именем пользователя, который получит доступ к системе. Это имя не всегда соответствует данным, возвращаемым функциями getuid или geteuid.
  • При работе с данными аутентификации следует убедиться в том, что они заменяются нулевыми значениями когда больше не требуются и, конечно же, перед освобождением зарезервированной для их хранения памяти.
  • Убедитесь, что память для хранения ответа приложения заполняется нулями или другими известными данными для проверки того, вернуло ли приложение ответ или вы читаете случайные данные.
  • Используйте функцию syslog вместо пользовательских сообщений для вывода большинства ошибок.
  • Убедитесь, что ваш модуль корректно возвращает статус неудачи в случае нехватки системных ресурсов.
  • Помните о недостатках статического связывания программ. Многие модули на практике будут загружены статически.

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

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

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