2001-05-27 11:59:30 +02:00
--
-- Test access privileges
--
2006-07-18 02:32:42 +02:00
-- Clean up in case a prior regression run failed
-- Suppress NOTICE messages when users/groups don't exist
2009-10-12 22:39:42 +02:00
SET client_min_messages TO 'warning';
2018-03-15 19:00:31 +01:00
DROP ROLE IF EXISTS regress_priv_group1;
DROP ROLE IF EXISTS regress_priv_group2;
DROP ROLE IF EXISTS regress_priv_user1;
DROP ROLE IF EXISTS regress_priv_user2;
DROP ROLE IF EXISTS regress_priv_user3;
DROP ROLE IF EXISTS regress_priv_user4;
DROP ROLE IF EXISTS regress_priv_user5;
DROP ROLE IF EXISTS regress_priv_user6;
2021-04-05 19:42:52 +02:00
DROP ROLE IF EXISTS regress_priv_user7;
pg_upgrade: Fix large object COMMENTS, SECURITY LABELS
When performing a pg_upgrade, we copy the files behind pg_largeobject
and pg_largeobject_metadata, allowing us to avoid having to dump out and
reload the actual data for large objects and their ACLs.
Unfortunately, that isn't all of the information which can be associated
with large objects. Currently, we also support COMMENTs and SECURITY
LABELs with large objects and these were being silently dropped during a
pg_upgrade as pg_dump would skip everything having to do with a large
object and pg_upgrade only copied the tables mentioned to the new
cluster.
As the file copies happen after the catalog dump and reload, we can't
simply include the COMMENTs and SECURITY LABELs in pg_dump's binary-mode
output but we also have to include the actual large object definition as
well. With the definition, comments, and security labels in the pg_dump
output and the file copies performed by pg_upgrade, all of the data and
metadata associated with large objects is able to be successfully pulled
forward across a pg_upgrade.
In 9.6 and master, we can simply adjust the dump bitmask to indicate
which components we don't want. In 9.5 and earlier, we have to put
explciit checks in in dumpBlob() and dumpBlobs() to not include the ACL
or the data when in binary-upgrade mode.
Adjustments made to the privileges regression test to allow another test
(large_object.sql) to be added which explicitly leaves a large object
with a comment in place to provide coverage of that case with
pg_upgrade.
Back-patch to all supported branches.
Discussion: https://postgr.es/m/20170221162655.GE9812@tamriel.snowman.net
2017-03-06 23:03:57 +01:00
SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
2009-12-11 04:34:57 +01:00
lo_unlink
-----------
(0 rows)
2006-07-18 02:32:42 +02:00
RESET client_min_messages;
-- test proper begins here
2018-03-15 19:00:31 +01:00
CREATE USER regress_priv_user1;
CREATE USER regress_priv_user2;
CREATE USER regress_priv_user3;
CREATE USER regress_priv_user4;
CREATE USER regress_priv_user5;
CREATE USER regress_priv_user5; -- duplicate
ERROR: role "regress_priv_user5" already exists
2021-04-05 19:42:52 +02:00
CREATE USER regress_priv_user6;
CREATE USER regress_priv_user7;
2021-11-26 14:02:14 +01:00
CREATE USER regress_priv_user8;
CREATE USER regress_priv_user9;
CREATE USER regress_priv_user10;
2021-11-26 14:02:01 +01:00
CREATE ROLE regress_priv_role;
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
-- circular ADMIN OPTION grants should be disallowed
GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION;
GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION GRANTED BY regress_priv_user2;
GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION GRANTED BY regress_priv_user3;
ERROR: admin option cannot be granted back to your own grantor
-- need CASCADE to revoke grant or admin option if dependent grants exist
REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2; -- fail
ERROR: dependent privileges exist
HINT: Use CASCADE to revoke them too.
REVOKE regress_priv_user1 FROM regress_priv_user2; -- fail
ERROR: dependent privileges exist
HINT: Use CASCADE to revoke them too.
SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole;
member | admin_option
--------------------+--------------
regress_priv_user2 | t
regress_priv_user3 | t
(2 rows)
BEGIN;
REVOKE ADMIN OPTION FOR regress_priv_user1 FROM regress_priv_user2 CASCADE;
SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole;
member | admin_option
--------------------+--------------
regress_priv_user2 | f
(1 row)
ROLLBACK;
REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE;
SELECT member::regrole, admin_option FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole;
member | admin_option
--------+--------------
(0 rows)
-- inferred grantor must be a role with ADMIN OPTION
GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION;
GRANT regress_priv_user2 TO regress_priv_user3;
SET ROLE regress_priv_user3;
GRANT regress_priv_user1 TO regress_priv_user4;
SELECT grantor::regrole FROM pg_auth_members WHERE roleid = 'regress_priv_user1'::regrole and member = 'regress_priv_user4'::regrole;
grantor
--------------------
regress_priv_user2
(1 row)
RESET ROLE;
REVOKE regress_priv_user2 FROM regress_priv_user3;
REVOKE regress_priv_user1 FROM regress_priv_user2 CASCADE;
Ensure that pg_auth_members.grantor is always valid.
Previously, "GRANT foo TO bar" or "GRANT foo TO bar GRANTED BY baz"
would record the OID of the grantor in pg_auth_members.grantor, but
that role could later be dropped without modifying or removing the
pg_auth_members record. That's not great, because we typically try
to avoid dangling references in catalog data.
Now, a role grant depends on the grantor, and the grantor can't be
dropped without removing the grant or changing the grantor. "DROP
OWNED BY" will remove the grant, just as it does for other kinds of
privileges. "REASSIGN OWNED BY" will not, again just like what we do
in other cases involving privileges.
pg_auth_members now has an OID column, because that is needed in order
for dependencies to work. It also now has an index on the grantor
column, because otherwise dropping a role would require a sequential
scan of the entire table to see whether the role's OID is in use as
a grantor. That probably wouldn't be too large a problem in practice,
but it seems better to have an index just in case.
A follow-on patch is planned with the goal of more thoroughly
rationalizing the behavior of role grants. This patch is just trying
to do enough to make sure that the data we store in the catalogs is at
some basic level valid.
Patch by me, reviewed by Stephen Frost
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-18 19:13:02 +02:00
-- test GRANTED BY with DROP OWNED and REASSIGN OWNED
GRANT regress_priv_user1 TO regress_priv_user2 WITH ADMIN OPTION;
GRANT regress_priv_user1 TO regress_priv_user3 GRANTED BY regress_priv_user2;
DROP ROLE regress_priv_user2; -- fail, dependency
ERROR: role "regress_priv_user2" cannot be dropped because some objects depend on it
DETAIL: privileges for membership of role regress_priv_user3 in role regress_priv_user1
REASSIGN OWNED BY regress_priv_user2 TO regress_priv_user4;
DROP ROLE regress_priv_user2; -- still fail, REASSIGN OWNED doesn't help
ERROR: role "regress_priv_user2" cannot be dropped because some objects depend on it
DETAIL: privileges for membership of role regress_priv_user3 in role regress_priv_user1
DROP OWNED BY regress_priv_user2;
DROP ROLE regress_priv_user2; -- ok now, DROP OWNED does the job
-- test that removing granted role or grantee role removes dependency
GRANT regress_priv_user1 TO regress_priv_user3 WITH ADMIN OPTION;
GRANT regress_priv_user1 TO regress_priv_user4 GRANTED BY regress_priv_user3;
DROP ROLE regress_priv_user3; -- should fail, dependency
ERROR: role "regress_priv_user3" cannot be dropped because some objects depend on it
DETAIL: privileges for membership of role regress_priv_user4 in role regress_priv_user1
DROP ROLE regress_priv_user4; -- ok
DROP ROLE regress_priv_user3; -- ok now
GRANT regress_priv_user1 TO regress_priv_user5 WITH ADMIN OPTION;
GRANT regress_priv_user1 TO regress_priv_user6 GRANTED BY regress_priv_user5;
DROP ROLE regress_priv_user5; -- should fail, dependency
ERROR: role "regress_priv_user5" cannot be dropped because some objects depend on it
DETAIL: privileges for membership of role regress_priv_user6 in role regress_priv_user1
DROP ROLE regress_priv_user1, regress_priv_user5; -- ok, despite order
-- recreate the roles we just dropped
CREATE USER regress_priv_user1;
CREATE USER regress_priv_user2;
CREATE USER regress_priv_user3;
CREATE USER regress_priv_user4;
CREATE USER regress_priv_user5;
2021-04-05 19:42:52 +02:00
GRANT pg_read_all_data TO regress_priv_user6;
GRANT pg_write_all_data TO regress_priv_user7;
2021-11-26 14:02:14 +01:00
GRANT pg_read_all_settings TO regress_priv_user8 WITH ADMIN OPTION;
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
GRANT regress_priv_user9 TO regress_priv_user8;
2021-11-26 14:02:14 +01:00
SET SESSION AUTHORIZATION regress_priv_user8;
GRANT pg_read_all_settings TO regress_priv_user9 WITH ADMIN OPTION;
SET SESSION AUTHORIZATION regress_priv_user9;
GRANT pg_read_all_settings TO regress_priv_user10;
SET SESSION AUTHORIZATION regress_priv_user8;
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
REVOKE pg_read_all_settings FROM regress_priv_user10 GRANTED BY regress_priv_user9;
2021-11-26 14:02:14 +01:00
REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user9;
REVOKE pg_read_all_settings FROM regress_priv_user9;
RESET SESSION AUTHORIZATION;
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
REVOKE regress_priv_user9 FROM regress_priv_user8;
2021-11-26 14:02:14 +01:00
REVOKE ADMIN OPTION FOR pg_read_all_settings FROM regress_priv_user8;
SET SESSION AUTHORIZATION regress_priv_user8;
SET ROLE pg_read_all_settings;
RESET ROLE;
RESET SESSION AUTHORIZATION;
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
REVOKE SET OPTION FOR pg_read_all_settings FROM regress_priv_user8;
GRANT pg_read_all_stats TO regress_priv_user8 WITH SET FALSE;
SET SESSION AUTHORIZATION regress_priv_user8;
SET ROLE pg_read_all_settings; -- fail, no SET option any more
ERROR: permission denied to set role "pg_read_all_settings"
SET ROLE pg_read_all_stats; -- fail, granted without SET option
ERROR: permission denied to set role "pg_read_all_stats"
RESET ROLE;
RESET SESSION AUTHORIZATION;
2021-11-26 14:02:14 +01:00
REVOKE pg_read_all_settings FROM regress_priv_user8;
DROP USER regress_priv_user10;
DROP USER regress_priv_user9;
DROP USER regress_priv_user8;
2018-03-15 19:00:31 +01:00
CREATE GROUP regress_priv_group1;
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
CREATE GROUP regress_priv_group2 WITH ADMIN regress_priv_user1 USER regress_priv_user2;
2018-03-15 19:00:31 +01:00
ALTER GROUP regress_priv_group1 ADD USER regress_priv_user4;
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
GRANT regress_priv_group2 TO regress_priv_user2 GRANTED BY regress_priv_user1;
SET SESSION AUTHORIZATION regress_priv_user1;
ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2;
NOTICE: role "regress_priv_user2" has already been granted membership in role "regress_priv_group2" by role "regress_priv_user1"
2018-03-15 19:00:31 +01:00
ALTER GROUP regress_priv_group2 ADD USER regress_priv_user2; -- duplicate
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
NOTICE: role "regress_priv_user2" has already been granted membership in role "regress_priv_group2" by role "regress_priv_user1"
ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2;
ALTER USER regress_priv_user2 PASSWORD 'verysecret'; -- not permitted
ERROR: must have CREATEROLE privilege to change another user's password
RESET SESSION AUTHORIZATION;
2018-03-15 19:00:31 +01:00
ALTER GROUP regress_priv_group2 DROP USER regress_priv_user2;
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
REVOKE ADMIN OPTION FOR regress_priv_group2 FROM regress_priv_user1;
2018-03-15 19:00:31 +01:00
GRANT regress_priv_group2 TO regress_priv_user4 WITH ADMIN OPTION;
2021-05-12 02:59:45 +02:00
-- prepare non-leakproof function for later
CREATE FUNCTION leak(integer,integer) RETURNS boolean
AS 'int4lt'
LANGUAGE internal IMMUTABLE STRICT; -- but deliberately not LEAKPROOF
ALTER FUNCTION leak(integer,integer) OWNER TO regress_priv_user1;
2001-05-27 11:59:30 +02:00
-- test owner privileges
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY regress_priv_role; -- error, doesn't have ADMIN OPTION
ERROR: grantor must have ADMIN OPTION on "regress_priv_role"
2021-11-26 14:02:01 +01:00
GRANT regress_priv_role TO regress_priv_user1 WITH ADMIN OPTION GRANTED BY CURRENT_ROLE;
REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY foo; -- error
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
ERROR: role "foo" does not exist
REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY regress_priv_user2; -- warning, noop
WARNING: role "regress_priv_user1" has not been granted membership in role "regress_priv_role" by role "regress_priv_user2"
2021-11-26 14:02:01 +01:00
REVOKE ADMIN OPTION FOR regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_USER;
REVOKE regress_priv_role FROM regress_priv_user1 GRANTED BY CURRENT_ROLE;
DROP ROLE regress_priv_role;
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
2001-05-27 11:59:30 +02:00
SELECT session_user, current_user;
2018-03-15 19:00:31 +01:00
session_user | current_user
--------------------+--------------------
regress_priv_user1 | regress_priv_user1
2001-05-27 11:59:30 +02:00
(1 row)
CREATE TABLE atest1 ( a int, b text );
SELECT * FROM atest1;
a | b
---+---
(0 rows)
INSERT INTO atest1 VALUES (1, 'one');
DELETE FROM atest1;
UPDATE atest1 SET a = 1 WHERE b = 'blech';
2008-09-08 02:47:41 +02:00
TRUNCATE atest1;
2008-11-04 01:57:19 +01:00
BEGIN;
2001-05-27 11:59:30 +02:00
LOCK atest1 IN ACCESS EXCLUSIVE MODE;
2008-11-04 01:57:19 +01:00
COMMIT;
2001-05-27 11:59:30 +02:00
REVOKE ALL ON atest1 FROM PUBLIC;
SELECT * FROM atest1;
a | b
---+---
(0 rows)
2018-03-15 19:00:31 +01:00
GRANT ALL ON atest1 TO regress_priv_user2;
GRANT SELECT ON atest1 TO regress_priv_user3, regress_priv_user4;
2001-05-27 11:59:30 +02:00
SELECT * FROM atest1;
a | b
---+---
(0 rows)
CREATE TABLE atest2 (col1 varchar(10), col2 boolean);
2018-03-15 19:00:31 +01:00
GRANT SELECT ON atest2 TO regress_priv_user2;
GRANT UPDATE ON atest2 TO regress_priv_user3;
2021-01-30 09:41:44 +01:00
GRANT INSERT ON atest2 TO regress_priv_user4 GRANTED BY CURRENT_USER;
GRANT TRUNCATE ON atest2 TO regress_priv_user5 GRANTED BY CURRENT_ROLE;
GRANT TRUNCATE ON atest2 TO regress_priv_user4 GRANTED BY regress_priv_user5; -- error
ERROR: grantor must be current user
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user2;
2001-05-27 11:59:30 +02:00
SELECT session_user, current_user;
2018-03-15 19:00:31 +01:00
session_user | current_user
--------------------+--------------------
regress_priv_user2 | regress_priv_user2
2001-05-27 11:59:30 +02:00
(1 row)
-- try various combinations of queries on atest1 and atest2
SELECT * FROM atest1; -- ok
a | b
---+---
(0 rows)
SELECT * FROM atest2; -- ok
col1 | col2
------+------
(0 rows)
INSERT INTO atest1 VALUES (2, 'two'); -- ok
INSERT INTO atest2 VALUES ('foo', true); -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2001-05-27 11:59:30 +02:00
INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok
UPDATE atest1 SET a = 1 WHERE a = 2; -- ok
UPDATE atest2 SET col2 = NOT col2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2001-05-27 11:59:30 +02:00
SELECT * FROM atest1 FOR UPDATE; -- ok
a | b
---+-----
1 | two
1 | two
(2 rows)
SELECT * FROM atest2 FOR UPDATE; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2001-05-27 11:59:30 +02:00
DELETE FROM atest2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2008-09-08 02:47:41 +02:00
TRUNCATE atest2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2008-11-04 01:57:19 +01:00
BEGIN;
2001-05-27 11:59:30 +02:00
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2008-11-04 01:57:19 +01:00
COMMIT;
2001-05-27 11:59:30 +02:00
COPY atest2 FROM stdin; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2001-05-27 11:59:30 +02:00
GRANT ALL ON atest1 TO PUBLIC; -- fail
2006-01-21 03:16:21 +01:00
WARNING: no privileges were granted for "atest1"
2001-05-27 11:59:30 +02:00
-- checks in subquery, both ok
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
a | b
---+---
(0 rows)
SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) );
col1 | col2
------+------
(0 rows)
2021-04-05 19:42:52 +02:00
SET SESSION AUTHORIZATION regress_priv_user6;
SELECT * FROM atest1; -- ok
a | b
---+-----
1 | two
1 | two
(2 rows)
SELECT * FROM atest2; -- ok
col1 | col2
------+------
(0 rows)
INSERT INTO atest2 VALUES ('foo', true); -- fail
ERROR: permission denied for table atest2
SET SESSION AUTHORIZATION regress_priv_user7;
SELECT * FROM atest1; -- fail
ERROR: permission denied for table atest1
SELECT * FROM atest2; -- fail
ERROR: permission denied for table atest2
INSERT INTO atest2 VALUES ('foo', true); -- ok
UPDATE atest2 SET col2 = true; -- ok
DELETE FROM atest2; -- ok
-- Make sure we are not able to modify system catalogs
UPDATE pg_catalog.pg_class SET relname = '123'; -- fail
ERROR: permission denied for table pg_class
DELETE FROM pg_catalog.pg_class; -- fail
ERROR: permission denied for table pg_class
UPDATE pg_toast.pg_toast_1213 SET chunk_id = 1; -- fail
ERROR: permission denied for table pg_toast_1213
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user3;
2001-05-27 11:59:30 +02:00
SELECT session_user, current_user;
2018-03-15 19:00:31 +01:00
session_user | current_user
--------------------+--------------------
regress_priv_user3 | regress_priv_user3
2001-05-27 11:59:30 +02:00
(1 row)
SELECT * FROM atest1; -- ok
a | b
---+-----
1 | two
1 | two
(2 rows)
SELECT * FROM atest2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2001-05-27 11:59:30 +02:00
INSERT INTO atest1 VALUES (2, 'two'); -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest1
2001-05-27 11:59:30 +02:00
INSERT INTO atest2 VALUES ('foo', true); -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2001-05-27 11:59:30 +02:00
INSERT INTO atest1 SELECT 1, b FROM atest1; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest1
2001-05-27 11:59:30 +02:00
UPDATE atest1 SET a = 1 WHERE a = 2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest1
2001-05-27 11:59:30 +02:00
UPDATE atest2 SET col2 = NULL; -- ok
UPDATE atest2 SET col2 = NOT col2; -- fails; requires SELECT on atest2
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2005-04-07 03:51:41 +02:00
UPDATE atest2 SET col2 = true FROM atest1 WHERE atest1.a = 5; -- ok
2001-05-27 11:59:30 +02:00
SELECT * FROM atest1 FOR UPDATE; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest1
2001-05-27 11:59:30 +02:00
SELECT * FROM atest2 FOR UPDATE; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2001-05-27 11:59:30 +02:00
DELETE FROM atest2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2008-09-08 02:47:41 +02:00
TRUNCATE atest2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2008-11-04 01:57:19 +01:00
BEGIN;
2001-05-27 11:59:30 +02:00
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
2008-11-04 01:57:19 +01:00
COMMIT;
2001-05-27 11:59:30 +02:00
COPY atest2 FROM stdin; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2001-05-27 11:59:30 +02:00
-- checks in subquery, both fail
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2001-05-27 11:59:30 +02:00
SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) );
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user4;
2001-05-27 11:59:30 +02:00
COPY atest2 FROM stdin; -- ok
2001-06-10 01:21:55 +02:00
SELECT * FROM atest1; -- ok
a | b
---+-----
1 | two
1 | two
(2 rows)
2017-05-05 18:18:48 +02:00
-- test leaky-function protections in selfuncs
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
-- regress_priv_user1 will own a table and provide views for it.
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
2017-05-05 18:18:48 +02:00
CREATE TABLE atest12 as
SELECT x AS a, 10001 - x AS b FROM generate_series(1,10000) x;
CREATE INDEX ON atest12 (a);
CREATE INDEX ON atest12 (abs(a));
2020-06-09 07:17:59 +02:00
-- results below depend on having quite accurate stats for atest12, so...
ALTER TABLE atest12 SET (autovacuum_enabled = off);
Improve ineq_histogram_selectivity's behavior for non-default orderings.
ineq_histogram_selectivity() can be invoked in situations where the
ordering we care about is not that of the column's histogram. We could
be considering some other collation, or even more drastically, the
query operator might not agree at all with what was used to construct
the histogram. (We'll get here for anything using scalarineqsel-based
estimators, so that's quite likely to happen for extension operators.)
Up to now we just ignored this issue and assumed we were dealing with
an operator/collation whose sort order exactly matches the histogram,
possibly resulting in junk estimates if the binary search gets confused.
It's past time to improve that, since the use of nondefault collations
is increasing. What we can do is verify that the given operator and
collation match what's recorded in pg_statistic, and use the existing
code only if so. When they don't match, instead execute the operator
against each histogram entry, and take the fraction of successes as our
selectivity estimate. This gives an estimate that is probably good to
about 1/histogram_size, with no assumptions about ordering. (The quality
of the estimate is likely to degrade near the ends of the value range,
since the two orderings probably don't agree on what is an extremal value;
but this is surely going to be more reliable than what we did before.)
At some point we might further improve matters by storing more than one
histogram calculated according to different orderings. But this code
would still be good fallback logic when no matches exist, so that is
not an argument for not doing this.
While here, also improve get_variable_range() to deal more honestly
with non-default collations.
This isn't back-patchable, because it requires adding another argument
to ineq_histogram_selectivity, and because it might have significant
impact on the estimation results for extension operators relying on
scalarineqsel --- mostly for the better, one hopes, but in any case
destabilizing plan choices in back branches is best avoided.
Per investigation of a report from James Lucas.
Discussion: https://postgr.es/m/CAAFmbbOvfi=wMM=3qRsPunBSLb8BFREno2oOzSBS=mzfLPKABw@mail.gmail.com
2020-06-05 22:55:16 +02:00
SET default_statistics_target = 10000;
2017-05-05 18:18:48 +02:00
VACUUM ANALYZE atest12;
Improve ineq_histogram_selectivity's behavior for non-default orderings.
ineq_histogram_selectivity() can be invoked in situations where the
ordering we care about is not that of the column's histogram. We could
be considering some other collation, or even more drastically, the
query operator might not agree at all with what was used to construct
the histogram. (We'll get here for anything using scalarineqsel-based
estimators, so that's quite likely to happen for extension operators.)
Up to now we just ignored this issue and assumed we were dealing with
an operator/collation whose sort order exactly matches the histogram,
possibly resulting in junk estimates if the binary search gets confused.
It's past time to improve that, since the use of nondefault collations
is increasing. What we can do is verify that the given operator and
collation match what's recorded in pg_statistic, and use the existing
code only if so. When they don't match, instead execute the operator
against each histogram entry, and take the fraction of successes as our
selectivity estimate. This gives an estimate that is probably good to
about 1/histogram_size, with no assumptions about ordering. (The quality
of the estimate is likely to degrade near the ends of the value range,
since the two orderings probably don't agree on what is an extremal value;
but this is surely going to be more reliable than what we did before.)
At some point we might further improve matters by storing more than one
histogram calculated according to different orderings. But this code
would still be good fallback logic when no matches exist, so that is
not an argument for not doing this.
While here, also improve get_variable_range() to deal more honestly
with non-default collations.
This isn't back-patchable, because it requires adding another argument
to ineq_histogram_selectivity, and because it might have significant
impact on the estimation results for extension operators relying on
scalarineqsel --- mostly for the better, one hopes, but in any case
destabilizing plan choices in back branches is best avoided.
Per investigation of a report from James Lucas.
Discussion: https://postgr.es/m/CAAFmbbOvfi=wMM=3qRsPunBSLb8BFREno2oOzSBS=mzfLPKABw@mail.gmail.com
2020-06-05 22:55:16 +02:00
RESET default_statistics_target;
2017-05-05 18:18:48 +02:00
CREATE OPERATOR <<< (procedure = leak, leftarg = integer, rightarg = integer,
restrict = scalarltsel);
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
-- views with leaky operator
2017-05-05 18:18:48 +02:00
CREATE VIEW atest12v AS
SELECT * FROM atest12 WHERE b <<< 5;
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
CREATE VIEW atest12sbv WITH (security_barrier=true) AS
SELECT * FROM atest12 WHERE b <<< 5;
2017-05-05 18:18:48 +02:00
GRANT SELECT ON atest12v TO PUBLIC;
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
GRANT SELECT ON atest12sbv TO PUBLIC;
2017-05-05 18:18:48 +02:00
-- This plan should use nestloop, knowing that few rows will be selected.
EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b;
QUERY PLAN
-------------------------------------------------
Nested Loop
-> Seq Scan on atest12 atest12_1
Filter: (b <<< 5)
-> Index Scan using atest12_a_idx on atest12
Index Cond: (a = atest12_1.b)
Filter: (b <<< 5)
(6 rows)
-- And this one.
EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y
WHERE x.a = y.b and abs(y.a) <<< 5;
QUERY PLAN
---------------------------------------------------
Nested Loop
-> Seq Scan on atest12 y
Filter: (abs(a) <<< 5)
-> Index Scan using atest12_a_idx on atest12 x
Index Cond: (a = y.b)
(5 rows)
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
-- This should also be a nestloop, but the security barrier forces the inner
-- scan to be materialized
EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b;
QUERY PLAN
-------------------------------------------
Nested Loop
Join Filter: (atest12.a = atest12_1.b)
-> Seq Scan on atest12
Filter: (b <<< 5)
-> Materialize
-> Seq Scan on atest12 atest12_1
Filter: (b <<< 5)
(7 rows)
2018-03-15 19:00:31 +01:00
-- Check if regress_priv_user2 can break security.
SET SESSION AUTHORIZATION regress_priv_user2;
2017-05-05 18:18:48 +02:00
CREATE FUNCTION leak2(integer,integer) RETURNS boolean
AS $$begin raise notice 'leak % %', $1, $2; return $1 > $2; end$$
LANGUAGE plpgsql immutable;
CREATE OPERATOR >>> (procedure = leak2, leftarg = integer, rightarg = integer,
restrict = scalargtsel);
-- This should not show any "leak" notices before failing.
EXPLAIN (COSTS OFF) SELECT * FROM atest12 WHERE a >>> 0;
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest12
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
-- These plans should continue to use a nestloop, since they execute with the
-- privileges of the view owner.
2017-05-05 18:18:48 +02:00
EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b;
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
QUERY PLAN
-------------------------------------------------
Nested Loop
-> Seq Scan on atest12 atest12_1
Filter: (b <<< 5)
-> Index Scan using atest12_a_idx on atest12
Index Cond: (a = atest12_1.b)
Filter: (b <<< 5)
(6 rows)
EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b;
2017-05-05 18:18:48 +02:00
QUERY PLAN
-------------------------------------------
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
Nested Loop
Join Filter: (atest12.a = atest12_1.b)
2017-05-05 18:18:48 +02:00
-> Seq Scan on atest12
Filter: (b <<< 5)
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
-> Materialize
2017-05-05 18:18:48 +02:00
-> Seq Scan on atest12 atest12_1
Filter: (b <<< 5)
(7 rows)
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
-- A non-security barrier view does not guard against information leakage.
EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y
WHERE x.a = y.b and abs(y.a) <<< 5;
QUERY PLAN
-------------------------------------------------
Nested Loop
-> Seq Scan on atest12 atest12_1
Filter: ((b <<< 5) AND (abs(a) <<< 5))
-> Index Scan using atest12_a_idx on atest12
Index Cond: (a = atest12_1.b)
Filter: (b <<< 5)
(6 rows)
-- But a security barrier view isolates the leaky operator.
EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y
WHERE x.a = y.b and abs(y.a) <<< 5;
QUERY PLAN
-------------------------------------
Nested Loop
Join Filter: (atest12_1.a = y.b)
-> Subquery Scan on y
Filter: (abs(y.a) <<< 5)
-> Seq Scan on atest12
Filter: (b <<< 5)
-> Seq Scan on atest12 atest12_1
Filter: (b <<< 5)
(8 rows)
2018-03-15 19:00:31 +01:00
-- Now regress_priv_user1 grants sufficient access to regress_priv_user2.
SET SESSION AUTHORIZATION regress_priv_user1;
2017-05-05 18:18:48 +02:00
GRANT SELECT (a, b) ON atest12 TO PUBLIC;
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user2;
Use checkAsUser for selectivity estimator checks, if it's set.
In examine_variable() and examine_simple_variable(), when checking the
user's table and column privileges to determine whether to grant
access to the pg_statistic data, use checkAsUser for the privilege
checks, if it's set. This will be the case if we're accessing the
table via a view, to indicate that we should perform privilege checks
as the view owner rather than the current user.
This change makes this planner check consistent with the check in the
executor, so the planner will be able to make use of statistics if the
table is accessible via the view. This fixes a performance regression
introduced by commit e2d4ef8de8, which affects queries against
non-security barrier views in the case where the user doesn't have
privileges on the underlying table, but the view owner does.
Note that it continues to provide the same safeguards controlling
access to pg_statistic for direct table access (in which case
checkAsUser won't be set) and for security barrier views, because of
the nearby checks on rte->security_barrier and rte->securityQuals.
Back-patch to all supported branches because e2d4ef8de8 was.
Dean Rasheed, reviewed by Jonathan Katz and Stephen Frost.
2019-05-06 12:54:32 +02:00
-- regress_priv_user2 should continue to get a good row estimate.
2017-05-05 18:18:48 +02:00
EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b;
QUERY PLAN
-------------------------------------------------
Nested Loop
-> Seq Scan on atest12 atest12_1
Filter: (b <<< 5)
-> Index Scan using atest12_a_idx on atest12
Index Cond: (a = atest12_1.b)
Filter: (b <<< 5)
(6 rows)
-- But not for this, due to lack of table-wide permissions needed
-- to make use of the expression index's statistics.
EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y
WHERE x.a = y.b and abs(y.a) <<< 5;
QUERY PLAN
--------------------------------------
Hash Join
Hash Cond: (x.a = y.b)
-> Seq Scan on atest12 x
-> Hash
-> Seq Scan on atest12 y
Filter: (abs(a) <<< 5)
(6 rows)
2018-03-15 19:00:31 +01:00
-- clean up (regress_priv_user1's objects are all dropped later)
2017-05-05 18:18:48 +02:00
DROP FUNCTION leak2(integer, integer) CASCADE;
NOTICE: drop cascades to operator >>>(integer,integer)
2001-05-27 11:59:30 +02:00
-- groups
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user3;
2001-05-27 11:59:30 +02:00
CREATE TABLE atest3 (one int, two int, three int);
2018-03-15 19:00:31 +01:00
GRANT DELETE ON atest3 TO GROUP regress_priv_group2;
SET SESSION AUTHORIZATION regress_priv_user1;
2001-05-27 11:59:30 +02:00
SELECT * FROM atest3; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest3
2001-05-27 11:59:30 +02:00
DELETE FROM atest3; -- ok
2020-12-25 19:41:59 +01:00
BEGIN;
RESET SESSION AUTHORIZATION;
ALTER ROLE regress_priv_user1 NOINHERIT;
SET SESSION AUTHORIZATION regress_priv_user1;
2022-08-25 16:06:02 +02:00
SAVEPOINT s1;
DELETE FROM atest3; -- ok because grant-level option is unchanged
ROLLBACK TO s1;
RESET SESSION AUTHORIZATION;
GRANT regress_priv_group2 TO regress_priv_user1 WITH INHERIT FALSE;
SET SESSION AUTHORIZATION regress_priv_user1;
DELETE FROM atest3; -- fail
ERROR: permission denied for table atest3
ROLLBACK TO s1;
RESET SESSION AUTHORIZATION;
REVOKE INHERIT OPTION FOR regress_priv_group2 FROM regress_priv_user1;
SET SESSION AUTHORIZATION regress_priv_user1;
DELETE FROM atest3; -- also fail
2020-12-25 19:41:59 +01:00
ERROR: permission denied for table atest3
ROLLBACK;
2001-05-27 11:59:30 +02:00
-- views
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user3;
2001-05-27 11:59:30 +02:00
CREATE VIEW atestv1 AS SELECT * FROM atest1; -- ok
/* The next *should* fail, but it's not implemented that way yet. */
CREATE VIEW atestv2 AS SELECT * FROM atest2;
CREATE VIEW atestv3 AS SELECT * FROM atest3; -- ok
2013-05-02 00:26:50 +02:00
/* Empty view is a corner case that failed in 9.2. */
CREATE VIEW atestv0 AS SELECT 0 as x WHERE false; -- ok
2001-05-27 11:59:30 +02:00
SELECT * FROM atestv1; -- ok
a | b
---+-----
1 | two
1 | two
(2 rows)
2002-05-19 17:13:20 +02:00
SELECT * FROM atestv2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2018-03-15 19:00:31 +01:00
GRANT SELECT ON atestv1, atestv3 TO regress_priv_user4;
GRANT SELECT ON atestv2 TO regress_priv_user2;
SET SESSION AUTHORIZATION regress_priv_user4;
2001-05-27 11:59:30 +02:00
SELECT * FROM atestv1; -- ok
a | b
---+-----
1 | two
1 | two
(2 rows)
2002-05-19 17:13:20 +02:00
SELECT * FROM atestv2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for view atestv2
2001-05-27 11:59:30 +02:00
SELECT * FROM atestv3; -- ok
one | two | three
-----+-----+-------
(0 rows)
2013-05-02 00:26:50 +02:00
SELECT * FROM atestv0; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for view atestv0
2013-05-08 22:59:09 +02:00
-- Appendrels excluded by constraints failed to check permissions in 8.4-9.2.
select * from
((select a.q1 as x from int8_tbl a offset 0)
union all
(select b.q2 as x from int8_tbl b offset 0)) ss
where false;
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table int8_tbl
2013-05-08 22:59:09 +02:00
set constraint_exclusion = on;
select * from
((select a.q1 as x, random() from int8_tbl a where q1 > 0)
union all
(select b.q2 as x, random() from int8_tbl b where q2 > 0)) ss
where x < 0;
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table int8_tbl
2013-05-08 22:59:09 +02:00
reset constraint_exclusion;
2002-05-19 17:13:20 +02:00
CREATE VIEW atestv4 AS SELECT * FROM atestv3; -- nested view
SELECT * FROM atestv4; -- ok
one | two | three
-----+-----+-------
(0 rows)
2018-03-15 19:00:31 +01:00
GRANT SELECT ON atestv4 TO regress_priv_user2;
SET SESSION AUTHORIZATION regress_priv_user2;
2002-05-19 17:13:20 +02:00
-- Two complex cases:
SELECT * FROM atestv3; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for view atestv3
2018-03-15 19:00:31 +01:00
SELECT * FROM atestv4; -- ok (even though regress_priv_user2 cannot access underlying atestv3)
2002-05-19 17:13:20 +02:00
one | two | three
-----+-----+-------
(0 rows)
SELECT * FROM atest2; -- ok
col1 | col2
------+------
bar | t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT * FROM atestv2; -- fail (even though regress_priv_user2 can access underlying atest2)
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
2009-01-22 21:16:10 +01:00
-- Test column level permissions
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative to
raising a unique or exclusion constraint violation error when inserting.
ON CONFLICT refers to constraints that can either be specified using a
inference clause (by specifying the columns of a unique constraint) or
by naming a unique or exclusion constraint. DO NOTHING avoids the
constraint violation, without touching the pre-existing row. DO UPDATE
SET ... [WHERE ...] updates the pre-existing tuple, and has access to
both the tuple proposed for insertion and the existing tuple; the
optional WHERE clause can be used to prevent an update from being
executed. The UPDATE SET and WHERE clauses have access to the tuple
proposed for insertion using the "magic" EXCLUDED alias, and to the
pre-existing tuple using the table name or its alias.
This feature is often referred to as upsert.
This is implemented using a new infrastructure called "speculative
insertion". It is an optimistic variant of regular insertion that first
does a pre-check for existing tuples and then attempts an insert. If a
violating tuple was inserted concurrently, the speculatively inserted
tuple is deleted and a new attempt is made. If the pre-check finds a
matching tuple the alternative DO NOTHING or DO UPDATE action is taken.
If the insertion succeeds without detecting a conflict, the tuple is
deemed inserted.
To handle the possible ambiguity between the excluded alias and a table
named excluded, and for convenience with long relation names, INSERT
INTO now can alias its target table.
Bumps catversion as stored rules change.
Author: Peter Geoghegan, with significant contributions from Heikki
Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.
Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs,
Dean Rasheed, Stephen Frost and many others.
2015-05-08 05:31:36 +02:00
CREATE TABLE atest5 (one int, two int unique, three int, four int unique);
2009-01-22 21:16:10 +01:00
CREATE TABLE atest6 (one int, two int, blue int);
2018-03-15 19:00:31 +01:00
GRANT SELECT (one), INSERT (two), UPDATE (three) ON atest5 TO regress_priv_user4;
GRANT ALL (one) ON atest5 TO regress_priv_user3;
2009-01-22 21:16:10 +01:00
INSERT INTO atest5 VALUES (1,2,3);
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user4;
2009-01-22 21:16:10 +01:00
SELECT * FROM atest5; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT one FROM atest5; -- ok
one
-----
1
(1 row)
2009-02-06 22:15:12 +01:00
COPY atest5 (one) TO stdout; -- ok
1
2009-01-22 21:16:10 +01:00
SELECT two FROM atest5; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-02-06 22:15:12 +01:00
COPY atest5 (two) TO stdout; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT atest5 FROM atest5; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-02-06 22:15:12 +01:00
COPY atest5 (one,two) TO stdout; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT 1 FROM atest5; -- ok
?column?
----------
1
(1 row)
SELECT 1 FROM atest5 a JOIN atest5 b USING (one); -- ok
?column?
----------
1
(1 row)
SELECT 1 FROM atest5 a JOIN atest5 b USING (two); -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT 1 FROM atest5 a NATURAL JOIN atest5 b; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
Fix mishandling of column-level SELECT privileges for join aliases.
scanNSItemForColumn, expandNSItemAttrs, and ExpandSingleTable would
pass the wrong RTE to markVarForSelectPriv when dealing with a join
ParseNamespaceItem: they'd pass the join RTE, when what we need to
mark is the base table that the join column came from. The end
result was to not fill the base table's selectedCols bitmap correctly,
resulting in an understatement of the set of columns that are read
by the query. The executor would still insist on there being at
least one selectable column; but with a correctly crafted query,
a user having SELECT privilege on just one column of a table would
nonetheless be allowed to read all its columns.
To fix, make markRTEForSelectPriv fetch the correct RTE for itself,
ignoring the possibly-mismatched RTE passed by the caller. Later,
we'll get rid of some now-unused RTE arguments, but that risks
API breaks so we won't do it in released branches.
This problem was introduced by commit 9ce77d75c, so back-patch
to v13 where that came in. Thanks to Sven Klemm for reporting
the problem.
Security: CVE-2021-20229
2021-02-08 16:14:09 +01:00
SELECT * FROM (atest5 a JOIN atest5 b USING (one)) j; -- fail
ERROR: permission denied for table atest5
SELECT j.* FROM (atest5 a JOIN atest5 b USING (one)) j; -- fail
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT (j.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)) j; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
Fix mishandling of column-level SELECT privileges for join aliases.
scanNSItemForColumn, expandNSItemAttrs, and ExpandSingleTable would
pass the wrong RTE to markVarForSelectPriv when dealing with a join
ParseNamespaceItem: they'd pass the join RTE, when what we need to
mark is the base table that the join column came from. The end
result was to not fill the base table's selectedCols bitmap correctly,
resulting in an understatement of the set of columns that are read
by the query. The executor would still insist on there being at
least one selectable column; but with a correctly crafted query,
a user having SELECT privilege on just one column of a table would
nonetheless be allowed to read all its columns.
To fix, make markRTEForSelectPriv fetch the correct RTE for itself,
ignoring the possibly-mismatched RTE passed by the caller. Later,
we'll get rid of some now-unused RTE arguments, but that risks
API breaks so we won't do it in released branches.
This problem was introduced by commit 9ce77d75c, so back-patch
to v13 where that came in. Thanks to Sven Klemm for reporting
the problem.
Security: CVE-2021-20229
2021-02-08 16:14:09 +01:00
SELECT one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- ok
one
-----
1
(1 row)
SELECT j.one FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- ok
one
-----
1
(1 row)
SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- fail
ERROR: permission denied for table atest5
SELECT j.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- fail
ERROR: permission denied for table atest5
SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- fail
ERROR: permission denied for table atest5
SELECT j.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)) j; -- fail
ERROR: permission denied for table atest5
SELECT * FROM (atest5 a JOIN atest5 b USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT a.* FROM (atest5 a JOIN atest5 b USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT (a.*) IS NULL FROM (atest5 a JOIN atest5 b USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT a.two FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT b.y FROM (atest5 a JOIN atest5 b(one,x,y,z) USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT b.y FROM (atest5 a LEFT JOIN atest5 b(one,x,y,z) USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)); -- fail
ERROR: permission denied for table atest5
SELECT b.y FROM (atest5 a FULL JOIN atest5 b(one,x,y,z) USING (one)); -- fail
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT 1 FROM atest5 WHERE two = 2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT * FROM atest1, atest5; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT atest1.* FROM atest1, atest5; -- ok
a | b
---+-----
1 | two
1 | two
(2 rows)
SELECT atest1.*,atest5.one FROM atest1, atest5; -- ok
a | b | one
---+-----+-----
1 | two | 1
1 | two | 1
(2 rows)
SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.two); -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT atest1.*,atest5.one FROM atest1 JOIN atest5 ON (atest1.a = atest5.one); -- ok
a | b | one
---+-----+-----
1 | two | 1
1 | two | 1
(2 rows)
SELECT one, two FROM atest5; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT SELECT (one,two) ON atest6 TO regress_priv_user4;
SET SESSION AUTHORIZATION regress_priv_user4;
2009-01-22 21:16:10 +01:00
SELECT one, two FROM atest5 NATURAL JOIN atest6; -- fail still
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT SELECT (two) ON atest5 TO regress_priv_user4;
SET SESSION AUTHORIZATION regress_priv_user4;
2009-01-22 21:16:10 +01:00
SELECT one, two FROM atest5 NATURAL JOIN atest6; -- ok now
one | two
-----+-----
(0 rows)
-- test column-level privileges for INSERT and UPDATE
INSERT INTO atest5 (two) VALUES (3); -- ok
2009-02-06 22:15:12 +01:00
COPY atest5 FROM stdin; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-02-06 22:15:12 +01:00
COPY atest5 (two) FROM stdin; -- ok
2009-01-22 21:16:10 +01:00
INSERT INTO atest5 (three) VALUES (4); -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
INSERT INTO atest5 VALUES (5,5,5); -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
UPDATE atest5 SET three = 10; -- ok
UPDATE atest5 SET one = 8; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
UPDATE atest5 SET three = 5, one = 2; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative to
raising a unique or exclusion constraint violation error when inserting.
ON CONFLICT refers to constraints that can either be specified using a
inference clause (by specifying the columns of a unique constraint) or
by naming a unique or exclusion constraint. DO NOTHING avoids the
constraint violation, without touching the pre-existing row. DO UPDATE
SET ... [WHERE ...] updates the pre-existing tuple, and has access to
both the tuple proposed for insertion and the existing tuple; the
optional WHERE clause can be used to prevent an update from being
executed. The UPDATE SET and WHERE clauses have access to the tuple
proposed for insertion using the "magic" EXCLUDED alias, and to the
pre-existing tuple using the table name or its alias.
This feature is often referred to as upsert.
This is implemented using a new infrastructure called "speculative
insertion". It is an optimistic variant of regular insertion that first
does a pre-check for existing tuples and then attempts an insert. If a
violating tuple was inserted concurrently, the speculatively inserted
tuple is deleted and a new attempt is made. If the pre-check finds a
matching tuple the alternative DO NOTHING or DO UPDATE action is taken.
If the insertion succeeds without detecting a conflict, the tuple is
deemed inserted.
To handle the possible ambiguity between the excluded alias and a table
named excluded, and for convenience with long relation names, INSERT
INTO now can alias its target table.
Bumps catversion as stored rules change.
Author: Peter Geoghegan, with significant contributions from Heikki
Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.
Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs,
Dean Rasheed, Stephen Frost and many others.
2015-05-08 05:31:36 +02:00
-- Check that column level privs are enforced in RETURNING
-- Ok.
INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10;
-- Error. No SELECT on column three.
INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10 RETURNING atest5.three;
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative to
raising a unique or exclusion constraint violation error when inserting.
ON CONFLICT refers to constraints that can either be specified using a
inference clause (by specifying the columns of a unique constraint) or
by naming a unique or exclusion constraint. DO NOTHING avoids the
constraint violation, without touching the pre-existing row. DO UPDATE
SET ... [WHERE ...] updates the pre-existing tuple, and has access to
both the tuple proposed for insertion and the existing tuple; the
optional WHERE clause can be used to prevent an update from being
executed. The UPDATE SET and WHERE clauses have access to the tuple
proposed for insertion using the "magic" EXCLUDED alias, and to the
pre-existing tuple using the table name or its alias.
This feature is often referred to as upsert.
This is implemented using a new infrastructure called "speculative
insertion". It is an optimistic variant of regular insertion that first
does a pre-check for existing tuples and then attempts an insert. If a
violating tuple was inserted concurrently, the speculatively inserted
tuple is deleted and a new attempt is made. If the pre-check finds a
matching tuple the alternative DO NOTHING or DO UPDATE action is taken.
If the insertion succeeds without detecting a conflict, the tuple is
deemed inserted.
To handle the possible ambiguity between the excluded alias and a table
named excluded, and for convenience with long relation names, INSERT
INTO now can alias its target table.
Bumps catversion as stored rules change.
Author: Peter Geoghegan, with significant contributions from Heikki
Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.
Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs,
Dean Rasheed, Stephen Frost and many others.
2015-05-08 05:31:36 +02:00
-- Ok. May SELECT on column "one":
INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = 10 RETURNING atest5.one;
one
-----
(1 row)
-- Check that column level privileges are enforced for EXCLUDED
-- Ok. we may select one
INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = EXCLUDED.one;
-- Error. No select rights on three
INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set three = EXCLUDED.three;
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative to
raising a unique or exclusion constraint violation error when inserting.
ON CONFLICT refers to constraints that can either be specified using a
inference clause (by specifying the columns of a unique constraint) or
by naming a unique or exclusion constraint. DO NOTHING avoids the
constraint violation, without touching the pre-existing row. DO UPDATE
SET ... [WHERE ...] updates the pre-existing tuple, and has access to
both the tuple proposed for insertion and the existing tuple; the
optional WHERE clause can be used to prevent an update from being
executed. The UPDATE SET and WHERE clauses have access to the tuple
proposed for insertion using the "magic" EXCLUDED alias, and to the
pre-existing tuple using the table name or its alias.
This feature is often referred to as upsert.
This is implemented using a new infrastructure called "speculative
insertion". It is an optimistic variant of regular insertion that first
does a pre-check for existing tuples and then attempts an insert. If a
violating tuple was inserted concurrently, the speculatively inserted
tuple is deleted and a new attempt is made. If the pre-check finds a
matching tuple the alternative DO NOTHING or DO UPDATE action is taken.
If the insertion succeeds without detecting a conflict, the tuple is
deemed inserted.
To handle the possible ambiguity between the excluded alias and a table
named excluded, and for convenience with long relation names, INSERT
INTO now can alias its target table.
Bumps catversion as stored rules change.
Author: Peter Geoghegan, with significant contributions from Heikki
Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.
Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs,
Dean Rasheed, Stephen Frost and many others.
2015-05-08 05:31:36 +02:00
INSERT INTO atest5(two) VALUES (6) ON CONFLICT (two) DO UPDATE set one = 8; -- fails (due to UPDATE)
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
Add support for INSERT ... ON CONFLICT DO NOTHING/UPDATE.
The newly added ON CONFLICT clause allows to specify an alternative to
raising a unique or exclusion constraint violation error when inserting.
ON CONFLICT refers to constraints that can either be specified using a
inference clause (by specifying the columns of a unique constraint) or
by naming a unique or exclusion constraint. DO NOTHING avoids the
constraint violation, without touching the pre-existing row. DO UPDATE
SET ... [WHERE ...] updates the pre-existing tuple, and has access to
both the tuple proposed for insertion and the existing tuple; the
optional WHERE clause can be used to prevent an update from being
executed. The UPDATE SET and WHERE clauses have access to the tuple
proposed for insertion using the "magic" EXCLUDED alias, and to the
pre-existing tuple using the table name or its alias.
This feature is often referred to as upsert.
This is implemented using a new infrastructure called "speculative
insertion". It is an optimistic variant of regular insertion that first
does a pre-check for existing tuples and then attempts an insert. If a
violating tuple was inserted concurrently, the speculatively inserted
tuple is deleted and a new attempt is made. If the pre-check finds a
matching tuple the alternative DO NOTHING or DO UPDATE action is taken.
If the insertion succeeds without detecting a conflict, the tuple is
deemed inserted.
To handle the possible ambiguity between the excluded alias and a table
named excluded, and for convenience with long relation names, INSERT
INTO now can alias its target table.
Bumps catversion as stored rules change.
Author: Peter Geoghegan, with significant contributions from Heikki
Linnakangas and Andres Freund. Testing infrastructure by Jeff Janes.
Reviewed-By: Heikki Linnakangas, Andres Freund, Robert Haas, Simon Riggs,
Dean Rasheed, Stephen Frost and many others.
2015-05-08 05:31:36 +02:00
INSERT INTO atest5(three) VALUES (4) ON CONFLICT (two) DO UPDATE set three = 10; -- fails (due to INSERT)
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2016-08-16 18:00:00 +02:00
-- Check that the columns in the inference require select privileges
2017-11-06 10:19:22 +01:00
INSERT INTO atest5(four) VALUES (4); -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT INSERT (four) ON atest5 TO regress_priv_user4;
SET SESSION AUTHORIZATION regress_priv_user4;
2017-11-06 10:19:22 +01:00
INSERT INTO atest5(four) VALUES (4) ON CONFLICT (four) DO UPDATE set three = 3; -- fails (due to SELECT)
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2017-11-06 10:19:22 +01:00
INSERT INTO atest5(four) VALUES (4) ON CONFLICT ON CONSTRAINT atest5_four_key DO UPDATE set three = 3; -- fails (due to SELECT)
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2017-11-06 10:19:22 +01:00
INSERT INTO atest5(four) VALUES (4); -- ok
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT SELECT (four) ON atest5 TO regress_priv_user4;
SET SESSION AUTHORIZATION regress_priv_user4;
2017-11-06 10:19:22 +01:00
INSERT INTO atest5(four) VALUES (4) ON CONFLICT (four) DO UPDATE set three = 3; -- ok
INSERT INTO atest5(four) VALUES (4) ON CONFLICT ON CONSTRAINT atest5_four_key DO UPDATE set three = 3; -- ok
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
REVOKE ALL (one) ON atest5 FROM regress_priv_user4;
GRANT SELECT (one,two,blue) ON atest6 TO regress_priv_user4;
SET SESSION AUTHORIZATION regress_priv_user4;
2009-01-22 21:16:10 +01:00
SELECT one FROM atest5; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
UPDATE atest5 SET one = 1; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
SELECT atest6 FROM atest6; -- ok
atest6
--------
(0 rows)
2009-02-06 22:15:12 +01:00
COPY atest6 TO stdout; -- ok
2022-03-28 16:45:58 +02:00
-- test column privileges with MERGE
SET SESSION AUTHORIZATION regress_priv_user1;
CREATE TABLE mtarget (a int, b text);
CREATE TABLE msource (a int, b text);
INSERT INTO mtarget VALUES (1, 'init1'), (2, 'init2');
INSERT INTO msource VALUES (1, 'source1'), (2, 'source2'), (3, 'source3');
GRANT SELECT (a) ON msource TO regress_priv_user4;
GRANT SELECT (a) ON mtarget TO regress_priv_user4;
GRANT INSERT (a,b) ON mtarget TO regress_priv_user4;
GRANT UPDATE (b) ON mtarget TO regress_priv_user4;
SET SESSION AUTHORIZATION regress_priv_user4;
--
-- test source privileges
--
-- fail (no SELECT priv on s.b)
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED THEN
UPDATE SET b = s.b
WHEN NOT MATCHED THEN
INSERT VALUES (a, NULL);
ERROR: permission denied for table msource
-- fail (s.b used in the INSERTed values)
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED THEN
UPDATE SET b = 'x'
WHEN NOT MATCHED THEN
INSERT VALUES (a, b);
ERROR: permission denied for table msource
-- fail (s.b used in the WHEN quals)
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED AND s.b = 'x' THEN
UPDATE SET b = 'x'
WHEN NOT MATCHED THEN
INSERT VALUES (a, NULL);
ERROR: permission denied for table msource
-- this should be ok since only s.a is accessed
BEGIN;
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED THEN
UPDATE SET b = 'ok'
WHEN NOT MATCHED THEN
INSERT VALUES (a, NULL);
ROLLBACK;
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT SELECT (b) ON msource TO regress_priv_user4;
SET SESSION AUTHORIZATION regress_priv_user4;
-- should now be ok
BEGIN;
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED THEN
UPDATE SET b = s.b
WHEN NOT MATCHED THEN
INSERT VALUES (a, b);
ROLLBACK;
--
-- test target privileges
--
-- fail (no SELECT priv on t.b)
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED THEN
UPDATE SET b = t.b
WHEN NOT MATCHED THEN
INSERT VALUES (a, NULL);
ERROR: permission denied for table mtarget
-- fail (no UPDATE on t.a)
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED THEN
UPDATE SET b = s.b, a = t.a + 1
WHEN NOT MATCHED THEN
INSERT VALUES (a, b);
ERROR: permission denied for table mtarget
-- fail (no SELECT on t.b)
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED AND t.b IS NOT NULL THEN
UPDATE SET b = s.b
WHEN NOT MATCHED THEN
INSERT VALUES (a, b);
ERROR: permission denied for table mtarget
-- ok
BEGIN;
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED THEN
UPDATE SET b = s.b;
ROLLBACK;
-- fail (no DELETE)
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED AND t.b IS NOT NULL THEN
DELETE;
ERROR: permission denied for table mtarget
-- grant delete privileges
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT DELETE ON mtarget TO regress_priv_user4;
-- should be ok now
BEGIN;
MERGE INTO mtarget t USING msource s ON t.a = s.a
WHEN MATCHED AND t.b IS NOT NULL THEN
DELETE;
ROLLBACK;
Fix column-privilege leak in error-message paths
While building error messages to return to the user,
BuildIndexValueDescription, ExecBuildSlotValueDescription and
ri_ReportViolation would happily include the entire key or entire row in
the result returned to the user, even if the user didn't have access to
view all of the columns being included.
Instead, include only those columns which the user is providing or which
the user has select rights on. If the user does not have any rights
to view the table or any of the columns involved then no detail is
provided and a NULL value is returned from BuildIndexValueDescription
and ExecBuildSlotValueDescription. Note that, for key cases, the user
must have access to all of the columns for the key to be shown; a
partial key will not be returned.
Further, in master only, do not return any data for cases where row
security is enabled on the relation and row security should be applied
for the user. This required a bit of refactoring and moving of things
around related to RLS- note the addition of utils/misc/rls.c.
Back-patch all the way, as column-level privileges are now in all
supported versions.
This has been assigned CVE-2014-8161, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
2015-01-12 23:04:11 +01:00
-- check error reporting with column privs
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
Fix column-privilege leak in error-message paths
While building error messages to return to the user,
BuildIndexValueDescription, ExecBuildSlotValueDescription and
ri_ReportViolation would happily include the entire key or entire row in
the result returned to the user, even if the user didn't have access to
view all of the columns being included.
Instead, include only those columns which the user is providing or which
the user has select rights on. If the user does not have any rights
to view the table or any of the columns involved then no detail is
provided and a NULL value is returned from BuildIndexValueDescription
and ExecBuildSlotValueDescription. Note that, for key cases, the user
must have access to all of the columns for the key to be shown; a
partial key will not be returned.
Further, in master only, do not return any data for cases where row
security is enabled on the relation and row security should be applied
for the user. This required a bit of refactoring and moving of things
around related to RLS- note the addition of utils/misc/rls.c.
Back-patch all the way, as column-level privileges are now in all
supported versions.
This has been assigned CVE-2014-8161, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
2015-01-12 23:04:11 +01:00
CREATE TABLE t1 (c1 int, c2 int, c3 int check (c3 < 5), primary key (c1, c2));
2018-03-15 19:00:31 +01:00
GRANT SELECT (c1) ON t1 TO regress_priv_user2;
GRANT INSERT (c1, c2, c3) ON t1 TO regress_priv_user2;
GRANT UPDATE (c1, c2, c3) ON t1 TO regress_priv_user2;
Fix column-privilege leak in error-message paths
While building error messages to return to the user,
BuildIndexValueDescription, ExecBuildSlotValueDescription and
ri_ReportViolation would happily include the entire key or entire row in
the result returned to the user, even if the user didn't have access to
view all of the columns being included.
Instead, include only those columns which the user is providing or which
the user has select rights on. If the user does not have any rights
to view the table or any of the columns involved then no detail is
provided and a NULL value is returned from BuildIndexValueDescription
and ExecBuildSlotValueDescription. Note that, for key cases, the user
must have access to all of the columns for the key to be shown; a
partial key will not be returned.
Further, in master only, do not return any data for cases where row
security is enabled on the relation and row security should be applied
for the user. This required a bit of refactoring and moving of things
around related to RLS- note the addition of utils/misc/rls.c.
Back-patch all the way, as column-level privileges are now in all
supported versions.
This has been assigned CVE-2014-8161, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
2015-01-12 23:04:11 +01:00
-- seed data
INSERT INTO t1 VALUES (1, 1, 1);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t1 VALUES (2, 1, 2);
INSERT INTO t1 VALUES (2, 2, 2);
INSERT INTO t1 VALUES (3, 1, 3);
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user2;
Fix column-privilege leak in error-message paths
While building error messages to return to the user,
BuildIndexValueDescription, ExecBuildSlotValueDescription and
ri_ReportViolation would happily include the entire key or entire row in
the result returned to the user, even if the user didn't have access to
view all of the columns being included.
Instead, include only those columns which the user is providing or which
the user has select rights on. If the user does not have any rights
to view the table or any of the columns involved then no detail is
provided and a NULL value is returned from BuildIndexValueDescription
and ExecBuildSlotValueDescription. Note that, for key cases, the user
must have access to all of the columns for the key to be shown; a
partial key will not be returned.
Further, in master only, do not return any data for cases where row
security is enabled on the relation and row security should be applied
for the user. This required a bit of refactoring and moving of things
around related to RLS- note the addition of utils/misc/rls.c.
Back-patch all the way, as column-level privileges are now in all
supported versions.
This has been assigned CVE-2014-8161, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
2015-01-12 23:04:11 +01:00
INSERT INTO t1 (c1, c2) VALUES (1, 1); -- fail, but row not shown
ERROR: duplicate key value violates unique constraint "t1_pkey"
UPDATE t1 SET c2 = 1; -- fail, but row not shown
ERROR: duplicate key value violates unique constraint "t1_pkey"
INSERT INTO t1 (c1, c2) VALUES (null, null); -- fail, but see columns being inserted
2020-01-28 03:18:10 +01:00
ERROR: null value in column "c1" of relation "t1" violates not-null constraint
Fix column-privilege leak in error-message paths
While building error messages to return to the user,
BuildIndexValueDescription, ExecBuildSlotValueDescription and
ri_ReportViolation would happily include the entire key or entire row in
the result returned to the user, even if the user didn't have access to
view all of the columns being included.
Instead, include only those columns which the user is providing or which
the user has select rights on. If the user does not have any rights
to view the table or any of the columns involved then no detail is
provided and a NULL value is returned from BuildIndexValueDescription
and ExecBuildSlotValueDescription. Note that, for key cases, the user
must have access to all of the columns for the key to be shown; a
partial key will not be returned.
Further, in master only, do not return any data for cases where row
security is enabled on the relation and row security should be applied
for the user. This required a bit of refactoring and moving of things
around related to RLS- note the addition of utils/misc/rls.c.
Back-patch all the way, as column-level privileges are now in all
supported versions.
This has been assigned CVE-2014-8161, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
2015-01-12 23:04:11 +01:00
DETAIL: Failing row contains (c1, c2) = (null, null).
INSERT INTO t1 (c3) VALUES (null); -- fail, but see columns being inserted or have SELECT
2020-01-28 03:18:10 +01:00
ERROR: null value in column "c1" of relation "t1" violates not-null constraint
Fix column-privilege leak in error-message paths
While building error messages to return to the user,
BuildIndexValueDescription, ExecBuildSlotValueDescription and
ri_ReportViolation would happily include the entire key or entire row in
the result returned to the user, even if the user didn't have access to
view all of the columns being included.
Instead, include only those columns which the user is providing or which
the user has select rights on. If the user does not have any rights
to view the table or any of the columns involved then no detail is
provided and a NULL value is returned from BuildIndexValueDescription
and ExecBuildSlotValueDescription. Note that, for key cases, the user
must have access to all of the columns for the key to be shown; a
partial key will not be returned.
Further, in master only, do not return any data for cases where row
security is enabled on the relation and row security should be applied
for the user. This required a bit of refactoring and moving of things
around related to RLS- note the addition of utils/misc/rls.c.
Back-patch all the way, as column-level privileges are now in all
supported versions.
This has been assigned CVE-2014-8161, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
2015-01-12 23:04:11 +01:00
DETAIL: Failing row contains (c1, c3) = (null, null).
INSERT INTO t1 (c1) VALUES (5); -- fail, but see columns being inserted or have SELECT
2020-01-28 03:18:10 +01:00
ERROR: null value in column "c2" of relation "t1" violates not-null constraint
Fix column-privilege leak in error-message paths
While building error messages to return to the user,
BuildIndexValueDescription, ExecBuildSlotValueDescription and
ri_ReportViolation would happily include the entire key or entire row in
the result returned to the user, even if the user didn't have access to
view all of the columns being included.
Instead, include only those columns which the user is providing or which
the user has select rights on. If the user does not have any rights
to view the table or any of the columns involved then no detail is
provided and a NULL value is returned from BuildIndexValueDescription
and ExecBuildSlotValueDescription. Note that, for key cases, the user
must have access to all of the columns for the key to be shown; a
partial key will not be returned.
Further, in master only, do not return any data for cases where row
security is enabled on the relation and row security should be applied
for the user. This required a bit of refactoring and moving of things
around related to RLS- note the addition of utils/misc/rls.c.
Back-patch all the way, as column-level privileges are now in all
supported versions.
This has been assigned CVE-2014-8161, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
2015-01-12 23:04:11 +01:00
DETAIL: Failing row contains (c1) = (5).
UPDATE t1 SET c3 = 10; -- fail, but see columns with SELECT rights, or being modified
ERROR: new row for relation "t1" violates check constraint "t1_c3_check"
DETAIL: Failing row contains (c1, c3) = (1, 10).
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
Fix column-privilege leak in error-message paths
While building error messages to return to the user,
BuildIndexValueDescription, ExecBuildSlotValueDescription and
ri_ReportViolation would happily include the entire key or entire row in
the result returned to the user, even if the user didn't have access to
view all of the columns being included.
Instead, include only those columns which the user is providing or which
the user has select rights on. If the user does not have any rights
to view the table or any of the columns involved then no detail is
provided and a NULL value is returned from BuildIndexValueDescription
and ExecBuildSlotValueDescription. Note that, for key cases, the user
must have access to all of the columns for the key to be shown; a
partial key will not be returned.
Further, in master only, do not return any data for cases where row
security is enabled on the relation and row security should be applied
for the user. This required a bit of refactoring and moving of things
around related to RLS- note the addition of utils/misc/rls.c.
Back-patch all the way, as column-level privileges are now in all
supported versions.
This has been assigned CVE-2014-8161, but since the issue and the patch
have already been publicized on pgsql-hackers, there's no point in trying
to hide this commit.
2015-01-12 23:04:11 +01:00
DROP TABLE t1;
Fix permission checks on constraint violation errors on partitions.
If a cross-partition UPDATE violates a constraint on the target partition,
and the columns in the new partition are in different physical order than
in the parent, the error message can reveal columns that the user does not
have SELECT permission on. A similar bug was fixed earlier in commit
804b6b6db4.
The cause of the bug is that the callers of the
ExecBuildSlotValueDescription() function got confused when constructing
the list of modified columns. If the tuple was routed from a parent, we
converted the tuple to the parent's format, but the list of modified
columns was grabbed directly from the child's RTE entry.
ExecUpdateLockMode() had a similar issue. That lead to confusion on which
columns are key columns, leading to wrong tuple lock being taken on tables
referenced by foreign keys, when a row is updated with INSERT ON CONFLICT
UPDATE. A new isolation test is added for that corner case.
With this patch, the ri_RangeTableIndex field is no longer set for
partitions that don't have an entry in the range table. Previously, it was
set to the RTE entry of the parent relation, but that was confusing.
NOTE: This modifies the ResultRelInfo struct, replacing the
ri_PartitionRoot field with ri_RootResultRelInfo. That's a bit risky to
backpatch, because it breaks any extensions accessing the field. The
change that ri_RangeTableIndex is not set for partitions could potentially
break extensions, too. The ResultRelInfos are visible to FDWs at least,
and this patch required small changes to postgres_fdw. Nevertheless, this
seem like the least bad option. I don't think these fields widely used in
extensions; I don't think there are FDWs out there that uses the FDW
"direct update" API, other than postgres_fdw. If there is, you will get a
compilation error, so hopefully it is caught quickly.
Backpatch to 11, where support for both cross-partition UPDATEs, and unique
indexes on partitioned tables, were added.
Reviewed-by: Amit Langote
Security: CVE-2021-3393
2021-02-08 10:01:51 +01:00
-- check error reporting with column privs on a partitioned table
CREATE TABLE errtst(a text, b text NOT NULL, c text, secret1 text, secret2 text) PARTITION BY LIST (a);
CREATE TABLE errtst_part_1(secret2 text, c text, a text, b text NOT NULL, secret1 text);
CREATE TABLE errtst_part_2(secret1 text, secret2 text, a text, c text, b text NOT NULL);
ALTER TABLE errtst ATTACH PARTITION errtst_part_1 FOR VALUES IN ('aaa');
ALTER TABLE errtst ATTACH PARTITION errtst_part_2 FOR VALUES IN ('aaaa');
GRANT SELECT (a, b, c) ON TABLE errtst TO regress_priv_user2;
GRANT UPDATE (a, b, c) ON TABLE errtst TO regress_priv_user2;
GRANT INSERT (a, b, c) ON TABLE errtst TO regress_priv_user2;
INSERT INTO errtst_part_1 (a, b, c, secret1, secret2)
VALUES ('aaa', 'bbb', 'ccc', 'the body', 'is in the attic');
SET SESSION AUTHORIZATION regress_priv_user2;
-- Perform a few updates that violate the NOT NULL constraint. Make sure
-- the error messages don't leak the secret fields.
-- simple insert.
INSERT INTO errtst (a, b) VALUES ('aaa', NULL);
ERROR: null value in column "b" of relation "errtst_part_1" violates not-null constraint
DETAIL: Failing row contains (a, b, c) = (aaa, null, null).
-- simple update.
UPDATE errtst SET b = NULL;
ERROR: null value in column "b" of relation "errtst_part_1" violates not-null constraint
Postpone some stuff out of ExecInitModifyTable.
Arrange to do some things on-demand, rather than immediately during
executor startup, because there's a fair chance of never having to do
them at all:
* Don't open result relations' indexes until needed.
* Don't initialize partition tuple routing, nor the child-to-root
tuple conversion map, until needed.
This wins in UPDATEs on partitioned tables when only some of the
partitions will actually receive updates; with larger partition
counts the savings is quite noticeable. Also, we can remove some
sketchy heuristics in ExecInitModifyTable about whether to set up
tuple routing.
Also, remove execPartition.c's private hash table tracking which
partitions were already opened by the ModifyTable node. Instead
use the hash added to ModifyTable itself by commit 86dc90056.
To allow lazy computation of the conversion maps, we now set
ri_RootResultRelInfo in all child ResultRelInfos. We formerly set it
only in some, not terribly well-defined, cases. This has user-visible
side effects in that now more error messages refer to the root
relation instead of some partition (and provide error data in the
root's column order, too). It looks to me like this is a strict
improvement in consistency, so I don't have a problem with the
output changes visible in this commit.
Extracted from a larger patch, which seemed to me to be too messy
to push in one commit.
Amit Langote, reviewed at different times by Heikki Linnakangas and
myself
Discussion: https://postgr.es/m/CA+HiwqG7ZruBmmih3wPsBZ4s0H2EhywrnXEduckY5Hr3fWzPWA@mail.gmail.com
2021-04-06 21:56:55 +02:00
DETAIL: Failing row contains (a, b, c) = (aaa, null, ccc).
Fix permission checks on constraint violation errors on partitions.
If a cross-partition UPDATE violates a constraint on the target partition,
and the columns in the new partition are in different physical order than
in the parent, the error message can reveal columns that the user does not
have SELECT permission on. A similar bug was fixed earlier in commit
804b6b6db4.
The cause of the bug is that the callers of the
ExecBuildSlotValueDescription() function got confused when constructing
the list of modified columns. If the tuple was routed from a parent, we
converted the tuple to the parent's format, but the list of modified
columns was grabbed directly from the child's RTE entry.
ExecUpdateLockMode() had a similar issue. That lead to confusion on which
columns are key columns, leading to wrong tuple lock being taken on tables
referenced by foreign keys, when a row is updated with INSERT ON CONFLICT
UPDATE. A new isolation test is added for that corner case.
With this patch, the ri_RangeTableIndex field is no longer set for
partitions that don't have an entry in the range table. Previously, it was
set to the RTE entry of the parent relation, but that was confusing.
NOTE: This modifies the ResultRelInfo struct, replacing the
ri_PartitionRoot field with ri_RootResultRelInfo. That's a bit risky to
backpatch, because it breaks any extensions accessing the field. The
change that ri_RangeTableIndex is not set for partitions could potentially
break extensions, too. The ResultRelInfos are visible to FDWs at least,
and this patch required small changes to postgres_fdw. Nevertheless, this
seem like the least bad option. I don't think these fields widely used in
extensions; I don't think there are FDWs out there that uses the FDW
"direct update" API, other than postgres_fdw. If there is, you will get a
compilation error, so hopefully it is caught quickly.
Backpatch to 11, where support for both cross-partition UPDATEs, and unique
indexes on partitioned tables, were added.
Reviewed-by: Amit Langote
Security: CVE-2021-3393
2021-02-08 10:01:51 +01:00
-- partitioning key is updated, doesn't move the row.
UPDATE errtst SET a = 'aaa', b = NULL;
ERROR: null value in column "b" of relation "errtst_part_1" violates not-null constraint
DETAIL: Failing row contains (a, b, c) = (aaa, null, ccc).
-- row is moved to another partition.
UPDATE errtst SET a = 'aaaa', b = NULL;
ERROR: null value in column "b" of relation "errtst_part_2" violates not-null constraint
DETAIL: Failing row contains (a, b, c) = (aaaa, null, ccc).
-- row is moved to another partition. This differs from the previous case in
-- that the new partition is excluded by constraint exclusion, so its
-- ResultRelInfo is not created at ExecInitModifyTable, but needs to be
-- constructed on the fly when the updated tuple is routed to it.
UPDATE errtst SET a = 'aaaa', b = NULL WHERE a = 'aaa';
ERROR: null value in column "b" of relation "errtst_part_2" violates not-null constraint
DETAIL: Failing row contains (a, b, c) = (aaaa, null, ccc).
SET SESSION AUTHORIZATION regress_priv_user1;
DROP TABLE errtst;
2009-01-22 21:16:10 +01:00
-- test column-level privileges when involved with DELETE
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
2009-01-22 21:16:10 +01:00
ALTER TABLE atest6 ADD COLUMN three integer;
2018-03-15 19:00:31 +01:00
GRANT DELETE ON atest5 TO regress_priv_user3;
GRANT SELECT (two) ON atest5 TO regress_priv_user3;
REVOKE ALL (one) ON atest5 FROM regress_priv_user3;
GRANT SELECT (one) ON atest5 TO regress_priv_user4;
SET SESSION AUTHORIZATION regress_priv_user4;
2009-01-22 21:16:10 +01:00
SELECT atest6 FROM atest6; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest6
2009-01-22 21:16:10 +01:00
SELECT one FROM atest5 NATURAL JOIN atest6; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
2009-01-22 21:16:10 +01:00
ALTER TABLE atest6 DROP COLUMN three;
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user4;
2009-01-22 21:16:10 +01:00
SELECT atest6 FROM atest6; -- ok
atest6
--------
(0 rows)
SELECT one FROM atest5 NATURAL JOIN atest6; -- ok
one
-----
(0 rows)
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
2009-01-22 21:16:10 +01:00
ALTER TABLE atest6 DROP COLUMN two;
2018-03-15 19:00:31 +01:00
REVOKE SELECT (one,blue) ON atest6 FROM regress_priv_user4;
SET SESSION AUTHORIZATION regress_priv_user4;
2009-01-22 21:16:10 +01:00
SELECT * FROM atest6; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest6
2009-01-22 21:16:10 +01:00
SELECT 1 FROM atest6; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest6
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user3;
2009-01-22 21:16:10 +01:00
DELETE FROM atest5 WHERE one = 1; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest5
2009-01-22 21:16:10 +01:00
DELETE FROM atest5 WHERE two = 2; -- ok
2009-03-05 18:30:29 +01:00
-- check inheritance cases
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
CREATE TABLE atestp1 (f1 int, f2 int);
CREATE TABLE atestp2 (fx int, fy int);
2009-03-05 18:30:29 +01:00
CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2);
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
GRANT SELECT(fx,fy,tableoid) ON atestp2 TO regress_priv_user2;
2018-03-15 19:00:31 +01:00
GRANT SELECT(fx) ON atestc TO regress_priv_user2;
SET SESSION AUTHORIZATION regress_priv_user2;
2009-03-05 18:30:29 +01:00
SELECT fx FROM atestp2; -- ok
fx
----
(0 rows)
2009-10-23 07:24:52 +02:00
SELECT fy FROM atestp2; -- ok
fy
----
(0 rows)
SELECT atestp2 FROM atestp2; -- ok
atestp2
---------
(0 rows)
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
SELECT tableoid FROM atestp2; -- ok
tableoid
----------
2009-10-23 07:24:52 +02:00
(0 rows)
SELECT fy FROM atestc; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atestc
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
GRANT SELECT(fy,tableoid) ON atestc TO regress_priv_user2;
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user2;
2009-03-05 18:30:29 +01:00
SELECT fx FROM atestp2; -- still ok
fx
----
(0 rows)
SELECT fy FROM atestp2; -- ok
fy
----
(0 rows)
SELECT atestp2 FROM atestp2; -- ok
atestp2
---------
(0 rows)
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
SELECT tableoid FROM atestp2; -- ok
tableoid
----------
2009-03-05 18:30:29 +01:00
(0 rows)
2020-01-30 16:42:06 +01:00
-- child's permissions do not apply when operating on parent
SET SESSION AUTHORIZATION regress_priv_user1;
REVOKE ALL ON atestc FROM regress_priv_user2;
GRANT ALL ON atestp1 TO regress_priv_user2;
SET SESSION AUTHORIZATION regress_priv_user2;
SELECT f2 FROM atestp1; -- ok
f2
----
(0 rows)
SELECT f2 FROM atestc; -- fail
ERROR: permission denied for table atestc
DELETE FROM atestp1; -- ok
DELETE FROM atestc; -- fail
ERROR: permission denied for table atestc
UPDATE atestp1 SET f1 = 1; -- ok
UPDATE atestc SET f1 = 1; -- fail
ERROR: permission denied for table atestc
TRUNCATE atestp1; -- ok
TRUNCATE atestc; -- fail
ERROR: permission denied for table atestc
2020-02-18 05:13:15 +01:00
BEGIN;
LOCK atestp1;
END;
BEGIN;
LOCK atestc;
ERROR: permission denied for table atestc
END;
2002-02-19 00:11:58 +01:00
-- privileges on functions, languages
-- switch to superuser
\c -
REVOKE ALL PRIVILEGES ON LANGUAGE sql FROM PUBLIC;
2018-03-15 19:00:31 +01:00
GRANT USAGE ON LANGUAGE sql TO regress_priv_user1; -- ok
2002-02-19 00:11:58 +01:00
GRANT USAGE ON LANGUAGE c TO PUBLIC; -- fail
ERROR: language "c" is not trusted
2016-06-19 01:38:59 +02:00
DETAIL: GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages.
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT USAGE ON LANGUAGE sql TO regress_priv_user2; -- fail
2006-01-21 03:16:21 +01:00
WARNING: no privileges were granted for "sql"
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CREATE FUNCTION priv_testfunc1(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql;
CREATE FUNCTION priv_testfunc2(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE priv_testagg1(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE priv_testproc1(int) AS 'select $1;' LANGUAGE sql;
REVOKE ALL ON FUNCTION priv_testfunc1(int), priv_testfunc2(int), priv_testagg1(int) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION priv_testfunc1(int), priv_testfunc2(int), priv_testagg1(int) TO regress_priv_user2;
REVOKE ALL ON FUNCTION priv_testproc1(int) FROM PUBLIC; -- fail, not a function
ERROR: priv_testproc1(integer) is not a function
REVOKE ALL ON PROCEDURE priv_testproc1(int) FROM PUBLIC;
GRANT EXECUTE ON PROCEDURE priv_testproc1(int) TO regress_priv_user2;
GRANT USAGE ON FUNCTION priv_testfunc1(int) TO regress_priv_user3; -- semantic error
2003-07-21 03:59:11 +02:00
ERROR: invalid privilege type USAGE for function
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
GRANT USAGE ON FUNCTION priv_testagg1(int) TO regress_priv_user3; -- semantic error
2017-11-30 14:46:13 +01:00
ERROR: invalid privilege type USAGE for function
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
GRANT USAGE ON PROCEDURE priv_testproc1(int) TO regress_priv_user3; -- semantic error
2017-11-30 14:46:13 +01:00
ERROR: invalid privilege type USAGE for procedure
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
GRANT ALL PRIVILEGES ON FUNCTION priv_testfunc1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON FUNCTION priv_testfunc_nosuch(int) TO regress_priv_user4;
ERROR: function priv_testfunc_nosuch(integer) does not exist
GRANT ALL PRIVILEGES ON FUNCTION priv_testagg1(int) TO regress_priv_user4;
GRANT ALL PRIVILEGES ON PROCEDURE priv_testproc1(int) TO regress_priv_user4;
CREATE FUNCTION priv_testfunc4(boolean) RETURNS text
2002-05-18 15:48:01 +02:00
AS 'select col1 from atest2 where col2 = $1;'
LANGUAGE sql SECURITY DEFINER;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
GRANT EXECUTE ON FUNCTION priv_testfunc4(boolean) TO regress_priv_user3;
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user2;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT priv_testfunc1(5), priv_testfunc2(5); -- ok
priv_testfunc1 | priv_testfunc2
----------------+----------------
10 | 15
2002-02-19 00:11:58 +01:00
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CREATE FUNCTION priv_testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
2003-08-01 02:15:26 +02:00
ERROR: permission denied for language sql
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
priv_testagg1
---------------
6
2017-11-30 14:46:13 +01:00
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CALL priv_testproc1(6); -- ok
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user3;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT priv_testfunc1(5); -- fail
ERROR: permission denied for function priv_testfunc1
SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- fail
ERROR: permission denied for aggregate priv_testagg1
CALL priv_testproc1(6); -- fail
ERROR: permission denied for procedure priv_testproc1
2002-05-18 15:48:01 +02:00
SELECT col1 FROM atest2 WHERE col2 = true; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest2
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT priv_testfunc4(true); -- ok
priv_testfunc4
----------------
2002-05-18 15:48:01 +02:00
bar
(1 row)
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user4;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT priv_testfunc1(5); -- ok
priv_testfunc1
----------------
10
2002-02-19 00:11:58 +01:00
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT priv_testagg1(x) FROM (VALUES (1), (2), (3)) _(x); -- ok
priv_testagg1
---------------
6
2017-11-30 14:46:13 +01:00
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CALL priv_testproc1(6); -- ok
DROP FUNCTION priv_testfunc1(int); -- fail
ERROR: must be owner of function priv_testfunc1
DROP AGGREGATE priv_testagg1(int); -- fail
ERROR: must be owner of aggregate priv_testagg1
DROP PROCEDURE priv_testproc1(int); -- fail
ERROR: must be owner of procedure priv_testproc1
2002-02-19 00:11:58 +01:00
\c -
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
DROP FUNCTION priv_testfunc1(int); -- ok
2002-02-19 00:11:58 +01:00
-- restore to sanity
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
Faster expression evaluation and targetlist projection.
This replaces the old, recursive tree-walk based evaluation, with
non-recursive, opcode dispatch based, expression evaluation.
Projection is now implemented as part of expression evaluation.
This both leads to significant performance improvements, and makes
future just-in-time compilation of expressions easier.
The speed gains primarily come from:
- non-recursive implementation reduces stack usage / overhead
- simple sub-expressions are implemented with a single jump, without
function calls
- sharing some state between different sub-expressions
- reduced amount of indirect/hard to predict memory accesses by laying
out operation metadata sequentially; including the avoidance of
nearly all of the previously used linked lists
- more code has been moved to expression initialization, avoiding
constant re-checks at evaluation time
Future just-in-time compilation (JIT) has become easier, as
demonstrated by released patches intended to be merged in a later
release, for primarily two reasons: Firstly, due to a stricter split
between expression initialization and evaluation, less code has to be
handled by the JIT. Secondly, due to the non-recursive nature of the
generated "instructions", less performance-critical code-paths can
easily be shared between interpreted and compiled evaluation.
The new framework allows for significant future optimizations. E.g.:
- basic infrastructure for to later reduce the per executor-startup
overhead of expression evaluation, by caching state in prepared
statements. That'd be helpful in OLTPish scenarios where
initialization overhead is measurable.
- optimizing the generated "code". A number of proposals for potential
work has already been made.
- optimizing the interpreter. Similarly a number of proposals have
been made here too.
The move of logic into the expression initialization step leads to some
backward-incompatible changes:
- Function permission checks are now done during expression
initialization, whereas previously they were done during
execution. In edge cases this can lead to errors being raised that
previously wouldn't have been, e.g. a NULL array being coerced to a
different array type previously didn't perform checks.
- The set of domain constraints to be checked, is now evaluated once
during expression initialization, previously it was re-built
every time a domain check was evaluated. For normal queries this
doesn't change much, but e.g. for plpgsql functions, which caches
ExprStates, the old set could stick around longer. The behavior
around might still change.
Author: Andres Freund, with significant changes by Tom Lane,
changes by Heikki Linnakangas
Reviewed-By: Tom Lane, Heikki Linnakangas
Discussion: https://postgr.es/m/20161206034955.bh33paeralxbtluv@alap3.anarazel.de
2017-03-14 23:45:36 +01:00
-- verify privilege checks on array-element coercions
2017-03-12 00:36:50 +01:00
BEGIN;
SELECT '{1}'::int4[]::int8[];
int8
------
{1}
(1 row)
REVOKE ALL ON FUNCTION int8(integer) FROM PUBLIC;
2018-11-02 13:56:16 +01:00
SELECT '{1}'::int4[]::int8[]; --superuser, succeed
2017-03-12 00:36:50 +01:00
int8
------
{1}
(1 row)
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user4;
2017-03-12 00:36:50 +01:00
SELECT '{1}'::int4[]::int8[]; --other user, fail
ERROR: permission denied for function int8
ROLLBACK;
2011-12-19 23:05:19 +01:00
-- privileges on types
-- switch to superuser
\c -
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CREATE TYPE priv_testtype1 AS (a int, b text);
REVOKE USAGE ON TYPE priv_testtype1 FROM PUBLIC;
GRANT USAGE ON TYPE priv_testtype1 TO regress_priv_user2;
GRANT USAGE ON TYPE _priv_testtype1 TO regress_priv_user2; -- fail
2011-12-19 23:05:19 +01:00
ERROR: cannot set privileges of array types
HINT: Set the privileges of the element type instead.
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
GRANT USAGE ON DOMAIN priv_testtype1 TO regress_priv_user2; -- fail
ERROR: "priv_testtype1" is not a domain
CREATE DOMAIN priv_testdomain1 AS int;
REVOKE USAGE on DOMAIN priv_testdomain1 FROM PUBLIC;
GRANT USAGE ON DOMAIN priv_testdomain1 TO regress_priv_user2;
GRANT USAGE ON TYPE priv_testdomain1 TO regress_priv_user2; -- ok
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
2011-12-19 23:05:19 +01:00
-- commands that should fail
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CREATE AGGREGATE priv_testagg1a(priv_testdomain1) (sfunc = int4_sum, stype = bigint);
ERROR: permission denied for type priv_testdomain1
CREATE DOMAIN priv_testdomain2a AS priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
CREATE DOMAIN priv_testdomain3a AS int;
CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3a AS $$ SELECT $1::priv_testdomain3a $$ LANGUAGE SQL;
CREATE CAST (priv_testdomain1 AS priv_testdomain3a) WITH FUNCTION castfunc(int);
ERROR: permission denied for type priv_testdomain1
2011-12-19 23:05:19 +01:00
DROP FUNCTION castfunc(int) CASCADE;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
DROP DOMAIN priv_testdomain3a;
CREATE FUNCTION priv_testfunc5a(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
ERROR: permission denied for type priv_testdomain1
CREATE FUNCTION priv_testfunc6a(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$;
ERROR: permission denied for type priv_testdomain1
CREATE OPERATOR !+! (PROCEDURE = int4pl, LEFTARG = priv_testdomain1, RIGHTARG = priv_testdomain1);
ERROR: permission denied for type priv_testdomain1
CREATE TABLE test5a (a int, b priv_testdomain1);
ERROR: permission denied for type priv_testdomain1
CREATE TABLE test6a OF priv_testtype1;
ERROR: permission denied for type priv_testtype1
CREATE TABLE test10a (a int[], b priv_testtype1[]);
ERROR: permission denied for type priv_testtype1
2011-12-19 23:05:19 +01:00
CREATE TABLE test9a (a int, b int);
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
ALTER TABLE test9a ADD COLUMN c priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
ALTER TABLE test9a ALTER COLUMN b TYPE priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
CREATE TYPE test7a AS (a int, b priv_testdomain1);
ERROR: permission denied for type priv_testdomain1
2011-12-19 23:05:19 +01:00
CREATE TYPE test8a AS (a int, b int);
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
ALTER TYPE test8a ADD ATTRIBUTE c priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
ALTER TYPE test8a ALTER ATTRIBUTE b TYPE priv_testdomain1;
ERROR: permission denied for type priv_testdomain1
CREATE TABLE test11a AS (SELECT 1::priv_testdomain1 AS a);
ERROR: permission denied for type priv_testdomain1
REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC;
ERROR: permission denied for type priv_testtype1
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user2;
2011-12-19 23:05:19 +01:00
-- commands that should succeed
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CREATE AGGREGATE priv_testagg1b(priv_testdomain1) (sfunc = int4_sum, stype = bigint);
CREATE DOMAIN priv_testdomain2b AS priv_testdomain1;
CREATE DOMAIN priv_testdomain3b AS int;
CREATE FUNCTION castfunc(int) RETURNS priv_testdomain3b AS $$ SELECT $1::priv_testdomain3b $$ LANGUAGE SQL;
CREATE CAST (priv_testdomain1 AS priv_testdomain3b) WITH FUNCTION castfunc(int);
2012-04-24 15:20:53 +02:00
WARNING: cast will be ignored because the source data type is a domain
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CREATE FUNCTION priv_testfunc5b(a priv_testdomain1) RETURNS int LANGUAGE SQL AS $$ SELECT $1 $$;
CREATE FUNCTION priv_testfunc6b(b int) RETURNS priv_testdomain1 LANGUAGE SQL AS $$ SELECT $1::priv_testdomain1 $$;
CREATE OPERATOR !! (PROCEDURE = priv_testfunc5b, RIGHTARG = priv_testdomain1);
CREATE TABLE test5b (a int, b priv_testdomain1);
CREATE TABLE test6b OF priv_testtype1;
CREATE TABLE test10b (a int[], b priv_testtype1[]);
2011-12-19 23:05:19 +01:00
CREATE TABLE test9b (a int, b int);
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
ALTER TABLE test9b ADD COLUMN c priv_testdomain1;
ALTER TABLE test9b ALTER COLUMN b TYPE priv_testdomain1;
CREATE TYPE test7b AS (a int, b priv_testdomain1);
2011-12-19 23:05:19 +01:00
CREATE TYPE test8b AS (a int, b int);
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
ALTER TYPE test8b ADD ATTRIBUTE c priv_testdomain1;
ALTER TYPE test8b ALTER ATTRIBUTE b TYPE priv_testdomain1;
CREATE TABLE test11b AS (SELECT 1::priv_testdomain1 AS a);
REVOKE ALL ON TYPE priv_testtype1 FROM PUBLIC;
WARNING: no privileges could be revoked for "priv_testtype1"
2011-12-19 23:05:19 +01:00
\c -
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
DROP AGGREGATE priv_testagg1b(priv_testdomain1);
DROP DOMAIN priv_testdomain2b;
DROP OPERATOR !! (NONE, priv_testdomain1);
DROP FUNCTION priv_testfunc5b(a priv_testdomain1);
DROP FUNCTION priv_testfunc6b(b int);
2011-12-19 23:05:19 +01:00
DROP TABLE test5b;
DROP TABLE test6b;
DROP TABLE test9b;
DROP TABLE test10b;
DROP TYPE test7b;
DROP TYPE test8b;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
DROP CAST (priv_testdomain1 AS priv_testdomain3b);
2011-12-19 23:05:19 +01:00
DROP FUNCTION castfunc(int) CASCADE;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
DROP DOMAIN priv_testdomain3b;
2011-12-19 23:05:19 +01:00
DROP TABLE test11b;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
DROP TYPE priv_testtype1; -- ok
DROP DOMAIN priv_testdomain1; -- ok
2008-09-08 02:47:41 +02:00
-- truncate
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user5;
2008-09-08 02:47:41 +02:00
TRUNCATE atest2; -- ok
TRUNCATE atest3; -- fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table atest3
2001-06-14 03:09:22 +02:00
-- has_table_privilege function
-- bad-input checks
2005-06-28 07:09:14 +02:00
select has_table_privilege(NULL,'pg_authid','select');
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
(1 row)
select has_table_privilege('pg_shad','select');
2003-07-21 03:59:11 +02:00
ERROR: relation "pg_shad" does not exist
2005-06-28 07:09:14 +02:00
select has_table_privilege('nosuchuser','pg_authid','select');
ERROR: role "nosuchuser" does not exist
select has_table_privilege('pg_authid','sel');
2003-07-27 06:53:12 +02:00
ERROR: unrecognized privilege type: "sel"
2005-06-28 07:09:14 +02:00
select has_table_privilege(-999999,'pg_authid','update');
2015-03-07 05:42:38 +01:00
has_table_privilege
---------------------
f
(1 row)
2006-09-05 23:08:36 +02:00
select has_table_privilege(1,'select');
2008-12-15 19:09:41 +01:00
has_table_privilege
---------------------
(1 row)
2001-06-14 03:09:22 +02:00
-- superuser
2002-02-19 00:11:58 +01:00
\c -
2005-06-28 07:09:14 +02:00
select has_table_privilege(current_user,'pg_authid','select');
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2005-06-28 07:09:14 +02:00
select has_table_privilege(current_user,'pg_authid','insert');
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,'pg_authid','update')
from (select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,'pg_authid','delete')
from (select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2006-09-05 23:08:36 +02:00
-- 'rule' privilege no longer exists, but for backwards compatibility
-- has_table_privilege still recognizes the keyword and says FALSE
2001-06-14 03:09:22 +02:00
select has_table_privilege(current_user,t1.oid,'rule')
2005-06-28 07:09:14 +02:00
from (select oid from pg_class where relname = 'pg_authid') as t1;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
2006-09-05 23:08:36 +02:00
f
2001-06-14 03:09:22 +02:00
(1 row)
select has_table_privilege(current_user,t1.oid,'references')
2005-06-28 07:09:14 +02:00
from (select oid from pg_class where relname = 'pg_authid') as t1;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,t1.oid,'select')
2005-06-28 07:09:14 +02:00
from (select oid from pg_class where relname = 'pg_authid') as t1,
2005-08-15 04:40:36 +02:00
(select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,t1.oid,'insert')
2005-06-28 07:09:14 +02:00
from (select oid from pg_class where relname = 'pg_authid') as t1,
2005-08-15 04:40:36 +02:00
(select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2005-06-28 07:09:14 +02:00
select has_table_privilege('pg_authid','update');
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2005-06-28 07:09:14 +02:00
select has_table_privilege('pg_authid','delete');
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2008-09-08 02:47:41 +02:00
select has_table_privilege('pg_authid','truncate');
has_table_privilege
---------------------
t
(1 row)
2001-06-14 03:09:22 +02:00
select has_table_privilege(t1.oid,'select')
2005-06-28 07:09:14 +02:00
from (select oid from pg_class where relname = 'pg_authid') as t1;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
select has_table_privilege(t1.oid,'trigger')
2005-06-28 07:09:14 +02:00
from (select oid from pg_class where relname = 'pg_authid') as t1;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
-- non-superuser
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user3;
2001-06-14 03:09:22 +02:00
select has_table_privilege(current_user,'pg_class','select');
has_table_privilege
---------------------
t
(1 row)
select has_table_privilege(current_user,'pg_class','insert');
has_table_privilege
---------------------
f
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,'pg_class','update')
from (select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
f
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,'pg_class','delete')
from (select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
f
(1 row)
select has_table_privilege(current_user,t1.oid,'references')
from (select oid from pg_class where relname = 'pg_class') as t1;
has_table_privilege
---------------------
f
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,t1.oid,'select')
2001-06-14 03:09:22 +02:00
from (select oid from pg_class where relname = 'pg_class') as t1,
2005-08-15 04:40:36 +02:00
(select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,t1.oid,'insert')
2001-06-14 03:09:22 +02:00
from (select oid from pg_class where relname = 'pg_class') as t1,
2005-08-15 04:40:36 +02:00
(select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
f
(1 row)
select has_table_privilege('pg_class','update');
has_table_privilege
---------------------
f
(1 row)
select has_table_privilege('pg_class','delete');
has_table_privilege
---------------------
f
(1 row)
2008-09-08 02:47:41 +02:00
select has_table_privilege('pg_class','truncate');
has_table_privilege
---------------------
f
(1 row)
2001-06-14 03:09:22 +02:00
select has_table_privilege(t1.oid,'select')
from (select oid from pg_class where relname = 'pg_class') as t1;
has_table_privilege
---------------------
t
(1 row)
select has_table_privilege(t1.oid,'trigger')
from (select oid from pg_class where relname = 'pg_class') as t1;
has_table_privilege
---------------------
f
(1 row)
select has_table_privilege(current_user,'atest1','select');
has_table_privilege
---------------------
t
(1 row)
select has_table_privilege(current_user,'atest1','insert');
has_table_privilege
---------------------
f
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,'atest1','update')
from (select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
f
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,'atest1','delete')
from (select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
f
(1 row)
select has_table_privilege(current_user,t1.oid,'references')
from (select oid from pg_class where relname = 'atest1') as t1;
has_table_privilege
---------------------
f
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,t1.oid,'select')
2001-06-14 03:09:22 +02:00
from (select oid from pg_class where relname = 'atest1') as t1,
2005-08-15 04:40:36 +02:00
(select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
t
(1 row)
2005-08-15 04:40:36 +02:00
select has_table_privilege(t2.oid,t1.oid,'insert')
2001-06-14 03:09:22 +02:00
from (select oid from pg_class where relname = 'atest1') as t1,
2005-08-15 04:40:36 +02:00
(select oid from pg_roles where rolname = current_user) as t2;
2001-06-14 03:09:22 +02:00
has_table_privilege
---------------------
f
(1 row)
select has_table_privilege('atest1','update');
has_table_privilege
---------------------
f
(1 row)
select has_table_privilege('atest1','delete');
has_table_privilege
---------------------
f
(1 row)
2008-09-08 02:47:41 +02:00
select has_table_privilege('atest1','truncate');
has_table_privilege
---------------------
f
(1 row)
2001-06-14 03:09:22 +02:00
select has_table_privilege(t1.oid,'select')
from (select oid from pg_class where relname = 'atest1') as t1;
has_table_privilege
---------------------
t
(1 row)
select has_table_privilege(t1.oid,'trigger')
from (select oid from pg_class where relname = 'atest1') as t1;
has_table_privilege
---------------------
f
(1 row)
Fix corner-case failures in has_foo_privilege() family of functions.
The variants of these functions that take numeric inputs (OIDs or
column numbers) are supposed to return NULL rather than failing
on bad input; this rule reduces problems with snapshot skew when
queries apply the functions to all rows of a catalog.
has_column_privilege() had careless handling of the case where the
table OID didn't exist. You might get something like this:
select has_column_privilege(9999,'nosuchcol','select');
ERROR: column "nosuchcol" of relation "(null)" does not exist
or you might get a crash, depending on the platform's printf's response
to a null string pointer.
In addition, while applying the column-number variant to a dropped
column returned NULL as desired, applying the column-name variant
did not:
select has_column_privilege('mytable','........pg.dropped.2........','select');
ERROR: column "........pg.dropped.2........" of relation "mytable" does not exist
It seems better to make this case return NULL as well.
Also, the OID-accepting variants of has_foreign_data_wrapper_privilege,
has_server_privilege, and has_tablespace_privilege didn't follow the
principle of returning NULL for nonexistent OIDs. Superusers got TRUE,
everybody else got an error.
Per investigation of Jaime Casanova's report of a new crash in HEAD.
These behaviors have been like this for a long time, so back-patch to
all supported branches.
Patch by me; thanks to Stephen Frost for discussion and review
Discussion: https://postgr.es/m/CAJGNTeP=-6Gyqq5TN9OvYEydi7Fv1oGyYj650LGTnW44oAzYCg@mail.gmail.com
2018-10-02 17:54:12 +02:00
-- has_column_privilege function
-- bad-input checks (as non-super-user)
select has_column_privilege('pg_authid',NULL,'select');
has_column_privilege
----------------------
(1 row)
select has_column_privilege('pg_authid','nosuchcol','select');
ERROR: column "nosuchcol" of relation "pg_authid" does not exist
select has_column_privilege(9999,'nosuchcol','select');
has_column_privilege
----------------------
(1 row)
select has_column_privilege(9999,99::int2,'select');
has_column_privilege
----------------------
(1 row)
select has_column_privilege('pg_authid',99::int2,'select');
has_column_privilege
----------------------
(1 row)
select has_column_privilege(9999,99::int2,'select');
has_column_privilege
----------------------
(1 row)
create temp table mytable(f1 int, f2 int, f3 int);
alter table mytable drop column f2;
select has_column_privilege('mytable','f2','select');
ERROR: column "f2" of relation "mytable" does not exist
select has_column_privilege('mytable','........pg.dropped.2........','select');
has_column_privilege
----------------------
(1 row)
select has_column_privilege('mytable',2::int2,'select');
has_column_privilege
----------------------
Fix has_column_privilege function corner case
According to the comments, when an invalid or dropped column oid is passed
to has_column_privilege(), the intention has always been to return NULL.
However, when the caller had table level privilege the invalid/missing
column was never discovered, because table permissions were checked first.
Fix that by introducing extended versions of pg_attribute_acl(check|mask)
and pg_class_acl(check|mask) which take a new argument, is_missing. When
is_missing is NULL, the old behavior is preserved. But when is_missing is
passed by the caller, no ERROR is thrown for dropped or missing
columns/relations, and is_missing is flipped to true. This in turn allows
has_column_privilege to check for column privileges first, providing the
desired semantics.
Not backpatched since it is a user visible behavioral change with no previous
complaints, and the fix is a bit on the invasive side.
Author: Joe Conway
Reviewed-By: Tom Lane
Reported by: Ian Barwick
Discussion: https://postgr.es/m/flat/9b5f4311-157b-4164-7fe7-077b4fe8ed84%40joeconway.com
2021-03-31 19:55:25 +02:00
(1 row)
select has_column_privilege('mytable',99::int2,'select');
has_column_privilege
----------------------
Fix corner-case failures in has_foo_privilege() family of functions.
The variants of these functions that take numeric inputs (OIDs or
column numbers) are supposed to return NULL rather than failing
on bad input; this rule reduces problems with snapshot skew when
queries apply the functions to all rows of a catalog.
has_column_privilege() had careless handling of the case where the
table OID didn't exist. You might get something like this:
select has_column_privilege(9999,'nosuchcol','select');
ERROR: column "nosuchcol" of relation "(null)" does not exist
or you might get a crash, depending on the platform's printf's response
to a null string pointer.
In addition, while applying the column-number variant to a dropped
column returned NULL as desired, applying the column-name variant
did not:
select has_column_privilege('mytable','........pg.dropped.2........','select');
ERROR: column "........pg.dropped.2........" of relation "mytable" does not exist
It seems better to make this case return NULL as well.
Also, the OID-accepting variants of has_foreign_data_wrapper_privilege,
has_server_privilege, and has_tablespace_privilege didn't follow the
principle of returning NULL for nonexistent OIDs. Superusers got TRUE,
everybody else got an error.
Per investigation of Jaime Casanova's report of a new crash in HEAD.
These behaviors have been like this for a long time, so back-patch to
all supported branches.
Patch by me; thanks to Stephen Frost for discussion and review
Discussion: https://postgr.es/m/CAJGNTeP=-6Gyqq5TN9OvYEydi7Fv1oGyYj650LGTnW44oAzYCg@mail.gmail.com
2018-10-02 17:54:12 +02:00
(1 row)
revoke select on table mytable from regress_priv_user3;
select has_column_privilege('mytable',2::int2,'select');
has_column_privilege
----------------------
(1 row)
Fix has_column_privilege function corner case
According to the comments, when an invalid or dropped column oid is passed
to has_column_privilege(), the intention has always been to return NULL.
However, when the caller had table level privilege the invalid/missing
column was never discovered, because table permissions were checked first.
Fix that by introducing extended versions of pg_attribute_acl(check|mask)
and pg_class_acl(check|mask) which take a new argument, is_missing. When
is_missing is NULL, the old behavior is preserved. But when is_missing is
passed by the caller, no ERROR is thrown for dropped or missing
columns/relations, and is_missing is flipped to true. This in turn allows
has_column_privilege to check for column privileges first, providing the
desired semantics.
Not backpatched since it is a user visible behavioral change with no previous
complaints, and the fix is a bit on the invasive side.
Author: Joe Conway
Reviewed-By: Tom Lane
Reported by: Ian Barwick
Discussion: https://postgr.es/m/flat/9b5f4311-157b-4164-7fe7-077b4fe8ed84%40joeconway.com
2021-03-31 19:55:25 +02:00
select has_column_privilege('mytable',99::int2,'select');
has_column_privilege
----------------------
(1 row)
2018-10-16 19:56:58 +02:00
drop table mytable;
2003-01-24 00:39:07 +01:00
-- Grant options
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
2003-01-24 00:39:07 +01:00
CREATE TABLE atest4 (a int);
2018-03-15 19:00:31 +01:00
GRANT SELECT ON atest4 TO regress_priv_user2 WITH GRANT OPTION;
GRANT UPDATE ON atest4 TO regress_priv_user2;
GRANT SELECT ON atest4 TO GROUP regress_priv_group1 WITH GRANT OPTION;
SET SESSION AUTHORIZATION regress_priv_user2;
GRANT SELECT ON atest4 TO regress_priv_user3;
GRANT UPDATE ON atest4 TO regress_priv_user3; -- fail
2006-01-21 03:16:21 +01:00
WARNING: no privileges were granted for "atest4"
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
REVOKE SELECT ON atest4 FROM regress_priv_user3; -- does nothing
SELECT has_table_privilege('regress_priv_user3', 'atest4', 'SELECT'); -- true
2003-01-24 00:39:07 +01:00
has_table_privilege
---------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
REVOKE SELECT ON atest4 FROM regress_priv_user2; -- fail
2003-07-27 06:53:12 +02:00
ERROR: dependent privileges exist
HINT: Use CASCADE to revoke them too.
2018-03-15 19:00:31 +01:00
REVOKE GRANT OPTION FOR SELECT ON atest4 FROM regress_priv_user2 CASCADE; -- ok
SELECT has_table_privilege('regress_priv_user2', 'atest4', 'SELECT'); -- true
2003-01-24 00:39:07 +01:00
has_table_privilege
---------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user3', 'atest4', 'SELECT'); -- false
2003-01-24 00:39:07 +01:00
has_table_privilege
---------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'atest4', 'SELECT WITH GRANT OPTION'); -- true
2003-01-24 00:39:07 +01:00
has_table_privilege
---------------------
t
(1 row)
In security-restricted operations, block enqueue of at-commit user code.
Specifically, this blocks DECLARE ... WITH HOLD and firing of deferred
triggers within index expressions and materialized view queries. An
attacker having permission to create non-temp objects in at least one
schema could execute arbitrary SQL functions under the identity of the
bootstrap superuser. One can work around the vulnerability by disabling
autovacuum and not manually running ANALYZE, CLUSTER, REINDEX, CREATE
INDEX, VACUUM FULL, or REFRESH MATERIALIZED VIEW. (Don't restore from
pg_dump, since it runs some of those commands.) Plain VACUUM (without
FULL) is safe, and all commands are fine when a trusted user owns the
target object. Performance may degrade quickly under this workaround,
however. Back-patch to 9.5 (all supported versions).
Reviewed by Robert Haas. Reported by Etienne Stalmans.
Security: CVE-2020-25695
2020-11-09 16:32:09 +01:00
-- security-restricted operations
\c -
CREATE ROLE regress_sro_user;
2022-05-09 17:35:08 +02:00
-- Check that index expressions and predicates are run as the table's owner
-- A dummy index function checking current_user
CREATE FUNCTION sro_ifun(int) RETURNS int AS $$
BEGIN
-- Below we set the table's owner to regress_sro_user
ASSERT current_user = 'regress_sro_user',
format('sro_ifun(%s) called by %s', $1, current_user);
RETURN $1;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
-- Create a table owned by regress_sro_user
CREATE TABLE sro_tab (a int);
ALTER TABLE sro_tab OWNER TO regress_sro_user;
INSERT INTO sro_tab VALUES (1), (2), (3);
-- Create an expression index with a predicate
CREATE INDEX sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0)))
WHERE sro_ifun(a + 10) > sro_ifun(10);
DROP INDEX sro_idx;
-- Do the same concurrently
CREATE INDEX CONCURRENTLY sro_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0)))
WHERE sro_ifun(a + 10) > sro_ifun(10);
-- REINDEX
REINDEX TABLE sro_tab;
REINDEX INDEX sro_idx;
REINDEX TABLE CONCURRENTLY sro_tab;
DROP INDEX sro_idx;
-- CLUSTER
CREATE INDEX sro_cluster_idx ON sro_tab ((sro_ifun(a) + sro_ifun(0)));
CLUSTER sro_tab USING sro_cluster_idx;
DROP INDEX sro_cluster_idx;
-- BRIN index
CREATE INDEX sro_brin ON sro_tab USING brin ((sro_ifun(a) + sro_ifun(0)));
SELECT brin_desummarize_range('sro_brin', 0);
brin_desummarize_range
------------------------
(1 row)
SELECT brin_summarize_range('sro_brin', 0);
brin_summarize_range
----------------------
1
(1 row)
DROP TABLE sro_tab;
-- Check with a partitioned table
CREATE TABLE sro_ptab (a int) PARTITION BY RANGE (a);
ALTER TABLE sro_ptab OWNER TO regress_sro_user;
CREATE TABLE sro_part PARTITION OF sro_ptab FOR VALUES FROM (1) TO (10);
ALTER TABLE sro_part OWNER TO regress_sro_user;
INSERT INTO sro_ptab VALUES (1), (2), (3);
CREATE INDEX sro_pidx ON sro_ptab ((sro_ifun(a) + sro_ifun(0)))
WHERE sro_ifun(a + 10) > sro_ifun(10);
REINDEX TABLE sro_ptab;
REINDEX INDEX CONCURRENTLY sro_pidx;
In security-restricted operations, block enqueue of at-commit user code.
Specifically, this blocks DECLARE ... WITH HOLD and firing of deferred
triggers within index expressions and materialized view queries. An
attacker having permission to create non-temp objects in at least one
schema could execute arbitrary SQL functions under the identity of the
bootstrap superuser. One can work around the vulnerability by disabling
autovacuum and not manually running ANALYZE, CLUSTER, REINDEX, CREATE
INDEX, VACUUM FULL, or REFRESH MATERIALIZED VIEW. (Don't restore from
pg_dump, since it runs some of those commands.) Plain VACUUM (without
FULL) is safe, and all commands are fine when a trusted user owns the
target object. Performance may degrade quickly under this workaround,
however. Back-patch to 9.5 (all supported versions).
Reviewed by Robert Haas. Reported by Etienne Stalmans.
Security: CVE-2020-25695
2020-11-09 16:32:09 +01:00
SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant() RETURNS void LANGUAGE sql AS
'GRANT regress_priv_group2 TO regress_sro_user';
CREATE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
'DECLARE c CURSOR WITH HOLD FOR SELECT unwanted_grant(); SELECT true';
-- REFRESH of this MV will queue a GRANT at end of transaction
CREATE MATERIALIZED VIEW sro_mv AS SELECT mv_action() WITH NO DATA;
REFRESH MATERIALIZED VIEW sro_mv;
ERROR: cannot create a cursor WITH HOLD within security-restricted operation
CONTEXT: SQL function "mv_action" statement 1
\c -
REFRESH MATERIALIZED VIEW sro_mv;
ERROR: cannot create a cursor WITH HOLD within security-restricted operation
CONTEXT: SQL function "mv_action" statement 1
SET SESSION AUTHORIZATION regress_sro_user;
-- INSERT to this table will queue a GRANT at end of transaction
CREATE TABLE sro_trojan_table ();
CREATE FUNCTION sro_trojan() RETURNS trigger LANGUAGE plpgsql AS
'BEGIN PERFORM unwanted_grant(); RETURN NULL; END';
CREATE CONSTRAINT TRIGGER t AFTER INSERT ON sro_trojan_table
INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE sro_trojan();
-- Now, REFRESH will issue such an INSERT, queueing the GRANT
CREATE OR REPLACE FUNCTION mv_action() RETURNS bool LANGUAGE sql AS
'INSERT INTO sro_trojan_table DEFAULT VALUES; SELECT true';
REFRESH MATERIALIZED VIEW sro_mv;
ERROR: cannot fire deferred trigger within security-restricted operation
CONTEXT: SQL function "mv_action" statement 1
\c -
REFRESH MATERIALIZED VIEW sro_mv;
ERROR: cannot fire deferred trigger within security-restricted operation
CONTEXT: SQL function "mv_action" statement 1
BEGIN; SET CONSTRAINTS ALL IMMEDIATE; REFRESH MATERIALIZED VIEW sro_mv; COMMIT;
ERROR: must have admin option on role "regress_priv_group2"
CONTEXT: SQL function "unwanted_grant" statement 1
SQL statement "SELECT unwanted_grant()"
PL/pgSQL function sro_trojan() line 1 at PERFORM
SQL function "mv_action" statement 1
2022-05-09 17:35:08 +02:00
-- REFRESH MATERIALIZED VIEW CONCURRENTLY use of eval_const_expressions()
SET SESSION AUTHORIZATION regress_sro_user;
CREATE FUNCTION unwanted_grant_nofail(int) RETURNS int
IMMUTABLE LANGUAGE plpgsql AS $$
BEGIN
PERFORM unwanted_grant();
RAISE WARNING 'owned';
RETURN 1;
EXCEPTION WHEN OTHERS THEN
RETURN 2;
END$$;
CREATE MATERIALIZED VIEW sro_index_mv AS SELECT 1 AS c;
CREATE UNIQUE INDEX ON sro_index_mv (c) WHERE unwanted_grant_nofail(1) > 0;
\c -
REFRESH MATERIALIZED VIEW CONCURRENTLY sro_index_mv;
REFRESH MATERIALIZED VIEW sro_index_mv;
In security-restricted operations, block enqueue of at-commit user code.
Specifically, this blocks DECLARE ... WITH HOLD and firing of deferred
triggers within index expressions and materialized view queries. An
attacker having permission to create non-temp objects in at least one
schema could execute arbitrary SQL functions under the identity of the
bootstrap superuser. One can work around the vulnerability by disabling
autovacuum and not manually running ANALYZE, CLUSTER, REINDEX, CREATE
INDEX, VACUUM FULL, or REFRESH MATERIALIZED VIEW. (Don't restore from
pg_dump, since it runs some of those commands.) Plain VACUUM (without
FULL) is safe, and all commands are fine when a trusted user owns the
target object. Performance may degrade quickly under this workaround,
however. Back-patch to 9.5 (all supported versions).
Reviewed by Robert Haas. Reported by Etienne Stalmans.
Security: CVE-2020-25695
2020-11-09 16:32:09 +01:00
DROP OWNED BY regress_sro_user;
DROP ROLE regress_sro_user;
2014-02-17 15:33:31 +01:00
-- Admin options
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user4;
2014-02-17 15:33:31 +01:00
CREATE FUNCTION dogrant_ok() RETURNS void LANGUAGE sql SECURITY DEFINER AS
2018-03-15 19:00:31 +01:00
'GRANT regress_priv_group2 TO regress_priv_user5';
GRANT regress_priv_group2 TO regress_priv_user5; -- ok: had ADMIN OPTION
SET ROLE regress_priv_group2;
GRANT regress_priv_group2 TO regress_priv_user5; -- fails: SET ROLE suspended privilege
ERROR: must have admin option on role "regress_priv_group2"
SET SESSION AUTHORIZATION regress_priv_user1;
GRANT regress_priv_group2 TO regress_priv_user5; -- fails: no ADMIN OPTION
ERROR: must have admin option on role "regress_priv_group2"
2014-02-17 15:33:31 +01:00
SELECT dogrant_ok(); -- ok: SECURITY DEFINER conveys ADMIN
Make role grant system more consistent with other privileges.
Previously, membership of role A in role B could be recorded in the
catalog tables only once. This meant that a new grant of role A to
role B would overwrite the previous grant. For other object types, a
new grant of permission on an object - in this case role A - exists
along side the existing grant provided that the grantor is different.
Either grant can be revoked independently of the other, and
permissions remain so long as at least one grant remains. Make role
grants work similarly.
Previously, when granting membership in a role, the superuser could
specify any role whatsoever as the grantor, but for other object types,
the grantor of record must be either the owner of the object, or a
role that currently has privileges to perform a similar GRANT.
Implement the same scheme for role grants, treating the bootstrap
superuser as the role owner since roles do not have owners. This means
that attempting to revoke a grant, or admin option on a grant, can now
fail if there are dependent privileges, and that CASCADE can be used
to revoke these. It also means that you can't grant ADMIN OPTION on
a role back to a user who granted it directly or indirectly to you,
similar to how you can't give WITH GRANT OPTION on a privilege back
to a role which granted it directly or indirectly to you.
Previously, only the superuser could specify GRANTED BY with a user
other than the current user. Relax that rule to allow the grantor
to be any role whose privileges the current user posseses. This
doesn't improve compatibility with what we do for other object types,
where support for GRANTED BY is entirely vestigial, but it makes this
feature more usable and seems to make sense to change at the same time
we're changing related behaviors.
Along the way, fix "ALTER GROUP group_name ADD USER user_name" to
require the same privileges as "GRANT group_name TO user_name".
Previously, CREATEROLE privileges were sufficient for either, but
only the former form was permissible with ADMIN OPTION on the role.
Now, either CREATEROLE or ADMIN OPTION on the role suffices for
either spelling.
Patch by me, reviewed by Stephen Frost.
Discussion: http://postgr.es/m/CA+TgmoaFr-RZeQ+WoQ5nKPv97oT9+aDgK_a5+qWHSgbDsMp1Vg@mail.gmail.com
2022-08-22 17:35:17 +02:00
NOTICE: role "regress_priv_user5" has already been granted membership in role "regress_priv_group2" by role "regress_priv_user4"
2014-02-17 15:33:31 +01:00
dogrant_ok
------------
(1 row)
2018-03-15 19:00:31 +01:00
SET ROLE regress_priv_group2;
GRANT regress_priv_group2 TO regress_priv_user5; -- fails: SET ROLE did not help
ERROR: must have admin option on role "regress_priv_group2"
SET SESSION AUTHORIZATION regress_priv_group2;
Remove the ability of a role to administer itself.
Commit f9fd1764615ed5d85fab703b0ffb0c323fe7dfd5 effectively gave
every role ADMIN OPTION on itself. However, this appears to be
something that happened accidentally as a result of refactoring
work rather than an intentional decision. Almost a decade later,
it was discovered that this was a security vulnerability. As a
result, commit fea164a72a7bfd50d77ba5fb418d357f8f2bb7d0 restricted
this implicit ADMIN OPTION privilege to be exercisable only when
the role being administered is the same as the session user and
when no security-restricted operation is in progress. That
commit also documented the existence of this implicit privilege
for what seems to be the first time.
The effect of the privilege is to allow a login role to grant
the privileges of that role, and optionally ADMIN OPTION on it,
to some other role. That's an unusual thing to do, because generally
membership is granted in roles used as groups, rather than roles
used as users. Therefore, it does not seem likely that removing
the privilege will break things for many PostgreSQL users.
However, it will make it easier to reason about the permissions
system. This is the only case where a user who has not been given any
special permission (superuser, or ADMIN OPTION on some role) can
modify role membership, so removing it makes things more consistent.
For example, if a superuser sets up role A and B and grants A to B
but no other privileges to anyone, she can now be sure that no one
else will be able to revoke that grant. Without this change, that
would have been true only if A was a non-login role.
Patch by me. Reviewed by Tom Lane and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmoawdt03kbA+dNyBcNWJpRxu0f4X=69Y3+DkXXZqmwMDLg@mail.gmail.com
2022-03-28 19:38:13 +02:00
GRANT regress_priv_group2 TO regress_priv_user5; -- fails: no self-admin
2018-03-15 19:00:31 +01:00
ERROR: must have admin option on role "regress_priv_group2"
SET SESSION AUTHORIZATION regress_priv_user4;
2014-02-17 15:33:31 +01:00
DROP FUNCTION dogrant_ok();
2018-03-15 19:00:31 +01:00
REVOKE regress_priv_group2 FROM regress_priv_user5;
2009-08-03 23:11:40 +02:00
-- has_sequence_privilege tests
\c -
CREATE SEQUENCE x_seq;
2018-03-15 19:00:31 +01:00
GRANT USAGE on x_seq to regress_priv_user2;
SELECT has_sequence_privilege('regress_priv_user1', 'atest1', 'SELECT');
2009-08-03 23:11:40 +02:00
ERROR: "atest1" is not a sequence
2018-03-15 19:00:31 +01:00
SELECT has_sequence_privilege('regress_priv_user1', 'x_seq', 'INSERT');
2009-08-03 23:11:40 +02:00
ERROR: unrecognized privilege type: "INSERT"
2018-03-15 19:00:31 +01:00
SELECT has_sequence_privilege('regress_priv_user1', 'x_seq', 'SELECT');
2009-08-03 23:11:40 +02:00
has_sequence_privilege
------------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user2;
2009-08-03 23:11:40 +02:00
SELECT has_sequence_privilege('x_seq', 'USAGE');
has_sequence_privilege
------------------------
t
(1 row)
2009-12-11 04:34:57 +01:00
-- largeobject privilege tests
\c -
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
2009-12-11 04:34:57 +01:00
SELECT lo_create(1001);
lo_create
-----------
1001
(1 row)
SELECT lo_create(1002);
lo_create
-----------
1002
(1 row)
SELECT lo_create(1003);
lo_create
-----------
1003
(1 row)
SELECT lo_create(1004);
lo_create
-----------
1004
(1 row)
SELECT lo_create(1005);
lo_create
-----------
1005
(1 row)
GRANT ALL ON LARGE OBJECT 1001 TO PUBLIC;
2018-03-15 19:00:31 +01:00
GRANT SELECT ON LARGE OBJECT 1003 TO regress_priv_user2;
GRANT SELECT,UPDATE ON LARGE OBJECT 1004 TO regress_priv_user2;
GRANT ALL ON LARGE OBJECT 1005 TO regress_priv_user2;
GRANT SELECT ON LARGE OBJECT 1005 TO regress_priv_user2 WITH GRANT OPTION;
2009-12-11 04:34:57 +01:00
GRANT SELECT, INSERT ON LARGE OBJECT 1001 TO PUBLIC; -- to be failed
ERROR: invalid privilege type INSERT for large object
GRANT SELECT, UPDATE ON LARGE OBJECT 1001 TO nosuchuser; -- to be failed
ERROR: role "nosuchuser" does not exist
GRANT SELECT, UPDATE ON LARGE OBJECT 999 TO PUBLIC; -- to be failed
ERROR: large object 999 does not exist
\c -
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user2;
2009-12-11 04:34:57 +01:00
SELECT lo_create(2001);
lo_create
-----------
2001
(1 row)
SELECT lo_create(2002);
lo_create
-----------
2002
(1 row)
2017-08-07 16:19:01 +02:00
SELECT loread(lo_open(1001, x'20000'::int), 32); -- allowed, for now
loread
--------
\x
(1 row)
SELECT lowrite(lo_open(1001, x'40000'::int), 'abcd'); -- fail, wrong mode
ERROR: large object descriptor 0 was not opened for writing
2009-12-11 04:34:57 +01:00
SELECT loread(lo_open(1001, x'40000'::int), 32);
loread
--------
\x
(1 row)
SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
ERROR: permission denied for large object 1002
SELECT loread(lo_open(1003, x'40000'::int), 32);
loread
--------
\x
(1 row)
SELECT loread(lo_open(1004, x'40000'::int), 32);
loread
--------
\x
(1 row)
SELECT lowrite(lo_open(1001, x'20000'::int), 'abcd');
lowrite
---------
4
(1 row)
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
ERROR: permission denied for large object 1002
SELECT lowrite(lo_open(1003, x'20000'::int), 'abcd'); -- to be denied
ERROR: permission denied for large object 1003
SELECT lowrite(lo_open(1004, x'20000'::int), 'abcd');
lowrite
---------
4
(1 row)
2018-03-15 19:00:31 +01:00
GRANT SELECT ON LARGE OBJECT 1005 TO regress_priv_user3;
GRANT UPDATE ON LARGE OBJECT 1006 TO regress_priv_user3; -- to be denied
2009-12-11 04:34:57 +01:00
ERROR: large object 1006 does not exist
REVOKE ALL ON LARGE OBJECT 2001, 2002 FROM PUBLIC;
2018-03-15 19:00:31 +01:00
GRANT ALL ON LARGE OBJECT 2001 TO regress_priv_user3;
2009-12-11 04:34:57 +01:00
SELECT lo_unlink(1001); -- to be denied
ERROR: must be owner of large object 1001
SELECT lo_unlink(2002);
lo_unlink
-----------
1
(1 row)
\c -
-- confirm ACL setting
pg_upgrade: Fix large object COMMENTS, SECURITY LABELS
When performing a pg_upgrade, we copy the files behind pg_largeobject
and pg_largeobject_metadata, allowing us to avoid having to dump out and
reload the actual data for large objects and their ACLs.
Unfortunately, that isn't all of the information which can be associated
with large objects. Currently, we also support COMMENTs and SECURITY
LABELs with large objects and these were being silently dropped during a
pg_upgrade as pg_dump would skip everything having to do with a large
object and pg_upgrade only copied the tables mentioned to the new
cluster.
As the file copies happen after the catalog dump and reload, we can't
simply include the COMMENTs and SECURITY LABELs in pg_dump's binary-mode
output but we also have to include the actual large object definition as
well. With the definition, comments, and security labels in the pg_dump
output and the file copies performed by pg_upgrade, all of the data and
metadata associated with large objects is able to be successfully pulled
forward across a pg_upgrade.
In 9.6 and master, we can simply adjust the dump bitmask to indicate
which components we don't want. In 9.5 and earlier, we have to put
explciit checks in in dumpBlob() and dumpBlobs() to not include the ACL
or the data when in binary-upgrade mode.
Adjustments made to the privileges regression test to allow another test
(large_object.sql) to be added which explicitly leaves a large object
with a comment in place to provide coverage of that case with
pg_upgrade.
Back-patch to all supported branches.
Discussion: https://postgr.es/m/20170221162655.GE9812@tamriel.snowman.net
2017-03-06 23:03:57 +01:00
SELECT oid, pg_get_userbyid(lomowner) ownername, lomacl FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
2018-03-15 19:00:31 +01:00
oid | ownername | lomacl
------+--------------------+------------------------------------------------------------------------------------------------------------------------------
1001 | regress_priv_user1 | {regress_priv_user1=rw/regress_priv_user1,=rw/regress_priv_user1}
1002 | regress_priv_user1 |
1003 | regress_priv_user1 | {regress_priv_user1=rw/regress_priv_user1,regress_priv_user2=r/regress_priv_user1}
1004 | regress_priv_user1 | {regress_priv_user1=rw/regress_priv_user1,regress_priv_user2=rw/regress_priv_user1}
1005 | regress_priv_user1 | {regress_priv_user1=rw/regress_priv_user1,regress_priv_user2=r*w/regress_priv_user1,regress_priv_user3=r/regress_priv_user2}
2001 | regress_priv_user2 | {regress_priv_user2=rw/regress_priv_user2,regress_priv_user3=rw/regress_priv_user2}
2009-12-11 04:34:57 +01:00
(6 rows)
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user3;
2009-12-11 04:34:57 +01:00
SELECT loread(lo_open(1001, x'40000'::int), 32);
loread
------------
\x61626364
(1 row)
SELECT loread(lo_open(1003, x'40000'::int), 32); -- to be denied
ERROR: permission denied for large object 1003
SELECT loread(lo_open(1005, x'40000'::int), 32);
loread
--------
\x
(1 row)
SELECT lo_truncate(lo_open(1005, x'20000'::int), 10); -- to be denied
ERROR: permission denied for large object 1005
SELECT lo_truncate(lo_open(2001, x'20000'::int), 10);
lo_truncate
-------------
0
(1 row)
-- compatibility mode in largeobject permission
\c -
SET lo_compat_privileges = false; -- default setting
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user4;
2009-12-11 04:34:57 +01:00
SELECT loread(lo_open(1002, x'40000'::int), 32); -- to be denied
ERROR: permission denied for large object 1002
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd'); -- to be denied
ERROR: permission denied for large object 1002
SELECT lo_truncate(lo_open(1002, x'20000'::int), 10); -- to be denied
ERROR: permission denied for large object 1002
2017-08-07 16:19:01 +02:00
SELECT lo_put(1002, 1, 'abcd'); -- to be denied
ERROR: permission denied for large object 1002
2009-12-11 04:34:57 +01:00
SELECT lo_unlink(1002); -- to be denied
ERROR: must be owner of large object 1002
SELECT lo_export(1001, '/dev/null'); -- to be denied
2017-11-09 18:36:58 +01:00
ERROR: permission denied for function lo_export
SELECT lo_import('/dev/null'); -- to be denied
ERROR: permission denied for function lo_import
SELECT lo_import('/dev/null', 2003); -- to be denied
ERROR: permission denied for function lo_import
2009-12-11 04:34:57 +01:00
\c -
SET lo_compat_privileges = true; -- compatibility mode
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user4;
2009-12-11 04:34:57 +01:00
SELECT loread(lo_open(1002, x'40000'::int), 32);
loread
--------
\x
(1 row)
SELECT lowrite(lo_open(1002, x'20000'::int), 'abcd');
lowrite
---------
4
(1 row)
SELECT lo_truncate(lo_open(1002, x'20000'::int), 10);
lo_truncate
-------------
0
(1 row)
SELECT lo_unlink(1002);
lo_unlink
-----------
1
(1 row)
SELECT lo_export(1001, '/dev/null'); -- to be denied
2017-11-09 18:36:58 +01:00
ERROR: permission denied for function lo_export
2009-12-14 01:39:11 +01:00
-- don't allow unpriv users to access pg_largeobject contents
\c -
SELECT * FROM pg_largeobject LIMIT 0;
loid | pageno | data
------+--------+------
(0 rows)
2018-03-15 19:00:31 +01:00
SET SESSION AUTHORIZATION regress_priv_user1;
2009-12-14 01:39:11 +01:00
SELECT * FROM pg_largeobject LIMIT 0; -- to be denied
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table pg_largeobject
2021-03-26 18:42:17 +01:00
-- test pg_database_owner
RESET SESSION AUTHORIZATION;
GRANT pg_database_owner TO regress_priv_user1;
ERROR: role "pg_database_owner" cannot have explicit members
GRANT regress_priv_user1 TO pg_database_owner;
ERROR: role "pg_database_owner" cannot be a member of any role
CREATE TABLE datdba_only ();
ALTER TABLE datdba_only OWNER TO pg_database_owner;
REVOKE DELETE ON datdba_only FROM pg_database_owner;
SELECT
pg_has_role('regress_priv_user1', 'pg_database_owner', 'USAGE') as priv,
pg_has_role('regress_priv_user1', 'pg_database_owner', 'MEMBER') as mem,
pg_has_role('regress_priv_user1', 'pg_database_owner',
'MEMBER WITH ADMIN OPTION') as admin;
priv | mem | admin
------+-----+-------
f | f | f
(1 row)
BEGIN;
DO $$BEGIN EXECUTE format(
'ALTER DATABASE %I OWNER TO regress_priv_group2', current_catalog); END$$;
SELECT
pg_has_role('regress_priv_user1', 'pg_database_owner', 'USAGE') as priv,
pg_has_role('regress_priv_user1', 'pg_database_owner', 'MEMBER') as mem,
pg_has_role('regress_priv_user1', 'pg_database_owner',
'MEMBER WITH ADMIN OPTION') as admin;
priv | mem | admin
------+-----+-------
t | t | f
(1 row)
SET SESSION AUTHORIZATION regress_priv_user1;
TABLE information_schema.enabled_roles ORDER BY role_name COLLATE "C";
role_name
---------------------
pg_database_owner
regress_priv_group2
regress_priv_user1
(3 rows)
TABLE information_schema.applicable_roles ORDER BY role_name COLLATE "C";
grantee | role_name | is_grantable
---------------------+---------------------+--------------
regress_priv_group2 | pg_database_owner | NO
regress_priv_user1 | regress_priv_group2 | NO
(2 rows)
INSERT INTO datdba_only DEFAULT VALUES;
SAVEPOINT q; DELETE FROM datdba_only; ROLLBACK TO q;
ERROR: permission denied for table datdba_only
SET SESSION AUTHORIZATION regress_priv_user2;
TABLE information_schema.enabled_roles;
role_name
--------------------
regress_priv_user2
(1 row)
INSERT INTO datdba_only DEFAULT VALUES;
ERROR: permission denied for table datdba_only
ROLLBACK;
2009-10-05 21:24:49 +02:00
-- test default ACLs
\c -
CREATE SCHEMA testns;
2018-03-15 19:00:31 +01:00
GRANT ALL ON SCHEMA testns TO regress_priv_user1;
2009-10-05 21:24:49 +02:00
CREATE TABLE testns.acltest1 (x int);
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); -- no
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); -- no
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
f
(1 row)
2021-01-20 03:38:17 +01:00
-- placeholder for test with duplicated schema and role names
ALTER DEFAULT PRIVILEGES IN SCHEMA testns,testns GRANT SELECT ON TABLES TO public,public;
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); -- no
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); -- no
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
f
(1 row)
DROP TABLE testns.acltest1;
CREATE TABLE testns.acltest1 (x int);
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); -- yes
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); -- no
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT INSERT ON TABLES TO regress_priv_user1;
2009-10-05 21:24:49 +02:00
DROP TABLE testns.acltest1;
CREATE TABLE testns.acltest1 (x int);
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); -- yes
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); -- yes
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
ALTER DEFAULT PRIVILEGES IN SCHEMA testns REVOKE INSERT ON TABLES FROM regress_priv_user1;
2009-10-05 21:24:49 +02:00
DROP TABLE testns.acltest1;
CREATE TABLE testns.acltest1 (x int);
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'SELECT'); -- yes
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); -- no
2009-10-05 21:24:49 +02:00
has_table_privilege
---------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE EXECUTE ON FUNCTIONS FROM public;
ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON SCHEMAS TO regress_priv_user2; -- error
2017-03-28 17:58:55 +02:00
ERROR: cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS
2022-07-03 22:49:12 +02:00
-- Test makeaclitem()
SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
'SELECT', TRUE); -- single privilege
makeaclitem
------------------------------------------
regress_priv_user1=r*/regress_priv_user2
(1 row)
SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
'SELECT, INSERT, UPDATE , DELETE ', FALSE); -- multiple privileges
makeaclitem
--------------------------------------------
regress_priv_user1=arwd/regress_priv_user2
(1 row)
SELECT makeaclitem('regress_priv_user1'::regrole, 'regress_priv_user2'::regrole,
'SELECT, fake_privilege', FALSE); -- error
ERROR: unrecognized privilege type: "fake_privilege"
Convert a few more datatype input functions to report errors softly.
Convert assorted internal-ish datatypes, namely aclitemin,
int2vectorin, oidin, oidvectorin, pg_lsn_in, pg_snapshot_in,
and tidin to the new style.
(Some others you might expect to find in this group, such as
cidin and xidin, need no changes because they never throw
errors at all. That seems a little cheesy ... but it is not in
the charter of this patch series to add new error conditions.)
Amul Sul, minor mods by me
Discussion: https://postgr.es/m/CAAJ_b97KeDWUdpTKGOaFYPv0OicjOu6EW+QYWj-Ywrgj_aEy1g@mail.gmail.com
2022-12-14 23:50:24 +01:00
-- Test non-throwing aclitem I/O
SELECT pg_input_is_valid('regress_priv_user1=r/regress_priv_user2', 'aclitem');
pg_input_is_valid
-------------------
t
(1 row)
SELECT pg_input_is_valid('regress_priv_user1=r/', 'aclitem');
pg_input_is_valid
-------------------
f
(1 row)
2023-02-28 00:04:13 +01:00
SELECT * FROM pg_input_error_info('regress_priv_user1=r/', 'aclitem');
message | detail | hint | sql_error_code
---------------------------------+--------+------+----------------
a name must follow the "/" sign | | | 22P02
Convert a few more datatype input functions to report errors softly.
Convert assorted internal-ish datatypes, namely aclitemin,
int2vectorin, oidin, oidvectorin, pg_lsn_in, pg_snapshot_in,
and tidin to the new style.
(Some others you might expect to find in this group, such as
cidin and xidin, need no changes because they never throw
errors at all. That seems a little cheesy ... but it is not in
the charter of this patch series to add new error conditions.)
Amul Sul, minor mods by me
Discussion: https://postgr.es/m/CAAJ_b97KeDWUdpTKGOaFYPv0OicjOu6EW+QYWj-Ywrgj_aEy1g@mail.gmail.com
2022-12-14 23:50:24 +01:00
(1 row)
SELECT pg_input_is_valid('regress_priv_user1=r/regress_no_such_user', 'aclitem');
pg_input_is_valid
-------------------
f
(1 row)
2023-02-28 00:04:13 +01:00
SELECT * FROM pg_input_error_info('regress_priv_user1=r/regress_no_such_user', 'aclitem');
message | detail | hint | sql_error_code
--------------------------------------------+--------+------+----------------
role "regress_no_such_user" does not exist | | | 42704
Convert a few more datatype input functions to report errors softly.
Convert assorted internal-ish datatypes, namely aclitemin,
int2vectorin, oidin, oidvectorin, pg_lsn_in, pg_snapshot_in,
and tidin to the new style.
(Some others you might expect to find in this group, such as
cidin and xidin, need no changes because they never throw
errors at all. That seems a little cheesy ... but it is not in
the charter of this patch series to add new error conditions.)
Amul Sul, minor mods by me
Discussion: https://postgr.es/m/CAAJ_b97KeDWUdpTKGOaFYPv0OicjOu6EW+QYWj-Ywrgj_aEy1g@mail.gmail.com
2022-12-14 23:50:24 +01:00
(1 row)
SELECT pg_input_is_valid('regress_priv_user1=rY', 'aclitem');
pg_input_is_valid
-------------------
f
(1 row)
2023-02-28 00:04:13 +01:00
SELECT * FROM pg_input_error_info('regress_priv_user1=rY', 'aclitem');
message | detail | hint | sql_error_code
----------------------------------------------------------+--------+------+----------------
invalid mode character: must be one of "arwdDxtXUCTcsAm" | | | 22P02
Convert a few more datatype input functions to report errors softly.
Convert assorted internal-ish datatypes, namely aclitemin,
int2vectorin, oidin, oidvectorin, pg_lsn_in, pg_snapshot_in,
and tidin to the new style.
(Some others you might expect to find in this group, such as
cidin and xidin, need no changes because they never throw
errors at all. That seems a little cheesy ... but it is not in
the charter of this patch series to add new error conditions.)
Amul Sul, minor mods by me
Discussion: https://postgr.es/m/CAAJ_b97KeDWUdpTKGOaFYPv0OicjOu6EW+QYWj-Ywrgj_aEy1g@mail.gmail.com
2022-12-14 23:50:24 +01:00
(1 row)
Fix missing role dependencies for some schema and type ACLs.
This patch fixes several related cases in which pg_shdepend entries were
never made, or were lost, for references to roles appearing in the ACLs of
schemas and/or types. While that did no immediate harm, if a referenced
role were later dropped, the drop would be allowed and would leave a
dangling reference in the object's ACL. That still wasn't a big problem
for normal database usage, but it would cause obscure failures in
subsequent dump/reload or pg_upgrade attempts, taking the form of
attempts to grant privileges to all-numeric role names. (I think I've
seen field reports matching that symptom, but can't find any right now.)
Several cases are fixed here:
1. ALTER DOMAIN SET/DROP DEFAULT would lose the dependencies for any
existing ACL entries for the domain. This case is ancient, dating
back as far as we've had pg_shdepend tracking at all.
2. If a default type privilege applies, CREATE TYPE recorded the
ACL properly but forgot to install dependency entries for it.
This dates to the addition of default privileges for types in 9.2.
3. If a default schema privilege applies, CREATE SCHEMA recorded the
ACL properly but forgot to install dependency entries for it.
This dates to the addition of default privileges for schemas in v10
(commit ab89e465c).
Another somewhat-related problem is that when creating a relation
rowtype or implicit array type, TypeCreate would apply any available
default type privileges to that type, which we don't really want
since such an object isn't supposed to have privileges of its own.
(You can't, for example, drop such privileges once they've been added
to an array type.)
ab89e465c is also to blame for a race condition in the regression tests:
privileges.sql transiently installed globally-applicable default
privileges on schemas, which sometimes got absorbed into the ACLs of
schemas created by concurrent test scripts. This should have resulted
in failures when privileges.sql tried to drop the role holding such
privileges; but thanks to the bug fixed here, it instead led to dangling
ACLs in the final state of the regression database. We'd managed not to
notice that, but it became obvious in the wake of commit da906766c, which
allowed the race condition to occur in pg_upgrade tests.
To fix, add a function recordDependencyOnNewAcl to encapsulate what
callers of get_user_default_acl need to do; while the original call
sites got that right via ad-hoc code, none of the later-added ones
have. Also change GenerateTypeDependencies to generate these
dependencies, which requires adding the typacl to its parameter list.
(That might be annoying if there are any extensions calling that
function directly; but if there are, they're most likely buggy in the
same way as the core callers were, so they need work anyway.) While
I was at it, I changed GenerateTypeDependencies to accept most of its
parameters in the form of a Form_pg_type pointer, making its parameter
list a bit less unwieldy and mistake-prone.
The test race condition is fixed just by wrapping the addition and
removal of default privileges into a single transaction, so that that
state is never visible externally. We might eventually prefer to
separate out tests of default privileges into a script that runs by
itself, but that would be a bigger change and would make the tests
run slower overall.
Back-patch relevant parts to all supported branches.
Discussion: https://postgr.es/m/15719.1541725287@sss.pgh.pa.us
2018-11-10 02:42:03 +01:00
--
-- Testing blanket default grants is very hazardous since it might change
-- the privileges attached to objects created by concurrent regression tests.
-- To avoid that, be sure to revoke the privileges again before committing.
--
BEGIN;
2018-03-15 19:00:31 +01:00
ALTER DEFAULT PRIVILEGES GRANT USAGE ON SCHEMAS TO regress_priv_user2;
2017-03-28 17:58:55 +02:00
CREATE SCHEMA testns2;
2018-03-15 19:00:31 +01:00
SELECT has_schema_privilege('regress_priv_user2', 'testns2', 'USAGE'); -- yes
2017-03-28 17:58:55 +02:00
has_schema_privilege
----------------------
t
(1 row)
2021-04-05 19:42:52 +02:00
SELECT has_schema_privilege('regress_priv_user6', 'testns2', 'USAGE'); -- yes
has_schema_privilege
----------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_schema_privilege('regress_priv_user2', 'testns2', 'CREATE'); -- no
2017-03-28 17:58:55 +02:00
has_schema_privilege
----------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
ALTER DEFAULT PRIVILEGES REVOKE USAGE ON SCHEMAS FROM regress_priv_user2;
2017-03-28 17:58:55 +02:00
CREATE SCHEMA testns3;
2018-03-15 19:00:31 +01:00
SELECT has_schema_privilege('regress_priv_user2', 'testns3', 'USAGE'); -- no
2017-03-28 17:58:55 +02:00
has_schema_privilege
----------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_schema_privilege('regress_priv_user2', 'testns3', 'CREATE'); -- no
2017-03-28 17:58:55 +02:00
has_schema_privilege
----------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_priv_user2;
2017-03-28 17:58:55 +02:00
CREATE SCHEMA testns4;
2018-03-15 19:00:31 +01:00
SELECT has_schema_privilege('regress_priv_user2', 'testns4', 'USAGE'); -- yes
2017-03-28 17:58:55 +02:00
has_schema_privilege
----------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_schema_privilege('regress_priv_user2', 'testns4', 'CREATE'); -- yes
2017-03-28 17:58:55 +02:00
has_schema_privilege
----------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
ALTER DEFAULT PRIVILEGES REVOKE ALL ON SCHEMAS FROM regress_priv_user2;
Fix missing role dependencies for some schema and type ACLs.
This patch fixes several related cases in which pg_shdepend entries were
never made, or were lost, for references to roles appearing in the ACLs of
schemas and/or types. While that did no immediate harm, if a referenced
role were later dropped, the drop would be allowed and would leave a
dangling reference in the object's ACL. That still wasn't a big problem
for normal database usage, but it would cause obscure failures in
subsequent dump/reload or pg_upgrade attempts, taking the form of
attempts to grant privileges to all-numeric role names. (I think I've
seen field reports matching that symptom, but can't find any right now.)
Several cases are fixed here:
1. ALTER DOMAIN SET/DROP DEFAULT would lose the dependencies for any
existing ACL entries for the domain. This case is ancient, dating
back as far as we've had pg_shdepend tracking at all.
2. If a default type privilege applies, CREATE TYPE recorded the
ACL properly but forgot to install dependency entries for it.
This dates to the addition of default privileges for types in 9.2.
3. If a default schema privilege applies, CREATE SCHEMA recorded the
ACL properly but forgot to install dependency entries for it.
This dates to the addition of default privileges for schemas in v10
(commit ab89e465c).
Another somewhat-related problem is that when creating a relation
rowtype or implicit array type, TypeCreate would apply any available
default type privileges to that type, which we don't really want
since such an object isn't supposed to have privileges of its own.
(You can't, for example, drop such privileges once they've been added
to an array type.)
ab89e465c is also to blame for a race condition in the regression tests:
privileges.sql transiently installed globally-applicable default
privileges on schemas, which sometimes got absorbed into the ACLs of
schemas created by concurrent test scripts. This should have resulted
in failures when privileges.sql tried to drop the role holding such
privileges; but thanks to the bug fixed here, it instead led to dangling
ACLs in the final state of the regression database. We'd managed not to
notice that, but it became obvious in the wake of commit da906766c, which
allowed the race condition to occur in pg_upgrade tests.
To fix, add a function recordDependencyOnNewAcl to encapsulate what
callers of get_user_default_acl need to do; while the original call
sites got that right via ad-hoc code, none of the later-added ones
have. Also change GenerateTypeDependencies to generate these
dependencies, which requires adding the typacl to its parameter list.
(That might be annoying if there are any extensions calling that
function directly; but if there are, they're most likely buggy in the
same way as the core callers were, so they need work anyway.) While
I was at it, I changed GenerateTypeDependencies to accept most of its
parameters in the form of a Form_pg_type pointer, making its parameter
list a bit less unwieldy and mistake-prone.
The test race condition is fixed just by wrapping the addition and
removal of default privileges into a single transaction, so that that
state is never visible externally. We might eventually prefer to
separate out tests of default privileges into a script that runs by
itself, but that would be a bigger change and would make the tests
run slower overall.
Back-patch relevant parts to all supported branches.
Discussion: https://postgr.es/m/15719.1541725287@sss.pgh.pa.us
2018-11-10 02:42:03 +01:00
COMMIT;
2021-01-20 05:28:10 +01:00
-- Test for DROP OWNED BY with shared dependencies. This is done in a
-- separate, rollbacked, transaction to avoid any trouble with other
-- regression sessions.
BEGIN;
ALTER DEFAULT PRIVILEGES GRANT ALL ON FUNCTIONS TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON SEQUENCES TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON TABLES TO regress_priv_user2;
ALTER DEFAULT PRIVILEGES GRANT ALL ON TYPES TO regress_priv_user2;
SELECT count(*) FROM pg_shdepend
WHERE deptype = 'a' AND
refobjid = 'regress_priv_user2'::regrole AND
classid = 'pg_default_acl'::regclass;
count
-------
5
(1 row)
DROP OWNED BY regress_priv_user2, regress_priv_user2;
SELECT count(*) FROM pg_shdepend
WHERE deptype = 'a' AND
refobjid = 'regress_priv_user2'::regrole AND
classid = 'pg_default_acl'::regclass;
count
-------
0
(1 row)
ROLLBACK;
2017-03-28 17:58:55 +02:00
CREATE SCHEMA testns5;
2018-03-15 19:00:31 +01:00
SELECT has_schema_privilege('regress_priv_user2', 'testns5', 'USAGE'); -- no
2017-03-28 17:58:55 +02:00
has_schema_privilege
----------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_schema_privilege('regress_priv_user2', 'testns5', 'CREATE'); -- no
2017-03-28 17:58:55 +02:00
has_schema_privilege
----------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SET ROLE regress_priv_user1;
2009-10-05 21:24:49 +02:00
CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql;
2017-11-30 14:46:13 +01:00
CREATE AGGREGATE testns.agg1(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE testns.bar() AS 'select 1' LANGUAGE sql;
2018-03-15 19:00:31 +01:00
SELECT has_function_privilege('regress_priv_user2', 'testns.foo()', 'EXECUTE'); -- no
2009-10-05 21:24:49 +02:00
has_function_privilege
------------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_function_privilege('regress_priv_user2', 'testns.agg1(int)', 'EXECUTE'); -- no
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_function_privilege('regress_priv_user2', 'testns.bar()', 'EXECUTE'); -- no
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
f
(1 row)
ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT EXECUTE ON ROUTINES to public;
2009-10-05 21:24:49 +02:00
DROP FUNCTION testns.foo();
CREATE FUNCTION testns.foo() RETURNS int AS 'select 1' LANGUAGE sql;
2017-11-30 14:46:13 +01:00
DROP AGGREGATE testns.agg1(int);
CREATE AGGREGATE testns.agg1(int) (sfunc = int4pl, stype = int4);
DROP PROCEDURE testns.bar();
CREATE PROCEDURE testns.bar() AS 'select 1' LANGUAGE sql;
2018-03-15 19:00:31 +01:00
SELECT has_function_privilege('regress_priv_user2', 'testns.foo()', 'EXECUTE'); -- yes
2009-10-05 21:24:49 +02:00
has_function_privilege
------------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_function_privilege('regress_priv_user2', 'testns.agg1(int)', 'EXECUTE'); -- yes
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_function_privilege('regress_priv_user2', 'testns.bar()', 'EXECUTE'); -- yes (counts as function here)
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
t
(1 row)
2009-10-05 21:24:49 +02:00
DROP FUNCTION testns.foo();
2017-11-30 14:46:13 +01:00
DROP AGGREGATE testns.agg1(int);
DROP PROCEDURE testns.bar();
2018-03-15 19:00:31 +01:00
ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE USAGE ON TYPES FROM public;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CREATE DOMAIN testns.priv_testdomain1 AS int;
SELECT has_type_privilege('regress_priv_user2', 'testns.priv_testdomain1', 'USAGE'); -- no
2011-12-19 23:05:19 +01:00
has_type_privilege
--------------------
f
(1 row)
ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON TYPES to public;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
DROP DOMAIN testns.priv_testdomain1;
CREATE DOMAIN testns.priv_testdomain1 AS int;
SELECT has_type_privilege('regress_priv_user2', 'testns.priv_testdomain1', 'USAGE'); -- yes
2011-12-19 23:05:19 +01:00
has_type_privilege
--------------------
t
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
DROP DOMAIN testns.priv_testdomain1;
2009-10-05 21:24:49 +02:00
RESET ROLE;
SELECT count(*)
FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
WHERE nspname = 'testns';
count
-------
2011-12-19 23:05:19 +01:00
3
2009-10-05 21:24:49 +02:00
(1 row)
DROP SCHEMA testns CASCADE;
NOTICE: drop cascades to table testns.acltest1
2017-03-28 17:58:55 +02:00
DROP SCHEMA testns2 CASCADE;
DROP SCHEMA testns3 CASCADE;
DROP SCHEMA testns4 CASCADE;
DROP SCHEMA testns5 CASCADE;
2009-10-05 21:24:49 +02:00
SELECT d.* -- check that entries went away
FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
WHERE nspname IS NULL AND defaclnamespace != 0;
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
oid | defaclrole | defaclnamespace | defaclobjtype | defaclacl
-----+------------+-----------------+---------------+-----------
2009-10-05 21:24:49 +02:00
(0 rows)
2009-10-12 22:39:42 +02:00
-- Grant on all objects of given type in a schema
\c -
CREATE SCHEMA testns;
CREATE TABLE testns.t1 (f1 int);
CREATE TABLE testns.t2 (f1 int);
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.t1', 'SELECT'); -- false
2009-10-12 22:39:42 +02:00
has_table_privilege
---------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
GRANT ALL ON ALL TABLES IN SCHEMA testns TO regress_priv_user1;
SELECT has_table_privilege('regress_priv_user1', 'testns.t1', 'SELECT'); -- true
2009-10-12 22:39:42 +02:00
has_table_privilege
---------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.t2', 'SELECT'); -- true
2009-10-12 22:39:42 +02:00
has_table_privilege
---------------------
t
(1 row)
2018-03-15 19:00:31 +01:00
REVOKE ALL ON ALL TABLES IN SCHEMA testns FROM regress_priv_user1;
SELECT has_table_privilege('regress_priv_user1', 'testns.t1', 'SELECT'); -- false
2009-10-12 22:39:42 +02:00
has_table_privilege
---------------------
f
(1 row)
2018-03-15 19:00:31 +01:00
SELECT has_table_privilege('regress_priv_user1', 'testns.t2', 'SELECT'); -- false
2009-10-12 22:39:42 +02:00
has_table_privilege
---------------------
f
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
CREATE FUNCTION testns.priv_testfunc(int) RETURNS int AS 'select 3 * $1;' LANGUAGE sql;
CREATE AGGREGATE testns.priv_testagg(int) (sfunc = int4pl, stype = int4);
CREATE PROCEDURE testns.priv_testproc(int) AS 'select 3' LANGUAGE sql;
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); -- true by default
2009-10-12 22:39:42 +02:00
has_function_privilege
------------------------
t
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- true by default
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
t
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- true by default
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
t
(1 row)
2009-10-12 22:39:42 +02:00
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA testns FROM PUBLIC;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); -- false
2009-10-12 22:39:42 +02:00
has_function_privilege
------------------------
f
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- false
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
f
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- still true, not a function
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
t
(1 row)
REVOKE ALL ON ALL PROCEDURES IN SCHEMA testns FROM PUBLIC;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- now false
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
f
(1 row)
GRANT ALL ON ALL ROUTINES IN SCHEMA testns TO PUBLIC;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', 'EXECUTE'); -- true
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
t
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- true
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
t
(1 row)
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- true
2017-11-30 14:46:13 +01:00
has_function_privilege
------------------------
t
(1 row)
2009-10-12 22:39:42 +02:00
DROP SCHEMA testns CASCADE;
2017-11-30 14:46:13 +01:00
NOTICE: drop cascades to 5 other objects
2019-03-25 00:15:37 +01:00
DETAIL: drop cascades to table testns.t1
drop cascades to table testns.t2
drop cascades to function testns.priv_testfunc(integer)
drop cascades to function testns.priv_testagg(integer)
drop cascades to function testns.priv_testproc(integer)
2013-12-11 21:45:15 +01:00
-- Change owner of the schema & and rename of new schema owner
\c -
2016-07-18 00:42:31 +02:00
CREATE ROLE regress_schemauser1 superuser login;
CREATE ROLE regress_schemauser2 superuser login;
SET SESSION ROLE regress_schemauser1;
2013-12-11 21:45:15 +01:00
CREATE SCHEMA testns;
SELECT nspname, rolname FROM pg_namespace, pg_roles WHERE pg_namespace.nspname = 'testns' AND pg_namespace.nspowner = pg_roles.oid;
2016-07-18 00:42:31 +02:00
nspname | rolname
---------+---------------------
testns | regress_schemauser1
2013-12-11 21:45:15 +01:00
(1 row)
2016-07-18 00:42:31 +02:00
ALTER SCHEMA testns OWNER TO regress_schemauser2;
ALTER ROLE regress_schemauser2 RENAME TO regress_schemauser_renamed;
2013-12-11 21:45:15 +01:00
SELECT nspname, rolname FROM pg_namespace, pg_roles WHERE pg_namespace.nspname = 'testns' AND pg_namespace.nspowner = pg_roles.oid;
2016-07-18 00:42:31 +02:00
nspname | rolname
---------+----------------------------
testns | regress_schemauser_renamed
2013-12-11 21:45:15 +01:00
(1 row)
2016-07-18 00:42:31 +02:00
set session role regress_schemauser_renamed;
2013-12-11 21:45:15 +01:00
DROP SCHEMA testns CASCADE;
-- clean up
\c -
2016-07-18 00:42:31 +02:00
DROP ROLE regress_schemauser1;
DROP ROLE regress_schemauser_renamed;
2012-08-23 23:25:10 +02:00
-- test that dependent privileges are revoked (or not) properly
\c -
2018-03-15 19:00:31 +01:00
set session role regress_priv_user1;
2012-08-23 23:25:10 +02:00
create table dep_priv_test (a int);
2018-03-15 19:00:31 +01:00
grant select on dep_priv_test to regress_priv_user2 with grant option;
grant select on dep_priv_test to regress_priv_user3 with grant option;
set session role regress_priv_user2;
grant select on dep_priv_test to regress_priv_user4 with grant option;
set session role regress_priv_user3;
grant select on dep_priv_test to regress_priv_user4 with grant option;
set session role regress_priv_user4;
grant select on dep_priv_test to regress_priv_user5;
2012-08-23 23:25:10 +02:00
\dp dep_priv_test
2022-12-14 02:33:28 +01:00
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+---------------+-------+------------------------------------------------+-------------------+----------
public | dep_priv_test | table | regress_priv_user1=arwdDxtm/regress_priv_user1+| |
| | | regress_priv_user2=r*/regress_priv_user1 +| |
| | | regress_priv_user3=r*/regress_priv_user1 +| |
| | | regress_priv_user4=r*/regress_priv_user2 +| |
| | | regress_priv_user4=r*/regress_priv_user3 +| |
| | | regress_priv_user5=r/regress_priv_user4 | |
2018-03-15 19:00:31 +01:00
(1 row)
set session role regress_priv_user2;
revoke select on dep_priv_test from regress_priv_user4 cascade;
2012-08-23 23:25:10 +02:00
\dp dep_priv_test
2022-12-14 02:33:28 +01:00
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+---------------+-------+------------------------------------------------+-------------------+----------
public | dep_priv_test | table | regress_priv_user1=arwdDxtm/regress_priv_user1+| |
| | | regress_priv_user2=r*/regress_priv_user1 +| |
| | | regress_priv_user3=r*/regress_priv_user1 +| |
| | | regress_priv_user4=r*/regress_priv_user3 +| |
| | | regress_priv_user5=r/regress_priv_user4 | |
2018-03-15 19:00:31 +01:00
(1 row)
set session role regress_priv_user3;
revoke select on dep_priv_test from regress_priv_user4 cascade;
2012-08-23 23:25:10 +02:00
\dp dep_priv_test
2022-12-14 02:33:28 +01:00
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+---------------+-------+------------------------------------------------+-------------------+----------
public | dep_priv_test | table | regress_priv_user1=arwdDxtm/regress_priv_user1+| |
| | | regress_priv_user2=r*/regress_priv_user1 +| |
| | | regress_priv_user3=r*/regress_priv_user1 | |
2012-08-23 23:25:10 +02:00
(1 row)
2018-03-15 19:00:31 +01:00
set session role regress_priv_user1;
2012-08-23 23:25:10 +02:00
drop table dep_priv_test;
2001-05-27 11:59:30 +02:00
-- clean up
2008-07-03 18:01:10 +02:00
\c
2009-08-03 23:11:40 +02:00
drop sequence x_seq;
Clean up duplicate table and function names in regression tests.
Many of the objects we create during the regression tests are put in the
public schema, so that using the same names in different regression tests
creates a hazard of test failures if any two such scripts run concurrently.
This patch cleans up a bunch of latent hazards of that sort, as well as two
live hazards.
The current situation in this regard is far worse than it was a year or two
back, because practically all of the partitioning-related test cases have
reused table names with enthusiasm. I despaired of cleaning up that mess
within the five most-affected tests (create_table, alter_table, insert,
update, inherit); fortunately those don't run concurrently.
Other than partitioning problems, most of the issues boil down to using
names like "foo", "bar", "tmp", etc, without thought for the fact that
other test scripts might use similar names concurrently. I've made an
effort to make all such names more specific.
One of the live hazards was that commit 7421f4b8 caused with.sql to
create a table named "test", conflicting with a similarly-named table
in alter_table.sql; this was exposed in the buildfarm recently.
The other one was that join.sql and transactions.sql both create tables
named "foo" and "bar"; but join.sql's uses of those names date back
only to December or so.
Since commit 7421f4b8 was back-patched to v10, back-patch a minimal
fix for that problem. The rest of this is just future-proofing.
Discussion: https://postgr.es/m/4627.1521070268@sss.pgh.pa.us
2018-03-15 22:08:51 +01:00
DROP AGGREGATE priv_testagg1(int);
DROP FUNCTION priv_testfunc2(int);
DROP FUNCTION priv_testfunc4(boolean);
DROP PROCEDURE priv_testproc1(int);
2013-05-02 00:26:50 +02:00
DROP VIEW atestv0;
2001-05-27 11:59:30 +02:00
DROP VIEW atestv1;
DROP VIEW atestv2;
2002-07-16 07:53:34 +02:00
-- this should cascade to drop atestv4
DROP VIEW atestv3 CASCADE;
2003-07-21 03:59:11 +02:00
NOTICE: drop cascades to view atestv4
2002-07-16 07:53:34 +02:00
-- this should complain "does not exist"
2002-05-19 17:13:20 +02:00
DROP VIEW atestv4;
2002-07-16 07:53:34 +02:00
ERROR: view "atestv4" does not exist
DROP TABLE atest1;
DROP TABLE atest2;
DROP TABLE atest3;
2003-01-24 00:39:07 +01:00
DROP TABLE atest4;
2009-01-22 21:16:10 +01:00
DROP TABLE atest5;
DROP TABLE atest6;
2009-03-05 18:30:29 +01:00
DROP TABLE atestc;
DROP TABLE atestp1;
DROP TABLE atestp2;
pg_upgrade: Fix large object COMMENTS, SECURITY LABELS
When performing a pg_upgrade, we copy the files behind pg_largeobject
and pg_largeobject_metadata, allowing us to avoid having to dump out and
reload the actual data for large objects and their ACLs.
Unfortunately, that isn't all of the information which can be associated
with large objects. Currently, we also support COMMENTs and SECURITY
LABELs with large objects and these were being silently dropped during a
pg_upgrade as pg_dump would skip everything having to do with a large
object and pg_upgrade only copied the tables mentioned to the new
cluster.
As the file copies happen after the catalog dump and reload, we can't
simply include the COMMENTs and SECURITY LABELs in pg_dump's binary-mode
output but we also have to include the actual large object definition as
well. With the definition, comments, and security labels in the pg_dump
output and the file copies performed by pg_upgrade, all of the data and
metadata associated with large objects is able to be successfully pulled
forward across a pg_upgrade.
In 9.6 and master, we can simply adjust the dump bitmask to indicate
which components we don't want. In 9.5 and earlier, we have to put
explciit checks in in dumpBlob() and dumpBlobs() to not include the ACL
or the data when in binary-upgrade mode.
Adjustments made to the privileges regression test to allow another test
(large_object.sql) to be added which explicitly leaves a large object
with a comment in place to provide coverage of that case with
pg_upgrade.
Back-patch to all supported branches.
Discussion: https://postgr.es/m/20170221162655.GE9812@tamriel.snowman.net
2017-03-06 23:03:57 +01:00
SELECT lo_unlink(oid) FROM pg_largeobject_metadata WHERE oid >= 1000 AND oid < 3000 ORDER BY oid;
2009-12-11 04:34:57 +01:00
lo_unlink
-----------
1
1
1
1
1
(5 rows)
2018-03-15 19:00:31 +01:00
DROP GROUP regress_priv_group1;
DROP GROUP regress_priv_group2;
2009-10-05 21:24:49 +02:00
-- these are needed to clean up permissions
2018-03-15 19:00:31 +01:00
REVOKE USAGE ON LANGUAGE sql FROM regress_priv_user1;
DROP OWNED BY regress_priv_user1;
DROP USER regress_priv_user1;
DROP USER regress_priv_user2;
DROP USER regress_priv_user3;
DROP USER regress_priv_user4;
DROP USER regress_priv_user5;
DROP USER regress_priv_user6;
2021-04-05 19:42:52 +02:00
DROP USER regress_priv_user7;
DROP USER regress_priv_user8; -- does not exist
ERROR: role "regress_priv_user8" does not exist
2015-07-07 23:35:35 +02:00
-- permissions with LOCK TABLE
2016-07-18 00:42:31 +02:00
CREATE USER regress_locktable_user;
2015-07-07 23:35:35 +02:00
CREATE TABLE lock_table (a int);
-- LOCK TABLE and SELECT permission
2016-07-18 00:42:31 +02:00
GRANT SELECT ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
2015-07-07 23:35:35 +02:00
BEGIN;
2023-01-13 23:14:54 +01:00
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
COMMIT;
BEGIN;
2015-07-07 23:35:35 +02:00
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table lock_table
2015-07-07 23:35:35 +02:00
ROLLBACK;
BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table lock_table
2015-07-07 23:35:35 +02:00
ROLLBACK;
\c
2016-07-18 00:42:31 +02:00
REVOKE SELECT ON lock_table FROM regress_locktable_user;
2015-07-07 23:35:35 +02:00
-- LOCK TABLE and INSERT permission
2016-07-18 00:42:31 +02:00
GRANT INSERT ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
2015-07-07 23:35:35 +02:00
BEGIN;
2023-01-13 23:14:54 +01:00
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
ROLLBACK;
BEGIN;
2015-07-07 23:35:35 +02:00
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
2017-12-02 15:26:34 +01:00
ERROR: permission denied for table lock_table
2015-07-07 23:35:35 +02:00
ROLLBACK;
\c
2016-07-18 00:42:31 +02:00
REVOKE INSERT ON lock_table FROM regress_locktable_user;
2015-07-07 23:35:35 +02:00
-- LOCK TABLE and UPDATE permission
2016-07-18 00:42:31 +02:00
GRANT UPDATE ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
2015-07-07 23:35:35 +02:00
BEGIN;
2023-01-13 23:14:54 +01:00
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
ROLLBACK;
BEGIN;
2015-07-07 23:35:35 +02:00
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
2016-07-18 00:42:31 +02:00
REVOKE UPDATE ON lock_table FROM regress_locktable_user;
2015-07-07 23:35:35 +02:00
-- LOCK TABLE and DELETE permission
2016-07-18 00:42:31 +02:00
GRANT DELETE ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
2015-07-07 23:35:35 +02:00
BEGIN;
2023-01-13 23:14:54 +01:00
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
ROLLBACK;
BEGIN;
2015-07-07 23:35:35 +02:00
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
2016-07-18 00:42:31 +02:00
REVOKE DELETE ON lock_table FROM regress_locktable_user;
2015-07-07 23:35:35 +02:00
-- LOCK TABLE and TRUNCATE permission
2016-07-18 00:42:31 +02:00
GRANT TRUNCATE ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
2015-07-07 23:35:35 +02:00
BEGIN;
2023-01-13 23:14:54 +01:00
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
ROLLBACK;
BEGIN;
2015-07-07 23:35:35 +02:00
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
2023-01-13 23:14:54 +01:00
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
REVOKE TRUNCATE ON lock_table FROM regress_locktable_user;
-- LOCK TABLE and MAINTAIN permission
GRANT MAINTAIN ON lock_table TO regress_locktable_user;
SET SESSION AUTHORIZATION regress_locktable_user;
BEGIN;
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
2015-07-07 23:35:35 +02:00
ROLLBACK;
BEGIN;
2023-01-13 23:14:54 +01:00
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
COMMIT;
BEGIN;
2015-07-07 23:35:35 +02:00
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
COMMIT;
\c
2023-01-13 23:14:54 +01:00
REVOKE MAINTAIN ON lock_table FROM regress_locktable_user;
2015-07-07 23:35:35 +02:00
-- clean up
DROP TABLE lock_table;
2016-07-18 00:42:31 +02:00
DROP USER regress_locktable_user;
2021-10-27 21:37:09 +02:00
-- test to check privileges of system views pg_shmem_allocations and
-- pg_backend_memory_contexts.
-- switch to superuser
\c -
CREATE ROLE regress_readallstats;
SELECT has_table_privilege('regress_readallstats','pg_backend_memory_contexts','SELECT'); -- no
has_table_privilege
---------------------
f
(1 row)
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations','SELECT'); -- no
has_table_privilege
---------------------
f
(1 row)
GRANT pg_read_all_stats TO regress_readallstats;
SELECT has_table_privilege('regress_readallstats','pg_backend_memory_contexts','SELECT'); -- yes
has_table_privilege
---------------------
t
(1 row)
SELECT has_table_privilege('regress_readallstats','pg_shmem_allocations','SELECT'); -- yes
has_table_privilege
---------------------
t
(1 row)
-- run query to ensure that functions within views can be executed
SET ROLE regress_readallstats;
SELECT COUNT(*) >= 0 AS ok FROM pg_backend_memory_contexts;
ok
----
t
(1 row)
SELECT COUNT(*) >= 0 AS ok FROM pg_shmem_allocations;
ok
----
t
(1 row)
RESET ROLE;
-- clean up
DROP ROLE regress_readallstats;
2022-08-30 14:32:35 +02:00
-- test role grantor machinery
CREATE ROLE regress_group;
CREATE ROLE regress_group_direct_manager;
CREATE ROLE regress_group_indirect_manager;
CREATE ROLE regress_group_member;
GRANT regress_group TO regress_group_direct_manager WITH INHERIT FALSE, ADMIN TRUE;
GRANT regress_group_direct_manager TO regress_group_indirect_manager;
SET SESSION AUTHORIZATION regress_group_direct_manager;
GRANT regress_group TO regress_group_member;
SELECT member::regrole::text, CASE WHEN grantor = 10 THEN 'BOOTSTRAP SUPERUSER' ELSE grantor::regrole::text END FROM pg_auth_members WHERE roleid = 'regress_group'::regrole ORDER BY 1, 2;
member | grantor
------------------------------+------------------------------
regress_group_direct_manager | BOOTSTRAP SUPERUSER
regress_group_member | regress_group_direct_manager
(2 rows)
REVOKE regress_group FROM regress_group_member;
SET SESSION AUTHORIZATION regress_group_indirect_manager;
GRANT regress_group TO regress_group_member;
SELECT member::regrole::text, CASE WHEN grantor = 10 THEN 'BOOTSTRAP SUPERUSER' ELSE grantor::regrole::text END FROM pg_auth_members WHERE roleid = 'regress_group'::regrole ORDER BY 1, 2;
member | grantor
------------------------------+------------------------------
regress_group_direct_manager | BOOTSTRAP SUPERUSER
regress_group_member | regress_group_direct_manager
(2 rows)
REVOKE regress_group FROM regress_group_member;
RESET SESSION AUTHORIZATION;
DROP ROLE regress_group;
DROP ROLE regress_group_direct_manager;
DROP ROLE regress_group_indirect_manager;
DROP ROLE regress_group_member;
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
-- test SET and INHERIT options with object ownership changes
CREATE ROLE regress_roleoption_protagonist;
CREATE ROLE regress_roleoption_donor;
CREATE ROLE regress_roleoption_recipient;
CREATE SCHEMA regress_roleoption;
GRANT CREATE, USAGE ON SCHEMA regress_roleoption TO PUBLIC;
GRANT regress_roleoption_donor TO regress_roleoption_protagonist WITH INHERIT TRUE, SET FALSE;
GRANT regress_roleoption_recipient TO regress_roleoption_protagonist WITH INHERIT FALSE, SET TRUE;
SET SESSION AUTHORIZATION regress_roleoption_protagonist;
CREATE TABLE regress_roleoption.t1 (a int);
CREATE TABLE regress_roleoption.t2 (a int);
SET SESSION AUTHORIZATION regress_roleoption_donor;
CREATE TABLE regress_roleoption.t3 (a int);
SET SESSION AUTHORIZATION regress_roleoption_recipient;
CREATE TABLE regress_roleoption.t4 (a int);
SET SESSION AUTHORIZATION regress_roleoption_protagonist;
ALTER TABLE regress_roleoption.t1 OWNER TO regress_roleoption_donor; -- fails, can't be come donor
ERROR: must be able to SET ROLE "regress_roleoption_donor"
ALTER TABLE regress_roleoption.t2 OWNER TO regress_roleoption_recipient; -- works
ALTER TABLE regress_roleoption.t3 OWNER TO regress_roleoption_protagonist; -- works
ALTER TABLE regress_roleoption.t4 OWNER TO regress_roleoption_protagonist; -- fails, we don't inherit from recipient
ERROR: must be owner of table t4
RESET SESSION AUTHORIZATION;
DROP TABLE regress_roleoption.t1;
DROP TABLE regress_roleoption.t2;
DROP TABLE regress_roleoption.t3;
DROP TABLE regress_roleoption.t4;
DROP SCHEMA regress_roleoption;
2022-11-20 17:30:50 +01:00
DROP ROLE regress_roleoption_protagonist;
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
DROP ROLE regress_roleoption_donor;
2022-11-20 17:30:50 +01:00
DROP ROLE regress_roleoption_recipient;
2022-12-14 02:33:28 +01:00
-- MAINTAIN
CREATE ROLE regress_no_maintain;
CREATE ROLE regress_maintain;
CREATE ROLE regress_maintain_all IN ROLE pg_maintain;
CREATE TABLE maintain_test (a INT);
CREATE INDEX ON maintain_test (a);
GRANT MAINTAIN ON maintain_test TO regress_maintain;
CREATE MATERIALIZED VIEW refresh_test AS SELECT 1;
GRANT MAINTAIN ON refresh_test TO regress_maintain;
CREATE SCHEMA reindex_test;
-- negative tests; should fail
SET ROLE regress_no_maintain;
VACUUM maintain_test;
WARNING: permission denied to vacuum "maintain_test", skipping it
ANALYZE maintain_test;
WARNING: permission denied to analyze "maintain_test", skipping it
VACUUM (ANALYZE) maintain_test;
WARNING: permission denied to vacuum "maintain_test", skipping it
CLUSTER maintain_test USING maintain_test_a_idx;
ERROR: must be owner of table maintain_test
REFRESH MATERIALIZED VIEW refresh_test;
ERROR: must be owner of table refresh_test
REINDEX TABLE maintain_test;
ERROR: must be owner of table maintain_test
REINDEX INDEX maintain_test_a_idx;
ERROR: must be owner of index maintain_test_a_idx
REINDEX SCHEMA reindex_test;
ERROR: must be owner of schema reindex_test
2022-11-28 17:57:28 +01:00
RESET ROLE;
2022-12-14 02:33:28 +01:00
SET ROLE regress_maintain;
VACUUM maintain_test;
ANALYZE maintain_test;
VACUUM (ANALYZE) maintain_test;
CLUSTER maintain_test USING maintain_test_a_idx;
REFRESH MATERIALIZED VIEW refresh_test;
REINDEX TABLE maintain_test;
REINDEX INDEX maintain_test_a_idx;
REINDEX SCHEMA reindex_test;
ERROR: must be owner of schema reindex_test
2022-11-28 17:57:28 +01:00
RESET ROLE;
2022-12-14 02:33:28 +01:00
SET ROLE regress_maintain_all;
VACUUM maintain_test;
ANALYZE maintain_test;
VACUUM (ANALYZE) maintain_test;
CLUSTER maintain_test USING maintain_test_a_idx;
REFRESH MATERIALIZED VIEW refresh_test;
REINDEX TABLE maintain_test;
REINDEX INDEX maintain_test_a_idx;
REINDEX SCHEMA reindex_test;
2022-11-28 17:57:28 +01:00
RESET ROLE;
2022-12-14 02:33:28 +01:00
DROP TABLE maintain_test;
DROP MATERIALIZED VIEW refresh_test;
DROP SCHEMA reindex_test;
DROP ROLE regress_no_maintain;
DROP ROLE regress_maintain;
DROP ROLE regress_maintain_all;