Защита файлов в операционной системе UNIX
Сергей Кузнецов
С самого начала ОС UNIX замышлялась как интерактивная система.
Другими словами, UNIX предназначен для терминальной работы. Чтобы
начать работать, человек должен "войти" в систему, введя со
свободного терминала свое учетное имя (account name) и, возможно,
пароль (password). Человек, зарегистрированный в учетных файлах
системы и, следовательно, имеющий учетное имя, называется
зарегистрированным пользователем системы. Регистрацию новых
пользователей обычно выполняет администратор системы.
Пользователь не может изменить свое учетное имя, но может
установить и/или изменить свой пароль. Пароли хранятся в
отдельном файле в закодированном виде. Не забывайте свой пароль,
снова узнать его не поможет даже администратор!
Все пользователи ОС UNIX явно или неявно работают с файлами.
Файловая система ОС UNIX имеет древовидную структуру.
Промежуточными узлами дерева являются каталоги со ссылками на
другие каталоги или файлы, а листья дерева соответствуют файлам
или пустым каталогам. Каждому зарегистрированному пользователю
соответствует некоторый каталог файловой системы, который
называется "домашним" (home) каталогом пользователя. При входе в
систему пользователь получает неограниченный доступ к своему
домашнему каталогу и всем каталогам и файлам, содержащимся в нем.
Пользователь может создавать, удалять и модифицировать каталоги и
файлы, содержащиеся в домашнем каталоге. Потенциально возможен
доступ и ко всем другим файлам, однако он может быть ограничен,
если пользователь не имеет достаточных привилегий.
Поскольку ОС UNIX с самого своего зарождения задумывалась как
многопользовательская операционная система, в ней всегда была
актуальна проблема авторизации доступа различных пользователей к
файлам файловой системы. Под авторизацией доступа понимаются
действия системы, которые допускают или не допускают доступ
данного пользователя к данному файлу в зависимости от прав
доступа пользователя и ограничений доступа, установленных для
файла. Схема авторизации доступа, примененная в ОС UNIX,
настолько проста и удобна и одновременно настолько мощна, что
стала фактическим стандартом современных операционных систем (не
претендующих на качества систем с многоуровневой защитой).
С каждым выполняемым процессом в ОС UNIX связываются реальный
идентификатор пользователя и действующий идентификатор
пользователя. Эти идентификаторы устанавливаются с помощью
системного вызова setuid, который можно выполнять только в режиме
суперпользователя (администратора системы). Аналогично, с каждым
процессом связываются два идентификатора группы пользователей -
реальный и действующий. Эти идентификаторы устанавливаются
привилегированным системным вызовом setgid.
При входе пользователя в систему программа login проверяет, что
пользователь зарегистрирован в систему и знает правильный пароль
(если он установлен), образует новый процесс и запускает в нем
требуемый для данного пользователя shell. Но перед этим login
устанавливает для вновь созданного процесса идентификаторы
пользователя и группы, используя информацию, хранящуюся в файлах
/etc/passwd и /etc/group. После того, как с процессом связаны
идентификаторы пользователя и группы, для этого процесса начинают
действовать ограничения для доступа к файлам. Процесс может
получить доступ к файлу или выполнить его (если файл содержит
выполняемую программу) только в том случае, если хранящиеся при
файле ограничения доступа позволяют это сделать. Связанные с
процессом идентификаторы передаются создаваемым им процессам,
распространяя на них те же ограничения. Однако в некоторых
случаях процесс может изменить свои права с использованием
системных вызовов setuid и setgid, а иногда система может
изменить права доступа процесса автоматически.
Рассмотрим, например, следующую ситуацию. В файл /etc/passwd
запрещена запись всем, кроме суперпользователя (суперпользователь
может писать в любой файл). Этот файл, помимо прочего, содержит
пароли пользователей, и каждому пользователю разрешается изменять
свой пароль. Имеется специальная программа /bin/passwd,
изменяющая пароли. Однако пользователь не может сделать это даже
с помощью этой программы, поскольку запись в файл /etc/passwd
запрещена. В системе UNIX эта проблема разрешается следующим
образом. При выполняемом файле может быть указано, что при его
запуске должны устанавливаться идентификаторы пользователя и/или
группы. Если пользователь запрашивает выполнение такой программы
(с помощью системного вызова exec), то для соответствующего
процесса устанавливаются идентификатор пользователя,
соответствующий идентификатору владельца выполняемого файла и/или
идентификатор группы этого владельца. В частности, при запуске
программы /bin/passwd процесс получит идентификатор
суперпользователя, и программа сможет произвести запись в файл
/etc/passwd.
И для идентификатора пользователя, и для идентификатора группы
реальный ID является истинным идентификатором, а действующий ID -
идентификатором текущего выполнения. Если текущий идентификатор
пользователя соответствует суперпользователю, то этот
идентификатор и идентификатор группы могут быть переустановлен в
любое значение системными вызовами setuid и setgid. Если же
текущий идентификатор пользователя отличается от идентификатора
суперпользователя, то выполнение системных вызовов setuid и
setgid приводит к замене текущего идентификатора истинным
идентификатором (пользователя или группы соответственно).
Как и полагается делать в многопользовательской операционной
системе, в UNIX поддерживается единообразный механизм контроля
доступа к файлам и справочникам файловой системы. Любой процесс
может получить доступ к некоторому файлу в том и только в том
случае, если права доступа, описанные при файле, соответствуют
возможностям данного процесса.
Защита файлов от несанкционированного доступа в ОС UNIX
основывается на трех фактах. Во-первых, с любым процессом,
создающим файл (или справочник), ассоциирован некоторый
уникальный в системе идентификатор пользователя, который в
дальнейшем можно трактовать как идентификатор владельца вновь
созданного файла. Во-вторых, с каждый процессом, пытающимся
получить некоторый доступ к файлу, связана пара идентификаторов -
действующие идентификаторы пользователя и его группы. В-третьих,
каждому файлу однозначно соответствует его описатель - i-узел.
На последнем факте стоит остановиться более подробно. Важно
понимать, что имена файлов и файлы как таковые - это не одно и то
же. В частности, при наличии нескольких жестких связей с одним
файлом несколько имен файла реально представляют один и тот же
файл и ассоциированы с одним и тем же i-узлом. Любому
используемому в файловой системе i-узлу всегда однозначно
соответствует один и только один файл. I-узел содержит достаточно
много разнообразной информации (большая ее часть доступна
пользователям через системные вызовы stat и fstat), и среди этой
информации находится часть, позволяющая файловой системе оценить
правомочность доступа данного процесса к данному файлу в
требуемом режиме.
Общие принципы защиты одинаковы для всех существующих вариантов
системы: Информация i-узла включает идентификаторы текущего
владельца файла (немедленно после создания файла идентификаторы
его текущего владельца устанавливаются соответствующими
действующим идентификатором процесса-создателя, но в дальнейшем
могут быть изменены системными вызовами chown и chgrp). Кроме
того, в i-узле файла хранится шкала, в которой отмечено, что
может делать с файлом пользователь - его владелец, что могут
делать с файлом пользователи, входящие в ту же группу
пользователей, что и владелец, и что могут делать с файлом
остальные пользователи.
Мелкие детали реализации в разных вариантах системы различаются,
однако в целом именно такова общая картина защиты файлов в ОС
UNIX.