diff options
| author | Tom Lane | 2018-10-02 15:54:12 +0000 |
|---|---|---|
| committer | Tom Lane | 2018-10-02 15:54:12 +0000 |
| commit | 3d0f68dd30612db8d8cf6529455a369ad121c521 (patch) | |
| tree | f11e448605bd2e258619de4dfab126ead41e104d /src/test | |
| parent | 80810ca629c159191387f677b368a0551bbf2351 (diff) | |
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
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/regress/expected/privileges.out | 57 | ||||
| -rw-r--r-- | src/test/regress/sql/privileges.sql | 17 |
2 files changed, 74 insertions, 0 deletions
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index ac8968d24f5..aebc89c1b08 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -1132,6 +1132,63 @@ from (select oid from pg_class where relname = 'atest1') as t1; f (1 row) +-- 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 +---------------------- + t +(1 row) + +revoke select on table mytable from regress_priv_user3; +select has_column_privilege('mytable',2::int2,'select'); + has_column_privilege +---------------------- + +(1 row) + -- Grant options SET SESSION AUTHORIZATION regress_priv_user1; CREATE TABLE atest4 (a int); diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index f7f3bbbeeb6..0c0bba6cf7f 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -715,6 +715,23 @@ from (select oid from pg_class where relname = 'atest1') as t1; select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'atest1') as t1; +-- has_column_privilege function + +-- bad-input checks (as non-super-user) +select has_column_privilege('pg_authid',NULL,'select'); +select has_column_privilege('pg_authid','nosuchcol','select'); +select has_column_privilege(9999,'nosuchcol','select'); +select has_column_privilege(9999,99::int2,'select'); +select has_column_privilege('pg_authid',99::int2,'select'); +select has_column_privilege(9999,99::int2,'select'); + +create temp table mytable(f1 int, f2 int, f3 int); +alter table mytable drop column f2; +select has_column_privilege('mytable','f2','select'); +select has_column_privilege('mytable','........pg.dropped.2........','select'); +select has_column_privilege('mytable',2::int2,'select'); +revoke select on table mytable from regress_priv_user3; +select has_column_privilege('mytable',2::int2,'select'); -- Grant options |
