DB2 revoke user privileges from a database from multiple users - db2

I want to revoke all privileges from all users but one from a database.
DB2 10.5 LUW
I was thinking along the lines of:
db2 "revoke all on database from user IN (select grantee from syscat.dbauth where grantee not IN 'SAFEUSER')"
but I can't get it to work.
Any ideas?

There is no ALL clause in the REVOKE (database authorities) statement.
You may generate the set of statements needed by the following select statement:
select
'REVOKE '
|| SUBSTR
(
CASE ACCESSCTRLAUTH WHEN 'N' THEN '' ELSE ', ACCESSCTRL' END
||CASE BINDADDAUTH WHEN 'N' THEN '' ELSE ', BINDADD' END
||CASE CONNECTAUTH WHEN 'N' THEN '' ELSE ', CONNECT' END
--- add here expressions with all other *AUTH columns
, 2)
||' ON DATABASE FROM '
|| CASE
WHEN GRANTEE = 'PUBLIC' THEN ''
WHEN GRANTEETYPE = 'U' THEN 'USER'
WHEN GRANTEETYPE = 'G' THEN 'GROUP'
WHEN GRANTEETYPE = 'R' THEN 'ROLE'
END
||' '||GRANTEE
from syscat.dbauth
WHERE 'Y' IN
(
ACCESSCTRLAUTH, BINDADDAUTH, CONNECTAUTH
--- add here all other *AUTH columns separated by ','
)
AND grantee <> 'SAFEUSER'
;

Related

Compare two tables and find the missing column using left join

I wanted to compare the two tables employees and employees_a and find the missing columns in the table comployees_a.
select a.Column_name,
From User_tab_columns a
LEFT JOIN User_tab_columns b
ON upper(a.table_name) = upper(b.table_name)||'_A'
AND a.column_name = b.column_name
Where upper(a.Table_name) = 'EMPLOYEES'
AND upper(b.table_name) = 'EMPLOYEES_A'
AND b.column_name is NULL
;
But this doesnt seems to be working. No rows are returned.
My employees table has the below columns
emp_name
emp_id
base_location
department
current_location
salary
manager
employees_a table has below columns
emp_name
emp_id
base_location
department
current_location
I want to find the rest two columns and add them into employees_a table.
I have more than 50 tables like this to compare them and find the missing column and add those columns into their respective "_a" table.
Missing columns? Why not using the MINUS set operator, seems to be way simpler, e.g.
select column_name from user_tables where table_name = 'EMP_1'
minus
select column_name from user_tables where table_name = 'EMP_2'
Thirstly, check if user_tab_columns table contains columns of your tables (in my case user_tab_columns is empty and I have to use all_tab_columns):
select a.Column_name
From User_tab_columns a
Where upper(a.Table_name) = 'EMPLOYEES'
Secondly, remove line AND upper(b.table_name) = 'EMPLOYEES_A', because upper(b.table_name) is null in case a column is not found. You have b.table_name in JOIN part of the SELECT already.
select a.Column_name
From User_tab_columns a
LEFT JOIN User_tab_columns b
ON upper(a.table_name) = upper(b.table_name)||'_A'
AND a.column_name = b.column_name
Where upper(a.Table_name) = 'EMPLOYEES'
AND b.column_name is NULL
You do not need any joins and can use:
select 'ALTER TABLE EMPLOYEES_A ADD "'
|| Column_name || '" '
|| CASE MAX(data_type)
WHEN 'NUMBER'
THEN 'NUMBER(' || MAX(data_precision) || ',' || MAX(data_scale) || ')'
WHEN 'VARCHAR2'
THEN 'VARCHAR2(' || MAX(data_length) || ')'
END
AS sql
From User_tab_columns
Where Table_name IN ('EMPLOYEES', 'EMPLOYEES_A')
GROUP BY COLUMN_NAME
HAVING COUNT(CASE table_name WHEN 'EMPLOYEES' THEN 1 END) = 1
AND COUNT(CASE table_name WHEN 'EMPLOYEES_A' THEN 1 END) = 0;
Or, for multiple tables:
select 'ALTER TABLE ' || MAX(table_name) || '_A ADD "'
|| Column_name || '" '
|| CASE MAX(data_type)
WHEN 'NUMBER'
THEN 'NUMBER(' || MAX(data_precision) || ',' || MAX(data_scale) || ')'
WHEN 'VARCHAR2'
THEN 'VARCHAR2(' || MAX(data_length) || ')'
END
AS sql
From User_tab_columns
Where Table_name IN ('EMPLOYEES', 'EMPLOYEES_A', 'SOMETHING', 'SOMETHING_A')
GROUP BY
CASE
WHEN table_name LIKE '%_A'
THEN SUBSTR(table_name, 1, LENGTH(table_name) - 2)
ELSE table_name
END,
COLUMN_NAME
HAVING COUNT(CASE WHEN table_name NOT LIKE '%_A' THEN 1 END) = 1
AND COUNT(CASE WHEN table_name LIKE '%_A' THEN 1 END) = 0;
fiddle

PostgreSQL - Find ALL Privileges for a Group

I have been attempting to remove a group role from an AWS PostgreSQL instance, and I've gotten stuck. I have successfully removed all dependencies from the group, except for 6, and I have no idea what those might be. I will explain what I have attempted to use to find these missing privileges, and I really appreciate some direction as to where I can look next. Each of these steps were performed on all of the databases and schemas within the Instance:
I used the following code to revoke all privileges from the group
REVOKE ALL ON DATABASE {dbname} FROM GROUP "Application_Access";
REVOKE ALL ON SCHEMA public FROM GROUP "Application_Access";
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM GROUP "Application_Access";
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM GROUP "Application_Access";
REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM GROUP "Application_Access";
I used the psql commands to list all objects and their privileges, and this is what I found
\z = Nothing listed for Application_Access
\du and \dg = Application_Access - No inheritance, Cannot login, Member of {}
\d = All relations owned by OurAdmin
\db = All tablespaces owned by rdsadmin (AWS Admin)
\dtisv = Nothing
\ddp = This command is the only one showing Application_Access
Results of \ddp Command
I understand that \ddp shows default privileges for future database additions. I attempted to run ALTER PRIVILEGES commands. It forced me to make myself a member of Application_Access (ERROR: Must be a member of Role. why?!?) in order to run the command. This reassigned all of my privileges back to Application_Access and I was back to square one.
ALTER DEFAULT PRIVILEGES ON ROLE "Application_Access" REVOKE ALL ON DATABASE {dbname} FROM "Application_Access";
ALTER DEFAULT PRIVILEGES ON ROLE "Application_Access" REVOKE ALL ON ALL SCHEMAS FROM "Application_Access";
ALTER DEFAULT PRIVILEGES ON ROLE "Application_Access" REVOKE ALL ON TABLES FROM "Application_Access";
ALTER DEFAULT PRIVILEGES ON ROLE "Application_Access" REVOKE ALL ON FUNCTIONS FROM "Application_Access";
ALTER DEFAULT PRIVILEGES ON ROLE "Application_Access" REVOKE ALL ON SEQUENCES FROM "Application_Access";
I reran all of my previous steps, however, now when I run \ddp on all databases, it has added the first 3 lines that you see in the attached image above.
I have a script that I found and altered to show me all of the privileges on each database. I can pass it a Role to simplify the search. It isn't showing Application_Access as being associated with any objects either.
SELECT relacl
, SUBSTRING(
CASE WHEN strpos('r', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', SELECT' ELSE '' END
|| CASE WHEN strpos('w', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', UPDATE' ELSE '' END
|| CASE WHEN strpos('a', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', INSERT' ELSE '' END
|| CASE WHEN strpos('d', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', DELETE' ELSE '' END
|| CASE WHEN strpos('R', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', RULE' ELSE '' END
|| CASE WHEN strpos('x', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', REFERENCES' ELSE '' END
|| CASE WHEN strpos('t', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', TRIGGER' ELSE '' END
|| CASE WHEN strpos('X', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', EXECUTE' ELSE '' END
|| CASE WHEN strpos('U', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', USAGE' ELSE '' END
|| CASE WHEN strpos('C', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', CREATE' ELSE '' END
|| CASE WHEN strpos('T', SPLIT_PART( SPLIT_PART( ARRAY_TO_STRING( RELACL, '|' ), pu.groname, 2 ) , '/', 1 ) ) > 0 THEN ', TEMPORARY' ELSE '' END
, 3,10000)
|| namespace ||'.'|| item ||' TO '|| pu.groname ||' ;' AS grantsql
FROM (SELECT use.usename AS subject
,nsp.nspname AS namespace
,cls.relname AS item
,cls.relkind AS type
,use2.usename AS owner
,cls.relacl
FROM pg_user use
CROSS JOIN pg_class cls
LEFT JOIN pg_namespace nsp
ON cls.relnamespace = nsp.oid
LEFT JOIN pg_user use2
ON cls.relowner = use2.usesysid
WHERE cls.relowner = use.usesysid
AND nsp.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
ORDER BY subject
,namespace
,item ) as x
JOIN pg_group pu ON array_to_string(relacl, '|') LIKE '%'|| pu.groname ||'%'
WHERE relacl IS NOT NULL
AND relacl::text LIKE '%Application%'
ORDER BY 2
***Based on everything that you see above, is there anything that anyone can think of that I left out, or didn't do correctly/completely? How can I resolve the default privileges - ALTER PRIVILEGES REVOKE ALL didn't work. Thank you for your help.
It took several days, but I guess I finally asked Google the right question. I thought I would post my solution in case anyone might be having a similar problem on PostgreSQL:
I was close with my ALTER PRIVILEGES commands. In this screenshot (psql command \ddp)-
there are 4 columns: Owner, Schema, Type, and Access Privilege. You will need each of these columns to generate the ALTER PRIVILEGES commands:
Owner - This is the user/group that will have the privileges altered - seemed weird to me too. :)
Schema - This is the schema containing the commands to assign the default privileges
Type - This will tell you what type of REVOKE command you need to use
Access Privilege - This is the user/group that you can't drop because "it has dependencies"
Based on this list, your command structure will look similar to this - filling {} in from above:
ALTER DEFAULT PRIVILEGES FOR ROLE {Owner} IN SCHEMA {Schema} REVOKE ALL PRIVILEGES ON {Type} FROM {Access Privilege};
In order to perform this command, you must be logged into the Postgres database as either the Owner, or a member of the Owner group, otherwise, you will get the error "ERROR: Must be a member of Role {Owner}."
I had to perform 2 sets of ALTER PRIVILEGES - logging into the database as the owner dbac and Application_Access.
Logging in as Application_Access and executing the commands below eliminated the first 3 rows (where Application_Access is the Owner) from the above screenshot of the \ddp psql command.
alter default privileges for role "Application_Access" in schema public revoke all privileges on functions from "Application_Access";
alter default privileges for role "Application_Access" in schema public revoke all privileges on sequences from "Application_Access";
alter default privileges for role "Application_Access" in schema public revoke all privileges on tables from "Application_Access";
Logging in as dbac and executing the commands below eliminated the other rows (where dbac is the Owner) from the above screenshot of the psql \ddp command.
alter default privileges for role "dbac" in schema public revoke all privileges on functions from "Application_Access";
alter default privileges for role "dbac" in schema public revoke all privileges on sequences from "Application_Access";
alter default privileges for role "dbac" in schema public revoke all privileges on tables from "Application_Access";

How do I find all the NUMERIC columns in a table and do a SUM() on them?

I have a few tables in Netezza, DB2 and PostgreSQL databases, for which I need to reconcile and the best way we have come out with is to do a SUM() across all the NUMERIC Table columns on all the 3 databases.
Does anyone have a quick and simple way to find all the COLUMNS which are either NUMERIC or INTEGER or BIGINT and then run a SUM() on all these?
For comparing the results, I can do it manually also, or if someone has a way to capture these results in a common table and automatically check the differences in the SUM?
For DB2 you can use this metadata which will help you to find out the data type for each column
SELECT
COLUMN_NAME || ' ' || REPLACE(REPLACE(DATA_TYPE,'DECIMAL','NUMERIC'),'CHARACTER','VARCHAR') ||
CASE
WHEN DATA_TYPE = 'TIMESTAMP' THEN ''
ELSE
' (' ||
CASE
WHEN CHARACTER_MAXIMUM_LENGTH IS NOT NULL THEN CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR(30))
WHEN NUMERIC_PRECISION IS NOT NULL THEN CAST(NUMERIC_PRECISION AS VARCHAR(30)) ||
CASE
WHEN NUMERIC_SCALE = 0 THEN ''
ELSE ',' || CAST(NUMERIC_SCALE AS VARCHAR(3))
END
ELSE ''
END || ')'
END || ',' "SQLCOL",
COLUMN_NAME,
DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, ORDINAL_POSITION
FROM SYSIBM.COLUMNS
WHERE TABLE_NAME = 'insert your table name'
AND TABLE_SCHEMA = 'insert your table schema'
ORDER BY ORDINAL_POSITION
For Netezza, I got the following query:
SELECT 0 AS ATTNUM, 'SELECT' AS SQL
UNION
SELECT ATTNUM, 'SUM(' || ATTNAME || ') AS S_' || ATTNAME || ',' AS COLMN
FROM _V_RELATION_COLUMN RC
WHERE NAME = '<table-name>'
AND FORMAT_TYPE= 'NUMERIC'
UNION
SELECT 10000 AS ATTNUM, ' 0 AS FLAG FROM ' || '<table-name>'
ORDER BY ATTNUM
Still looking how to do this across DB2 and PostgreSQL.

How to revoke the access using LOOP - redshift

Team,
I am using Amazon redshift. below is the version:
PostgreSQL 8.0.2 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), Redshift 1.0.748
I would like to drop one user account. if this user has access to any table/schemas/datbase, then that has to be revoked first and then it will allow us to drop the user. In redshift, "drop owned by ;" is not working. so, i need to programatically find out the access to granted to user before dropping it.
for e.g. i am giving access to this user on 2 schemas. But while revoking it, i need to use some FOR ..LOOP and then find out the schemas this user has access and revoke it, not thro manually ( as below ). Coudl you please help me ? i need to write a small procedure wherein need to create one cursor and store these 2 schemas, and under FOR..loop, i need to call them and revoke them one by one. If you provide this functionality, i can use this to revoke other table grants, database grants etc..
redshift=# GRANT all on schema schema44 to proj_user1;
GRANT
redshift=# grant all on schema proj_schema1 to proj_user1;
GRANT
redshift=#
redshift=# select nspname from pg_catalog.pg_namespace where array_to_string(nspacl,',') like '%proj_user1%';
nspname
--------------
schema44
proj_schema1
(2 rows)
redshift=# revoke all on schema schema44 from proj_user1;
REVOKE
redshift=# revoke all on schema proj_schema1 from proj_user1;
REVOKE
redshift=# select nspname from pg_catalog.pg_namespace where array_to_string(nspacl,',') like '%proj_user1%';
nspname
---------
(0 rows)
Thank you
There's no scripting available in Redshift that provides loop functionality. You can run the queries below from psql and use the output as the script to remove the user.
This query builds the revoke cmds for objects:
select
'revoke ' || substring(
case when charindex('r',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',select ' else '' end
||case when charindex('w',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',update ' else '' end
||case when charindex('a',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',insert ' else '' end
||case when charindex('d',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',delete ' else '' end
||case when charindex('R',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',rule ' else '' end
||case when charindex('x',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',references ' else '' end
||case when charindex('t',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',trigger ' else '' end
||case when charindex('X',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',execute ' else '' end
||case when charindex('U',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',usage ' else '' end
||case when charindex('C',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',create ' else '' end
||case when charindex('T',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',temporary ' else '' end
, 2,10000)
|| ' on '||namespace||'.'||item ||' from "'||pu.usename||'";' as grantsql
from
(SELECT
use.usename as subject,
nsp.nspname as namespace,
c.relname as item,
c.relkind as type,
use2.usename as owner,
c.relacl
FROM
pg_user use
cross join pg_class c
left join pg_namespace nsp on (c.relnamespace = nsp.oid)
left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE
c.relowner = use.usesysid
and nsp.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
ORDER BY
subject, namespace, item
) join pg_user pu on array_to_string(relacl, '|') like '%'||pu.usename||'%'
where relacl is not null
and pu.usename='<username>'
order by 1;
Then you will need to change any table ownerships:
select 'alter table '||schemaname||'.'||tablename||' owner to <newowner>;' from pg_tables where tableowner = '<username>';
You can't change ownerships of views, so you have to drop them:
select 'drop view '||schemaname||'.'||viewname||' ;' from pg_views where viewowner = '<username>';
You'll need to remove the user from any groups:
select 'alter group '||nvl(groname,'default')||' drop user '||usename||';' from pg_user u left join pg_group g on ','||array_to_string(grolist,',')||',' like '%,'||cast(usesysid as varchar(10))||',%' where usename='<username>' ;
Finally remove from schemas:
select
'revoke ' || substring(
case when charindex('U',split_part(split_part(array_to_string(nspacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',usage ' else '' end
||case when charindex('C',split_part(split_part(array_to_string(nspacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',create ' else '' end
, 2,10000)
|| ' on schema '||nspname||' from "'||pu.usename||'";'
from pg_namespace pn,pg_user pu
where pu.usename='<username>' and array_to_string(nspacl,',') like '%'||pu.usename||'%'
and nspowner > 1 ;

How to find the privileges granted to a user in AWS Redshift?

I am using a Redshift cluster.
Version:
PostgreSQL 8.0.2 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), Redshift 1.0.735
I just need to drop a user but it gives the following error message:
redshiftpocdb=# drop user test_55;
ERROR: user "test_55" cannot be dropped because the user has a privilege on some object
Here is the output of the \dp command:
redshiftpocdb=# \dp
Access privileges
schema | name | type | access privileges
--------+---------+-------+-------------------
public | company | table |
public | test2 | table |
public | test22 | table |
public | test222 | table |
public | v_date | table |
(5 rows)
In a Postgresql environment, we have the command DROP OWNED BY but it does not work in Redshift.
How can I find out what privileges were granted to the TEST_55 user? Is there any system view we can query ( for e..g in Oracle, we have DBA_ROLE_PRIVS, DBA_TAB_PRIVS...DBA_SYS_PRIVS .etc )?
To be able to drop a user, you have to (at least)
if they own any objects, change the owner to a different user
remove grants from any objects
remove them from groups
remove grants from schemas
You can use this to find any tables they own (then run "alter table owner to "):
select * from pg_tables where tableowner = 'test_55'
You can use this to build the script to revoke any grants:
select relacl ,
'revoke ' || substring(
case when charindex('r',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',select ' else '' end
||case when charindex('w',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',update ' else '' end
||case when charindex('a',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',insert ' else '' end
||case when charindex('d',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',delete ' else '' end
||case when charindex('R',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',rule ' else '' end
||case when charindex('x',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',references ' else '' end
||case when charindex('t',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',trigger ' else '' end
||case when charindex('X',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',execute ' else '' end
||case when charindex('U',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',usage ' else '' end
||case when charindex('C',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',create ' else '' end
||case when charindex('T',split_part(split_part(array_to_string(relacl, '|'),pu.usename,2 ) ,'/',1)) > 0 then ',temporary ' else '' end
, 2,10000)
|| ' on '||namespace||'.'||item ||' from "'||pu.usename||'";' as grantsql
from
(SELECT
use.usename as subject,
nsp.nspname as namespace,
c.relname as item,
c.relkind as type,
use2.usename as owner,
c.relacl
FROM
pg_user use
cross join pg_class c
left join pg_namespace nsp on (c.relnamespace = nsp.oid)
left join pg_user use2 on (c.relowner = use2.usesysid)
WHERE
c.relowner = use.usesysid
and nsp.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
ORDER BY subject, namespace, item
) join pg_user pu on array_to_string(relacl, '|') like '%'||pu.usename||'%'
where relacl is not null
and pu.usename='test_55'
You can use a variation of this query to see if a user belongs to any groups (then use "alter group drop user "):
select usesysid, usename, nvl(groname,'default') from pg_user u
left join pg_group g on ','||array_to_string(grolist,',')||','
like '%,'||cast(usesysid as varchar(10))||',%'
where usename='test_55' order by 2,1;
You can use this query to see if they have any schema grants:
select * from pg_namespace where nspowner > 1 and array_to_string(nspacl,',') like '%test_55%';
Another variation, to get all users' privilege organized together:
WITH
usrs as (SELECT * FROM pg_user),
objs as (
SELECT
schemaname, 't' AS obj_type,
tablename AS objectname,
schemaname + '.' + tablename AS fullobj
FROM pg_tables
WHERE schemaname not in ('pg_internal')
UNION
SELECT
schemaname, 'v' AS obj_type,
viewname AS objectname,
schemaname + '.' + viewname AS fullobj
FROM pg_views
WHERE schemaname NOT IN ('pg_internal')
),
query as (
SELECT
schemaname,
objectname,
usename,
HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'select') AS sel,
HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'insert') AS ins,
HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'update') AS upd,
HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'delete') AS del,
HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'references') AS ref
FROM objs, usrs
ORDER BY fullobj
)
SELECT * FROM query
WHERE (
sel = TRUE
OR ins = TRUE
OR upd = TRUE
OR del = TRUE
OR ref = TRUE
) AND schemaname='[optional schemaname]'
AND usename = '[optional username]';
I had to use || to concatenate strings, and a little difference as I have case-sensitive object names
'"' || schemaname || '"."' || tablename || '"' AS fullobj
'"' || schemaname || '"."' || viewname || '"' AS fullobj
instead of
schemaname + '.' + tablename AS fullobj
schemaname + '.' + viewname AS fullobj