mirror of
https://github.com/postgres/postgres.git
synced 2025-05-31 00:01:57 -04:00
PG-1440 Only let superusers modify the global key proviers
Since as soon as we have installed pg_tde the database owner can call any function created by the extension so any database owner can meddle with any global key provider. The only way to prevent the database owner to do whatever they want add permissions checks to the C code and here we keep that check simple by limiting modifying the global key provider to only the super user. Additionally we also protect the function for settting the WAL key, for setting the default key and to be paranoid also the function for using a global key provider to set the database key. The third is not obvious if it is necessary or not but I chose to be paranoid and relax that restirction later once we have demed it to be secure.
This commit is contained in:
parent
dcdcebbf92
commit
99ef6b20f9
@ -4,7 +4,7 @@ The `pg_tde` extension provides functions for managing different aspects of its
|
||||
|
||||
## Permission management
|
||||
|
||||
By default, `pg_tde` is restrictive. It doesn't allow any operations until permissions are granted to the user. Only superusers can run permission management functions to manage user permissions.
|
||||
By default, `pg_tde` is restrictive. It doesn't allow any operations until permissions are granted to the user. Only superusers can run permission management functions to manage user permissions. Operations on the global scope are limited to superusers only.
|
||||
|
||||
Permissions are based on the normal `EXECUTE` permission on the functions provided by `pg_tde`. Superusers manage them using the `GRANT EXECUTE` and `REVOKE EXECUTE` commands.
|
||||
|
||||
@ -19,10 +19,7 @@ Use these functions to grant or revoke permissions to manage permissions for the
|
||||
|
||||
### Global scope key management
|
||||
|
||||
Use these functions to grant or revoke permissions to manage permissions for the global scope - the entire PostgreSQL instance. They enable or disable all functions related to the providers and keys for the global scope:
|
||||
|
||||
* `pg_tde_grant_global_key_management_to_role(role)`
|
||||
* `pg_tde_revoke_global_key_management_from_role(role)`
|
||||
Managment of the global scope is restricted to superusers only.
|
||||
|
||||
### Permission management
|
||||
|
||||
|
@ -52,6 +52,19 @@ SELECT key_name, key_provider_name, key_provider_id FROM pg_tde_key_info();
|
||||
test-db-key | file-vault | 1
|
||||
(1 row)
|
||||
|
||||
-- only superuser
|
||||
SELECT pg_tde_add_global_key_provider_file('file-vault', '/tmp/pg_tde_test_keyring.per');
|
||||
ERROR: must be superuser to modify global key providers
|
||||
SELECT pg_tde_change_global_key_provider_file('file-vault', '/tmp/pg_tde_test_keyring.per');
|
||||
ERROR: must be superuser to modify global key providers
|
||||
SELECT pg_tde_delete_global_key_provider('file-vault');
|
||||
ERROR: must be superuser to modify global key providers
|
||||
SELECT pg_tde_set_key_using_global_key_provider('key1', 'file-vault');
|
||||
ERROR: must be superuser to access global key providers
|
||||
SELECT pg_tde_set_default_key_using_global_key_provider('key1', 'file-vault');
|
||||
ERROR: must be superuser to access global key providers
|
||||
SELECT pg_tde_set_server_key_using_global_key_provider('key1', 'file-vault');
|
||||
ERROR: must be superuser to access global key providers
|
||||
RESET ROLE;
|
||||
SELECT pg_tde_revoke_key_viewer_from_role('regress_pg_tde_access_control');
|
||||
pg_tde_revoke_key_viewer_from_role
|
||||
|
@ -528,39 +528,6 @@ ALTER EVENT TRIGGER pg_tde_trigger_create_index_2 ENABLE ALWAYS;
|
||||
-- Per database extension initialization
|
||||
SELECT pg_tde_extension_initialize();
|
||||
|
||||
CREATE FUNCTION pg_tde_grant_global_key_management_to_role(
|
||||
target_role TEXT)
|
||||
RETURNS VOID
|
||||
LANGUAGE plpgsql
|
||||
SET search_path = @extschema@
|
||||
AS $$
|
||||
BEGIN
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_add_global_key_provider(text, text, JSON) TO %I', target_role);
|
||||
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_add_global_key_provider_file(text, json) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_add_global_key_provider_file(text, text) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_add_global_key_provider_vault_v2(text, text, text, text, text) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_add_global_key_provider_vault_v2(text, JSON, JSON, JSON, JSON) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_add_global_key_provider_kmip(text, text, int, text, text) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_add_global_key_provider_kmip(text, JSON, JSON, JSON, JSON) TO %I', target_role);
|
||||
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_change_global_key_provider(text, text, JSON) TO %I', target_role);
|
||||
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_change_global_key_provider_file(text, json) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_change_global_key_provider_file(text, text) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_change_global_key_provider_vault_v2(text, text, text, text, text) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_change_global_key_provider_vault_v2(text, JSON, JSON, JSON, JSON) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_change_global_key_provider_kmip(text, text, int, text, text) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_change_global_key_provider_kmip(text, JSON, JSON, JSON, JSON) TO %I', target_role);
|
||||
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_delete_global_key_provider(text) TO %I', target_role);
|
||||
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_set_key_using_global_key_provider(text, text, BOOLEAN) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_set_server_key_using_global_key_provider(text, text, BOOLEAN) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_set_default_key_using_global_key_provider(text, text, BOOLEAN) TO %I', target_role);
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION pg_tde_grant_database_key_management_to_role(
|
||||
target_role TEXT)
|
||||
RETURNS VOID
|
||||
@ -612,39 +579,6 @@ BEGIN
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION pg_tde_revoke_global_key_management_from_role(
|
||||
target_role TEXT)
|
||||
RETURNS VOID
|
||||
LANGUAGE plpgsql
|
||||
SET search_path = @extschema@
|
||||
AS $$
|
||||
BEGIN
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_add_global_key_provider(text, text, JSON) FROM %I', target_role);
|
||||
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_add_global_key_provider_file(text, json) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_add_global_key_provider_file(text, text) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_add_global_key_provider_vault_v2(text, text, text, text, text) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_add_global_key_provider_vault_v2(text, JSON, JSON, JSON, JSON) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_add_global_key_provider_kmip(text, text, int, text, text) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_add_global_key_provider_kmip(text, JSON, JSON, JSON, JSON) FROM %I', target_role);
|
||||
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_change_global_key_provider(text, text, JSON) FROM %I', target_role);
|
||||
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_change_global_key_provider_file(text, json) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_change_global_key_provider_file(text, text) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_change_global_key_provider_vault_v2(text, text, text, text, text) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_change_global_key_provider_vault_v2(text, JSON, JSON, JSON, JSON) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_change_global_key_provider_kmip(text, text, int, text, text) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_change_global_key_provider_kmip(text, JSON, JSON, JSON, JSON) FROM %I', target_role);
|
||||
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_delete_global_key_provider(text) FROM %I', target_role);
|
||||
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_set_key_using_global_key_provider(text, text, BOOLEAN) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_set_server_key_using_global_key_provider(text, text, BOOLEAN) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_set_default_key_using_global_key_provider(text, text, BOOLEAN) FROM %I', target_role);
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION pg_tde_revoke_database_key_management_from_role(
|
||||
target_role TEXT)
|
||||
RETURNS VOID
|
||||
@ -703,7 +637,6 @@ LANGUAGE plpgsql
|
||||
SET search_path = @extschema@
|
||||
AS $$
|
||||
BEGIN
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_grant_global_key_management_to_role(TEXT) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_grant_database_key_management_to_role(TEXT) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_grant_grant_management_to_role(TEXT) TO %I', target_role);
|
||||
EXECUTE format('GRANT EXECUTE ON FUNCTION pg_tde_grant_key_viewer_to_role(TEXT) TO %I', target_role);
|
||||
@ -722,12 +655,10 @@ LANGUAGE plpgsql
|
||||
SET search_path = @extschema@
|
||||
AS $$
|
||||
BEGIN
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_grant_global_key_management_to_role(TEXT) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_grant_database_key_management_to_role(TEXT) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_grant_grant_management_to_role(TEXT) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_grant_key_viewer_to_role(TEXT) FROM %I', target_role);
|
||||
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_revoke_global_key_management_from_role(TEXT) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_revoke_database_key_management_from_role(TEXT) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_revoke_grant_management_from_role(TEXT) FROM %I', target_role);
|
||||
EXECUTE format('REVOKE EXECUTE ON FUNCTION pg_tde_revoke_key_viewer_from_role(TEXT) FROM %I', target_role);
|
||||
@ -736,6 +667,5 @@ $$;
|
||||
|
||||
-- Revoking all the privileges from the public role
|
||||
SELECT pg_tde_revoke_database_key_management_from_role('public');
|
||||
SELECT pg_tde_revoke_global_key_management_from_role('public');
|
||||
SELECT pg_tde_revoke_grant_management_from_role('public');
|
||||
SELECT pg_tde_revoke_key_viewer_from_role('public');
|
||||
|
@ -22,6 +22,14 @@ SELECT pg_tde_set_key_using_database_key_provider('test-db-key', 'file-vault');
|
||||
SELECT * FROM pg_tde_list_all_database_key_providers();
|
||||
SELECT key_name, key_provider_name, key_provider_id FROM pg_tde_key_info();
|
||||
|
||||
-- only superuser
|
||||
SELECT pg_tde_add_global_key_provider_file('file-vault', '/tmp/pg_tde_test_keyring.per');
|
||||
SELECT pg_tde_change_global_key_provider_file('file-vault', '/tmp/pg_tde_test_keyring.per');
|
||||
SELECT pg_tde_delete_global_key_provider('file-vault');
|
||||
SELECT pg_tde_set_key_using_global_key_provider('key1', 'file-vault');
|
||||
SELECT pg_tde_set_default_key_using_global_key_provider('key1', 'file-vault');
|
||||
SELECT pg_tde_set_server_key_using_global_key_provider('key1', 'file-vault');
|
||||
|
||||
RESET ROLE;
|
||||
|
||||
SELECT pg_tde_revoke_key_viewer_from_role('regress_pg_tde_access_control');
|
||||
|
@ -214,6 +214,11 @@ pg_tde_change_database_key_provider(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_tde_change_global_key_provider(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser to modify global key providers")));
|
||||
|
||||
return pg_tde_change_key_provider_internal(fcinfo, GLOBAL_DATA_TDE_OID);
|
||||
}
|
||||
|
||||
@ -264,6 +269,11 @@ pg_tde_add_database_key_provider(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_tde_add_global_key_provider(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser to modify global key providers")));
|
||||
|
||||
return pg_tde_add_key_provider_internal(fcinfo, GLOBAL_DATA_TDE_OID);
|
||||
}
|
||||
|
||||
|
@ -485,6 +485,11 @@ pg_tde_set_default_key_using_global_key_provider(PG_FUNCTION_ARGS)
|
||||
char *provider_name = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(1));
|
||||
bool ensure_new_key = PG_GETARG_BOOL(2);
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser to access global key providers")));
|
||||
|
||||
pg_tde_set_principal_key_internal(principal_key_name, GS_DEFAULT, provider_name, ensure_new_key);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
@ -509,6 +514,11 @@ pg_tde_set_key_using_global_key_provider(PG_FUNCTION_ARGS)
|
||||
char *provider_name = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(1));
|
||||
bool ensure_new_key = PG_GETARG_BOOL(2);
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser to access global key providers")));
|
||||
|
||||
pg_tde_set_principal_key_internal(principal_key_name, GS_GLOBAL, provider_name, ensure_new_key);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
@ -521,6 +531,11 @@ pg_tde_set_server_key_using_global_key_provider(PG_FUNCTION_ARGS)
|
||||
char *provider_name = PG_ARGISNULL(1) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(1));
|
||||
bool ensure_new_key = PG_GETARG_BOOL(2);
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser to access global key providers")));
|
||||
|
||||
pg_tde_set_principal_key_internal(principal_key_name, GS_SERVER, provider_name, ensure_new_key);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
@ -1045,6 +1060,11 @@ pg_tde_delete_database_key_provider(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
pg_tde_delete_global_key_provider(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser to modify global key providers")));
|
||||
|
||||
return pg_tde_delete_key_provider_internal(fcinfo, 1);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user