Изменение идентификатора пользователя
В некоторых случаях у разработчиков приложений или ОС возникает потребность
или, во всяком случае, желание разрешить контролируемую смену идентичности
для исполнения одной операции или группы тесно связанных операций над
данными. Требование контролируемости означает, что нельзя разрешать пользователю
свободное выполнение таких операций: например, в системе документооборота
пользователю может быть разрешено поставить под документом подпись, что
он с ним ознакомился, но при этом не дано права изменять содержание документа
или удалять ранее поставленную подпись. Если предоставляемый системой
список прав на документ либо позволяет редактирование документа целиком,
либо опять-таки целиком запрещает его редактирование, то мы сталкиваемся
с неразрешимой проблемой.
Авторизация доступа к полям документа
в Notes
Программный комплекс Lotus Notes, широко признанный как лучшая основа
для реализации систем документооборота, позволяет устанавливать права
на отдельные поля или группы полей документа, а стандартная техника реализации
вышеприведенных требований состоит в том, чтобы сначала предоставить пользователю
право записи в поле, где должна быть подпись, а потом — после подписания
— это право тут же снять. Впрочем, при реализации сложных циклов документооборота,
включающих много взаимосвязанных документов, нередко возникают ситуации,
неразрешимые с помощью только этих средств [Керн/Линд 2000].
Можно привести и другой пример, более тесно связанный с темой книги:
для изменения информации о пользователе необходим доступ для записи в
соответствующую базу данных, но не во всю, а только в определенную запись.
Вполне естественно и даже необходимо дать пользователю возможность менять
пароль, не обращаясь к администратору. С другой стороны, совершенно недопустимо,
чтобы один пользователь, не являясь администратором учетных записей, мог
сменить пароль другому.
Одним из решений было бы хранение пароля для каждого из пользователей
в отдельном файле, но это во многих отношениях неудобно. Другое решение
может состоять в использовании модели клиент-сервер с процессом-сервером,
исполняющимся с привилегиями администратора, который является единственным
средством доступа к паролям. Например, в Win32 весь доступ к пользовательской
базе данных осуществляется через системные вызовы, т. е. функции процесса-сервера
исполняет само ядро системы.
В системах семейства Unix для этой цели был предложен оригинальный механизм,
известный как setuid (setting of user id - установка
[эффективного] идентификатора пользователя). По легенде, идея этого механизма
возникла именно при решении задачи о том, как же пользователи смогут менять
свои пароли, если их хэши будут храниться в одном файле.
Установка идентификатора пользователя
в Unix
В Unix каждая задача имеет два пользовательских идентификатора: реальный
и эффективный. Реальный идентификатор обычно совпадает с идентификатором
пользователя, запустившего задание. Для проверки прав доступа к файлам
и другим объектам, однако, используется эффективный идентификатор. При
запуске обычных задач реальный и эффективный идентификаторы совпадают.
Несовпадение может возникнуть при запуске программы с установленным признаком
setuid. При этом эффективный идентификатор для задачи устанавливается
равным идентификатору хозяина файла, содержащего программу.
Признак setuid является атрибутом файла, хранящего загрузочный модуль
программы. Только хозяин может установить этот признак, таким образом,
передавая другим пользователям право исполнять эту программу от своего
имени. При модификации файла или при передаче его другому пользователю
признак setuid автоматически сбрасывается.
Например, программа /bin/passwd, вызываемая для смены пароля, принадлежит
пользователю root, и у нее установлен признак setuid. Любой пользователь,
запустивший эту программу, получает задачу, имеющую право модификации
пользовательской базы данных, — файлов /etc/passwd и /etc/shadow. Однако,
прежде чем произвести модификацию, программа passwd проверяет допустимость
модификации. Например, при смене пароля она требует ввести
старый пароль (рис. 12.20). Сменить пароль пользователю, который его забыл,
может только root.
Другим примером setuid-программы может служить программа /bin/ps (process
status — состояние процессов) в старых системах. До установления стандарта
на псевдофайловую систему /proc, Unix не предоставляла штатных средств
для получения статистики об исполняющихся процессах. Программа /bin/ps
в таких системах анализировала виртуальную память ядра системы, доступную
как файл устройства /dev/kmem, находила в ней список процессов и выводила
содержащиеся в списке данные. Естественно, только привилегированная программа
может осуществлять доступ к /dev/kmem.
Рис. 12.20. Смена идентификатора пользователя в Unix
Механизм setuid был изобретен одним из отцов-основателей
Unix, Деннисом Ритчи, и запатентован компанией AT&T в 1975 г. Через
несколько месяцев после получения патента, ему был дан статус public domain.
Официально AT&T объяснила это тем, что плату за использование данного
патента нецелесообразно делать высокой, а сбор небольшой платы с большого
числа пользователей неудобен и тоже нецелесообразен.
Механизм setuid позволяет выдавать привилегии,
доступные только суперпользователю, как отдельным пользователям (при этом
setuid-программа должна явным образом проверять реальный идентификатор
пользователя и сравнивать его с собственной базой данных), так и группам
(при этом достаточно передать setuid-программу соответствующей группе
и дать ей право исполнения на эту программу), таким образом, отчасти компенсируя
недостаточную гибкость стандартной системы прав доступа и привилегий в
системе Unix.
Серверные агенты в Notes
До совершенства механизм setuid доведен в Lotus Notes (этот пакет относится
к прикладным программам, а не операционным системам, но реализует собственные
схемы аутентификации и авторизации). В этой системе все объекты базы данных,
в том числе и агенты (хранимые процедуры), снабжены электронной подписью.
Серверные агенты исполняются не от имени пользователя, инициировавшего
операцию, а от имени того, кем агент подписан. В данном случае подпись
кода означает, что либо пользователь сам занимался разработкой агента,
либо он явным образом согласился взять на себя ответственность за результаты
его работы. Подпись подделать практически невозможно (используется алгоритм
RSA с 631-битным ключом) [redbooks.ibm.com
sg245341]. |