In AlterRole, make bypassrls an int

When reworking bypassrls in AlterRole to operate the same way the other
attribute handling is done, I missed that the variable was incorrectly a
bool rather than an int.  This meant that on platforms with an unsigned
char, we could end up with incorrect behavior during ALTER ROLE.

Pointed out by Andres thanks to tests he did changing our bool to be the
one from stdbool.h which showed this and a number of other issues.

Add regression tests to test CREATE/ALTER role for the various role
attributes.  Arrange to leave roles behind for testing pg_dumpall, but
none which have the LOGIN attribute.

Back-patch to 9.5 where the AlterRole bug exists.
This commit is contained in:
Stephen Frost 2015-08-21 08:22:29 -04:00
parent 338a862256
commit 0070fd8d3c
5 changed files with 324 additions and 2 deletions

View File

@ -493,7 +493,7 @@ AlterRole(AlterRoleStmt *stmt)
char *validUntil = NULL; /* time the login is valid until */
Datum validUntil_datum; /* same, as timestamptz Datum */
bool validUntil_null;
bool bypassrls = -1;
int bypassrls = -1;
DefElem *dpassword = NULL;
DefElem *dissuper = NULL;
DefElem *dinherit = NULL;

View File

@ -0,0 +1,236 @@
-- default for superuser is false
CREATE ROLE test_def_superuser;
SELECT * FROM pg_authid WHERE rolname = 'test_def_superuser';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_def_superuser | f | t | f | f | f | f | f | -1 | |
(1 row)
CREATE ROLE test_superuser WITH SUPERUSER;
SELECT * FROM pg_authid WHERE rolname = 'test_superuser';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
----------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_superuser | t | t | f | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_superuser WITH NOSUPERUSER;
SELECT * FROM pg_authid WHERE rolname = 'test_superuser';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
----------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_superuser | f | t | f | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_superuser WITH SUPERUSER;
SELECT * FROM pg_authid WHERE rolname = 'test_superuser';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
----------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_superuser | t | t | f | f | f | f | f | -1 | |
(1 row)
-- default for inherit is true
CREATE ROLE test_def_inherit;
SELECT * FROM pg_authid WHERE rolname = 'test_def_inherit';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_def_inherit | f | t | f | f | f | f | f | -1 | |
(1 row)
CREATE ROLE test_inherit WITH NOINHERIT;
SELECT * FROM pg_authid WHERE rolname = 'test_inherit';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_inherit | f | f | f | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_inherit WITH INHERIT;
SELECT * FROM pg_authid WHERE rolname = 'test_inherit';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_inherit | f | t | f | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_inherit WITH NOINHERIT;
SELECT * FROM pg_authid WHERE rolname = 'test_inherit';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_inherit | f | f | f | f | f | f | f | -1 | |
(1 row)
-- default for create role is false
CREATE ROLE test_def_createrole;
SELECT * FROM pg_authid WHERE rolname = 'test_def_createrole';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
---------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_def_createrole | f | t | f | f | f | f | f | -1 | |
(1 row)
CREATE ROLE test_createrole WITH CREATEROLE;
SELECT * FROM pg_authid WHERE rolname = 'test_createrole';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
-----------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_createrole | f | t | t | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_createrole WITH NOCREATEROLE;
SELECT * FROM pg_authid WHERE rolname = 'test_createrole';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
-----------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_createrole | f | t | f | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_createrole WITH CREATEROLE;
SELECT * FROM pg_authid WHERE rolname = 'test_createrole';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
-----------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_createrole | f | t | t | f | f | f | f | -1 | |
(1 row)
-- default for create database is false
CREATE ROLE test_def_createdb;
SELECT * FROM pg_authid WHERE rolname = 'test_def_createdb';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
-------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_def_createdb | f | t | f | f | f | f | f | -1 | |
(1 row)
CREATE ROLE test_createdb WITH CREATEDB;
SELECT * FROM pg_authid WHERE rolname = 'test_createdb';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
---------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_createdb | f | t | f | t | f | f | f | -1 | |
(1 row)
ALTER ROLE test_createdb WITH NOCREATEDB;
SELECT * FROM pg_authid WHERE rolname = 'test_createdb';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
---------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_createdb | f | t | f | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_createdb WITH CREATEDB;
SELECT * FROM pg_authid WHERE rolname = 'test_createdb';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
---------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_createdb | f | t | f | t | f | f | f | -1 | |
(1 row)
-- default for can login is false for role
CREATE ROLE test_def_role_canlogin;
SELECT * FROM pg_authid WHERE rolname = 'test_def_role_canlogin';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_def_role_canlogin | f | t | f | f | f | f | f | -1 | |
(1 row)
CREATE ROLE test_role_canlogin WITH LOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_role_canlogin';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_role_canlogin | f | t | f | f | t | f | f | -1 | |
(1 row)
ALTER ROLE test_role_canlogin WITH NOLOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_role_canlogin';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_role_canlogin | f | t | f | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_role_canlogin WITH LOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_role_canlogin';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_role_canlogin | f | t | f | f | t | f | f | -1 | |
(1 row)
-- default for can login is true for user
CREATE USER test_def_user_canlogin;
SELECT * FROM pg_authid WHERE rolname = 'test_def_user_canlogin';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_def_user_canlogin | f | t | f | f | t | f | f | -1 | |
(1 row)
CREATE USER test_user_canlogin WITH NOLOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_user_canlogin';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_user_canlogin | f | t | f | f | f | f | f | -1 | |
(1 row)
ALTER USER test_user_canlogin WITH LOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_user_canlogin';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_user_canlogin | f | t | f | f | t | f | f | -1 | |
(1 row)
ALTER USER test_user_canlogin WITH NOLOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_user_canlogin';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_user_canlogin | f | t | f | f | f | f | f | -1 | |
(1 row)
-- default for replication is false
CREATE ROLE test_def_replication;
SELECT * FROM pg_authid WHERE rolname = 'test_def_replication';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_def_replication | f | t | f | f | f | f | f | -1 | |
(1 row)
CREATE ROLE test_replication WITH REPLICATION;
SELECT * FROM pg_authid WHERE rolname = 'test_replication';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_replication | f | t | f | f | f | t | f | -1 | |
(1 row)
ALTER ROLE test_replication WITH NOREPLICATION;
SELECT * FROM pg_authid WHERE rolname = 'test_replication';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_replication | f | t | f | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_replication WITH REPLICATION;
SELECT * FROM pg_authid WHERE rolname = 'test_replication';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_replication | f | t | f | f | f | t | f | -1 | |
(1 row)
-- default for bypassrls is false
CREATE ROLE test_def_bypassrls;
SELECT * FROM pg_authid WHERE rolname = 'test_def_bypassrls';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
--------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_def_bypassrls | f | t | f | f | f | f | f | -1 | |
(1 row)
CREATE ROLE test_bypassrls WITH BYPASSRLS;
SELECT * FROM pg_authid WHERE rolname = 'test_bypassrls';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
----------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_bypassrls | f | t | f | f | f | f | t | -1 | |
(1 row)
ALTER ROLE test_bypassrls WITH NOBYPASSRLS;
SELECT * FROM pg_authid WHERE rolname = 'test_bypassrls';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
----------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_bypassrls | f | t | f | f | f | f | f | -1 | |
(1 row)
ALTER ROLE test_bypassrls WITH BYPASSRLS;
SELECT * FROM pg_authid WHERE rolname = 'test_bypassrls';
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil
----------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
test_bypassrls | f | t | f | f | f | f | t | -1 | |
(1 row)
-- remove the one role with LOGIN rights
DROP ROLE test_role_canlogin;
-- other roles not removed to test pg_dumpall role dump through
-- pg_upgrade

View File

@ -60,7 +60,7 @@ test: create_index create_view
# ----------
# Another group of parallel tests
# ----------
test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views rolenames
test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views rolenames roleattributes
# ----------
# sanity_check does a vacuum, affecting the sort order of SELECT *

View File

@ -73,6 +73,7 @@ test: vacuum
test: drop_if_exists
test: updatable_views
test: rolenames
test: roleattributes
test: sanity_check
test: errors
test: select

View File

@ -0,0 +1,85 @@
-- default for superuser is false
CREATE ROLE test_def_superuser;
SELECT * FROM pg_authid WHERE rolname = 'test_def_superuser';
CREATE ROLE test_superuser WITH SUPERUSER;
SELECT * FROM pg_authid WHERE rolname = 'test_superuser';
ALTER ROLE test_superuser WITH NOSUPERUSER;
SELECT * FROM pg_authid WHERE rolname = 'test_superuser';
ALTER ROLE test_superuser WITH SUPERUSER;
SELECT * FROM pg_authid WHERE rolname = 'test_superuser';
-- default for inherit is true
CREATE ROLE test_def_inherit;
SELECT * FROM pg_authid WHERE rolname = 'test_def_inherit';
CREATE ROLE test_inherit WITH NOINHERIT;
SELECT * FROM pg_authid WHERE rolname = 'test_inherit';
ALTER ROLE test_inherit WITH INHERIT;
SELECT * FROM pg_authid WHERE rolname = 'test_inherit';
ALTER ROLE test_inherit WITH NOINHERIT;
SELECT * FROM pg_authid WHERE rolname = 'test_inherit';
-- default for create role is false
CREATE ROLE test_def_createrole;
SELECT * FROM pg_authid WHERE rolname = 'test_def_createrole';
CREATE ROLE test_createrole WITH CREATEROLE;
SELECT * FROM pg_authid WHERE rolname = 'test_createrole';
ALTER ROLE test_createrole WITH NOCREATEROLE;
SELECT * FROM pg_authid WHERE rolname = 'test_createrole';
ALTER ROLE test_createrole WITH CREATEROLE;
SELECT * FROM pg_authid WHERE rolname = 'test_createrole';
-- default for create database is false
CREATE ROLE test_def_createdb;
SELECT * FROM pg_authid WHERE rolname = 'test_def_createdb';
CREATE ROLE test_createdb WITH CREATEDB;
SELECT * FROM pg_authid WHERE rolname = 'test_createdb';
ALTER ROLE test_createdb WITH NOCREATEDB;
SELECT * FROM pg_authid WHERE rolname = 'test_createdb';
ALTER ROLE test_createdb WITH CREATEDB;
SELECT * FROM pg_authid WHERE rolname = 'test_createdb';
-- default for can login is false for role
CREATE ROLE test_def_role_canlogin;
SELECT * FROM pg_authid WHERE rolname = 'test_def_role_canlogin';
CREATE ROLE test_role_canlogin WITH LOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_role_canlogin';
ALTER ROLE test_role_canlogin WITH NOLOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_role_canlogin';
ALTER ROLE test_role_canlogin WITH LOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_role_canlogin';
-- default for can login is true for user
CREATE USER test_def_user_canlogin;
SELECT * FROM pg_authid WHERE rolname = 'test_def_user_canlogin';
CREATE USER test_user_canlogin WITH NOLOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_user_canlogin';
ALTER USER test_user_canlogin WITH LOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_user_canlogin';
ALTER USER test_user_canlogin WITH NOLOGIN;
SELECT * FROM pg_authid WHERE rolname = 'test_user_canlogin';
-- default for replication is false
CREATE ROLE test_def_replication;
SELECT * FROM pg_authid WHERE rolname = 'test_def_replication';
CREATE ROLE test_replication WITH REPLICATION;
SELECT * FROM pg_authid WHERE rolname = 'test_replication';
ALTER ROLE test_replication WITH NOREPLICATION;
SELECT * FROM pg_authid WHERE rolname = 'test_replication';
ALTER ROLE test_replication WITH REPLICATION;
SELECT * FROM pg_authid WHERE rolname = 'test_replication';
-- default for bypassrls is false
CREATE ROLE test_def_bypassrls;
SELECT * FROM pg_authid WHERE rolname = 'test_def_bypassrls';
CREATE ROLE test_bypassrls WITH BYPASSRLS;
SELECT * FROM pg_authid WHERE rolname = 'test_bypassrls';
ALTER ROLE test_bypassrls WITH NOBYPASSRLS;
SELECT * FROM pg_authid WHERE rolname = 'test_bypassrls';
ALTER ROLE test_bypassrls WITH BYPASSRLS;
SELECT * FROM pg_authid WHERE rolname = 'test_bypassrls';
-- remove the one role with LOGIN rights
DROP ROLE test_role_canlogin;
-- other roles not removed to test pg_dumpall role dump through
-- pg_upgrade