355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Брайан Керниган » UNIX — универсальная среда программирования » Текст книги (страница 5)
UNIX — универсальная среда программирования
  • Текст добавлен: 6 октября 2016, 20:23

Текст книги "UNIX — универсальная среда программирования"


Автор книги: Брайан Керниган


Соавторы: Роб Пайк

Жанры:

   

ОС и Сети

,

сообщить о нарушении

Текущая страница: 5 (всего у книги 31 страниц) [доступный отрывок для чтения: 12 страниц]

2.3. Каталоги и имена файлов

Все ваши файлы имеют вполне определенные имена, начиная с /usr/you, но если у вас есть только файл junk, то при задании команды ls не выдается /usr/you/junk; имя файла выводится без всякого префикса:

$ ls

junk

$

Это происходит потому, что любая выполняемая программа, т.е. каждый процесс, имеет текущий каталог и неявно предполагается, что все имена файлов начинаются с имени этого каталога, если они явно не начинаются с дробной черты. Таким образом, у интерпретатора shell, в который вы вошли, и команды ls есть текущий каталог. Команда pwd ("print working directory" печать текущего каталога) выдает имя текущего каталога:

$ pwd

/usr/you

$

Текущий каталог представляет собой атрибут процесса, а не пользователя или программы: пользователям соответствуют начальные каталоги, а процессам – текущие. Если процесс порождает процесс-потомка, последний наследует текущий каталог родителя. Но, если затем потомок сменит текущий каталог, родителя это не затронет: его текущий каталог останется тем же, независимо от действий потомка.

Понятие текущего каталога, конечно, обеспечивает удобство обозначения, поскольку освобождает от излишнего ввода, но настоящее его назначение – организационное. Связанные друг с другом файлы находятся в одном каталоге. Каталог /usr обычно является начальным каталогом файловой системы пользователей (usr – сокращение от user, подобно cmp, ls и т.д.). Ваш начальный каталог /usr/you – это ваш текущий каталог при первом вхождении в систему. Каталог /usr/src содержит исходные тексты системных программ, каталог /usr/src/cmd – исходные тексты команд UNIX, /usr/src/cmd/sh – исходные тексты интерпретатора shell и т.д. Всякий раз, когда вы приступаете к новому проекту или когда у вас появляется группа связанных файлов, скажем, набор рецептов, вы можете создать новый каталог с помощью команды mkdir и поместить в него файлы.

$ pwd

/usr/you

$ mkdir recipes

$ cd recipes

$ pwd

/usr/you/recipes

$ mkdir pie cookie

$ ed pie/apple

...

$ ed

...

$

Заметьте, как легко ссылаться на вложенные каталоги. Файл pie/apple имеет очевидный смысл: рецепт яблочного пирога из каталога /usr/you/recipes/pie. Вместо этого вы могли бы поместить рецепт, например, в каталог recipes/apple.pie, а не во вложенный каталог в каталоге recipes, но лучшее решение – собрать все рецепты пирогов вместе. Так, рецепт крема мог бы храниться в recipes/pie/crust, чтобы не дублировать его в рецепте для каждого пирога. Хотя файловая система предоставляет мощное средство организации данных, вы можете забыть, куда помещен файл, и даже какие файлы у вас есть. Естественным решением было бы иметь одну или несколько команд, позволяющих "порыться" в каталогах. Конечно, команда ls помогает искать файлы, но не дает возможности исследовать вложенные каталоги:

$ cd

$ ls

junk

recipes

$ file *

junk: ascii text

recipes: directory

$ ls recipes

cookie

pie

$ ls recipes/pie

apple

crust

$

Эту часть файловой системы можно изобразить графически:

Рис. 2.1: Часть файловой системы

С помощью команды du ("disk usage" – использование диска) вы можете выяснить, какое пространство на диске занято файлами каталога, включая все вложенные каталоги:

$ du

 6 ./recipes/pie

 4 ./recipes/cookie

11 ./recipes

13 .

$

Смысл имен файлов понятен; числа соответствуют количеству блоков на диске (обычно размер блока составляет 512 или 1024 байта) для хранения каждого файла. При использовании каталога число показывает, сколько блоков задействовано всеми файлами этого каталога, включая вложенные каталоги и сам каталог.

Команда du имеет флаг -a ("all" – все), который означает, что требуется выдавать все файлы в каталоге. Если один из них является каталогом, команда du сообщает и о нем:

$ du -а

 2 ./recipes/pie/apple

 3 ./recipes/pie/crust

 6 ./recipes/pie

 3 ./recipes/cookie/choc.chip

 4 ./recipes/cookie

11 ./recipes

 1 ./junk

13 .

$

Выходной поток команды du -a можно направить по программному каналу через команду grep для поиска каких-либо файлов:

$ du -a | grep choc

 3 ./recipes/cookie/choc.chip

$

Напомним (см. гл. 1), что имя '.' – это запись в каталоге, обозначающая сам каталог; оно обеспечивает доступ к каталогу в тех случаях, когда не известно его полное имя. Команда du просматривает файлы в каталоге, причем если вы не указали, в каком именно каталоге следует производить поиск, то она выберет '.', т. е. каталог, с которым вы работаете в данный момент. Значит, junk и ./junk – имена одного и того же файла.

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

Теперь представим содержимое каталога в байтовой форме:

$ od -cb

000000  4   ;   .                       

       064 073 056 000 000 000 000 000 000 000 000 000 000 000 000

000020 273  (   .   .                     

       273 050 056 056 000 000 000 000 000 000 000 000 000 000 000

000040 252  ;   p   е   ц   е   п   т   ы           

       252 073 256 243 263 243 255 260 273 000 000 000 000 000 000

000060 230  =   j   u   n   k                 

       230 075 152 165 156 153 000 000 000 000 000 000 000 000 000

000100 $

Видите имена файлов, "спрятанные" здесь? Формат каталога – это комбинация двоичного и текстового представлений. Каталог строится из фрагментов по 16 байт, причем последние 14 байт здесь содержат имя файла, дополненное символом NUL из ASCII (нулевой код, имеющий значение 0), а первые два байта указывают системе, где находится служебная информация, относящаяся к файлу (мы вернемся к этому вопросу позднее). Каждый каталог начинается двумя записями: '.' (точка) и '..' (точка-точка).

$ cd         Начальный каталог

$ cd recipes

$ pwd

/usr/you/recipes

$ cd ..; pwd На один уровень выше

/usr/you

$ cd ..; pwd Еще на один уровень выше

/usr

$ cd ..; pwd Еще на один уровень выше

/

$ cd ..; pwd Еще на один уровень выше

/            Выше некуда

$

Каталог / называется корнем файловой системы. Каждый файл системы находится в корневом каталоге или в одном из вложенных в него каталогов, и корневой каталог является родителем самому себе.

Упражнение 2.2

На основании изложенного выше представьте приблизительно действие команды ls. Подсказка: cat . > foo; ls -f foo.

Упражнение 2.3

(Более сложное) Как действует команда pwd?

Упражнение 2.4

Команда du предназначена для учета использования дискового пространства. Осуществлять с ее помощью поиск файлов в иерархии каталогов – довольно странное решение, возможно, даже неподходящее. За альтернативой обратитесь к странице справочного руководства find(1) и сравните две команды, в частности du -a | grep ... и find. Какая из них сработает быстрее? Что лучше: создать новую команду или воспользоваться побочным эффектом уже существующей?

2.4. Права доступа

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

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

Если нужна большая защищенность, то можно изменить данные в файле так, что даже суперпользователь не сможет прочесть (или, по крайней мере, понять) их, для чего служит команда crypt (см. crypt(1)). Конечно, даже эта команда не дает абсолютной защиты. Суперпользователь может изменить команду crypt, или кто-то попытается расшифровать алгоритм crypt. Правда, и то и другое является трудно выполнимым, так что практически команда crypt достаточно надежна.

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

При входе в систему вы вводите имя и подтверждаете, что это вы, задавая пароль. Имя представляет собой ваш входной идентификатор, или login-id. На самом деле, система распознает вас по числу, называемому идентификатором пользователя, или uid. В действительности различным login-id может соответствовать один uid, что делает их неразличимыми для системы, хотя такое бывает относительно редко, и, по всей видимости, является нежелательным по соображениям безопасности. Кроме uid, вам приписывается идентификатор группы, или group-id, который относит вас к определенной группе пользователей. Во многих системах обычных пользователей (в отличие от тех, кто имеет login-id типа root) объединяют в одну группу под именем other (другие), но в вашей системе может быть иначе. Файловая система, а значит, и вся система UNIX в целом определяет ваши возможности исходя из прав доступа, предоставляемых вашему uid и group-id.

Файл /etc/passwd – это файл паролей; он содержит всю информацию, связанную со входом каждого пользователя в систему. Подобно системе, вы можете определить свой uid и group-id, если найдете свое имя в /etc/passwd:

$ grep you /etc/passwd

you:gkmbCTrJ04C0M:604:1:Y.0.А.People:/usr/you:

$

Поля в файле паролей разделяются двоеточием и расположены следующим образом (как видим из passwd(5)):

login-id:зашифрованный_пароль:uid:group-id:разное:начальный_каталог:shell

Файл паролей представляет собой обычный текстовый файл, но назначение и разделитель полей определяются по соглашению между программами, работающими с информацией этого файла. Поле shell обычно пустое; значит, по умолчанию используется стандартный интерпретатор /bin/sh. Поле "разное" может содержать что угодно (как правило, ваше имя, адрес или телефон).

Заметьте, что ваш пароль присутствует здесь во втором поле, но в зашифрованном виде. Файл паролей могут прочесть все (вы только что это сделали), и если ваш пароль бы там, то любой, кто пожелает, может выдать себя за вас. Когда вы вводите свой пароль при входе в систему, он шифруется, и результат сравнивается с зашифрованным паролем из /etc/passwd. Если они совпадают, то вам разрешают войти. Этот механизм работоспособен, потому что алгоритм шифрации таков, что позволяет легко перейти от раскрытой формы к зашифрованной, тогда как обратный переход очень труден. Например, если ваш пароль ka-boom, он может быть зашифрован как gkmbCTrJ04COM, но, получив последний, вам будет нелегко вернуться к оригиналу.

Ядро решает, что вам можно позволить читать файл /etc/passwd исходя из прав доступа, связанных с файлом. Для каждого файла предусмотрены три вида прав доступа: чтение (т.е. исследование его содержимого), запись (т. е. изменение его содержимого) и выполнение (т. е. запуск его как программы). Далее, разным пользователям могут быть предоставлены различные права доступа. Как владелец файла вы имеете один набор прав на чтение, запись и выполнение. У "вашей" группы – другой набор прав доступа, у всех остальных – третий набор.

Команда ls с флагом -l сообщает среди прочего права доступа:

$ ls -l /etc/passwd

-rw-r–r– 1 root 5115 Aug 30 10:40 /etc/passwd

$ ls -lq /etc/passwd

-rw–r–r– 1 adm 5115 Aug 30 10:40 /etc/passwd

Информацию, содержащуюся в двух строках вывода команды ls, можно интерпретировать так: владельцем файла /etc/passwd является пользователь с login-id, равным root; его группа называется adm; размер файла 5115 байт; последний раз изменен был 30 августа в 10:40; файл имеет единственную связь, т.е. одно имя в файловой системе (вопрос о связях мы обсудим в следующем разделе). Некоторые варианты команды ls выдают имена владельца и группы сразу при однократном вызове.

Строка -rw-r–r– показывает, как представляет права доступа к файлу команда ls. Первый дефис (-) означает, что это обычный файл. В случае каталога на его месте стояла бы буква d. Следующие три символа обозначают права владельца файла на чтение, запись и выполнение (исходя из uid). Строка rw- свидетельствует о том, что владелец (root) может читать, писать, но не выполнять файл. В случае выполняемого файла дефис был бы заменен символом x.

Три символа (r–) обозначают права доступа группы, в данном случае пользователей из группы adm – по-видимому, системных администраторов, которые могут читать файл, но не писать и не выполнять его. Следующие три символа (также r–) определяют права доступа для всех остальных пользователей системы. Таким образом, на данной машине только root может изменить информацию по входу в систему для пользователя, но прочесть файл и узнать эту информацию может любой. Разумным был бы вариант, при котором группа adm также имела бы право на запись в файл /etc/passwd.

Файл /etc/group хранит в зашифрованном виде имена групп и их group-id и определяет, какие пользователи входят в какие группы. В файле /etc/passwd определяется только ваша группа при входе в систему; команда newgrp изменяет ее права доступа на права другой группы.

Кто угодно может задать:

$ ed /etc/passwd

и редактировать файл паролей, но только root может записать измененный файл. Поэтому вполне правомочен вопрос: как изменить свой пароль, если это требует редактирования файла паролей. Программа, изменяющая пароли, называется passwd, вероятно, вы найдете ее в /bin:

$ ls -l /bin/passwd

-rwsr-xr-x 1 root 8454 Jan 4 1983 /bin/passwd

$

(Обратите внимание на то, что /etc/passwd – текстовый файл, содержащий информацию по входу в систему, тогда как /bin/passwd находится в другом каталоге, содержит программу, готовую к выполнению, и позволяет изменить данные, связанные с паролем). Права доступа к этому файлу показывают, что выполнить команду может кто угодно, но изменить команду passwd – только root. Буква s вместо x в поле прав на выполнение для владельца файла означает, что при выполнении команды ей предоставляются права, соответствующие праву владельца файла, в данном случае root. Поскольку файл /bin/passwd имеет такой признак установки uid и при выполнении получает права root, любой пользователь, выполняя команду passwd, может редактировать файл /etc/passwd.

Введение признака установки uid – простое элегантное решение целого ряда проблем безопасности.[7] 7
  Признак установки uid введен Д. Ритчи


[Закрыть]
Например, автор игровой программы может установить свой uid для программы, поэтому она сможет изменять файл с результатами игр, который защищен от доступа со стороны других пользователей. Но идея введения признака установки uid потенциально опасна. Программа /bin/passwd должна быть правильной, иначе она может уничтожить системную информацию под прикрытием суперпользователя root. При наличии прав доступа -rwsrwxrwx ее мог бы переписать любой пользователь, и, таким образом, заменить файл на неработоспособную программу. Это особенно опасно для программ, обладающих признаком установки uid, поскольку root имеет доступ к каждому файлу, системы. (В некоторых системах UNIX происходит отключение признака установки uid всякий раз, когда файл изменяется, что уменьшает вероятность нарушения защиты).

Признак установки uid – мощное средство, но оно используется в основном для нескольких системных программ, таких, как passwd. Рассмотрим более типичный файл:

$ ls -l /bin/who

-rwxrwxr-x 1 root 6348 Mar 29 1983 /bin/who

$

Этот файл доступен для выполнения всем, а писать в него могут только root и пользователь той же группы. Слова "доступен для выполнения" означают, что при вводе

$ who

интерпретатор shell просматривает ряд каталогов, в том числе /bin, отыскивая файл с именем who. Если такой файл найден и он имеет право доступа на выполнение, то shell обращается к ядру для его запуска. Ядро проверяет права доступа, и, если они действительны, запускает программу. Отметим, что программа – это просто файл с правом доступа на выполнение. В следующей главе вы познакомитесь с программами, являющимися обычными текстовыми файлами, но они могут выполняться как команды, поскольку имеют право доступа на выполнение.

Права доступа к каталогам действуют несколько иначе, но основной принцип остается тем же:

$ ls -ld .

drwxrwxr-x 3 you 80 Sep 27 06:11 .

$

Команда ls с флагом -d сообщает скорее о самом каталоге, чем о его содержимом, и первая буква d в выводе означает, что '.' в действительности является каталогом. Поле r показывает, что можно читать каталог, поэтому с помощью команды ls (или od для данного случая) можно выяснить, какие файлы хранятся в нем. Буква w свидетельствует о том, что можно создавать и исключать файлы из каталога, поскольку это требует изменения, а значит, записи в файл каталога.

На самом деле нельзя просто писать в каталог, даже суперпользователю root это запрещено:

$ who > .        Попытка затереть '.'

.: cannot create Нельзя

$

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

Право на удаление файла не зависит от самого файла. Если у вас есть право записи в каталог, вы можете удалять файлы из него, причем даже те, которые защищены от записи. Команда rm все-таки запрашивает подтверждение, прежде чем удалить защищенный файл, чтобы убедиться, что вы действительно хотите это сделать, – редкий для команд системы UNIX случай двойной проверки намерений пользователя. (Флаг -f команды rm обеспечивает удаление файлов без запроса.)

Поле x в случае каталога означает не выполнение, а поиск. Право на выполнение определяет возможность поиска файла в каталоге. Поэтому возможно создать каталог с правом доступа "x" для других пользователей, предполагая, что пользователи будут иметь доступ к любому известному им файлу в каталоге, но не смогут выполнять команду ls или читать каталог, чтобы узнать, какие файлы в нем находятся. Аналогично каталог с правом доступа r– можно читать (с помощью ls), но нельзя работать с его файлами. В некоторых системах используют это свойство, чтобы закрыть каталог /usr/games в рабочее время.

Команда chmod ("change mode" – изменить режим) меняет права доступа к файлам:

$ chmod права_доступа имена файлов...

Синтаксис конструкции "права_доступа", к сожалению, громоздкий. Она может определяться двумя способами: с помощью восьмеричных чисел и последовательностью символов. Проще использовать восьмеричные числа, хотя иногда более удобными оказываются символьные обозначения, так как с их помощью можно показать, какие изменения произошли в правах доступа. Лучше, конечно, было бы задать

$ chmod rw-rw-rw– junk Так нельзя!

чем вводить

$ chmod 666 junk

но так не получается. Восьмеричное значение режима складывается из значений прав доступа: 4 – для чтения, 2 – для записи и 1 – для выполнения. Три цифры, как и в выводе команды ls, показывают права доступа для владельца, группы и всех остальных. Символьные обозначения объяснить труднее; их точное описание приводится в справочном руководстве chmod(1). Для наших же целей достаточно указать, что "+" устанавливает право доступа, а "-" лишает его. Например,

$ chmod +x command

позволяет всем выполнять команду, а

$ chmod -w file

лишает всех права записи в файл, включая и владельца файла. Если не принимать во внимание существование суперпользователя, то только владелец файла может изменить права доступа к файлу, независимо от текущих прав доступа. В том случае, когда кто-то еще предоставил вам право записи в файл, система не позволит изменить код прав доступа к файлу:

$ ls -ld /usr/mary

drwxrwxrwx 5 mary 704 Sep 25 10:18 /usr/mary

$ chmod 444 /usr/mary

chmod: can't change /usr/mary

$

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

$ cd

$ date > temp

$ chmod -w .         Закрыть каталог по записи

$ ls -ld .

dr-xr-xr-x 3 you 80 Sep 27 11:48 .

$ rm temp

rm: temp not removed Нельзя удалить файл

$ chmod 775 .        Восстановление прав доступа

$ ls -ld .

drwxrwxr-x 3 you 80 Sep 27 11:48 .

$ rm temp            Теперь можно

$

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

Упражнение 2.5

Поэкспериментируйте с командой chmod. Попробуйте разные простые варианты типа 0 или 1. Будьте осторожны, чтобы не испортить свой начальный каталог.


    Ваша оценка произведения:

Популярные книги за неделю