Хрестоматия по программированию на Си в Unix



Системные вызовы и взаимодействие с UNIX. Хрестоматия по программированию на Си в Unix - стр. 12


Откуда же изначально берутся значения uid и ruid (а также gid и rgid) у процесса? Они берутся из процесса регистрации пользователя в системе: /etc/getty. Этот процесс запускается на каждом терминале как процесс, принадлежащий суперпользователю (u_uid==0). Сначала он запрашивает имя и пароль пользователя:

#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 );




Содержание  Назад  Вперед