Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Программная аутентификация пользователя под Linux

1.7K
01 марта 2006 года
cubereality
65 / / 28.06.2005
Всем привет,

Вот клиент хочет, чтобы мы написали клиент-сервер, и при этом чтобы при коннекте клиент логинился под определенным эккаунтом при чем существующим под данной системой Linux. Все остальное мы знаем как написать, но я в жизни никогда не использовал юзверей системы из программы. Подскажите пожалуйста как реализовать то что он хочет? Серверная программа работает под амином. А клиентская должна логинится запрашивать логин-пароль, после чего сервер должен выполнять действия для данного клиента но в процессе под правами данного пользователя.

Возможно ли это реализовать и в какую сторону копать?

Заранее спасибо.

С уважением,
Иванов Артем.
15K
02 марта 2006 года
borodatyi
16 / / 06.02.2006
Цитата:
Originally posted by cubereality
Всем привет,

Вот клиент хочет, чтобы мы написали клиент-сервер, и при этом чтобы при коннекте клиент логинился под определенным эккаунтом при чем существующим под данной системой Linux. Все остальное мы знаем как написать, но я в жизни никогда не использовал юзверей системы из программы. Подскажите пожалуйста как реализовать то что он хочет? Серверная программа работает под амином. А клиентская должна логинится запрашивать логин-пароль, после чего сервер должен выполнять действия для данного клиента но в процессе под правами данного пользователя.

Возможно ли это реализовать и в какую сторону копать?

Заранее спасибо.

С уважением,
Иванов Артем.



привет.
да все просто - тебе надо вызвать
setuid(newuid);
и т.к. твоя программа изначально запущена из под рута, то тебе это позволено. Ну и дальше делай что надо....потом сменишь обратно.

ну и так же с поомщью getuid() можно проверить текушие привелегии.


То есть алгоритм такой :
1. от клиента передается login
2. производится попытка сменить id процеса на этот id и заодно проверяется на существование в си-ме этого id:

Код:
#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 );


это конечно просто пример, много лишнего, но суть, думаю, ясна.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог