mirror of
https://github.com/postgres/postgres.git
synced 2026-05-28 04:35:45 -04:00
Allow pg_{read,write}_all_data to access large objects.
Since the initial goal of pg_read_all_data was to be able to run pg_dump as a non-superuser without explicitly granting access to every object, it follows that it should allow reading all large objects. For consistency, pg_write_all_data should allow writing all large objects, too. Author: Nitin Motiani <nitinmotiani@google.com> Co-authored-by: Nathan Bossart <nathandbossart@gmail.com> Reviewed-by: Dilip Kumar <dilipbalaut@gmail.com> Discussion: https://postgr.es/m/CAH5HC96dxAEvP78s1-JK_nDABH5c4w2MDfyx4vEWxBEfofGWsw%40mail.gmail.com
This commit is contained in:
parent
d743545d84
commit
d981976027
4 changed files with 90 additions and 4 deletions
|
|
@ -713,7 +713,7 @@ GRANT pg_signal_backend TO admin_user;
|
|||
<listitem>
|
||||
<para>
|
||||
<literal>pg_read_all_data</literal> allows reading all data (tables,
|
||||
views, sequences), as if having <command>SELECT</command> rights on
|
||||
views, sequences, large objects), as if having <command>SELECT</command> rights on
|
||||
those objects and <literal>USAGE</literal> rights on all schemas. This
|
||||
role does not bypass row-level security (RLS) policies. If RLS is being
|
||||
used, an administrator may wish to set <literal>BYPASSRLS</literal> on
|
||||
|
|
@ -721,7 +721,7 @@ GRANT pg_signal_backend TO admin_user;
|
|||
</para>
|
||||
<para>
|
||||
<literal>pg_write_all_data</literal> allows writing all data (tables,
|
||||
views, sequences), as if having <command>INSERT</command>,
|
||||
views, sequences, large objects), as if having <command>INSERT</command>,
|
||||
<command>UPDATE</command>, and <command>DELETE</command> rights on those
|
||||
objects and <literal>USAGE</literal> rights on all schemas. This role
|
||||
does not bypass row-level security (RLS) policies. If RLS is being
|
||||
|
|
|
|||
|
|
@ -3598,6 +3598,24 @@ pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
|
|||
|
||||
table_close(pg_lo_meta, AccessShareLock);
|
||||
|
||||
/*
|
||||
* Check if ACL_SELECT is being checked and, if so, and not set already as
|
||||
* part of the result, then check if the user has privileges of the
|
||||
* pg_read_all_data role, which allows read access to all large objects.
|
||||
*/
|
||||
if (mask & ACL_SELECT && !(result & ACL_SELECT) &&
|
||||
has_privs_of_role(roleid, ROLE_PG_READ_ALL_DATA))
|
||||
result |= ACL_SELECT;
|
||||
|
||||
/*
|
||||
* Check if ACL_UPDATE is being checked and, if so, and not set already as
|
||||
* part of the result, then check if the user has privileges of the
|
||||
* pg_write_all_data role, which allows write access to all large objects.
|
||||
*/
|
||||
if (mask & ACL_UPDATE && !(result & ACL_UPDATE) &&
|
||||
has_privs_of_role(roleid, ROLE_PG_WRITE_ALL_DATA))
|
||||
result |= ACL_UPDATE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2175,6 +2175,53 @@ SELECT lo_truncate(lo_open(2001, x'20000'::int), 10);
|
|||
0
|
||||
(1 row)
|
||||
|
||||
\c -
|
||||
-- confirm role with privileges of pg_read_all_data can read large objects
|
||||
SET SESSION AUTHORIZATION regress_priv_user6;
|
||||
SELECT loread(lo_open(1002, x'40000'::int), 32);
|
||||
loread
|
||||
--------
|
||||
\x
|
||||
(1 row)
|
||||
|
||||
SELECT lo_get(1002);
|
||||
lo_get
|
||||
--------
|
||||
\x
|
||||
(1 row)
|
||||
|
||||
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
|
||||
ERROR: permission denied for large object 1002
|
||||
SELECT lo_put(1002, 1, 'abcd'); -- to be denied
|
||||
ERROR: permission denied for large object 1002
|
||||
SELECT lo_truncate(lo_open(1002, x'20000'::int), 0); -- to be denied
|
||||
ERROR: permission denied for large object 1002
|
||||
SELECT lo_unlink(1002); -- to be denied
|
||||
ERROR: must be owner of large object 1002
|
||||
\c -
|
||||
-- confirm role with privileges of pg_write_all_data can write large objects
|
||||
GRANT SELECT ON LARGE OBJECT 1002 TO regress_priv_user7;
|
||||
SET SESSION AUTHORIZATION regress_priv_user7;
|
||||
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd');
|
||||
lowrite
|
||||
---------
|
||||
4
|
||||
(1 row)
|
||||
|
||||
SELECT lo_put(1002, 1, 'abcd');
|
||||
lo_put
|
||||
--------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT lo_truncate(lo_open(1002, x'20000'::int), 0);
|
||||
lo_truncate
|
||||
-------------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SELECT lo_unlink(1002); -- to be denied
|
||||
ERROR: must be owner of large object 1002
|
||||
-- has_largeobject_privilege function
|
||||
-- superuser
|
||||
\c -
|
||||
|
|
@ -2727,7 +2774,7 @@ SELECT has_largeobject_privilege('regress_priv_user2', 1008, 'SELECT'); -- yes
|
|||
t
|
||||
(1 row)
|
||||
|
||||
SELECT has_largeobject_privilege('regress_priv_user6', 1008, 'SELECT'); -- no
|
||||
SELECT has_largeobject_privilege('regress_priv_user3', 1008, 'SELECT'); -- no
|
||||
has_largeobject_privilege
|
||||
---------------------------
|
||||
f
|
||||
|
|
|
|||
|
|
@ -1384,6 +1384,27 @@ SELECT loread(lo_open(1005, x'40000'::int), 32);
|
|||
SELECT lo_truncate(lo_open(1005, x'20000'::int), 10); -- to be denied
|
||||
SELECT lo_truncate(lo_open(2001, x'20000'::int), 10);
|
||||
|
||||
\c -
|
||||
-- confirm role with privileges of pg_read_all_data can read large objects
|
||||
SET SESSION AUTHORIZATION regress_priv_user6;
|
||||
|
||||
SELECT loread(lo_open(1002, x'40000'::int), 32);
|
||||
SELECT lo_get(1002);
|
||||
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
|
||||
SELECT lo_put(1002, 1, 'abcd'); -- to be denied
|
||||
SELECT lo_truncate(lo_open(1002, x'20000'::int), 0); -- to be denied
|
||||
SELECT lo_unlink(1002); -- to be denied
|
||||
|
||||
\c -
|
||||
-- confirm role with privileges of pg_write_all_data can write large objects
|
||||
GRANT SELECT ON LARGE OBJECT 1002 TO regress_priv_user7;
|
||||
SET SESSION AUTHORIZATION regress_priv_user7;
|
||||
|
||||
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd');
|
||||
SELECT lo_put(1002, 1, 'abcd');
|
||||
SELECT lo_truncate(lo_open(1002, x'20000'::int), 0);
|
||||
SELECT lo_unlink(1002); -- to be denied
|
||||
|
||||
-- has_largeobject_privilege function
|
||||
|
||||
-- superuser
|
||||
|
|
@ -1619,7 +1640,7 @@ ALTER DEFAULT PRIVILEGES GRANT SELECT ON LARGE OBJECTS TO regress_priv_user2;
|
|||
|
||||
SELECT lo_create(1008);
|
||||
SELECT has_largeobject_privilege('regress_priv_user2', 1008, 'SELECT'); -- yes
|
||||
SELECT has_largeobject_privilege('regress_priv_user6', 1008, 'SELECT'); -- no
|
||||
SELECT has_largeobject_privilege('regress_priv_user3', 1008, 'SELECT'); -- no
|
||||
SELECT has_largeobject_privilege('regress_priv_user2', 1008, 'UPDATE'); -- no
|
||||
|
||||
ALTER DEFAULT PRIVILEGES GRANT ALL ON LARGE OBJECTS TO regress_priv_user2;
|
||||
|
|
|
|||
Loading…
Reference in a new issue