|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
Hi all! Столкнулся с такой проблемой: Есть таблица test(id int, name text). Есть пользователь vst. Есть view test_view AS SELECT * FROM test WHERE id > 10; На таблицу test у пользователя нет никаких прав. На test_view у пользователя есть права на SELECT. Т.о. пользователь vst может видеть только строки у которых id > 10 из таблицы test. Едем дальше. Я хочу, что бы пользователь мог изменять и добавлять строки таблице test но видеть он должен только то, что я ему разрешу через test_view. Т.е. у пользователя будут права на UPDATE и INSERT таблицы и не будет прав на SELECT. Сказано - сделано: GRANT INSERT, UPDATE ON test TO vst; Кульминация (pgsql под юзером vst): testdb=> INSERT INTO test VALUES (1, 'test'); INSERT 17213 1 testdb=> UPDATE test SET name = '321' WHERE id = 1; ERROR: permission denied for relation test Если я из под админа сделаю GRANT SELECT ON test TO vst; то всё будет впорядке. Вот такие пироги. С уважением, Владимир Тихонюк ... |
|||
:
Нравится:
Не нравится:
|
|||
10.04.2004, 16:55 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
Задачка простая, но тема с подвохом. Все нижесказанное - результат RTFM+expirience, опробывалось на PG 7.3-7.4 ,так что гарантировать ничего не могу. Тихонюк Владимир Я хочу, что бы пользователь мог изменять и добавлять строки таблице test но видеть он должен только то, что я ему разрешу через test_view. Т.е. у пользователя будут права на UPDATE и INSERT таблицы и не будет прав на SELECT. Это делается вот так: Код: plaintext 1. 2. 3.
И все. НИКАКИХ прав на таблицу test пользователь vst не имеет-он работает только с просмотром. Аналогично пишем правило ON UPDATE (ну может и ON DELETE) и вроде бы все. Но тут есть одна неявная особенность: Все действия с привилегями просмотра нужно реализовывать в правилах. ( то что по умолчанию работает GRANT SELECT on test_view to vts значит : a) CREATE VIEW как бы создает "неявное" правило на SELECT, которое анализирует права доступа. (кое-что об этом см в гл 34.2.1. How SELECT Rules Work) б) Достаточно перекрыть это правило и все будет в Ваших руках - не напишете рестиктов - GRANT/REVOKE перестанут влиять на доступ к просмотру ) Думаю это нечто среднее между багом и фичей 8)) Например незная этого можно написать : REVOKE INSERT on test_view from vst; увидев что это не работает заорать "Ага, в Постгресе безопастность глюкавая!!!" IMHO все совсем не так - багом является другое : в доке гл. 34.4. Rules and Privileges я не обнаружил описания подобных ситуаций. Вот это опасно. Может тут дело только в моем "Forgive-my-dirty-engleze" ;)\ То что я нашел в доке меня только развеселило. Пользователь vst создал _СВОЙ_ просмотр и сделал грант на него для кого-то кому этих данных видеть не стоит. Ну например представьте: секретарь(!!!) опубликовала список телефонов шефа доступных ей. Какая жуть. "Я плакаль...." (c) IMHO беда СБ Постгреса не в том что она "плохая/сложная",а в том что у писатели доки до этого раздела понастоящему никогда не добирались. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.04.2004, 00:24 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
Да забыл -вот примитивнейший вариант использования функции проверки прав в правиле. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
Все конечно нужно в реальности делать чуть иначе, например можно обойтись и баз "обвязки" на pl/pgsql Т.е "простор открыт и ничего святого!"(с) ... |
|||
:
Нравится:
Не нравится:
|
|||
11.04.2004, 02:05 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
Hi, Shweik ! Спасибо за совет. Всё сделал как хотел. Правда возник новый вопрос: если я переопределяю правило на INSERT, то при вставке, постгрес не хавает значения по-умолчанию. Например: CREATE TABLE test ( id SERIAL, name text ); В этой таблице, значение по-умолчанию для поля id = nextval('test_id_seq'); Т.е. комманда INSERT INTO test (name) VALUES ('Vladimir'); проходит. Если я сделаю правило на INSERT для этой таблицы: CREATE RULE "test_insert_rule" AS ON INSERT TO test DO INSTEAD INSERT INTO test (id, name) VALUES (NEW.id. NEW.name); То комманда INSERT INTO test (name) VALUES ('Vladimir'); уже не пройдёт. В принципе я могу вытащить значения по-умолчанию для колонок из системных таблиц (pg_class, pg_attribude, pg_attrdef) но тогда возникают проблемы, если в значении по-умолчанию записано не статическое значение, а функция. Та же петрушка возникает и при правиле на UPDATE. При UPDATE'e какого-нибудь одного поля таблицы через правило, будут UPDATиться все поля таблицы. В принципе и этого можно избежать, написав функцию, которая будет просматривать запись NEW и поля со значением NULL не вставлять в INSERT/UPDATE, но это тоже не выход. Может есть какой-нибудь более цивилизованный способ с этим бороться ? С уважением, Владимир Тихонюк ... |
|||
:
Нравится:
Не нравится:
|
|||
13.04.2004, 09:47 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
>>То комманда INSERT INTO test (name) VALUES ('Vladimir'); уже не пройдёт. попробуй такой вариант INSERT INTO test (id,name) SELECT nextval('test_id_seq'),'Vladimir'; не забуть про доступ к последовательности, например GRANT ALL ON test_id_seq TO PUBLIC; >>При UPDATE'e какого-нибудь одного поля таблицы через правило, будут UPDATиться все поля таблицы. у меня подобное было для таблицы пользователей программы, я создал 2 отображения - одно отвечало за добавку/изменение/удаления id, имени, описания и т.п., а второе отображение только за изменение поля с паролем. первая вьюшка: CREATE VIEW users_v AS SELECT id,id_parent,depth,CASE WHEN visible_lvl>0 THEN inv2str(name) ELSE name END AS name,descript,inv2str(coalesce(pswd,descript)) as pswd,modify_date,visible_lvl,modify_lvl,modify_user FROM users; GRANT SELECT,INSERT,UPDATE,DELETE ON users_v TO GROUP usr; CREATE RULE users_v_ins AS ON INSERT TO users_v DO INSTEAD INSERT INTO users (id,id_parent,depth,name,descript,visible_lvl,modify_lvl) VALUES(new.id,new.id_parent,new.depth,new.name,new.descript,new.visible_lvl,new.modify_lvl); CREATE RULE users_v_upd AS ON UPDATE TO users_v DO INSTEAD UPDATE users SET id=new.id,id_parent=new.id_parent,descript=new.descript,name=new.name,visible_lvl=new.visible_lvl,modify_lvl=new.modify_lvl WHERE id=old.id; CREATE RULE users_v_del AS ON DELETE TO users_v DO INSTEAD DELETE FROM users WHERE id=old.id; вторая вьюшка: CREATE VIEW users_pswd_v AS SELECT id,inv2str(coalesce(pswd,'')) as pswd FROM users; GRANT SELECT,UPDATE ON users_pswd_v TO GROUP usr; CREATE RULE users_pswd_v_upd AS ON UPDATE TO users_pswd_v DO INSTEAD UPDATE users SET pswd=new.pswd WHERE id=old.id; где inv2str - функция шифрования пароля. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2004, 11:53 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.
Таким образом, если обновление таблицы осуществляется по условию WHERE, требуется разрешение на выборку данных из таблицы. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19.
То есть, никакие проверки прав при выполнении операций над таблицей через правила не производятся. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.
Таки да, вместо значений по умолчанию значения null. А вот если исключить из представления столбцы, где требуется вводить значения по умолчанию (например, столбец первичного ключа), то все будет работать, только вот ввести в них через представление ничего нельзя будет. ;-) Действительно, можно создать несколько представлений и обойти эту проблему. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2004, 15:13 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
Продолжение. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
Как видим, можно для представлений назначить значения по умолчанию, но почему-то этот трюк не проходит для значений, генерируемых последовательностями. Хм. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2004, 16:42 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
>> test=# alter table test_view alter id set default nextval('seq_test_id'); >> test=# insert into test_view(name) select nextval('ins name'); >>ERROR: nextval: invalid name syntax названия последовательностей разные ('seq_test_id' и 'ins name'), но это скорее опечатка. >> Как видим, можно для представлений назначить значения по умолчанию, но почему-то этот трюк не проходит для значений, генерируемых последовательностями. можно использовать отображения, у которых правила добавления будут задовать значения для полей по-умолчанию c использованеим конструкции CASE WHEN ... IS NULL THEN ... END и/или которых нет в отображении. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2004, 09:53 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
Действительно, поторопился я с выводами. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
2 OAN: Имеется в виду что-то наподобие такого? Код: plaintext 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2004, 13:36 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
да, именно так. а еще есть второй вариант - повесить триггер на изменение/обновление на таблицу и там добавлять чего не хватает в значениях. именно этот способ нашел как наиболее удобный. так можно заодно сделать "хитрые" проверки возможности записи и сложные вычисления. я долго пытался разобраться с правилами, и мне думается, что параметр "DEFAULT ..." в описании структуры таблиц просто добавляет правило с "CASE WHEN ... IS NULL THEN ... END" на значение поля перед записью данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2004, 20:31 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
OAN я долго пытался разобраться с правилами, и мне думается, что параметр "DEFAULT ..." в описании структуры таблиц просто добавляет правило с "CASE WHEN ... IS NULL THEN ... END" на значение поля перед записью данных. Похоже на то. Замечу только, что я создавал правила на представления, и навешивал значения по умолчанию именно на поля представления, а не таблицы. С таблицей-то было бы совсем просто. Я пока глубоко с правилами не разбирался, для меня это пока способ переписывания запросов, как бы еще один промежуточный уровень перед парсером и оптимизатором. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.04.2004, 10:31 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
а все таки, в продолжение темы, поправьте меня, если не прав: тест GRANT выполняется только 1 раз при первом обращении к отношению, а дальше проверок нет, даже если у пользователя отсутствуют права на родителя отношения (например, таблица является родителем по отношению к отображению). в приведенном ранее мною примере отображений у пользователя usr на таблицу users прав вообще не имеет, но через отображение user_v пользователь usr может править любую запись таблицы users с указанием "WHERE id=...". pl2=> \z users* Access privileges for database "pl2" Schema | Table | Access privileges --------+--------------+------------------------------------------------------ public | users | {=,oan=arwdRxt,"group prg=arwdRxt"} public | users_pswd_v | {=,oan=arwdRxt,"group usr=rw","group prg=arwdRxt"} public | users_seq | {=arwdRxt,oan=arwdRxt} public | users_v | {=,oan=arwdRxt,"group usr=arwd","group prg=arwdRxt"} ... |
|||
:
Нравится:
Не нравится:
|
|||
30.04.2004, 14:59 |
|
GRANT UPDATE и SELECT
|
|||
---|---|---|---|
#18+
2 OAN: Во-первых, представления реализуются в Постгрес как неявные правила. Во всяком случае, так написано в документации. Во-вторых, правила -- это своего рода "процедуры с правами создателя". То есть, права на доступ к объектам БД для SQL-операторов внутри каждого конкретного правила проверяются по отношению к создателю, а не к вызывающему. В моем представлении это выглядит так: 1. Пользователь запрашивает для обновления некий объект БД, например, представление. 2. Система проверяет, есть ли у него права доступа к этому объекту. Если нет, то на этом все и заканчивается. 3. Система проверяет, существуют ли для этого объекта правила. Если нет, то в данном конкретном примере "Cannot update a view". 4. Если находится подходящее правило (на обновление, в данном случае), то система анализирует действия, которые необходимо выполнить и наличие необходимых полномочий у создателя правила. ... В каком-то смысле правила -- это подобие suid-ных программ в Юниксе. 2 Shweik: Пример из документации иллюстрировал принцип проверки "rule-by-rule". Иными словами, если секретарша создает на основе тех данных, к которым имеет доступ, свое представление, и грантирует к ним доступ, то мы фактически теряем контроль над доступом. А вот и пример. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75.
Извините за многословность. ;-) ... |
|||
:
Нравится:
Не нравится:
|
|||
30.04.2004, 16:36 |
|
|
start [/forum/topic.php?fid=53&fpage=358&tid=2007880]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
5ms |
check topic access: |
5ms |
track hit: |
50ms |
get topic data: |
14ms |
get forum data: |
3ms |
get page messages: |
140ms |
get tp. blocked users: |
2ms |
others: | 12ms |
total: | 254ms |
0 / 0 |