set client_min_messages to warning; create extension roleman; \set VERBOSITY terse -- whitelist errors -- no tables so pick a random number and cast to oid select roleman.grant_table('postgres', 1::oid, array['execute', 'drop']); select roleman.grant_schema('postgres', 'foo', array['execute']); select roleman.grant_schema_all('postgres', 'foo', 'tables', array['execute', 'drop everything']); select roleman.grant_database('postgres', 'foo', array['execute']); select roleman.grant_function('postgres', 1::OID, array['wheeee']); select roleman.grant_seq('postgres', 1::oid, array['execute']); create schema testing; create table testing.foo(id int); create table testing."foo(id int)"" drop table testing.foo; --"(id int); create table testing."foo(id int)' drop table testing.foo; --"(id int); insert into testing.foo values (1); insert into testing."foo(id int)"" drop table testing.foo; --" values (2); insert into testing."foo(id int)' drop table testing.foo; --" values (3); create schema "testing; drop table testing.foo; --"; create table "testing; drop table testing.foo; --".foo(); create schema "testing'; drop table testing.foo; --"; create table "testing'; drop table testing.foo; --".foo(); create schema "testing""; drop table testing.foo; --"; create table "testing""; drop table testing.foo; --".foo(); create function pg_temp.array_lower(text[]) returns text[] language plpgsql as $$ BEGIN RAISE EXCEPTION 'Bobby Tables Strikes Again'; return array['foo'::text]; END; $$; create sequence testing."foo1"" drop table testing.foo; --"; create function testing.foo(testing."foo(id int)"" drop table testing.foo; --", testing."foo(id int)' drop table testing.foo; --") returns bool language sql as $$ select true; $$; create schema testing2; create table testing2.foo(id int); create schema testing3; create table testing3.foo(id int); -- Create roles for Bobby Tables -- die with error select roleman.create_role('bobby"; drop table testing.foo; --', array['login', 'password ''foo''']); -- succeed select roleman.create_role('bobby"; drop table testing.foo; --', array['login', 'noinherit']); select roleman.create_role('bobby_tables"; foo', array['inherit', 'nologin']); select roleman.alter_base('bobby_tables"; foo', array['noinherit', 'login']); select roleman.create_role('bobby''; drop table testing.foo; --'); -- succeed no perms select roleman.role_blank_perms('bobby"; drop table testing.foo; --'); set role "bobby'; drop table testing.foo; --"; -- permission denied errors select * from testing.foo; reset role; select roleman.grant_schema(r, s, array['all']) FROM unnest(array['bobby"; drop table testing.foo; --'::text, 'bobby_tables"; foo', 'bobby''; drop table testing.foo; --']) r cross join unnest (array['testing', 'testing''; drop table testing.foo; --', 'testing; drop table testing.foo; --', 'testing"; drop table testing.foo; --']) s; select roleman.grant_table(r, t.oid::regclass, array['select']) FROM unnest(array['bobby"; drop table testing.foo; --'::text, 'bobby_tables"; foo', 'bobby''; drop table testing.foo; --']) r CROSS JOIN pg_class t WHERE t.relname like '%--%' and t.relkind = 'r'; SET ROLE "bobby'; drop table testing.foo; --"; select * from testing."foo(id int)"" drop table testing.foo; --"; select * from testing."foo(id int)' drop table testing.foo; --"; SELECT * FROM testing.foo; RESET ROLE; SET ROLE "bobby_tables""; foo"; select * from testing."foo(id int)"" drop table testing.foo; --"; select * from testing."foo(id int)' drop table testing.foo; --"; SELECT * FROM testing.foo; RESET ROLE; SET ROLE "bobby""; drop table testing.foo; --"; select * from testing."foo(id int)"" drop table testing.foo; --"; select * from testing."foo(id int)' drop table testing.foo; --"; SELECT * FROM testing.foo; RESET ROLE; select roleman.grant_schema_all(r, s, 'table', array['select']) FROM unnest(array['bobby"; drop table testing.foo; --'::text, 'bobby_tables"; foo', 'bobby''; drop table testing.foo; --']) r cross join unnest (array['testing''; drop table testing.foo; --', 'testing; drop table testing.foo; --', 'testing"; drop table testing.foo; --']) s; SET ROLE "bobby'; drop table testing.foo; --"; select * from testing."foo(id int)"" drop table testing.foo; --"; select * from testing."foo(id int)' drop table testing.foo; --"; SELECT * FROM testing.foo; RESET ROLE; SET ROLE "bobby_tables""; foo"; select * from testing."foo(id int)"" drop table testing.foo; --"; select * from testing."foo(id int)' drop table testing.foo; --"; SELECT * FROM testing.foo; RESET ROLE; SET ROLE "bobby""; drop table testing.foo; --"; select * from testing."foo(id int)"" drop table testing.foo; --"; select * from testing."foo(id int)' drop table testing.foo; --"; SELECT * FROM testing.foo; RESET ROLE; select roleman.grant_function(r, testing.foo::regproc::oid::regprocedure, array['execute'])) FROM unnest(array['bobby"; drop table testing.foo; --'::text, 'bobby_tables"; foo', 'bobby''; drop table testing.foo; --']) r; SET ROLE "bobby'; drop table testing.foo; --"; select * from testing."foo(id int)"" drop table testing.foo; --"; reset role; select roleman.role_blank_perms('bobby"; drop table testing.foo; --'); select roleman.drop_role('bobby"; drop table testing.foo; --'); select roleman.role_blank_perms('bobby''; drop table testing.foo; --'); select roleman.drop_role('bobby''; drop table testing.foo; --'); select roleman.role_blank_perms('bobby_tables"; foo'); select roleman.drop_role('bobby_tables"; foo'); select 'testing.foo'::regclass::text;