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
Related
I have a Postgres database in Cloud SQL and would like to utilize the pg_trgm extension to do similarity searches. However, the default threshold parameters are not sensitive enough in my use case so they should be altered.
The problem is that Cloud SQL does not provide database flags for either pg_trgm.similarity_threshold or pg_trgm.word_similarity_threshold and the database users do not have the privileges to alter the user or database:
postgres=> ALTER ROLE postgres SET pg_trgm.similarity_threshold = 0.1;
ERROR: permission denied to set parameter "pg_trgm.similarity_threshold"
postgres=> ALTER DATABASE postgres SET pg_trgm.similarity_threshold = 0.1;
ERROR: permission denied to set parameter "pg_trgm.similarity_threshold"
Is there any other way to alter these parameters?
Can you do the straightforward SET pg_trgm.similarity_threshold = 0.1;? You would have to repeat it in every session, so maybe incorporate it into your connection sub.
For similarity_threshold, you can use the function set_limit unless Google has also disabled that. You would also have to set it this way in each session, though. There is no alternative way to set word_similarity_threshold, though, unless Google has invented one.
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.
I'm using postgreSQL as a database for an application that I build. When I run the application, I open dbeaver and typed the SQL query:
select * from pg_stat_activity
in order to see a list of SQL queries that has been processed during the application running.
In "query" column I got "insufficient privilege" for some queries. Do you know what I can do to see the actual SQL query?
You would have to run the query as a root-user to see all the queries. This is usually the postgres user.
On certain managed postgresql services (AWS), access to the root-user is restricted, and it is not possible to see queries executed by that user by design.
In general, the more privileges your user has, the more queries you can see in pg_stat_activity
If you are using Postgresql 10 and above, you can grant pg_read_all_stats role to your user from superuser account (postgres)
GRANT pg_read_all_stats TO username;
You do not necessarily have to run the query as a root-user. Giving someone root user access could have very bad security implications, as they could literally do anything. There is a workaround where you can create a function as root that has access to pg_stat_statements, and then grant the read-only user access to the function. For example:
CREATE OR REPLACE FUNCTION your_schema.get_stat_statements(showtext boolean = true) RETURNS SETOF pg_stat_statements AS
$$
/* pganalyze-collector */ SELECT * FROM public.pg_stat_statements(showtext) LIMIT 100;
$$ LANGUAGE sql VOLATILE SECURITY DEFINER;
GRANT USAGE on SCHEMA your_schema TO your_readonly_user;
GRANT EXECUTE on FUNCTION your_schema.get_stat_statements(boolean) TO your_readonly_user;
Thanks to https://pganalyze.com/docs/install/amazon_rds/02_create_monitoring_user
You can find an example of a similar approach here.
One possible workaround to this is defining a MATERIALIZED VIEW using a user that has enough privileges to view the data, and granting access to the view to the use that does not have the privileges.
One downside to this is that the view will have to be refreshed periodically using REFRESH MATERIALIZED VIEW, also by the owner of the view (or some other user with privileges).
Encountered this issue when trying to modify the search_path to my new Redshift db.
Presently, I've migrated the contents of my MySQL db into a redshift cluster via AWS' Data Migration Service. The data was imported into a schema lets call my_schema. When I try to execute queries against the cluster it requires me to prefix table names with the schema name
i.e.
select * from my_schema.my_table
I wanted to change the setup so that I can reference the table directly without needing the prefix. After a bit of looking around I found out that this was possible by modifying the search_path attribute.
First I tried doing this by running
set search_path = "$user", my_schema;
This appeared to work but then I realized that this was simply setting my_schema as the default schema in the context of the current session, I wanted it set on a database level. I found several sources saying that the way to do this was to use the alter command like so...
alter database my_db set search_path = "$user", public, my_schema
However, running this command results in the following error which somehow shows up in 0 google results:
SET/RESET commmand in ALTER DATABASE is not supported
I'm pretty baffled by how the above error hasn't ever had a post made about it but I'm also pretty interested in figuring out how to resolve my initial issue of setting a global default schema for my redshift cluster.
ALTER DATABASE SET is not supported in Redshift. However you can SET/RESET configuration parameters at USER level using the ALTER USER SET SEARCH_PATH TO <SCHEMA1>,<SCHMEA2>;
Please check: http://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_USER.html
http://docs.aws.amazon.com/redshift/latest/dg/r_search_path.html
When you set the search_path to <SCHEMA1>,<SCHMEA2> in db1 for a user it is not for just current session, it will be set for all future sessions.
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.