|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #1 : 01-07-2004 10:43 » |
|
Russian, ты хочешь сказать, чтобы запуск программы требовал авторизации? "научить ее авторизироваться в системе" - как-то странно звучит. То что тебе рекомендовали - pam (pluggable authentication modules).
в общем, уточни вопрос.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Russian
Гость
|
|
« Ответ #2 : 01-07-2004 13:24 » |
|
Ммм, прога моя что-то вроде терминала... Мне нужно чтобы она выполняла команду su login, где логин задан. Проблема еще в том, что я не знаю как перехватить запрос на ввод пароля. Вот программка: #include <iostream> #include <string> #include <unistd.h> #include <sys/types.h>
using namespace std;
int main() { pid_t pid; char cmd[]="ls";
if ((pid=fork())==0) { execlp(cmd, cmd, NULL); }
return 0; }
Она выполняет команду ls - показывает листинг каталога. Также я пытался дать команду su login, но нечего не получилось. ИМХО из-за присутсвия параметра. Да еще как-то нужно перехватить запрос пароля!!! Я не знаю как это сделать и надеюсь что вы мне тут поможете. RXL, а зачем ты тему перенес? Вопрос же о C++, а не о UNIX!!!
|
|
« Последнее редактирование: 29-11-2007 17:05 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #3 : 01-07-2004 14:00 » |
|
Russian, перенес потому, что считаю ее более Unix (точнее - Linux), чем С проблемой. По Unix вопросов меньше и лучше их группировать в одном месте.
Вызывом внешней программы ты своей прав не добавишь! Это я о su. Сменить UID может только программа, запущенная с правами root-а.
Уточни - тебе нужно чтобы программа запускалась с правами определенного пользователя, или этот пользователь может менятся?
Для первого случая, установи: 1) chown user твой-исполняемый-файл 2) chmod u+X твой-исполняемый-файл Программа будет запускаться с правами этого пользователя.
Для второго случая, установи: 1) chown root твой-исполняемый-файл 2) chmod u+X твой-исполняемый-файл В программе выполни ф-ию setuid(номер-пользователя)
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Russian
Гость
|
|
« Ответ #4 : 02-07-2004 13:22 » |
|
Нет, нет, нет!!! Я всегда прохо обяснял!.. Короче, мне нужно чтобы программа проверяла пару логин:пароль на провильность в моей системе. Если подходят, если такая пара есть, то чтобы она говорила ОК, в противном случае НеОК. Вы не подумайте что это для взлома, просто задался целью и теперь очень хочу ее исполнить
|
|
|
Записан
|
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #5 : 02-07-2004 14:18 » |
|
вот, посмотри, как это делает login: http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/login/login.c... struct passwd *pwd; ... /* * PAM data */ static pam_handle_t *pamh = NULL; static struct pam_conv pamc = { openpam_ttyconv, NULL }; static int pam_err; static int pam_silent = PAM_SILENT; static int pam_cred_established; static int pam_session_established; ... pam_err = pam_start("login", username, &pamc, &pamh); if (pam_err != PAM_SUCCESS) { pam_syslog("pam_start()"); bail(NO_SLEEP_EXIT, 1); } pam_err = pam_set_item(pamh, PAM_TTY, tty); if (pam_err != PAM_SUCCESS) { pam_syslog("pam_set_item(PAM_TTY)"); bail(NO_SLEEP_EXIT, 1); } pam_err = pam_set_item(pamh, PAM_RHOST, hostname); if (pam_err != PAM_SUCCESS) { pam_syslog("pam_set_item(PAM_RHOST)"); bail(NO_SLEEP_EXIT, 1); }
pwd = getpwnam(username); ... rval = auth_pam(); ... if (pwd && rval == 0) break; // success ...
подробнее, смотри ссылочку на login.c
|
|
« Последнее редактирование: 29-11-2007 17:07 от Алексей1153++ »
|
Записан
|
|
|
|
Russian
Гость
|
|
« Ответ #6 : 02-07-2004 22:23 » |
|
О, это уже что-то! Но все же я попрожу чтобы вы, уважаемые добавили немного коментариев. Я Си пока только учу и мне тяжело разобрать этот исходник без коментариев
|
|
|
Записан
|
|
|
|
Russian
Гость
|
|
« Ответ #7 : 02-07-2004 22:25 » |
|
У + за помощь я могу TJSoft`у поставить?
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #8 : 03-07-2004 14:49 » |
|
Russian, вполне.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Russian
Гость
|
|
« Ответ #9 : 04-07-2004 08:38 » |
|
Для этого нужен ослик? О опере не получилось, но давайте вернемся к теме! Пожалуйста раскажите что к чему в этом исходнике. Я буду тут вопросы задавать, а вы отвечайте.
1. *pamh = NULL - это как? Чему теперь равна *pamh 2. pamc = { openpam_ttyconv, NULL }; ... Оёёй, горе мне, гореее... Нечего понять не могу. Я прошу помогите! Очень прошу т.к. я нечего понять не могу!
|
|
|
Записан
|
|
|
|
Russian
Гость
|
|
« Ответ #10 : 04-07-2004 21:11 » |
|
Так получаеться что и в "Клубе программистов" мне тоже не помогут?
|
|
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #11 : 05-07-2004 07:01 » |
|
Russian, Вам бы для начала, почитать какую нибудь книгу по C. static pam_handle_t *pamh = NULL;
инициализирует (1 раз) pamh нулевым значением. static struct pam_conv pamc = { openpam_ttyconv, NULL };
первое поле структуры pamc, инициализируется значением openpam_ttyconv, а второе - значение NULL.
|
|
« Последнее редактирование: 29-11-2007 17:08 от Алексей1153++ »
|
Записан
|
|
|
|
Russian
Гость
|
|
« Ответ #12 : 06-07-2004 07:13 » |
|
darkelf, очень хорошо то что ты решил помочь! Объясни теперь это ... struct passwd *pwd; ... /* * PAM data */ static pam_handle_t *pamh = NULL; static struct pam_conv pamc = { openpam_ttyconv, NULL }; static int pam_err; static int pam_silent = PAM_SILENT; static int pam_cred_established; static int pam_session_established; ... pam_err = pam_start("login", username, &pamc, &pamh); if (pam_err != PAM_SUCCESS) { pam_syslog("pam_start()"); bail(NO_SLEEP_EXIT, 1); } pam_err = pam_set_item(pamh, PAM_TTY, tty); if (pam_err != PAM_SUCCESS) { pam_syslog("pam_set_item(PAM_TTY)"); bail(NO_SLEEP_EXIT, 1); } pam_err = pam_set_item(pamh, PAM_RHOST, hostname); if (pam_err != PAM_SUCCESS) { pam_syslog("pam_set_item(PAM_RHOST)"); bail(NO_SLEEP_EXIT, 1); }
pwd = getpwnam(username); ... rval = auth_pam(); ... if (pwd && rval == 0) break; // success ...
|
|
« Последнее редактирование: 29-11-2007 17:09 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #13 : 06-07-2004 09:11 » |
|
Russian, ну коли у тебя есть документация и есть пример, то почему бы не попробовать разобраться самостоятельно. Задавай более конкретные вопросы. См.: man getpwnam "Linux-PAM Application Developer's Guide"
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #14 : 06-07-2004 15:46 » |
|
итак, начнем-с: я тоже через Оперу сижу.ты, конечно же не догадался выбрать версию, последняя находится по ссылке http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/login/login.c?rev=1.98&content-type=text/x-cvsweb-markup ... struct passwd *pwd; // структура пароля из master.passwd или shadow ... /* * PAM data */ static pam_handle_t *pamh = NULL; // это нам нужно для сессии с модулями PAM static struct pam_conv pamc = { openpam_ttyconv, NULL }; static int pam_err; // ошибка static int pam_silent = PAM_SILENT; static int pam_cred_established; static int pam_session_established; ... pam_err = pam_start("login", username, &pamc, &pamh); // инициализация: сервис, пользователь, две ссылки (в мане все написано) if (pam_err != PAM_SUCCESS) { pam_syslog("pam_start()"); bail(NO_SLEEP_EXIT, 1); //регситрируем ошибку } pam_err = pam_set_item(pamh, PAM_TTY, tty); // имя текущего терминала if (pam_err != PAM_SUCCESS) { pam_syslog("pam_set_item(PAM_TTY)"); bail(NO_SLEEP_EXIT, 1); //регситрируем ошибку } pam_err = pam_set_item(pamh, PAM_RHOST, hostname); // мой host if (pam_err != PAM_SUCCESS) { pam_syslog("pam_set_item(PAM_RHOST)"); bail(NO_SLEEP_EXIT, 1); //регситрируем ошибку }
pwd = getpwnam(username); // берем из passwd ... rval = auth_pam(); ... if (pwd && rval == 0) break; // success ...
да, я совсем забыл описать, что такое auth_pam /* * Attempt to authenticate the user using PAM. Returns 0 if the user is * authenticated, or 1 if not authenticated. If some sort of PAM system * error occurs (e.g., the "/etc/pam.conf" file is missing) then this * function returns -1. This can be used as an indication that we should * fall back to a different authentication mechanism. */ static int auth_pam(void) { const char *tmpl_user; const void *item; int rval;
pam_err = pam_authenticate(pamh, pam_silent); switch (pam_err) {
case PAM_SUCCESS: /* * With PAM we support the concept of a "template" * user. The user enters a login name which is * authenticated by PAM, usually via a remote service * such as RADIUS or TACACS+. If authentication * succeeds, a different but related "template" name * is used for setting the credentials, shell, and * home directory. The name the user enters need only * exist on the remote authentication server, but the * template name must be present in the local password * database. * * This is supported by two various mechanisms in the * individual modules. However, from the application's * point of view, the template user is always passed * back as a changed value of the PAM_USER item. */ pam_err = pam_get_item(pamh, PAM_USER, &item); if (pam_err == PAM_SUCCESS) { tmpl_user = (const char *)item; if (strcmp(username, tmpl_user) != 0) pwd = getpwnam(tmpl_user); } else { pam_syslog("pam_get_item(PAM_USER)"); } rval = 0; break;
case PAM_AUTH_ERR: case PAM_USER_UNKNOWN: case PAM_MAXTRIES: rval = 1; break;
default: pam_syslog("pam_authenticate()"); rval = -1; break; }
if (rval == 0) { pam_err = pam_acct_mgmt(pamh, pam_silent); switch (pam_err) { case PAM_SUCCESS: break; case PAM_NEW_AUTHTOK_REQD: pam_err = pam_chauthtok(pamh, pam_silent|PAM_CHANGE_EXPIRED_AUTHTOK); if (pam_err != PAM_SUCCESS) { pam_syslog("pam_chauthtok()"); rval = 1; } break; default: pam_syslog("pam_acct_mgmt()"); rval = 1; break; } }
if (rval != 0) { pam_end(pamh, pam_err); pamh = NULL; } return (rval); }
здесь вроде комментов много, да и код достаточно прозрачный, вот. таким образом, пользуйся. да, не забудь еще и в /etc/pam.d/ залезть и почитать README
|
|
« Последнее редактирование: 29-11-2007 17:11 от Алексей1153++ »
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #15 : 09-07-2004 09:21 » |
|
Russian, вобще эта тема обсуждалась только с друго бока обсуждалась здесь: https://forum.shelek.ru/index.php/topic,3123.0.htmlИ еще есть книга "Advanced Linux Programming" лежит тут: http://www.advancedlinuxprogramming.comСкачиваешь книгу. Читаешь главу 10. Там на паре страницы есть интересующие тебя разъяснения на тему pam и пример. Код примера можно взять там же. Вот он(думаю коментариев в коде достаточно да понимания): *********************************************************************** * Code listing from "Advanced Linux Programming," by CodeSourcery LLC * * Copyright (C) 2001 by New Riders Publishing * * See COPYRIGHT for license information. * ***********************************************************************/
#include <security/pam_appl.h> #include <security/pam_misc.h> #include <stdio.h>
int main () { pam_handle_t* pamh; struct pam_conv pamc;
/* Set up the PAM conversation. */ pamc.conv = &misc_conv; pamc.appdata_ptr = NULL; /* Start a new authentication session. */ pam_start ("su", getenv ("USER"), &pamc, &pamh); /* Authenticate the user. */ if (pam_authenticate (pamh, 0) != PAM_SUCCESS) fprintf (stderr, "Authentication failed!\n"); else fprintf (stderr, "Authentication OK.\n"); /* All done. */ pam_end (pamh, 0); return 0; }
При сборке незабуть указать библиотеки: -lpam -lpam_misc
|
|
« Последнее редактирование: 29-11-2007 17:12 от Алексей1153++ »
|
Записан
|
Странно всё это....
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #16 : 09-07-2004 11:36 » |
|
тоже не плохо
|
|
|
Записан
|
|
|
|
Russian
Гость
|
|
« Ответ #17 : 24-07-2004 15:05 » |
|
RXL, программист из меня пока некакой, вот я и прошу помощи!
LogRus, просмотрел я пока твой пример. Программу скомпилировал, запустил. Если запустить из под рута то всегда получаю положительный результат (это ясно почему), а если из под простого юзера, то запрашиваеться логин:пароль. Я ввожу их и получаю отрицательный ответ, хотя ввожу все правильно! Почему так? Может нужно производить настройки в /etc/pam.d/ !? И если да, то какие.
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #18 : 24-07-2004 15:36 » |
|
Russian, под рутом нужно для программы выполнить chmod u+s progname таким образом ты разрешишь программе меня UID пользователя.
|
|
|
Записан
|
Странно всё это....
|
|
|
Russian
Гость
|
|
« Ответ #19 : 25-07-2004 15:00 » |
|
LogRus, ура. Все получилось очень доже хорошо!!!! Большое спасибо всем-всем,... но из простого юзера я чтоли не могу запустить программу? Тогда это не очень хорошо или как?
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #20 : 26-07-2004 07:03 » |
|
но из простого юзера я чтоли не могу запустить программу? Тогда это не очень хорошо или как? Я тебя не понял. по подробней можно. может сделаем как надо .
|
|
|
Записан
|
Странно всё это....
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #21 : 26-07-2004 09:01 » |
|
Russian, а ты права на чтения дирректории /etc/pam.d и всем файлом в ней дал простому юзверю? надо сделать `chmod 644 /etc/pam.d/*`
|
|
|
Записан
|
|
|
|
Russian
Гость
|
|
« Ответ #22 : 26-07-2004 11:57 » |
|
Дело в том что мне нужно запустить прогу на серваке хостера! -bash-2.05b$ gcc -lpam -lpam_misc pam3.c -o pam3 /usr/libexec/elf/ld: cannot find -lpam_misc
Это то что я получил в ответ Если компилировать без -lpam_misc то компилируеться без проблем, но опять в любом случае дает ответ Authentication failed! Даю команду chmod u+s pam но и тут без результатов
|
|
« Последнее редактирование: 29-11-2007 17:14 от Алексей1153++ »
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #23 : 26-07-2004 12:41 » |
|
а ты на своей машине собрать не можешь. chmod u+s только root кажется может делать.
по позже попробую сам собрать её. мосмотрим чего получится. часов в 7 смотри что получилось
|
|
|
Записан
|
Странно всё это....
|
|
|
Антон (LogRus)
|
|
« Ответ #24 : 26-07-2004 15:07 » |
|
Посмотрел код, попробовал собрать. У меня собиралось только с -lpam_misc Далее программа пробует провести аутентификацю за пользователя чей логин находится в переменной окружения USER. я запускал для теста рута так: logrus@gentoo_chaos_comp pam $ gcc -o pam pam.c -lpam -lpam_misc logrus@gentoo_chaos_comp pam $ sudo chown root pam logrus@gentoo_chaos_comp pam $ sudo chmod u+s pam logrus@gentoo_chaos_comp pam $ ./pam Password: Authentication failed! logrus@gentoo_chaos_comp pam $ ./pam Password: Authentication OK. logrus@gentoo_chaos_comp pam $ env|grep USER USER=logrus logrus@gentoo_chaos_comp pam $ USER="root" ./pam Password: Authentication failed! logrus@gentoo_chaos_comp pam $ USER="root" ./pam Password: Authentication OK.
1. собрал 2. сменил владельца 3. сменил режим доступа 4. пробуем атентифицию для своего пользователя. вводим не верный пароль. 5. пробуем атентифицию для своего пользователя. вводим верный пароль. 6. смотрим состояние переменной окружения USER 7. пробуем атентификацию для рута. вводим не верный пароль. 8. пробуем атентификацию для рута. вводим верный пароль. Вот так. Как и обещал.
|
|
« Последнее редактирование: 29-11-2007 17:16 от Алексей1153++ »
|
Записан
|
Странно всё это....
|
|
|
Russian
Гость
|
|
« Ответ #25 : 26-07-2004 16:56 » |
|
LogRus, дело то в том что я не могу выполнить sudo chown root pam т.к. я не знаю пароль рута! Система то не моя, а провайдера. На своей машине у меня все без проблем!, конечно не без вашей помощи. Допустим я собрал на своей машине и закатал прогу на сервак. Но это нечего не даст! Собирать я могу и на сервере. Плохи дела как я понимаю
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #26 : 26-07-2004 18:30 » |
|
Russian, вообще-то есть вполне нормальный выход из сложившейся ситуации. вернее два выхода первый: для sudo не нужен пароль рута. нужен твой пароль -> можно попрасить админа свисать тебя в список sudo. второй: попросить админа выполнить за тебя эти процедуры.(более вероятно) Большенство нормальных хостеров разрешают ставит всякие такие штуки, но при условии, что ты об этом просишь. А может тебе оно нафиг не надо? И еще помоему можно менять пользователей внутри группы без установки в качестве владельца рута.
|
|
|
Записан
|
Странно всё это....
|
|
|
Russian
Гость
|
|
« Ответ #27 : 27-07-2004 11:52 » |
|
LogRus, ясно. Ну ладно, спасибо всем. Программа работает и это главное, а как ее запустить я уж сам подумаю
|
|
|
Записан
|
|
|
|
Russian
Гость
|
|
« Ответ #28 : 11-08-2004 22:19 » |
|
Вот еще вопрос появился! В выше указаной программе пароль можно ввести только после запроса, а как его ввести уже через программу?
|
|
|
Записан
|
|
|
|
.
Молодой специалист
Offline
Пол:
|
|
« Ответ #29 : 12-08-2004 08:02 » |
|
Russian, в начале следующей недели я положу статью по PAM'у Если дело терпит, то подожди, пожалуйста... я ее доработаю, рассмотрев дополнително и этот вопрос.
|
|
|
Записан
|
|
|
|
|