Библиотека сайта 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);
Сессия
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_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 приложений. Для получения дополнительной информации, пожалуйста обратитесь к руководству разработчика приложений.
Дополнительные ресурсы