Unable to drop user because I cannot revoke default priviliges in Redshift - postgresql

I am having issues with dropping a user becauase it has default privileges, but I am as well unable to revoke those privileges.
To reproduce my issue:
-- executed with master user redshift_master
CREATE USER anton_test_user PASSWORD '***' IN GROUP redshift_dev;
Then using anton_test_user
CREATE SCHEMA anton_test_schema;
CREATE TABLE anton_test_schema.anton_test_table AS SELECT 1 AS anton;
ALTER DEFAULT PRIVILEGES IN SCHEMA anton_test_schema
GRANT SELECT ON TABLES TO GROUP redshift_readonly;
Again with redshift_master
ALTER SCHEMA anton_test_schema OWNER TO redshift_master;
ALTER TABLE anton_test_schema.anton_test_table OWNER TO redshift_master;
Now trying to drop the user it complains about default privileges:
DROP USER anton_test_user;
Result as expected:
owner of default privileges on new relations belonging to user
anton_test_user in schema anton_test_schema;
Now to the weird part, still with redshift_master
ALTER DEFAULT PRIVILEGES FOR USER anton_test_user IN SCHEMA anton_test_schema
REVOKE ALL ON TABLES FROM redshift_readonly;
Gives Invalid operation: permission denied for schema anton_test_schema. What?
If running with anton_test_user
ALTER DEFAULT PRIVILEGES IN SCHEMA anton_test_schema
REVOKE ALL ON TABLES FROM redshift_readonly;
As well gives Invalid operation: permission denied for schema anton_test_schema.
The only way for me to solve this and being able to drop anton_test_user was to, with redshift_master drop the schema and table completely
DROP TABLE anton_test_schema.anton_test_table;
DROP SCHEMA anton_test_schema;
DROP USER anton_test_user; -- it works now
Transfering ownership back to anton_test_user and then revoking default privileges did not help - dropping the table and schema was the only solution I could find.
My completely uninformed guess is that anton_test_user had lost permissions to the schema, so no grants for the user could be applied or revoked in that schema.
Question(s):
Is there any way to avoid dropping anton_test_schema and anton_test_table while also dropping anton_test_user?
Is it supposed to work this way?
Do Postgres behave in the same way?
This is a bit of a follow up to a question already asked, to which I gave an answer - but I have no idea what is going on even though I came up with a "solution" ("" because dropping objects was a solution, albeit a pretty poor one). It might be that I have completely misunderstood user privileges in Redshift as well.
The original question is not completely the same as this - and I would like to know what is going on, so it is not really a repost even though it might look like it.

I had the same issue myself. I was able to avoid dropping the user/schema by first re-granting access of the schema to my end user (my version of anton_test_user).
grant all on schema analyst_data to anton_test_user;
After doing so, I was able to run my alter default privileges command
ALTER DEFAULT PRIVILEGES for user <user> in schema <schema> REVOKE ALL on tables FROM group <group>;
Your uninformed guess was spot on 😀

Related

How to add admin user to existing postgres database?

We have an existing postgres database gsrdb in production with superuser gsr. We have been doing all the database maintenance with that user gsr. Also, the same user gsr is used by our app service to do transactions on the database.
We want to change this now. We want a separate superuser gsr_admin(whose credentials are managed by Vault) that can do the dba maintenance but still have our app service use existing user gsr.
The problem I am facing is that all the database objects so far are owned by gsr user and if I run updates, as user gsr_admin, on the database w.r.t. either table constraints or sequences it fails saying error: must be owner of relation...blah blah
How can I fix this?
So I was thinking if I could create a superuser admin group role called admin_group and reassign all the ownerships of all the database objects to it from user gsr and then alter both users gsr and gsr_admin to belong to this admin group role. Wouldn't that way everything that has been created so far would be owned by role admin_group ? And whether I create new objects as a user gsr or as gsr_admin either of them can still update the objects?
I might be wrong. Would really appreciate some inputs.
Simply run
ALTER ROLE gsr NOSUPERUSER;
ALTER ROLE gsr RENAME TO gsr_admin; -- needs a new password now
CREATE ROLE gsr LOGIN;
GRANT USAGE ON SCHEMA myschema TO gsr;
GRANT SELECT, INSERT, UPDATE, DELETE
ON ALL TABLES IN SCHEMA myschema TO gsr;
Similarly, grant USAGE on sequences and other required privileges. You may want to run some ALTER DEFAULT PRIVILEGES for future objects as well.

Forbid the owner of a user from GRANTing on that table

I'm trying to allow a database user to be able to alter/drop (certain) tables, but not GRANT privileges on them. Is this possible?
It looks like they need to be the owner of the tables, but from https://www.postgresql.org/docs/current/sql-grant.html
The right to drop an object, or to alter its definition in any way, is not treated as a grantable privilege; it is inherent in the owner, and cannot be granted or revoked. (However, a similar effect can be obtained by granting or revoking membership in the role that owns the object; see below.) The owner implicitly has all grant options for the object, too.
This sounds like it's not possible. However, is this definitely the case? Is there some way with triggers for example to make certain GRANTs fail?
Yes, only the owner of a table or a superuser can ALTER or DROP it, and these users can always GRANT privileges on the table.
Your only option is to create an event trigger that fires on GRANT and throws an error for the tables where it should be forbidden.

Altering view/access permissions for a schema in DB2

I am working around a workaround to a "feature" in IBM DB2.
This fancy database has a "feature" in it which if I try to use a CREATE TABLE statement and it doesn't find the schema, it will create this schema for me, even if I don't want it to. This bug has caused me a lot of hours in debugging, because my code right now exists with the expectation that it won't create the schema if it doesn't exist
My question is -- how do I change the permissions of a particular schema (or even during the create schema phase) which a particular user does not have access to view?
I checked out this doc..
It seems with GRANT, there are the following three permissions:
ALTERIN
Grants the privilege to alter or comment on all objects in the
schema. The owner of an explicitly created schema automatically
receives ALTERIN privilege.
CREATEIN
Grants the privilege to create
objects in the schema. Other authorities or privileges required to
create the object (such as CREATETAB) are still required. The owner of
an explicitly created schema automatically receives CREATEIN
privilege. An implicitly created schema has CREATEIN privilege
automatically granted to PUBLIC.
DROPIN
Grants the privilege to drop
all objects in the schema. The owner of an explicitly created schema
automatically receives DROPIN privilege
With only ALTERIN, CREATEIN, and DROPIN, I don't see anything relevant to view access permissions :/
EDIT:
I checked out our Dash DB database for this particular table which has these special permissions for particular users using the following SQL:
SELECT * FROM SYSIBMADM.PRIVILEGES WHERE OBJECTSCHEMA = 'FAKE_SCRATCH';
This is the result:
EDIT 2:
I tried the following to emulate Dash DB's permissions for that user for that schema:
GRANT ALTERIN, CREATEIN, DROPIN ON SCHEMA FAKE_SCRATCH TO USER TEST_USER;
Still doesn't work :/
The following SQL query executed in DB2 fixed the problem:
REVOKE IMPLICIT_SCHEMA ON DATABASE FROM PUBLIC

Amazon Redshift Grants - New table can't be accessed even though user has grants to all tables in schema

I have a bit of a funny situation in Amazon Redshift where I have a user X who has grant select on all tables in schema public, but once a new table is created, this grant doesn't seem to apply to the new table. Is this normal behaviour? If yes, how does one deal with it such that the schema level grants are maintained. Thank you.
Executing the following command as super user (master):
alter default privileges
for user staging_user
in schema staging
grant select on tables
to reporting_user;
will allow reporting_user to select data from all future tables created by staging_user in schema staging.
In Redshift tables and views do not automatically inherit the permissions of their parent schema. Your newly created tables are only accessible to the user who created them, and the superuser.
In a recent patch to Redshift a new feature to grant default privileges was implemented that addresses this issue.
Alter Default Privileges
The following code snippet will grant select privileges only for all future tables in the sales schema to the sales_admin group. If you want this to apply to existing tables in a schema you will need to combine it with a second grant statement.
alter default privileges in schema sales grant select on tables to group sales_admin;
This is a normal behavior. Only the object owner/superuser have permission to use the object by default.
http://docs.aws.amazon.com/redshift/latest/dg/r_Privileges.html
You can add grant command to your create table statement and grant needed privileges for the user.
When we first spotted new tables not appearing in our reporting tool, I discovered a quick workaround is to re-execute the following SQL statement for the groups/users impacted:
ALTER DEFAULT PRIVILEGES IN SCHEMA <SCHEMANAME> GRANT SELECT ON TABLES TO GROUP <USER/GROUPNAME>;

PostgreSQL: making a schema restricted/unchangable?

We like our production environment with a restricted/unchangable schema -- the development side can be owned by the developers and changed as they like -- and we like to vet changes as they are promoted.
I'm wondering if this may be a solution to making that happen:
postgres% create proddb with owner=postgres;
unixside% pg_restore --dbname=devdb [--schema-only] --no-owner proddb
/* grants to users on schema objects appear to remain intact */
/* here's the magic, I hope... */
postgres% revoke create on schema public from public;
postgres% grant usage on schema public to produser(s);
Some testing seems to show that a user in this new proddb can interact with tables normally (with appropriate grants) and cannot alter the schema (alter table, create table, drop table, etc). But I'm paranoid and very new to Postgres, so...
Q: Is this correct?
Q: Am I missing anything?
Thanks muchly.
Yes, that is correct. The only addition is that the owner of a table can always delete or modify it. So it may not work if you have existing tables in the schema.
Discovered a missing element: sequences.
The user was finding errors in his scripts; similar errors appeared in the logs:
ERROR: permission denied for sequence <sequence>
The production schema showed that although sequences were created, they were owned by postgres and no explicit grants were given to the users. As per the GRANT documentation:
Granting permission on a table does not automatically extend permissions to any sequences used by the table, including sequences tied to SERIAL columns. Permissions on sequence must be set separately.
Our fix (verbose for this demonstration) was to find all sequences:
unixside% pg_dump --schema-only proddb > proddb.schema
unixside% grep -i 'create sequence' proddb.schema
...and apply appropriate grants (select to prevent table scans, update to prevent the above errors):
postgres% grant select,update on <sequence> to produser(s);
So far, the user says it's working and errors to the log have stopped...
I forget what version PostgreSQL added the syntax, but one of the easiest ways to administer permissions in PostgreSQL is through the "GRANT foo, priv ON ALL something IN SCHEMA" syntax.
BEGIN;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA my_schema TO my_role;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA my_schema TO my_role;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA my_schema TO my_role;
COMMIT;
Very handy for making sure that permissions are always set correctly.
The EXECUTE for FUNCTIONS may seem spooky, but shouldn't be unless your functions were created with the SECURITY DEFINER attribute (and if you are using SECURITY DEFINER, you'd better be cautious since you're playing around with the PostgreSQL version of a "setuid" function). If you space out your TABLES across different SCHEMAS based on the expected permissions, then this becomes a pretty handy convention when used with the search_path variable.
ALTER ROLE my_role SET search_path = my_schema, auth_schema, public;
-- Avoid using the public schema (pretty please)
Where auth_schema has a collection of tables that my_role shouldn't have direct read or write privileges on. Assigning privs to GROUPS is also useful.
Here are some relevant docs:
http://developer.postgresql.org/pgdocs/postgres/sql-grant.html
Don't forget you can use "\h GRANT" in psql to easily figure out the syntax or remember what can be done on all objects in a schema (search for "IN SCHEMA").