Теперь немного изменим ситуацию, показанную на рис. 10.15. Предположим, что UserA не владеет ни temp_table, ни RecordFullClasses, а оба эти объекта принадлежат пользователю UserB. Кроме того, изменим RecordFullClasses так, чтобы эта процедура явно ссылалась на объекты пользователя UserA (см. рис. 10.16).
Для того чтобы процедура RecordFullClasses была корректно скомпилирована, пользователь UserA должен предоставить привилегию SELECT на таблицу classes и привилегию EXECUTE на функцию AlmostFull пользователю UserB (см. рис. 1.0.16). Более того, предоставить эти привилегии необходимо явно, а не через роль. Ниже приведены операторы GRANT, выполняемые пользователем UserA для обеспечения успешной компиляции UserB.RecordFullClasses.
то привилегии предоставлены не будут. Использование роли показано на рис. 10.17.
Итак, уточним правило, сформулированное в предыдущем разделе:
Подпрограмма выполняется на основании привилегий, которые предоставлены ее владельцу явно, а не через роль.
Если предоставить привилегии через роль, то при попытке компиляции RecordFullClasses будет выдано сообщение об ошибке PLS-2GT:
Это правило распространяется на триггеры и модули, которые хранятся в базе данных. Таким образом, в хранимых процедурах, функциях, модулях и триггерах доступны только те объекты, которые принадлежат владельцам этих подпрограмм или пользователям, которым явно предоставлены привилегии на применение этих подпрограмм.
Почему же установлено такое ограничение? Для ответа на этот вопрос необходимо обратиться к процессу связывания. В PL/SQL используется раннее связывание: ссылки определяются во время компиляции, а не выполнения подпрограммы. Операторы GRANT и REVOKE являются операторами DDL. Они начинают действовать немедленно, и новые записываются в словарь данных. Во всех соединениях, установленных с базой данных, будет виден новый набор привилегий. Однако это не всегда справедливо для ролей. Роль можно предоставить пользователю, а этот пользователь затем вправе запретить ее при помощи команды SET ROLE. Отличие заключается в том, что команда SET ROLE действует только в одном сеансе базы данных, в то время как операторы GRANT и REVOKE применяются для всех сеансов. Роль может быть запрещена в одном сеансе, но разрешена в других.
Чтобы использовать в хранимых подпрограммах и триггерах привилегии, предоставляемые через роль, эти привилегии нужно проверять всякий раз при запуске процедуры. Проверка привилегий является этапом процесса связывания. Но раннее связывание означает, что привилегии проверяются во время компиляции, а не выполнения. Для того чтобы раннее связывание было осуществимо, все роли внутри хранимых процедур, функций, модулей и триггеров запрещаются
< Предыдущая | Следующая > |
---|