© Владимир Пржиялковский,
координатор Евро-Азиатской Группы Пользователей Oracle,
преподаватель УКЦ Interface Ltd.
"Наступила темнота, Не ходи за ворота: Кто на улицу попал - Заблудился и пропал". |
Корней Чуковский, "Краденое солнце" |
"And neither the angels in heaven above, Nor the demons down under the sea, Can ever dissever my soul from the soul Of the beautiful Annabel Lee …" |
Edgar Allan Poe, "Annabel Lee" |
Эта статья является непосредственным продолжением статьи Изучаем метки доступа к строкам в Oracle: задание свойств столбца доступа в таблице, и рассматривает примеры поведения средства Label Security в Oracle, не являющиеся очевидными для неспециалиста по мандатному доступу к данным. Показана возможность страховать пользователя от непредусмотренных для его уровня секретности действий и неочевидная особенность выдачи пользователю засекреченных данных.
Подразумеваемые в статье состояние базы и сценарные файлы соответствуют концу предыдущей статьи.
Одна из интересных особенностей меточного ("мандатного") доступа в том, что он позволяет обладателю определенного уровня доступа запретить правку строк, не только более секретных, чем ему положено, но также и строк, менее секретных. Это напоминает кастовость по части действия; так сказать, "что положено быку, нельзя делать Юпитеру". В Oracle Label Security эта особенность нашла воплощение, в чем легко убедиться.
Создадим нового пользователя и дадим ему полномочия работы исключительно с "секретными" строками:
CONNECT / AS SYSDBA
CREATE USER secretmanager IDENTIFIED BY secretmanager;
GRANT minimal TO secretmanager;
CONNECT lbacsys/lbacsys
BEGIN
SA_USER_ADMIN.SET_USER_LABELS
(
(Заметьте, что ранее параметр MIN_WRITE_LABEL в процедуре SET_USER_LABELS мы не использовали; в результате умолчательного поведения Label Security для пользователя HEAD было MIN_WRITE_LABEL = 'OPEN', что легко проверяется по справочным таблицам).
Проверим теперь возможности SECRETMANAGER по чтению и по изменению полей строк, в том числе поля метки:
SQL> CONNECT secretmanager/secretmanager
Connected.
SQL> @phones
ENAME | PNO |
---------- | -------------------- |
SMITH ALLEN WARD JONES MARTIN BLAKE CLARK SCOTT KING TURNER ADAMS JAMES FORD MILLER |
665-7282 882-3154 610-1718 100-6539 103-1983 193-3112 310-2673 680-4853 542-6672 293-1398 278-5105 932-6728 485-9127 865-6706 |
14 rows selected.
SQL> @updateallenpnumber
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...
SQL> @updateallen OPEN
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...
SQL> @updateallen LIMITED
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...
Невозможно поменять ни "основную" строку для Аллена, ни метку доступа к его телефону. Обратите внимание: несмотря на это пользователю SECRETMANAGER видны все строки - как помеченные более слабой меткой OPEN, так и помеченные меткой LIMITED. А теперь переведем телефон Аллена из категории OPEN в категорию LIMITED и понаблюдаем, что он может делать со строкой "своей" категории секретности:
SQL> CONNECT head/head
Connected.
SQL> @updateallen LIMITED
1 row updated.
SQL> CONNECT secretmanager/secretmanager
Connected.
SQL> @updateallenpnumber
1 row updated.
SQL> @updateallen LIMITED
1 row updated.
SQL> @updateallen OPEN
1 row updated.
SQL> @updateallen OPEN
UPDATE scott.phone
*
ERROR at line 1:
ORA-12406: unauthorized SQL statement for policy EMPSEC_POLICY
... ... ... ...
Очевидно, пользователь может читать как "свои" строки, так и менее секретные, а вот изменять менее секретные, чем ему положено, строки он не сможет. В приведенном примере тайный SECRETMANAGER понизил секретность строки и потерял былую возможность строку править. Ну, а более секретные строки он даже не увидит !
В завершение знакомства с меточным доступом к строкам в Oracle мне хотелось бы подчеркнуть, что даже без учета структуры меток, привилегий, группирования пользователей и многого прочего, большая часть которого в этих статьях не рассматривалась, мандатный метод доступа не так прямолинеен в поведении, как мог бы показаться поначалу.
Рассмотрим обычную выдачу данных, помеченных метками доступа. Вспомним, что до сих пор в таблице PHONE у нас имелось по одному номеру телефона на каждого сотрудника. Попробуем добавить второй телефон Аллену, а так как сценарий phones.sql использует для выдачи на экран полуоткрытое соединение, употребление его останется корректным и для этих новых данных. Интерес представляет случай, когда телефоны Аллена (когда их станет два) будут иметь метку LIMITED, и когда к ним обратится пользователь EMPLOYEE. Интуиция подсказывает, что "невидимые" телефоны Аллена будут обрабатываться полуоткрытым соединением подобно пропущенному значению (NULL), и в результате выборки мы увидим несколько строк для Аллена с пропущенными значениями номеров телефона. А что на самом деле?
Добавим в таблицу PHONE для Аллена новый телефон и "засекретим" оба:
CONNECT head/head
INSERT INTO scott.phone
@updateallen LIMITED
Проверяем:
SQL> @phones
ENAME | PNO |
---------- | -------------------- |
SMITH ALLEN ALLEN WARD JONES MARTIN BLAKE CLARK SCOTT KING TURNER ADAMS JAMES FORD MILLER |
665-7282 111-2222 882-3154 610-1718 100-6539 103-1983 193-3112 310-2673 680-4853 542-6672 293-1398 278-5105 932-6728 485-9127 865-6706 |
15 rows selected.
SQL> CONNECT employee/employee
Connected.
SQL> @phones
ENAME | PNO |
---------- | -------------------- |
ALLEN | |
WARD | 610-1718 |
MARTIN | 103-1983 |
BLAKE | |
CLARK | |
KING | |
TURNER | 293-1398 |
JAMES | 932-6728 |
MILLER | 865-6706 |
9 rows selected.
Меточный доступ в Oracle справедливо показал пользователю EMPLOYEE имя Аллена (его строка в таблице EMP в открытом доступе), и не показал его телефоны (мы закрыли доступ к телефонам Аллена в таблице PHONE), но вот только открытое соединение таблиц EMP и PHONE показало "отсутствие" (на деле - недоступность) телефона одной строкой, а не двумя! Ничего лишнего: телефон недоступен, а сколько их недоступно - не сообщается. Если же сделать один из телефонов Аллена открытым, информация о наличии второго, недоступного телефона и вовсе пропадет:
SQL> CONNECT head/head
Connected.
SQL> UPDATE scott.phone
1 row updated.
SQL> CONNECT employee/employee
Connected.
SQL> @phones
ENAME | PNO |
---------- | -------------------- |
ALLEN | 111-2222 |
WARD | 610-1718 |
MARTIN | 103-1983 |
BLAKE | |
CLARK | |
KING | |
TURNER | 293-1398 |
JAMES | 932-6728 |
MILLER | 865-6706 |
9 rows selected.
Не думаю, что такое поведение для всех очевидно, а значит приведенные выше примеры могут оказаться небесполезными.
INTERFACE Ltd. |
|