#include <stdio.h> /* cc -lc_s */
#include <pwd.h>
#include <signal.h>
struct passwd *p;
char userName[80], *pass, *crpass;
extern char *getpass(), *crypt();
...
/* Не прерываться по сигналам с клавиатуры */
signal (SIGINT, SIG_IGN);
for(;;){
/* Запросить имя пользователя: */
printf("Login: "); gets(userName);
/* Запросить пароль (без эха): */
pass = getpass("Password: ");
/* Проверить имя: */
if(p = getpwnam(userName)){
/* есть такой пользователь */
crpass = (p->pw_passwd[0]) ? /* если есть пароль */
crypt(pass, p->pw_passwd) : pass;
if( !strcmp( crpass, p->pw_passwd))
break; /* верный пароль */
}
printf("Login incorrect.\a\n");
}
signal (SIGINT, SIG_DFL);
// ... запись информации о входе пользователя в систему
// в файлы /etc/utmp (кто работает в системе сейчас)
// и /etc/wtmp (список всех входов в систему)
...
setuid( p->pw_uid ); setgid( p->pw_gid );
chdir ( p->pw_dir ); /* GO HOME! */
// эти параметры будут унаследованы
// интерпретатором команд.
...
// настройка некоторых переменных окружения envp:
// HOME = p->pw_dir
// SHELL = p->pw_shell
// PATH = нечто по умолчанию, вроде :/bin:/usr/bin
// LOGNAME (USER) = p->pw_name
// TERM = считывается из файла
// /etc/ttytype по имени устройства av[1]
// Делается это как-то подобно
// char *envp[MAXENV], buffer[512]; int envc = 0;
// ...
// sprintf(buffer, "HOME=%s", p->pw_dir);
// envp[envc++] = strdup(buffer);
// ...
// envp[envc] = NULL;
...
// настройка кодов доступа к терминалу. Имя устройства
// содержится в параметре av[1] функции main.
chown (av[1], p->pw_uid, p->pw_gid);
chmod (av[1], 0600 ); /* -rw------- */
// теперь доступ к данному терминалу имеют только
// вошедший в систему пользователь и суперпользователь.
// В случае смерти интерпретатора команд,
// которым заменится getty, процесс init сойдет
// с системного вызова ожидания wait() и выполнит
// chown ( этот_терминал, 2 /*bin*/, 15 /*terminal*/ );
// chmod ( этот_терминал, 0600 );
// и, если терминал числится в файле описания линий
// связи /etc/inittab как активный (метка respawn), то
// init перезапустит на этом_терминале новый
// процесс getty при помощи пары вызовов fork() и exec().
...
// запуск интерпретатора команд:
execle( *p->pw_shell ? p->pw_shell : "/bin/sh",
"-", NULL, envp );
Программная аутентификация пользователя под Linux
Вот клиент хочет, чтобы мы написали клиент-сервер, и при этом чтобы при коннекте клиент логинился под определенным эккаунтом при чем существующим под данной системой Linux. Все остальное мы знаем как написать, но я в жизни никогда не использовал юзверей системы из программы. Подскажите пожалуйста как реализовать то что он хочет? Серверная программа работает под амином. А клиентская должна логинится запрашивать логин-пароль, после чего сервер должен выполнять действия для данного клиента но в процессе под правами данного пользователя.
Возможно ли это реализовать и в какую сторону копать?
Заранее спасибо.
С уважением,
Иванов Артем.
Цитата:
Originally posted by cubereality
Всем привет,
Вот клиент хочет, чтобы мы написали клиент-сервер, и при этом чтобы при коннекте клиент логинился под определенным эккаунтом при чем существующим под данной системой Linux. Все остальное мы знаем как написать, но я в жизни никогда не использовал юзверей системы из программы. Подскажите пожалуйста как реализовать то что он хочет? Серверная программа работает под амином. А клиентская должна логинится запрашивать логин-пароль, после чего сервер должен выполнять действия для данного клиента но в процессе под правами данного пользователя.
Возможно ли это реализовать и в какую сторону копать?
Заранее спасибо.
С уважением,
Иванов Артем.
Всем привет,
Вот клиент хочет, чтобы мы написали клиент-сервер, и при этом чтобы при коннекте клиент логинился под определенным эккаунтом при чем существующим под данной системой Linux. Все остальное мы знаем как написать, но я в жизни никогда не использовал юзверей системы из программы. Подскажите пожалуйста как реализовать то что он хочет? Серверная программа работает под амином. А клиентская должна логинится запрашивать логин-пароль, после чего сервер должен выполнять действия для данного клиента но в процессе под правами данного пользователя.
Возможно ли это реализовать и в какую сторону копать?
Заранее спасибо.
С уважением,
Иванов Артем.
привет.
да все просто - тебе надо вызвать
setuid(newuid);
и т.к. твоя программа изначально запущена из под рута, то тебе это позволено. Ну и дальше делай что надо....потом сменишь обратно.
ну и так же с поомщью getuid() можно проверить текушие привелегии.
То есть алгоритм такой :
1. от клиента передается login
2. производится попытка сменить id процеса на этот id и заодно проверяется на существование в си-ме этого id:
Код:
это конечно просто пример, много лишнего, но суть, думаю, ясна.