Когда запускается set-user-ID-программа, действующий пользовательский идентификатор процесса устанавливается на то значение, которое имеется у владельца файла. Этот механизм позволяет пользователю присвоить идентификатор, а следовательно, и полномочия другого пользователя при запуске конкретной программы. Аналогично, программы с полномочиями setgid изменяют действующий групповой ID процесса, в котором выполняется программа. Сохраненный установленный идентификатор пользователя (saved set-user-ID) и сохраненный установленный идентификатор группы (saved set-group-ID) позволяют программам с полномочиями setuid и setgid временно сбрасывать, а затем позже восстанавливать полномочия.

Пользовательский ID, равный нулю, имеет специальное значение. Обычно его имеет только одна учетная запись с именем root. Процессы с действующим идентификатором пользователя, равным нулю, являются привилегированными, то есть освобождаются от многих проверок полномочий, которые обычно выполняются при осуществлении процессом различных системных вызовов (например, при произвольном изменении различных пользовательских и групповых идентификаторов процесса).

9.9. Упражнения

9.1. Предположим, что в каждом из следующих случаев исходный набор пользовательских идентификаторов процесса такой: реальный = 1000, действующий = 0, сохраненный = 0, файловой системы = 0. Какими станут пользовательские идентификаторы после следующих вызовов:

1) setuid(2000);

2) setreuid(–1, 2000);

3) seteuid(2000);

4) setfsuid(2000);

5) setresuid(–1, 2000, 3000)?

9.2. Является ли привилегированным процесс со следующими идентификаторами пользователя? Обоснуйте ответ.

real=0 effective=1000 saved=1000 file-system=1000

9.3. Реализуйте функцию initgroups(), используя setgroups() и библиотечные функции, для извлечения информации из файлов паролей и групп (см. раздел 8.4). Не забудьте, что для возможности вызова setgroups() процесс должен быть привилегированным.

9.4. Если процесс, чьи пользовательские идентификаторы имеют одинаковое значение X, выполняет set-user-ID-программу, пользовательский идентификатор которой равен Y и имеет ненулевое значение, то полномочия процесса устанавливаются следующим образом:

real=X effective=Y saved=Y

(Мы игнорируем пользовательский идентификатор файловой системы, поскольку его значение следует за действующим идентификатором пользователя.) Запишите соответственно вызовы setuid(), seteuid(), setreuid() и setresuid(), которые будут применяться для выполнения таких операций, как:

1) приостановление и возобновление set-user-ID-идентичности (то есть переключение действующего идентификатора пользователя на значение реального пользовательского идентификатора, а затем возвращение к сохраненному установленному идентификатору пользователя);

2) безвозвратный сброс set-user-ID-идентичности (то есть гарантия того, что для действующего пользовательского идентификатора и сохраненного установленного идентификатора пользователя устанавливается значение реального идентификатора пользователя).

(Это упражнение также требует использования вызовов getuid() и geteuid() для извлечения реального и действующего идентификаторов пользователя.) Учтите, что для некоторых системных вызовов ряд этих операций не может быть выполнен.

9.5. Повторите предыдущее упражнение для процесса выполнения set-user-ID-root-программы, у которой следующий исходный набор идентификаторов процесса:

real=X effective=0 saved=0

<p>10. Время</p>

При выполнении программы нас могут интересовать два вида времени.

• Реальное время. Это время, отмеренное либо от какого-то стандартного момента (календарное время), либо от какого-то фиксированного момента в жизни процесса, обычно от его запуска (затраченное или физическое время). Получение календарного времени требуется в программах, которые, к примеру, ставят отметки времени на записях баз данных или на файлах. Замеры затраченного времени нужны в программах, предпринимающих периодические действия или совершающих регулярные замеры на основе данных, поступающих от внешних устройств ввода.

• Время процесса. Это продолжительность использования процессом центрального процессора. Замеры времени процесса нужны для проверки или оптимизации производительности программы либо алгоритма.

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

10.1. Календарное время
Перейти на страницу:

Похожие книги