Postgresql: handle all queries to change user's password? - postgresql

I have to log all such queries to my database on Amazon RDS
The best way, of course, create a trigger on pg_catalog.pg_authid, but I have no privileges to operate system catalog.
Any advice?

The best you can do is to set log_statement = 'ddl'. That will log other DDL statements as well.

Related

very confused about permissions in postgres

I have multiple databases and each of them have multiple schemas.
I have a set of apps that connect to these databases. Each app has it own user and, depending on their function, the apps can:
read / write all schemas and tables of a specific db, set functions/notifications
read only all schemas and tables of a specific db
The schemas and tables can be created at any time, so the permissions need to be set with ALTER DEFAULT.
My understanding is that the ALTER DEFAULT has to be done by the user that will create the future tables. Is that correct?
Since I can have scenarios where User 1 can RO db A, but RW db B, while User 2 can only RO db B, etc.. using roles doesn't seem to be of any help here.
So I'm a bit confused how to set that up.
Then comes the next complication:
I can assign permissions as either SELECT (RO), or SELECT, INSERT, UPDATE, DELETE (RW), but:
what about sequences? I don't want a RW user to be able to alter the sequences, but they need to be able to use them
then how does it work with functions? the RW users need to be able to set/update their own functions
Any example of this setup would be greatly appreciated because going through the doc didn't help me much and most of the questions / answers on SO seems to be very similar yet never exactly the same, so it's quite confusing :)
Edit, following 'a_horse_with_no_name''s suggestion in the comments, I did this:
here is my init.sql:
CREATE DATABASE accounts;
CREATE DATABASE analysis;
CREATE DATABASE exchange;
GRANT CONNECT ON DATABASE exchange TO capture, analyzer, sunny, viewer;
GRANT CONNECT ON DATABASE analysis TO analyzer, sunny, viewer;
GRANT CONNECT ON DATABASE accounts TO sunny;
then I log in as admin to db exchange and do:
GRANT pg_write_all_data TO capture;
GRANT pg_read_all_data TO analyzer, sunny, viewer;
and I create a table called instruments there
then I log in as capture to to db exchange and do an insert, and I get:
42501: permission denied for table instruments
so using the capture user on the exchange db, I should have the pg_write_all_data property; why do I get the error?
It looks like I have to grant usage of instruments to capture.. which defeats the purpose of the pg_write_all_data. If I do the grant, then it works. So it looks like adding the role doesn't work.
Since your users shall have different permissions in different databases, define read-only and read-write roles for each database.
For example, db1_ro has read-only permissions in db1, and db2_rw has read-write permissions in db2. Then you can grant them both to a user, and the user will have different permissions in different databases.
Using a sequence typically means to call nextval(). So you should give that user the USAGE privilege. To use setval(), the user would need UPDATE. Nobody except the owner can ALTER an object anyway.
Functions cannot be set or updated, only executed, for which there is the EXECUTE privilege, which is granted to PUBLIC by default.

what is the way to analyse specific schema queries in Postgres?

Queries of multiple schemas of DB are logged in the pg_log directory in an application server, and the performance of specific schema needs to be profiled.
The same queries that are running, the difference is that search_path is set to include different schemas in each case.
How to log queries using a specific in pg_log? Or is there any way to "tail" specific the log for queries using a specific schema on the command line?
There is no way to do that.
What you could do is use different users to run the queries with different search_path settings, and then only log queries by a certain user:
ALTER ROLE myuser SET log_min_duration_statement = 0;

How to create a read-only user in postgres for all schema?

I am wondering if anyone knows a command to create a read-only user for all schemas and tables in a postgres DB. I have found ways to do it for specific tables and specific schemas but not across the board (we have many schemas and I would rather not run the command 60+ times). Thanks in advance
There is no simple way to do that in PostgreSQL.
What you should do is create a role that has read access to all tables (and yes, you'll have to run at least one GRANT statement per schema) and grant that role to all login users that need read access.
That way you have to do the work only once, and dropping the user becomes so much easier.

Loging activity for one user on specific database in Postgres

I need to log all activity for some specific user on database. I have set up the logging with ALTER ROLE username SET log_statement TO 'all'; and the logging works fine, all queries from user are logged. The problem is that for this user queries to Postgres internal schemas (pg_catalog) from clients like psql and pgAdmin are also logged. I have a bunch of lines with SELECT pg_catalog.quote_ident(n.nspname) || '.' || pg_catalog.quote_ident(c.relname).... in the log that are of no use to me. Even worse this queries are more then one line in the log so it's not easy to filter them out.
Is it possible to somehow restrict the logging only to one specific database or schema and not to include queries to other schemas like pg_catalog?
I don't know if the standard logging utility in postgres has that option (my guess is no). But maybe it's worth a look to the pgaudit external library for postgres.
The module pgadmin is designed to generate audit logs, but it uses the standard postgres logging tool. You can tweak several parameters to customize the logs, and it has a specific parameter that I think is perfect for your use case. From the documentation:
pgaudit.log_catalog
Specifies that session logging should be enabled in the case where all
relations in a statement are in pg_catalog. Disabling this setting
will reduce noise in the log from tools like psql and PgAdmin that
query the catalog heavily.
The default is on.
I hope it helps!
Change your logging format from text to csv (log_destination=csvlog) — you can then import the data to the database and then filter out the queries you are not interested in:
Using CSV-Format Log Output

db2 creating proxy user account

SQL server has an option to create proxy user accounts with the statement
CREATE USER proxyUser WITHOUT LOGIN;
I couldn't find much help on internet on getting the db2 (v8) equivalent of this. I'm not sure whether this is possible, if yes please let me know how.
The scenario where i want to use this is as follows.
I have table with ~8 million records which gets updated daily. Before the inserts happen, few records are deleted from the table and the number is ~2 million. Since these deletes need not be logged, we decided on setting off Logging during the deletes. Since our credentials do not have alter table rights, we decided to put the ALTER and DELETE statements in a script and and execute the script using the proxy account irrespective of what user executes the SP.
I foud this article which closely describes the scenario which i described above. The differences are that i need to do this on db2 and i need to do deletes without logging them.
http://www.mssqltips.com/sqlservertip/2583/grant-truncate-table-permissions-in-sql-server-without-alter-table/
Thanks
Arjun
It will work basically in the same manner in DB2, with a few exceptions. Firstly, there's no TRUNCATE TABLE statement in DB2 8.2 (and there's no DB2 version 8 on Linux). Secondly, there are no database users in DB2 -- all users are defined externally in the operating system, so there's no CREATE USER statement either.
All statements in a stored procedure, except dynamic SQL, are executed with the authorization of the procedure creator.
So, using the authorized ID, e.g. the database administrator's ID, create the stored procedure that does what you need (ALTER, DELETE, whatever), then grant the EXECUTE privilege on that procedure to whoever needs to run it.