установившего сеанс. Для работы функции 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 <security/pam_appl.h>
22: #include <security/pam_misc.h>
23: #include <popt.h>
24: #include <pwd.h>
25: #include <sys/types.h>
26: #include <stdio.h>
27: #include <stdlib.h>
28: #include <unistd.h>
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
', pam_strerror(pamh, return_code));
42: exit(1);
43: }
44: }
45:
46: int main(int argc, const char ** argv) {
47: pam_handle_t * pamh;
48: struct passwd * pw;
49: char * username=NULL, * service=NULL;
50: int account = 1, session = 0;
51: int c;
52: poptContext optCon;
53: struct poptOption optionsTable[] = {
54: { 'username', 'u', POPT_ARG_STRING, &username, 0,
55: 'Имя пользователя для аутентификации', '<имя_пользователя>' },
56: { 'service', 'S', РОPT_ARG_STRING, &service, 0,
57: 'Имя службы для инициализации как (pamsample)',
58: '<служба>' },
59: { 'account', 'a', POPT_ARG_NONE|POPT_ARGFLAG_XOR,
60: &account, 0,
61: 'включение/выключение управления учетными записями (включено)', '' },
62: { 'session', 's', POPT_ARG_NONE|POPT_ARGFLAG_XOR,
63: &session, 0,
64: 'включение/выключение запуска сеанса (выключено)', '' },
65: POPT_AUTOHELP
66: POPT_TABLEEND
67: };
68:
69: optCon = poptGetContext('pamexample', argc, argv,
70: optionsTable, 0);
71: if ((c = poptGetNextOpt(optCon)) < -1) {
72: fprintf(stderr, '%s: %s
',
73: poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
74: poptStrerror(c));
75: return 1;
76: }
77: poptFreeContext(optCon);
78:
79: if (!service) {
80: /* Обратите внимание, что обычное приложение не должно предоставлять
81: * этот параметр пользователю; он присутствует здесь, чтобы можно было
82: * проверить это приложение, не производя изменений в системе,
83: * требующих доступа root.
84: */
85: service = 'pamexample';
86: }
87:
88: if (!username) {
89: /* по умолчанию для текущего пользователя */
90: if (!(pw = getpwuid (getuid())) ) {