I have postgresql and using pg admin.
the problem is my system and everything is in English except errors and messages in output pane.
I have already set the user language to English but still the messages are in German!
You can execute the following SQL statement:
SET lc_messages="C";
That will change the messages you get and also the messages in the log file.
You can only set this parameter when you are a superuser, but you can create a superuser-owned function with SECURITY DEFINER and grant EXECUTE on it to a normal user:
CREATE OR REPLACE FUNCTION set_english() RETURNS void
LANGUAGE sql SECURITY DEFINER AS
'SET lc_messages="C"';
REVOKE EXECUTE ON FUNCTION set_english() FROM PUBLIC;
GRANT EXECUTE ON FUNCTION set_english() TO laurenz;
Then user laurenz can call the function to change the setting.
Related
A script has to import SQL data into an PostgreSQL database. The SQL includes these two lines of code:
SET session_replication_role = 'replica';
...
SET session_replication_role = 'origin';
The user xyz who starts the import doesn't have the power to do this yet. The error PG::InsufficientPrivilege gets displayed.
How (with which SQL query) can the user postgres grant the user xyz the right to set session_replication_role? I can't find any documentation about that.
As of PostgreSQL 15+ there is a way to do this:
GRANT SET ON PARAMETER session_replication_role TO xyz;
https://www.postgresql.org/docs/15/sql-grant.html
I haven't tried this yet but I bet it works good - in version 14, I used SECURITY DEFINER at the end of a plpgsql procedure with "SET session_replication_role" statements inside of it, and made sure a superuser account was the definer/owner of the procedure - then, any user with EXECUTE privilege can still run it and the parameter setting works as you would hope.
It is impossible :-(. See:
It seems this is currently only possible with superuser privilege:
Setting this variable requires superuser privilege, cf.
postgresql.org/docs/current/runtime-config-client.html
So I am having an issue that I wanted to clear up. I am granting access to a user in postgres, but I only want that user to be able to execute functions.
I have the following code:
GRANT USAGE ON SCHEMA not_public TO test_id;
GRANT USAGE ON SCHEMA public TO test_id;
GRANT EXECUTE ON FUNCTION testFunction TO web_reporting_id;
When this is ran, though, and I try to run the function under that user, I get a permissions error on the first table the function tries to read from.
I know some db languages you only need to grant permissions for the functions/procedures and not the underlying objects. In postgres, do I need to grant permissions on the tables too? Or do I need to update my grant scripts?
Thanks!
Normally, functions run with the privileges of the user calling them, so all SQL statements in them will be executed by that user.
You could define the function as SECURITY DEFINER to have it run with the privileges of the function owner, but then you must use the SET clause of CREATE FUNCTION to fix the search_path for the duration of the function execution for security reasons.
Also note that by default, everybody (PUBLIC) has execute privileges on functions, so you might want to revoke that.
Documentation says:
For other types of objects, the default privileges granted to PUBLIC are as follows: CONNECT and TEMPORARY (create temporary tables) privileges for databases; EXECUTE privilege for functions; and USAGE privilege for languages and data types (including domains).
I execute:
create user test_user password 'test_user';
grant create on database "NLP" to test_user;
Then I connect under this user and do:
create schema s;
create function s.f() returns void as $$begin null; end;$$ language plpgsql;
I expect that EXECUTE will be granted to PUBLIC on the function but this does not happen. Why?
Additionally I discovered a curious thing. If I alter default function privileges for the schema the mechanism starts to work.
create role test_role;
Under test_user:
alter default privileges in schema s grant execute on functions to test_role;
create function s.x() returns void as $$begin null; end;$$ language plpgsql;
Voila! In addition to EXECUTE on x() for test_role I got EXECUTE for PUBLIC!
My DB report version():
PostgreSQL 10.3 (Ubuntu 10.3-1.pgdg14.04+1) on x86_64-pc-linux-gnu,
compiled by gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4, 64-bit
Is something wrong with my database? I tested it on another database (same version()) and got the same results.
Answering my own question. Everything works as expected, but I misinterpreted pgAdmin's indications.
select proacl from pg_proc where proname = 'f'
Gives NULL, which according to documentation:
If the “Access privileges” column is empty for a given object, it means the object has default privileges (that is, its privileges column is null). Default privileges always include all privileges for the owner, and can include some privileges for PUBLIC depending on the object type, as explained above.
And for such object type as function, it assumes EXECUTE for PUBLIC (as I posted in initial question).
Effective permissions for a user can also be conveniently tested by (thanks Laurenz):
select has_function_privilege('username', 's.f()', 'EXECUTE');
Which gave TRUE for any user.
The fact that pgAdming generated explicit grant for PUBLIC in one case and nothing in another, was misleading. Absence of grant to PUBLIC does not necessarily mean that PUBLIC does not have permissions.
I'm building an app using AWS RDS PostgreSQL.
I need to allow one group to use CREATE, INSERT INTO and UPDATE statements, but at the same time not allow them to use DROP TABLE or DROP DATABASE.
Is there a way to do this on the database layer, as I would prefer not to do it on server-side layer? Thank you.
You can create one privileged user that can do all these things – let's call it creator – and a normal user luser that is used to log into the database.
creator then defines PL/pgSQL functions with SECURITY DEFINER that perform the required CREATE statements (probably using dynamic SQL with an EXECUTE statement).
Then creator runs
REVOKE EXECUTE ON FUNCTION ... FROM PUBLIC;
GRANT EXECUTE ON FUNCTION ... TO luser;
so that luser can execute the functions.
INSERT and UPDATE privileges are granted to luser inside the functions.
Documentation links:
Language PL/pgSQL to write functions in PostgreSQL
Executing dynamic statements in PL/pgSQL
CREATE FUNCTION SQL sommand
Privileges in PostgreSQL
I have streaming replication which I need to monitor. So there is a special user for Zabbix. I don't want to use pg_mongz and decided to set my own queries to pg_catalog schema's view pg_stat_replication to get replication state.
When I use query:
select *
from pg_stat_replication;
it returns replication state record for admin. But when I logged in as monitoring user it returns just:
pid, usesysid, usename, application_name
So such parameters as client_addr, client_hostname, client_port, backend_start, state, sent_location, write_location, etc. are empty.
First I granted rights to my user on schema and tables:
grant usage on schema pg_catalog to usrmonitor;
grant select on all tables in schema pg_catalog to usrmonitor;
but it didn't help. When I looked at view I found that query uses functions and granted execution:
grant execute on function pg_stat_get_wal_senders() to usrmonitor;
grant execute on function pg_stat_get_activity(integer) to usrmonitor;
But the select query still returns empty columns. What maybe the problem?
Since PostgreSQL 10, it is as simple as :
GRANT pg_monitor TO monitoring_user;
(Source: https://pganalyze.com/blog/whats-new-in-postgres-10-monitoring-improvements)
Yes, access to these fields is intentionally restricted to superusers.
As a workaround, you may use a function as a proxy with the SECURITY DEFINER attribute:
SECURITY DEFINER specifies that the function is to be executed with
the privileges of the user that created it.
So as a superuser (typically the postgres user), do:
CREATE FUNCTION func_stat_replication() RETURNS SETOF pg_stat_replication as
$$ select * from pg_stat_replication; $$
LANGUAGE sql SECURITY DEFINER;
Then revoke/grant the permission to use that function so that only the monitoring
user is allowed to execute it:
REVOKE EXECUTE ON FUNCTION func_stat_replication() FROM public;
GRANT EXECUTE ON FUNCTION func_stat_replication() to usrmonitor;
Then usrmonitor should execute:
SELECT * FROM func_stat_replication();
and it will have the same results as if it was superuser.