Рассел Сейдж. Приемы профессиональной работы в unix перевод "Tricks of the unix masters" by Russel G

Вид материалаДокументы

Содержание


Защита личной информации
Формат вызова
Переменные среды выполнения
Формат вызова
Текст программы
Подобный материал:
1   ...   24   25   26   27   28   29   30   31   ...   45

мастер сможет себе это представить.


Во всяком случае, вы можете видеть полезность отладки.


Цикл, выполняющий такое же присваивание, имеет такой вид при

обычном стиле записи на языке shell:


| while read LINE

do

NAME=`echo $LINE | cut -d' ' -f1`

ENTRY=`grep "$NAME:" /etc/passwd`

echo "$LINE\t\`echo $ENTRY|$CUT6\`\t\`echo $ENTRY|$CUT5\`\"

done


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

экранировать в этом тексте все специальные символы.


Строки 45-60 - это оператор case, который реализует различные ре-

жимы отображения. Строка 46 выполняет обычный режим отображения коман-

ды who. Поскольку в обычном режиме имеется возможность использовать

переменную EXTRA, нам необходимо произвести повторный разбор командной

строки командой eval, чтобы эта переменная приняла свое истинное зна-

чение во время исполнения. Обратите внимание, что в команде eval име-

ются кавычки, заключающие всю командную строку. Это необходимо потому,

что вся строка является одним набором входных данных для команды eval.

Без кавычек команда eval не работала бы. Переменная EXTRA не подверга-

ется повторному разбору.


Строки 47-50 управляют режимами указания пользователя и выдачи

информации из файла паролей. Оба эти режима используют один и тот же

цикл. Цикл for использован для установки переменной NAME в значение

первого поля каждой строки, полученной от команды who. Для каждого

имени, вырезанного из результата работы команды who, выполняется пов-

торный синтаксический разбор командой eval переменной COMMAND (которая

была установлена в операторе case, выполнявшем разбор аргументов). Тем

самым повторно анализируются и выполняются команды, находящиеся в пе-

ременной COMMAND. Для режима указания пользователя переменная COMMAND

содержит команду finger, а для режима паролей в COMMAND хранится ко-

манда grep.


Строки 51-58 похожи на режим указания пользователя. Этот цикл то-

же требует имена от команды who, но вместо использования оператора for

мы используем метод прямой пересылки по конвейеру. Результат работы

команды who по конвейеру передается команде cut (переменная CUT1 и

здесь бы не работала), которая по конвейеру передает данные в цикл

чтения while. Обратите внимание, что в этом месте нет никакой сорти-

ровки. По умолчанию результат команды who выводится в порядке номеров

терминальных устройств. Я не думаю, однако, что порядок вывода этих

данных имеет большое значение.


Для каждого имени пользователя выводится запрос о том, хотите ли

вы передать ему почтовое сообщение. При чтении ответа в строке 54

должна быть использована команда UNIX'а line. Почему? Потому что весь

цикл использует оператор read для чтения имен. Оператор read читает

только со стандартного ввода, который в данном случае привязан к кон-

вейеру. Для получения входных данных с клавиатуры мы должны использо-

вать команду line, которая получает их из файла /dev/tty. Это расп-

ространенный способ чтения данных с клавиатуры из переадресованного

цикла.


Строка 55 проверяет, является ли ответом символ y. Если да, вызы-

вается команда UNIX'а mail, и снова ввод переадресовывается из файла

/dev/tty (поскольку строки почтового сообщения мы должны вводить с

клавиатуры.) В данном случае мы фактически переадресовываем стандарт-

ный ввод для вызова подчиненного shell-процесса, выполняющего команду

mail. Без выполнения переадресации команда mail читает из файла

/dev/null, что нарушает выполнение всего цикла whox.


Строка 59 управляет режимом показа возможности записи на терми-

нал. Цель здесь такова - использовать одну команду ls и, применяя под-

чиненный процесс, извлечь файлы терминальных устройств из выходных

данных команды who. Эти файлы являются вторым полем результата команды

who. Сначала запускается команда who, которая по конвейеру передает

свои данные команде sed.


Затем sed использует команду подстановки для отбрасывания всего,

кроме того, что ограничено символами \( и \). Последующая часть коман-

ды подстановки ссылается на этот ограниченный участок с помощью обоз-

начения \1. Используя символ . как соответствующий любому символу

распечатки, мы должны всего лишь посчитать столбцы, которые нам нужно

вырезать. Кроме того, имена устройств в команде who не имеют префикса

/dev/, который нам необходим. Команда sed вставляет его перед текстом,

вырезанным из команды who. В результате команде ls дается список пол-

ных маршрутных имен ко всем файлам устройств зарегистрированных поль-

зователей. Затем это выводится на экран.


ЗАЩИТА ЛИЧНОЙ ИНФОРМАЦИИ


Другой стороной осведомленности пользователя является обеспечение

разумной степени безопасности. Ваша потребность в защите информации

зависит от рода выполняемой вами работы и от чувствительности информа-

ции, которой вы управляете. Однако все хотят секретности и чувства бе-

зопасности, которое появляется вместе с обоснованной уверенностью в

том, что они не могут стать жертвой нарушения защиты информации. Так

же, как вы можете изготавливать приспособления, помогающие сделать ваш

дом менее привлекательным для грабителей, так и каждый пользователь

может сделать приспособления, которые помогают поддерживать секретность

и безопасность его работы. Подобно полиции, системные администраторы

обычно имеют дело только с нарушением защиты уже после свершившегося

факта. Вы можете использовать средства, представленные нами в данном

разделе, чтобы помочь уберечь ваши файлы от несанкционированного

просмотра или разрушения.


Любая компьютерная система требует некоторого рода защиты. Уровни

защиты включают в себя физическую защиту (центрального процессора,

дисков и терминалов), защиту файлов, защиту процессов и всей работаю-

щей системы. В многопользовательской среде еще более важно усиливать

защиту. Каждый пользователь имеет право засекречивать и защищать свою

среду и свои файлы. Ни один компьютер не имеет стопроцентной защиты.

Ваша среда лишь настолько защищена, насколько вы сделали ее таковой.

Защитные мероприятия могут достигать такой степени, что начинают ме-

шать свободному обмену идеями и затруднять использование гибкости

системы или исследование ее новых аспектов. Лично я считаю, что поль-

зователи должны иметь свободу делать все, что они хотят, пока это не

вредит системе или другим пользователям. Большинство информации, при-

веденной в данной книге, подтверждает это убеждение.


Тип защиты, который обсуждается в данной главе, касается личного

аспекта защиты пользователя системы UNIX. Я хочу, чтобы место, где фи-

зически находятся мои разработки, мой регистрационный каталог и любые

процессы, которые я запускаю в системе, были защищены. Для полного

комфорта мне нужно знать, что никто не влезет в мои вещи (посредством

обычных методов доступа или взлома) и не будет заглядывать мне через

плечо, чтобы наблюдать, чем я занимаюсь.


В данном разделе мы рассмотрим инструментальные средства acme,

inuse и lock. Acme - это препроцессор к команде UNIX'а acctcom.

Acctcom выполняет довольно неплохую работу по отображению учетной ин-

формации, но некоторые опции требуется указывать все время. Acme уста-

навливает их для нас. Напомним, что учетные записи хранятся в виде

структуры, а не в текстовом виде, и поэтому мы заставляем acctcom по-

казывать их для нас.


Следующее средство, inuse, позволяет вам установить ваш терминал

как "занятый", когда вы куда-нибудь уходите. Это эффективно блокирует

его и не позволяет никому использовать его. Для реализации такого бло-

кирования представлены программы как на языке Си, так и на языке ин-

терпретатора shell.


Последнее средство, lock, используется для блокирования и разбло-

кирования прав доступа к файлу и является на самом деле простым интер-

фейсом с командой chmod.


------------------------------------------------------------------------


ИМЯ: acme

------------------------------------------------------------------------


acme Отображение учетной информации обо мне


НАЗНАЧЕНИЕ


Генерирует опции, необходимые для вывода на экран информации обо

мне, которая хранится в учетном файле.


ФОРМАТ ВЫЗОВА


acme [-l] [-u]


ПРИМЕР ВЫЗОВА


acme -u Выводит всю учетную информацию о пользователе с

именем $LOGNAME


ТЕКСТ ПРОГРАММЫ


1 :

2 # @(#) acme v1.0 Give accounting info on me Author: Russ Sage

2а Дать учетную информацию обо мне


4 if [ "$1" != "-l" -a "$1" != "-u" ]

5 then echo "usage: acme [-l] [-u]" >&2

6 echo " -l for ttyline" >&2

7 echo " -u for user name" >&2

8 exit 0

9 fi


11 OPT=""

12 for ARG in $*

13 do

14 case $ARG in

15 -l) OPT="$OPT -l `basename \`tty\``";;

16 -u) OPT="$OPT -u $LOGNAME";;

17 *) OPT="$OPT $ARG";;

18 esac

19 done


21 echo "acctcom $OPT"

22 acctcom $OPT


ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ


ARG Каждое значение, указанное в командной строке

LOGNAME Переменная среды, содержащая мое регистрационное имя

OPT Объединенный список всех опций и их аргументов


ОПИСАНИЕ


ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ acme?


Большинство больших систем UNIX запускают стандартное программное

обеспечение для сбора учетной информации об использовании системы. Ре-

зультаты учетных транзакций передаются обычно в файл /usr/adm/pacct.

Фактически сбор учетной информации выполняется ядром системы. Каждый

раз при завершении процесса программы сбора учетной информации в ядре

производят одну запись. Переключателем, который включает и выключает

эту операцию, является acct(2). Команды пользовательского уровня также

взаимодействуют с системным вызовом (accton(1M)) и печатают результаты

сбора учетной информации (acctcom(1)).


Теперь, когда мы знаем, где находятся учетные записи и как они

туда попадают, нам нужно напечатать эту информацию. Acctcom может пе-

чатать таблицы с информацией, но вам необходимо знать, какой использо-

вать индекс. Просмотр может производится по номеру терминальной линии

(это полезно, если идентификатор процесса был изменен командой

setuid), по имени пользователя, по группе, по времени и т.д. Я наибо-

лее часто использую опции поиска информации по номеру линии терминала

и по имени пользователя. С их помощью вы можете получить список всех

основных данных, имеющих отношение к вам. Когда вы вызываете acctcom с

этими опциями, вам необходимо указать дополнительную информацию, такую

как имя вашего терминала и ваше пользовательское имя. Было бы хорошо,

если бы мы могли уменьшить количество нажатий на клавиши и объем вы-

числений, требуемых для получения информации. Для этого и предназначен

acme.


ЧТО ДЕЛАЕТ acme?


Acme - это интерфейсный процессор для команды acctcom(1). Он слу-

жит для выдачи информации, которая требуется согласно указанным опци-

ям. Вы должны только дать командному файлу acme опции в сокращенном

виде, а все остальное он сделает сам. Если acme вызывается без аргу-

ментов, программа acctcom выведет по умолчанию все записи.


Команда acctcom имеет много опций. В действительности мы исполь-

зуем одну или две, но зато используем их часто. Двумя опциями, которые

понимает acme, являются -l и -u. Когда указана опция -l, acme получает

имя вашего терминала и помещает его в командную строку. Если указана

опция -u, acme получает ваше пользовательское имя и тоже вставляет его

в командную строку. Время от времени используются другие опции для

бавления специфической информации или небольшого изменения выходного

формата. Для того чтобы была возможность использовать другие опции ко-

манды acctcom, acme включает в командную строку, формируемую для

fcctcom, любые дополнительные корректные опции acctcom, переданные в

командной строке для acme. Таким образом, acme поддерживает базовые

возможности, а кроме того позволяет вам подгонять команду под ваш

вкус.


Перед тем, как начнется выполнение команды acctcom, на экран вы-

водится расширенный вид командной строки, так что вы можете видеть ко-

мандную строку, сгенерированную acme. Без этого может получиться пута-

ница, поскольку вы не будете знать, что собирается делать программа.


ПРИМЕРЫ


1. $ acme


Выдача ВСЕХ моих учетных данных. Это последовательный список всех

команд, которые были запущены начиная с момента загрузки по настоящее

время. Счастливого чтения!


2. $ acme -u -b


Печать в обратном порядке всех учетных записей с моим пользова-

тельским именем. Обратный порядок означает - от самой последней из

предыдущих команд до моей первой команды.


3. $ acme -l


Вывод всех учетных записей для терминальной линии, которую я сей-

час занимаю. Сюда могут быть включены фоновые процессы, оставшиеся в

системе от предыдущих пользователей моей терминальной линии или даже

процессы, имеющие другие идентификационные номера пользователей (из-за

программ типа setuid, которые я мог запустить), которые запущены с

этой же терминальной линии.


ПОЯСНЕНИЯ


В строках 4-9 выполняется проверка на наличие ошибок. Если пер-

вый позиционный параметр не -l и не -u, то это ошибка. Выводится сооб-

щение об этом и программа завершается.


В строке 11 переменная OPT инициализируется пустой строкой. Эта

переменная содержит все дополнительные опции acctcom и их аргументы.


Строки 12-19 представляют собой цикл for, который повторяется по

всем позиционным параметрам. Каждый аргумент сверяется в операторе

case с допустимыми опциями. Если опцией является -l (строка 15), в пе-

ременную OPT заносится то значение, которое она уже имеет, опция -l и

добавляется имя терминального устройства, полученное от команды UNIX'а

tty. Команда tty выводит и префикс /dev, который не нужен. Для того

чтобы избавиться от этого префикса, мы берем из этой символьной строки

только основное имя.


Если указана опция -u, в переменную OPT добавляется -u и наше ре-

гистрационное имя. Если аргументом являются любые другие данные, то

они просто добавляются в переменную OPT. Поступая таким образом, мы

можем передать в командной строке acme другие опции команде acctcom.

Обратите внимание, что здесь не выполняется проверка на ошибки в аргу-

ментах командной строки. Вы можете ввести неверное значение, которое

нарушит работу команды acctcom. Однако это та цена, которую мы вынуж-

дены платить за гибкость при передаче аргументов в командной строке,

иначе нам придется значительно увеличивать текст командного файла.


После того обработки всех опций строка 21 выводит на экран ко-

мандную строку, которая должна быть выполнена, так что мы знаем, что

мы задавали. В строке 22 выполняется сама команда acctcom. Выходной

результат соответствует описанию acctcom(1).


------------------------------------------------------------------------


ИМЯ: inuse

------------------------------------------------------------------------


inuse Запретить использование терминала


НАЗНАЧЕНИЕ


Блокирует ваш терминал путем перевода в состояние занятости. Если

кто-либо попытается вторгнуться, вы это заметите.


ФОРМАТ ВЫЗОВА


inuse


ПРИМЕРЫ ВЫЗОВА


inuse Перевод терминала в состояние занятости

mypasswd Вводится мой пароль, но не отображается на экран


ТЕКСТ ПРОГРАММЫ


1 :

2 # @(#) inuse v1.0 Disable terminal and alert if used Author: Russ Sage

2а Запретить использование терминала и сообщить о попытке использования


4 trap "echo you\'re BUSTED!!; stty echo; kill $$" 2 15


6 PATH=/bin:/usr/bin

7 SECRET="secret"


9 stty -echo

10 echo "Lock string: \c"

11 read BUF1

12 echo


14 while :

15 do

16 BUF2=`line < /dev/tty`

17 if [ "$BUF2" = "$BUF1" ]

18 then break

19 elif [ "$BUF2" = "$SECRET" ]

20 then break

21 fi

22 echo "G\c"

23 done

24 stty echo


ОПИСАНИЕ


ЗАЧЕМ НАМ НУЖЕН КОМАНДНЫЙ ФАЙЛ inuse?


Рабочий день всегда загружен: много людей, еще больше бумаг, вся-

кие поручения и так далее и так далее. Когда вы покидаете свое рабочее

место, что вы собираетесь делать со своим зарегистрированным термина-

лом? Каждый раз входить в систему и выходить из нее слишком долго, но

вы не хотите оставлять вашу работу открытой для всех. Вам необходима

программа, которую вы можете запустить на время вашего отсутствия и

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


Конечно, не достаточно иметь некий процесс, который выполняется в

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

должны перехватывать прерывания в случае, если кто-нибудь введет сим-

волы "прерывания" или "выхода" с вашей клавиатуры. Единственным спосо-

бом разблокирования терминала должен быть ввод пароля или заранее оп-

ределенного слова, которое в любом случае разблокирует его.


ЧТО ДЕЛАЕТ inuse?


Inuse переводит ваш терминал в режим вечной работы. Это означает,

что терминал не отвечает на ваши запросы или запросы кого-то другого.

Когда вы готовы разблокировать ваш терминал, введите секретный пароль

или пароль, который вы придумали.


Когда вы первый раз вызываете inuse, у вас запрашивается пароль.

Эхо-отображение на терминал отключено, поэтому пароль не выводится на

экран. Для гарантии того, что никто не пытается переадресовать команд-

ному файлу inuse какой-либо файл данных, все операции чтения произво-

дятся непосредственно из файла терминального устройства /dev/tty, а не

через файловый дескриптор стандартного ввода. Это позволяет защититься

от попыток других пользователей вторгнуться в работу терминала путем

посылки на стандартный ввод файла большого размера, содержащего разные

слова.


После чтения вашего пароля inuse попадает в бесконечный цикл, ко-

торый читает символы с клавиатуры и сравнивает полученные входные дан-

ные с двумя паролями. Каждый раз, когда кто-то вводит что-то некор-

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

паролей, программа останавливается и терминал разблокируется.


Мы предлагаем две реализации inuse: командный файл интерпретатора

shell, приведенный выше, и программу на языке Си. Они выполняют одну и

ту же работу довольно похожими способами. Они демонстрируют, насколько

похожи эти два подхода, а их небольшие отличия рассматриваются ниже.

Сначала обсуждается командный файл, а затем Си-программа.


ПОЯСНЕНИЯ


Строка 4 инициализирует оператор trap. При активизации обработчи-

ка trap выполняются три команды.


Целью применения ловушки trap является реагирование на любую по-

пытку прервать работу командного файла и прорваться на ваш терминал.

Первая команда выдает предупреждение о том, что вы вторгаетесь. Вторая

команда переключает терминал обратно в режим эхо-отображения, так что

все, что будет впоследствии введено с клавиатуры, отобразится на экра-

не. и последняя команда заставляет программу совершить самоубийство.

Как мы увидим позже, это самоубийство является особым родом прекраще-