- •Введение
- •Глава 1. Фундаментальные концепции unix Систем
- •Программы, процессы и потоки
- •Сигналы
- •Идентификаторы процессов, группы процессов и сеансы
- •Система прав
- •Другие атрибуты процесса
- •Межпроцессное взаимодействие
- •Использование системных вызовов
- •Краткие описания функций и обработка ошибок
- •Контрольные вопросы
- •Литература
- •Глава 2. Базовые операции ввода-вывода
- •Файловые операции ввода - вывода
- •Стандартные дескрипторы
- •Системные вызовы open и creat
- •Системный вызов umask
- •Системный вызов unlink
- •Текущая позиция в файле
- •Системный вызов write
- •2.8. Системный вызов read
- •2.9. Системный вызов close
- •2.10. Системный вызов lseek
- •2.11. Системные вызовы pread и pwrite
- •2.12. Системные вызовы truncate и ftruncate
- •Контрольные вопросы
- •Литература
- •Глава 3. Дополнительные операции файлового ввода_вывода
- •Низкоуровневый доступ к файловой системе
- •Жесткие и символические ссылки
- •Системный вызов getcwd
- •Отображение метаданных файла
- •Системные вызовы getpwuid, getgrgid и getlogin
- •Каталоги
- •Системные вызовы chdir и fchdir
- •Системные вызовы mkdir и rmdir
- •Контрольные вопросы
- •Литература
- •Глава 4. Процессы и потоки
- •4.1. Среда окружения
- •Системный вызов exec
- •Системный вызов fork
- •Завершение процесса и системные вызовы exit
- •Системные вызовы wait, waitpid и waitid
- •Получение и изменение идентификаторов пользователя и группы
- •Получение и изменение приоритета
- •Контрольные вопросы
- •Литература
- •Глава 5. Механизмы межпроцессного взаимодействия
- •5.1. Каналы
- •5.2. Системные вызовы dup и dup2
- •5.3. Двунаправленное взаимодействие с использованием однонаправленных каналов
- •Контрольные вопросы
- •Литература
- •Глава 6.Механизмы взаимодействия процессов
- •Именованные каналы (fifo)
- •Системные вызовы для работы с очередями сообщений posix
- •Семафоры
- •Системные вызовы для работы с общей памятью posix
- •Контрольные вопросы
- •Литература
- •Глава 7.Сетевое взаимодействие и сокеты
- •Основные системные вызовы для работы с сокетами, образующими логические соединения
- •Обслуживание нескольких клиентов
- •Адресация сокетов
- •In_port_t sin_port; /* номер порта (uint16_t) */
- •In_addr_t s_addr; /* адрес iPv4 (uint32_t) */
- •Домен адресов af_inet6
- •In_port_t sin6_port; /* номер порта (uint16_t) */
- •Доменная система именования
- •Параметры сокетов
- •Контрольные вопросы
- •Литература
- •Глава 8.Сигналы и таймеры
- •Введение в сигналы
- •Жизненный цикл сигналов
- •Типы сигналов
- •Системный вызов sigaction
- •Контрольные вопросы
- •Литература
- •Заключение
- •Список литературы
- •Глава 2. Базовые операции ввода-вывода 14
- •Глава 3. Дополнительные операции файлового ввода_вывода 25
- •Глава 6. Механизмы взаимодействия процессов 58
Получение и изменение идентификаторов пользователя и группы
Приведем группу системных вызовов, с помощью которых можно узнать реальные и действующие идентификаторы пользователя и группы:
getuid - возвращает реальный идентификатор пользователя
#include <unistd.h>
uid_t getuid(void);
/* Возвращает идентификатор пользователя (коды ошибок не предусмотрены) */
geteuid - возвращает действующий идентификатор пользователя
#include <unistd.h>
uid_t geteuid(void);
/* Возвращает идентификатор пользователя (коды ошибок не предусмотрены) */
getgid - возвращает реальный идентификатор группы
#include <unistd.h>
gid_t getgid(void);
/* Возвращает идентификатор группы (коды ошибок не предусмотрены) */
getegid - возвращает действующий идентификатор группы
#include <unistd.h>
gid_t getegid(void);
/* Возвращает идентификатор группы (коды ошибок не предусмотрены) */
Идентификатор пользователя или группы - это просто некоторое число. Если хотите получить имя, то нужно обратиться к системным вызовам getpwuid и getgrgid.
Правила изменения реального и действующего идентификаторов пользователя и группы достаточно сложны и различаются для обычных процессов и процессов, работающих с правами суперпользователя. Помимо текущих реальных и действующих идентификаторов, для каждого процесса ядро хранит оригинальные действующие идентификаторы, которые были установлены последним вызовом exec. Они называются сохраненные идентификаторы. Ниже приводятся правила изменения идентификатора пользователя (они применимы и для идентификатора группы):
Обычный процесс не может изменить реальный или сохраненный идентификаторы иначе как через вызов exec, который может изменить сохраненный идентификатор.
Обычный процесс может изменить действующий идентификатор на реальный или сохраненный.
Процесс, обладающий правами суперпользователя, может изменить реальный и действующий идентификаторы на любой другой.
Когда суперпользовательский процесс изменяет реальный идентификатор, сохраненный идентификатор получает то же значение.
С суперпользовательскими процессами все понятно - допускается все, что угодно. Два правила, затрагивающие обычные процессы означают следующее: если вызов exec изменил реальный и действующий идентификаторы, то процесс имеет возможность переключаться между ними. Системные вызовы для процесса с правами обычного пользователя - seteuid и setegid:
seteuid - устанавливает действующий идентификатор пользователя
#include <unistd.h>
int seteuid (
uid_t uid /* действующий идентификатор пользователя */
);
/* Возвращает 0 в случае успеха, -1 в случае ошибки (код ошибки в переменной errno) */
setegid - устанавливает действующий идентификатор группы
#include <unistd.h>
int setegid (
gid_t gid /* действующий идентификатор группы */
);
/* Возвращает 0 в случае успеха, -1 в случае ошибки (код ошибки в переменной errno) */
В распоряжении суперпользователя имеются два дополнительных системных вызова:
setuid - устанавливает реальный идентификатор пользователя
#include <unistd.h>
int setuid (
uid_t uid /* реальный и сохраненный идентификатор пользователя */
);
/* Возвращает 0 в случае успеха, -1 в случае ошибки (код ошибки в переменной errno) */
setgid - устанавливает реальный идентификатор группы
#include <unistd.h>
int setgid (
gid_t gid /* реальный и сохраненный идентификатор группы */
);
/* Возвращает 0 в случае успеха, -1 в случае ошибки (код ошибки в переменной errno) */
В случае суперпользователя, в качестве аргумента допускается передавать идентификатор любого пользователя, который станет сразу и реальным и сохраненным. В случае обычного пользователя эти вызовы ведут себя аналогично двум предыдущим, что может порой вводить в заблуждение.
Процесс может получить свой идентификатор и идентификатор предка с помощью системных вызовов:
getpid - возвращает идентификатор процесса
#include <unistd.h>
pid_t getpid(void);
/* Возвращает идентификатор процесса */
getppid - возвращает идентификатор родительского процесса
#include <unistd.h>
pid_t getppid(void);
/* Возвращает идентификатор родительского процесса */