-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathall_access.sql
188 lines (184 loc) · 6.76 KB
/
all_access.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
check permisssion in following object: database, parameter (superuser granted), schema, table, view, materialzied view
,column,function, sequence for all the roles in the database.
predefined role also checked permission against all the objects.
a specified function. all_access(name) will return a role's priviledge info.
*/
CREATE OR REPLACE VIEW public.all_access AS
(
---------------------database permission---------------
SELECT
NULL::text AS obj_schema,
text 'database' AS kind,
pd.datname::text AS obj_name,
rolname AS role,
priv AS privilege
FROM
pg_database pd
CROSS JOIN (
VALUES ('CREATE'),
('CONNECT'),
('TEMPORARY')) s (priv)
CROSS JOIN pg_roles pr
WHERE
pd.datname = current_database()
AND has_database_privilege(pr.oid, pd.oid, priv))
UNION ALL
(
---------------------parameter permission---------------
SELECT
NULL::text AS obj_schema,
text 'parameter' AS kind,
ppa.parname AS obj_name,
rolname,
priv privilege
FROM
pg_parameter_acl ppa
CROSS JOIN (
VALUES ('ALTER SYSTEM'),
('SET')) s (priv)
CROSS JOIN pg_roles pr
WHERE has_parameter_privilege (pr.oid, ppa.parname, priv)
)
---------------------schema permission---------------
UNION ALL (
SELECT
pn.nspname::text AS schema,
text 'schema' AS kind,
pn.nspname::text AS obj_name,
rolname,
priv privilege
FROM
pg_namespace pn
CROSS JOIN pg_roles pr
CROSS JOIN (
VALUES ('CREATE'),
('USAGE')) s (priv)
WHERE
pn.nspname::text <> 'information_schema'::text
AND NOT pn.nspname::text ~* '^pg_'
AND has_schema_privilege(pr.oid, pn.oid, priv))
UNION ALL
(
----------------------------------------table,view, materialized view permission---------------
SELECT
pc.relnamespace::regnamespace::text AS schema,
CASE pc.relkind
WHEN 'r' THEN
text 'table'
WHEN 'v' THEN
'view'
WHEN 'm' THEN
'matview'
END AS kind,
pc.relname::text, --relation name
rolname,
priv privilege
FROM
pg_class pc
CROSS JOIN (
VALUES ('SELECT'),
('INSERT'),
('UPDATE'),
('DELETE'),
('TRUNCATE'),
('REFERENCES'),
('TRIGGER'),
('MAINTAIN')) s (priv)
CROSS JOIN pg_roles pr
WHERE
pc.relnamespace::regnamespace::text <> 'information_schema'::text
AND NOT pc.relnamespace::regnamespace::text ~* '^pg_'
AND has_table_privilege(pr.oid, pc.oid, priv)
AND pc.relkind IN ('r','v','m')
)
UNION ALL
(
----------------column permission---------------
SELECT
pc.relnamespace::regnamespace::text AS schema,
text 'column' AS kind,
pc.relname::text || '.' || pa.attname AS rel_col,
rolname,
priv privilege
FROM
pg_class pc
JOIN pg_attribute pa ON pa. attrelid = pc.oid
CROSS JOIN pg_roles pr
CROSS JOIN (
VALUES ('SELECT'),
('INSERT'),
('UPDATE'),
('REFERENCES')) s (priv)
WHERE
pc.relnamespace::regnamespace::text <> 'information_schema'::text
AND has_column_privilege(pr.oid, pc.oid, pa.attnum, priv)
AND NOT pc.relnamespace::regnamespace::text ~* '^pg_'
AND relkind IN ('r', 'm', 'v')
AND pa.attnum > 0
)
UNION ALL
(
------------------------------------------function permission------------------------------
SELECT
pp.pronamespace::regnamespace::text AS object_schema,
text 'function' AS kind,
pp.oid::regprocedure::text AS obj_name,
rolname,
priv privilege
FROM
pg_proc pp
CROSS JOIN (
VALUES ('EXECUTE')) s (priv)
CROSS JOIN pg_roles pr
WHERE
has_function_privilege(pr.oid, pp.oid, priv)
AND pp.pronamespace <> 'information_schema'::regnamespace
AND NOT pp.pronamespace::regnamespace::text ~* '^pg_'
AND prolang <> (
SELECT
oid
FROM
pg_language
WHERE
lanname = 'c')
)
UNION ALL
(
------------------------------------------sequence permission---------------
SELECT
pc.relnamespace::regnamespace::text AS schema, --schema
text 'sequence' AS kind,
pc.relname::text AS obj_name, --relation name
rolname,
priv privilege
FROM
pg_class pc
CROSS JOIN (
VALUES ('USAGE'),
('SELECT'),
('UPDATE')) s (priv)
CROSS JOIN pg_roles pr
WHERE
has_sequence_privilege(pr.oid, pc.oid, priv)
AND pc.relnamespace <> 'information_schema'::regnamespace
AND NOT pc.relnamespace::text ~* '^pg_'
AND pc.relkind = 'S'::"char"
);
--test time.
revoke all on table all_access from public;
grant select on table all_access to public;
select string_agg(distinct kind,', ' order by kind) from all_access;
CREATE OR REPLACE FUNCTION public.all_access (name DEFAULT CURRENT_USER)
RETURNS SETOF public.all_access
SET search_path FROM current
AS $$
SELECT
*
FROM
public.all_access
WHERE
ROLE = $1
$$
LANGUAGE SQL;
select kind, obj_schema, obj_name from all_access('test');