Функция pam_acct_mgmt()
, показанная в строке 107, предполагает, что функция pam_authenticate()
уже была вызвана и продолжает свою работу, а затем проверяет (также по имени), разрешено ли пользователю осуществлять запрошенный доступ. Она может рассматривать элементы РАМ PAM_USER
, PAM_TTY
, PAM_RUSER
и PAM_RHOST
, определяя разрешение на доступ. Например, какому-то одному пользователю могут быть разрешены некоторые tty только в течение определенных часов, или каждому пользователю в некотором классе может быть разрешено только некоторое количество параллельных регистраций, или некоторым совокупностям удаленных пользователей и хостов могут быть даны разрешения только на несколько часов.
Функция pam_setcred()
, показанная в строке 118, предполагает, что аутентификация была пройдена, и затем устанавливает сертификаты для пользователя. Хотя uid, gid и дополнительные группы технически являются сертификатами, они не находятся под управлением функции pam_setcred()
, поскольку во многих приложениях это не будет соответствовать модели безопасности. Наоборот, она устанавливает дополнительные сертификаты. Вероятным кандидатом для использования в качестве сертификата является мандат Kerberos — файл, содержащий зашифрованные данные, которые предоставляют пользователю разрешение на доступ к некоторым ресурсам.
Функция pam_open_session()
, показанная в строке 113, открывает новый сеанс. Если в процессе есть ветвления, то функцию pam_open_session()
необходимо вызывать после ветвления, поскольку при этом могут происходить такие действия, как установка rlimits
(см. стр. 120–121). Если ваш процесс запускается как root, а затем изменяется на uid аутентифицированного пользователя, функцию pam_open_session()
нужно вызывать перед сбросом привилегий root, поскольку модули сеанса могут попытаться выполнить системные операции (например, монтирование домашних каталогов), которые зарезервированы только для root.
Функция pam_close_session()
, показанная в строке 128, закрывает существующий сеанс. Ее можно вызывать из другого процесса, а не только из того, который вызвал функцию pam_open_session()
, при том условии, что РАМ будут доступны одни и те же данные — те же аргументы, заданные для РАМ, и те же элементы РАМ, которые используются для открытия сеанса. Обратите внимание, что поскольку элемент PAM_USER
может быть изменен во время аутентификации и управления учетной записью, вы должны убедиться, что производится учет любых изменений, производимых с PAM_USER
, если вы вызываете ее из отдельного процесса, установившего сеанс. Для работы функции pam_close_session()
могут потребоваться привилегии root.
1: /* pamexample.с */
2:
3: /* Программа pamexample демонстрирует вариант простой обработки РАМ.
4: * Вам нужно будет либо использовать параметр командной строки —service
5: * для выбора имени уже установленной службы (может работать "system-auth",
6: * проверьте наличие /etc/pam.d/system-auth в своей системе), либо
7: * установки системного файла */etc/pam.d/pamexample со следующими
8: * четырьмя строками (игнорируя ведущие символы "*") :
9: * #%РАМ-1.0
10: * auth required /lib/security/pam_unix.so
11: * account required /lib/security/pam_unix.so
12: * session required /lib/security/pam_limits.so
13: *
14: * Обратите внимание, что если вы запустите эту программу не как root, то
15: * можете столкнуться с ограничениями системы; при управлении учетными
16: * записями может произойти сбой, вам может быть не разрешено проверять
17: * другие пароли пользователей, в управлении сеансом может произойти
18: * сбой - все будет зависеть от того, как сконфигурирована служба.
19: */
20:
21: #include
22: #include
23: #include
24: #include
25: #include
26: #include
27: #include
28: #include
29:
30: /* Эта структура может быть автоматической, но она не должна выходить
31: * за пределы между функциями pam_start() и pam_end(), поэтому в простых
32: * программах легче всего сделать ее статической.
33: */
34: static struct pam_conv my_conv = {
35: misc_conv, /* использование функции диалога TTY из libpam_misc */
36: NULL /* у нас нет специальных данных для передачи в misc_conf */
37: };
38:
39: void check_success(pam_handle_t * pamh, int return_code) {
40: if (return_code != PAM_SUCCESS) {
41: fprintf (stderr, '"%s\n", pam_strerror(pamh, return_code));
42: exit(1);
43: }
Читать дальше