Мир на трёх кашалотах мается
2. Файлы

Глава из книги Сага о FreeBSD

Алексей Федорчук

2008-11-19

назад | к началу

Право на файл

В начале этого параграфа были вскользь упомянуты прочие атрибуты файла — принадлежности, доступа и режима. Это — очень важные понятия для FreeBSD, которые, однако, психологически трудны для понимания пользователя, пришедшего из мира DOS/Windows.

Впрочем, смысл атрибутов принадлежности интуитивно понятен: каждый файл в системе, а) имеет своего хозяина, б) приписан к какой-либо группе пользователей, и в) находится в неких отношениях со всеми прочими пользователями. В качестве хозяина файла обычно выступает его создатель. Точнее, хозяин процесса, этот файл создавшего. А еще точнее — пользователь, идентификатор которого был унаследован процессом, создавшим файл, в качестве эффективного UID. То есть если процесс этот по каким-либо причинам получил привилегии root-оператора, то и созданный им файл будет иметь своим хозяином его, а не пользователя, на самом деле процесс запустившего.

Далее, каждый файл приписывается по умолчанию к некоторой группе. По умолчанию во FreeBSD, в отличие от Linux'а, групповая его принадлежность наследуется от родительского каталога, а не от группы пользователя — хозяина файла. Однако хозяин файла может изменить группу своего файла, правда, только на ту, членом которой он сам является. И именно отнесение файла к некоей группе широко используется для разграничения доступа, организации коллективной работы и прочих задач администрирования. Ну и все "прочие" также имеют некие права на файл — и не обязательно более узкие, чем члены его группы (или даже хозяин).

С атрибутами доступа дело несколько сложнее. Основных из них также три: атрибут чтения, изменения, исполнения, причем смысл их различается для каталогов и всех прочих файлов. Начнем со вторых.

Право на чтение (read или, сокращённо, r) файла — это возможность увидеть его содержимое командой просмотра файлов (естественно, только для обычного файла, файлы устройств, сокеты или каналы просмотреть таким образом нельзя, а попытка просмотра символической ссылки вызовет ее файл-источник), открыть в текстовом редакторе или какой-либо иной прикладной программе. Атрибут изменения (write, сокращенно w) также понятен — он дает право изменить содержимое файла, вплоть до полного удаления (содержимого, но не файла! — никакие атрибуты файла не имеют отношения к возможности его удаления). А атрибут исполнения (execute, сокращённо x) означает возможность запустить откомпилированный бинарник или скрипт: именно присвоение этого атрибута волшебным образом превращает набранную в текстовом редакторе последовательность команд в сценарий оболочки.

Для каталога же атрибут чтения позволяет просмотреть командой ls (или каким бы то ни было иным способом) его содержимое. А по предыдущему параграфу мы помним, что все содержимое каталога — это просто список имен входящих в него файлов. И потому право на изменение каталога — это возможность этот самый список модифицировать. Например, удалить из него какое-либо имя, или создать новое (путем перемещения ли, копирования файла, или записи некоторых данных из программы). А поскольку больше имя файла нигде не фигурирует, лишившись его, файл становится недоступным для системы — то есть удаленным. При этом прошу обратить внимание: никаких особенных прав на сам файл не требуется, в общем случае можно удалить файл, не имея на него прав не только изменения, но даже чтения, достаточно обладать правом на изменение каталога. При этом, зная точно имя удаляемого файла и полный путь к нему, можно не иметь и права на чтение каталога, к которому файл приписан.

Наконец, атрибут исполнения для каталога дает право входить в него командой cd. Всего-то навсего, но без этого права какие-либо операции над файлами внутри каталога становятся затруднительными. Хотя и не невозможными — достаточно знать имя файла и полный путь к нему. Однако право исполнения и право чтения для каталога тесно сопряжены друг с другом — возможность перехода в каталог дает мало радости при отсутствии права его просмотреть. И обычно следует предоставлять для каталога или оба права, или ни одного. Тем не менее, права эти — разные, и иногда это может быть использовано для разграничения доступа.

Атрибуты доступа сцеплены с атрибутами принадлежности. То есть для каждой категории обладателей файла (даже прочих — они тоже в определенной мере обладатели файла) может быть установлено свое (и теоретически любое) сочетание прав на доступ к нему. Так, пользователь может иметь право на чтение, изменение и (если это оправдано по смыслу) исполнение файла или каталога (очевидно, что право исполнения, например, TIFF-файла ни малейшего смысла не имеет), группа и прочие — иметь права чтения и, если нужно, исполнения: это схема, по которой обычно по умолчанию распределяются атрибуты вновь создаваемого файла.

Можно запретить любой доступ к своим файлам для прочих, оставив их только для группы особо избранных товарищей. А можно, напротив, запретить право чтения и исполнения для группы, сохранив их для прочих: в этом случае группа товарищей превращается в группу, скажем так, не-товарищей. Ведь права доступа проверяются при обращении к нему в строгом порядке: пользователь -> группа -> прочие. И потому, если чтение файла запрещено для членов группы, к которой файл приписан, их попытки ознакомиться с ним будут отвергнуты, тогда как все прочие прочтут файл беспрепятственно...

Кроме атрибутов принадлежности и доступа, которые присваиваются файлу (или, напротив, отнимаются у него) в обязательном порядке, он может иметь и три дополнительных атрибута, называемых иногда атрибутами режима. Для названия их удобочитаемого русского перевода не существует. А на вражьей мове это атрибут suid (Set User IDentificator), иногда именуемый битом "суидности", sgid (Set Group IDentificator) и sticky (что можно трактовать как атрибут "липкости" или "сохранности"). Первые два, сокращенно обозначаемые s, имеют смысл только для исполняемых обычных файлов, последний же (сокращённо t) — в основном для каталогов.

Атрибут "суидности" обеспечивает механизм, благодаря которому пользователю удается изменить свой пароль без помощи администратора. А именно: файл, которому он присвоен, при запуске на выполнение (именно потому он имеет смысл только для файлов с атрибутом исполнения) порождает процесс, наследующий эффективный UID не юзера, его запустившего, а хозяина файла, правами доступа которого и определяются привилегии процесса. А поскольку хозяином подавляющего большинства файлов за пределами домашних каталогов является root, именно его-то права процессу обычно и достаются. Смысл атрибута sgid аналогичен, только тут процессом наследуется не эффективный UID пользователя, а эффективный GID группы, к которой приписан помеченный файл.

Атрибут sticky присваивается обычно каталогам, и влечет за собой невозможность удаления из него файла кем бы то ни было, за исключением владельца файла — ведь в обычном случае для этого достаточно иметь права доступа не к файлу, а к каталогу. Установка его целесообразна для каталогов, хранящих всякого рода временные данные (типа /tmp и некоторых подкаталогов ветви /var), права доступа к которым по умолчанию (и по смыслу) допускают их модификацию всеми пользователями. Однако, если право на запись временных файлов пользователь вряд ли сможет использовать во вред, то удаление из таких каталогов чужих файлов наверняка не будет приветствоваться их хозяином. И именно для предотвращения такой ситуации предназначен атрибут sticky.

Сведения обо всех атрибутах файла можно получить посредством команды ls в "длинном" формате (с опцией -l). Или — от какого-либо файлового менеджера. Хотя, на мой взгляд, команда ls ничуть не менее информативна и выразительна. Что я и попытаюсь продемонстрировать в соответствующей главе.

В обычном выводе команды ls -l имена пользователя и группы находятся в третьем и четвертом полях, а атрибуты доступа объединены в первом. Он имеет вид

-rwxrwxrwx

что расшифровывается следующим образом. Первая позиция последовательности — тип файла. Символ дефиса, -, в примере означает, что мы имеем дело с обычным файлом. Для каталога на этом месте был бы символ d — от directory, для символьного устройства — символ c. А так как блочных устройств во FreeBSD больше нет, то символом c будут маркированы все файлы в каталоге /dev.

Следующие три символа определяют атрибуты доступа для хозяина файла (owner): r — чтение, w — изменение, x — исполнение. Две последние тройки символов — суть то же самое, но для группы (group) и прочих (other), соответственно. То есть в данном примере фигурирует исполняемый файл, открытый на чтение, запись и запуск для всех. Если же у кого-либо какое-то право отнято — в соответствующей позиции мы увидим символ дефиса. Так, атрибуты нового текстового файла по описанной выше умолчальной схеме будут выглядеть как

-rw-r--r--

Если файлу приписан атрибут суидности, в тройке владельца место символа x займет символ s, а при наличии атрибута sgid то же s окажется на месте x в тройке группы. Атрибут "липкости" маркируется символом t в последней позиции (вместо x для "прочих"). То есть вывод команды

ls -l /usr/bin/passwd

будет выглядеть так:

-r-sr-xr-x

а прочие возможные варианты предлагается домыслить самостоятельно.

Выше при описании прав доступа использована так называемая символьная нотация, простая и мнемонически понятная (r — от read, w — от write, и т.д.). Однако наряду с ней существует (и активно используется) нотация цифровая, где права доступа обозначаются числами типа 0644. Поначалу она кажется загадочной. Однако при ближайшем рассмотрении — ничего подобного. О первой цифре мы поговорим чуть позже, вторая соответствует правам хозяина файла, третья — правам членов группы, четвёртая — правам разных там прочих, как и при символьной нотации. А сама цифра представляет собой простую арифметическую сумму прав, также выраженных численно — только в двоичной системе счисления, трансформированной в восьмеричную для компактности. А именно: наличию любого права соответствует двоичная единица, отсутствию — двоичный ноль. То есть символьной форме rwxrwxrwx будет соответствовать двоичная 111 111 111, что в восьмеричном пересчете и даст "число юзверя" — 0777 (полный доступ для всех атрибутов принадлежности). Образуется она из суммы прав чтения (восьмеричное 4), изменения (восьмеричное 2) и исполнения (восьмеричная 1) в трех позициях. Из чего можно догадаться, что число 0000, напротив, означает отсутствие прав на любые действия у кого бы то ни было.

Теперь вернёмся к первой цифре в числовой нотации прав. Она обозначает биты режима, и возможные её значения такие:

  • 4 — бит "суидности" для владельца исполняемого файла;
  • 2 — бит "суидности" для его группы;
  • 1 — бит "липкости" для каталога;
  • 0 — отсутствие атрибутов режима.

Арифметические вычисления того, какие числа соответствуют каким соотношениям прав, я предоставляю читателю. Скажу только, что "умолчальная" атрибутика новорожденного файла rw-r--r-- в численной нотации будет выглядеть как 0644.

В численной нотации определяются обычно и права, даруемые файлу при рождении. Для этого существует команда umask, и ее аргумент в численной форме показывает, какие права из их суммы должны быть отняты (на этот раз — именно отняты) от совокупности исходных прав у файла. То есть для получения стандартных (в большинстве систем) прав 0644 этот аргумент должен быть равен 0022.

Догадались, почему во второй позиции стандартной совокупности прав фигурирует 6, хотя в аргументе команды umask видим 0? Правильно, потому, что ни один создаваемый непосредственно пользователем файл не рождается как исполняемый: этот атрибут должен быть присвоен ему принудительно. А от рождения право на исполнение обретают только двоичные файлы, создаваемые компилятором (например, gcc). Также и все атрибуты режима при создании файла ему не присваиваются, а могут быть даны ему "насильно".

Команда umask и её аргумент, определяющие атрибуты доступа вновь создаваемых файлов, задаётся обычно раз и навсегда в профильном файле пользователя. Что же до изменения атрибутов доступа и режима файлов существующих — пользователь может менять их по своему усмотрению. Но, разумеется, только для файлов, хозяином которых он является. Столь же очевидно, что суперпользователь может изменять любые атрибуты всех файлов — как общесистемных, так и пользовательских.

О времени и о файле

В заключение — несколько слов о временных атрибутах файла, которые в некоторых случаях оказываются очень важными. Их — опять же три: время доступа (atime — от Access Time), время модификации (mtime — от Modification Time) и время изменения (ctime — от Change Time). Первый атрибут фиксирует время последнего обращения к файлу — любого, например, просмотра его командой less. Атрибут этот на практике используется редко, а пересчет времени доступа для изобилия файлов на древе файловой иерархии FreeBSD отъедает ресурсы. И потому часто он (пересчет, конечно, а не атрибут) отменяется, о чем будет разговор в главе о иерархии файлов и монтировании файловых систем.

Атрибут модификации, mtime, устанавливает время последнего изменения файла, вернее — изменения области его данных (например, правки текста в редакторе). А атрибут изменения, ctime, (по-русски лучше для определенности добавлять — изменения статуса) фиксирует время изменения метаданных файла — например, прав доступа, владельца, группы и т.д.

Характерно, что ни один из временных атрибутов файла не отражает непосредственно времени его создания. В качестве такового можно рассматривать атрибут ctime — но только в том случае, если в дальнейшем статус файла не изменялся (например, если файлу текста скрипта не был присвоен атрибут исполнения). В противном случае определить истинное время создания файла невозможно.

назад | к началу