Unexpected behavior from changing owner in postgres - sql

I have a schema of tables myschema with different owners in postgres - owner 'foo' and owner 'bar'
After granting all privileges on the database to owner 'bar', and then re-logging in as user 'bar', I try to change the ownership of all bar-owned tables to 'foo' with the following command:
SELECT format(
'ALTER TABLE %I.%I.%I OWNER TO %I;',
table_catalog,
table_schema,
table_name,
'foo'
)
FROM information_schema.tables
WHERE table_schema = 'myschema'
This then returns:
ALTER TABLE my_db.my_schema.my_tableA OWNER TO foo;
ALTER TABLE my_db.my_schema.my_tableB OWNER TO foo;
ALTER TABLE my_db.my_schema.my_tableC OWNER TO foo;
successfully
Then, when I run select * from pg_tables;, I see that none of the tableowners have changed. How is this possible and what could be happening?

To change ownership of tables from bar to foo, a user must be a member of both roles. So if bar should be able to do that, it must be a superuser or a member of foo:
GRANT foo TO bar;
I guess your statements caused an error that you somehow failed to see and didn't do anything.

Related

Oracle Users Tables

I've created some TABLES in 1 DB with the user name DEVICE.
Querying the tables I see that they belong to the user DEVICE
SELECT owner, table_name FROM dba_tables
Then I created a user named CAR, I logged in the DB with that user and create some tables, I've tried to query the other tables with
SELECT * FROM DEVICE.table_name;
with the result
00942. 00000 - "table or view does not exist"
and logged with the user CAR and don't see the user DEVICE in others users from SQL Developer
This error comes up because CAR doesn't have privileges to query the DEVICE's table.
You need to grant access to this table to CAR.
1- login as DEVICE
2- Issue the following grant:
GRANT SELECT ON TABLE_NAME TO CAR;
If you want to do it for all the tables of the DEVICE user, create a script like that:
select 'GRANT SELECT ON ' || table_name || ' TO CAR;' FROM USER_TABLES;
My advice would be to create a ROLE if you do that:
CREATE ROLE DEVICE_READ_ROLE;
select 'GRANT SELECT ON ' || table_name || ' TO DEVICE_READ_ROLE;' FROM USER_TABLES;
GRANT DEVICE_READ_ROLE TO CAR;
Note that if you create new tables in the DEVICE schema you will need to grant select on the new table to the ROLE for CAR to have access to it.
Here the script to generate grant select on all the tables.
select 'grant select on Admin.' || object_name || ' to User;'
from user_objects
where object_type in('TABLE');
Then you have to create a script to run these grant statements at once or you can use PL/SQL as well. Type the following in the SQL prompt.
SQL> spool grant_statements.sql
SQL> set pagesize 0
SQL> set feedback off
SQL> set linesize 300
SQL> set trimout on
SQL> set trimspool on
SQL> select 'grant select on Admin.' || object_name || ' to User;' from user_objects where object_type in('TABLE','SYNONYM')
/
SQL> spool off
And you have got the script file you can run it.
OR
You can run the following PL/SQL block (Run as admin user).
BEGIN
FOR s IN (SELECT *
FROM user_objects where object_type in('TABLE','SYNONYM'))
LOOP
EXECUTE IMMEDIATE 'grant select on admin.' || s.object_name || ' to user';
END LOOP;
END;
you need to grant access to user CAR for the tables created by DEVICE . login using DEVICE user and grant access to the tables CAR should be able to access using sql like below
GRANT SELECT , UPDATE , INSERT ON TABLE_NAME TO CAR;

Schema level SELECT privilege on all new tables in Vertica

I am trying to work on a scenario , where one user creates tables in a 'schema', and all such tables should be visible to a specific user/role, even if the tables are created in future (after grant SELECT command).
My current flow is as:
USERS: dbadmin, user1, user2
SCHEMA: myschema
dbadmin=> GRANT ALL ON SCHEMA myschema to user1;
dbadmin=> GRANT SELECT ON ALL TABLES IN SCHEMA myschema TO user2;
dbadmin=> ALTER SCHEMA myschema DEFAULT INCLUDE PRIVILEGES;
-- user1 now creates table
user1=> CREATE TABLE myschema.table1 (id INT);
-- can user2 see that table
user2=> SELECT * FROM myschema.table1;
-- Permission Denied for table1
Any Ideas on how to do this ?
Thanks.
Figured out the issue from here. Posting here for others.
The only catch in above queries was using "GRANT SELECT ON ALL TABLES IN SCHEMA "
Instead it should be "GRANT SELECT ON SCHEMA"

Dropping postgres role and database after many grants

I'm trying to efficiently drop role from a postgres instance, and running into some problems. I'm looking for some SQL to drop role so that I can stop reading error messages and don't have to do this manually.
In the setup I'm working in, every roles gets its own database of the same name:
CREATE ROLE alpha_user;
CREATE DATABASE alpha_user;
ALTER DATABASE alpha_user OWNER TO alpha_user;
Users often grant access to schemas in their database to other users:
-- alpha_user logs in to the alpha_user database
GRANT USAGE ON SCHEMA myschema TO beta_user;
When I attempt to drop beta_user, this happens:
-- log in as superuser
DROP ROLE beta_user;
-- ERROR: role "beta_user" cannot be dropped because some objects depend on it
-- DETAIL: N objects in database alpha_user
I can connect to the alpha_user database, and drop OWNED BY, but this is inefficient:
-- log in as superuser
\c alpha_user;
DROP OWNED BY beta_user CASCADE;
DROP beta_user;
-- success
Users can grant access to any number of databases, and there are many users. Is there a statement (or series of statements) that a super user can execute to DROP OWNED BY for a user across all databases where the user has been granted access?
Maybe this will help you:
with
user_id as (select oid, rolname as my_user from pg_authid where rolname in('abc', 'xyz'))
select 'REVOKE ' || rolname || ' FROM ' || my_user || ' CASCADE;' as sql
from pg_auth_members
join pg_authid on pg_auth_members.roleid = pg_authid.oid
JOIN user_id ON pg_auth_members.member = user_id.oid
union
SELECT 'REVOKE ALL ON ' || datname || ' FROM ' || my_user || ' CASCADE;'
FROM pg_database
JOIN user_id ON pg_database.datdba = user_id.oid

SQL Statement to Find Out Which Schema Owns an Oracle Table?

What is a SQL statement to find out which Schema owns an Oracle table?
To see information about any object in the database, in your case USER_TABLES use:
select * from all_objects where object_name = 'USER_TABLES';
OWNER OBJECT_NAME OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_TIME
SYS USER_TABLES 3922 VIEW 24-MAY-13 24-MAY-13
USER_TABLES is a dictionary view. All dictionary views are owned by SYS.
SELECT OWNER FROM DBA_TABLES WHERE TABLE_NAME = '<your table>'
If you don't have privilege to DBA_TABLES use ALL_TABLES.
Here are the queries:
SELECT TABLE_NAME FROM USER_TABLES WHERE TABLE_NAME='<TABLE_NAME>'; -- There is no owner column in this view
SELECT OWNER, TABLE_NAME FROM ALL_TABLES WHERE OWNER='<OWNER_NAME>' AND TABLE_NAME='<TABLE_NAME>';
SELECT OWNER, TABLE_NAME FROM DBA_TABLES WHERE OWNER='<OWNER_NAME>' AND TABLE_NAME='<TABLE_NAME>';
Also you can query USER_OBJECTS, ALL_OBJECTS, DBA_OBJECTS using OBJECT_TYPE='TABLE' and OWNER= '<OWNER_NAME>' and OBJECT_NAME='<TABLE_NAME>'
There are 3 views, which can give that information:
USER_TABLES, if the login schema is the owner of the table
ALL_TABLES, if the login schema have permission on the table or owner of the table or have SELECT_CATALOG role
DBA_TABLES, if the login schema have SELECT_CATALOG role or any other role which have SELECT_CATALOG role

Select access to all tables

In oracle 11g, I have a owner schema which contains the relevant tables required for an app.
For my external application i am trying to create another user which should have select access on certain tables to the above schema.
Lets call the owner schema A and the new schema B
create user B identified by blah;
grant connect to B;
After logging into the original schema A i ran the following (for demo i am giving select on all tables)
begin
FOR x IN (select * from user_tables)
LOOP
EXECUTE IMMEDIATE 'GRANT SELECT ON ' || x.table_name || ' TO some_role';
END LOOP;
end;
grant some_role to B;
If i login as user B and execute a query like
select count(*) from A.some_table ;
it works. But without creating a public synonym is it possible for me to grant
in such a way that the following works when logged in as user B?
select count(*) from some_table;
Thanks
You can create private synonyms for user B to use.
As user B, run the following block:
begin
FOR t IN (SELECT * FROM role_tab_privs WHERE grantee = 'SOME_ROLE' and owner = 'A')
LOOP
EXECUTE IMMEDIATE 'CREAETE SYNONYM ' || table_name || ' FOR A.' || table_name';
END LOOP;
end;
if you are just reading data from tables owned by userB, you can set below command and run SELECT on tables as if they were in userA schema:
alter session set current_schema=userB
(logged as UserA)
Then below two commands will be equivalent (have same result):
select ... from userB.TABLE1
select ... from TABLE1
GRANT SELECT ANY TABLE TO YOUR_USER_OR_ROL;