Триггер PostgreSQL с заданной ролью

Я сделал небольшой триггер PostgreSQL с Plpython. Этот триггер играет немного с файловой системой, создает и удаляет некоторые мои файлы. Созданные файлы принадлежат пользователю unix "postgres", но я бы хотел, чтобы они принадлежали другому пользователю, скажем, foobar. Триггеры устанавливаются с пользователем "foobar" и выполняются также с пользователем "foobar".

Есть ли способ выполнить триггер SQL с пользователем Unix 'foobar' с PostgreSQL или Plpython? Должен ли я использовать SET ROLE foobar?

Играть с SECURITY INVOKER а также SECURITY DEFINER не кажется достаточно хорошим.

2 ответа

Решение

Вы путаете пользователей операционной системы и пользователей PostgreSQL.

SECURITY DEFINER позволяет запускать функцию в качестве определяющего пользователя postgresql. Но независимо от того, какой пользователь PostgreSQL работает с пользователем операционной системы, внутренний сервер работает как всегда один и тот же - обычно пользователь операционной системы postgres,

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

Однако, если вы хотите разрешить это, вы можете. Вы могли бы:

  • Даруй postgres пользователь sudo права на запуск некоторых или всех команд других пользователей; или же
  • Напишите программу для запуска setuid права делать то, что вы хотите, и предоставить postgres Пользователь имеет право выполнить его.

В любом случае, единственный способ запустить эти программы - запустить их из ненадежного процедурного языка, такого как plpython или plperl, или из расширения C ".

Непонятно, почему вы хотите установить владение файлом таким образом, но я подозреваю, что это не очень хорошая идея. Что если клиент и сервер PostgreSQL даже не находятся на одном компьютере? Что, если для этого пользователя PostgreSQL нет пользователя операционной системы или имена пользователей разные? и т.п.

"Роль", которую ваши пользователи принимают в Postgres, является локальной для базы данных. Ваша роль в базе данных обеспечивает права доступа к базе данных. Таким образом, вы можете сказать, что foobar может запустить этот сохраненный процесс или выбрать эту таблицу, и Postgres обеспечит это. Если вы создаете свою процедуру с помощью SECURITY INVOKER, это означает, что выполняемая процедура будет выполняться с использованием текущего зарегистрированного пользователя Postgres. SEFURITY DEFINER означает, что процедура будет выполняться с использованием роли, создавшей процедуру. В любом случае, если ваша процедура делает что-то за пределами Postgres (например, создает файл), это будет сделано как личность, которая запустила Postgres (как вы узнали). В моем случае у меня есть пользователь Unix с именем 'postgres', и когда я запускаю Postgres, я делаю это как этот пользователь. Таким образом, любой созданный файл будет принадлежать пользователю postgres.

Вы не сказали нам свою операционную систему. Windows будет отличаться от * nix. Этот ответ для * nix.

Вы упомянули, что ваш сохраненный язык proc был plpython. Таким образом, вы можете создать файл, а затем изменить его владельца после создания его в своей процедуре. Подобно:

import os
import pwd

f = open('/tmp/myfile','w')
f.write('hello')
f.close()
user_id = pwd.getpwnam("foobar").pw_uid    
os.chown('/tmp/myfile', user_id, -1)

Предполагая, что на хосте, на котором работает Postgres, есть пользователь foobar, это должно сработать.

Другие вопросы по тегам