diff options
author | Noah Misch <noah@leadboat.com> | 2015-09-20 20:45:41 -0400 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2015-09-20 20:45:54 -0400 |
commit | 6dae6edcd88cf3be06acf247c10de925bc065274 (patch) | |
tree | 0f3cebd0d38a7d31cf29a145d51933b2ed5fa224 /src/backend/utils | |
parent | 1be9d65e17abc6215a6faae9bc3f714dd3d040b6 (diff) | |
download | postgresql-6dae6edcd88cf3be06acf247c10de925bc065274.tar.gz postgresql-6dae6edcd88cf3be06acf247c10de925bc065274.zip |
Remove the row_security=force GUC value.
Every query of a single ENABLE ROW SECURITY table has two meanings, with
the row_security GUC selecting between them. With row_security=force
available, every function author would have been advised to either set
the GUC locally or test both meanings. Non-compliance would have
threatened reliability and, for SECURITY DEFINER functions, security.
Authors already face an obligation to account for search_path, and we
should not mimic that example. With this change, only BYPASSRLS roles
need exercise the aforementioned care. Back-patch to 9.5, where the
row_security GUC was introduced.
Since this narrows the domain of pg_db_role_setting.setconfig and
pg_proc.proconfig, one might bump catversion. A row_security=force
setting in one of those columns will elicit a clear message, so don't.
Diffstat (limited to 'src/backend/utils')
-rw-r--r-- | src/backend/utils/misc/guc.c | 39 | ||||
-rw-r--r-- | src/backend/utils/misc/rls.c | 29 |
2 files changed, 18 insertions, 50 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index eed5a75845f..25cef4fc112 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -380,23 +380,6 @@ static const struct config_enum_entry huge_pages_options[] = { }; /* - * Although only "on", "off", and "force" are documented, we - * accept all the likely variants of "on" and "off". - */ -static const struct config_enum_entry row_security_options[] = { - {"on", ROW_SECURITY_ON, false}, - {"off", ROW_SECURITY_OFF, false}, - {"force", ROW_SECURITY_FORCE, false}, - {"true", ROW_SECURITY_ON, true}, - {"false", ROW_SECURITY_OFF, true}, - {"yes", ROW_SECURITY_ON, true}, - {"no", ROW_SECURITY_OFF, true}, - {"1", ROW_SECURITY_ON, true}, - {"0", ROW_SECURITY_OFF, true}, - {NULL, 0, false} -}; - -/* * Options for enum values stored in other modules */ extern const struct config_enum_entry wal_level_options[]; @@ -421,6 +404,7 @@ bool log_statement_stats = false; /* this is sort of all three bool log_btree_build_stats = false; char *event_source; +bool row_security; bool check_function_bodies = true; bool default_with_oids = false; bool SQL_inheritance = true; @@ -452,8 +436,6 @@ int tcp_keepalives_idle; int tcp_keepalives_interval; int tcp_keepalives_count; -int row_security; - /* * This really belongs in pg_shmem.c, but is defined here so that it doesn't * need to be duplicated in all the different implementations of pg_shmem.c. @@ -1375,6 +1357,15 @@ static struct config_bool ConfigureNamesBool[] = check_transaction_deferrable, NULL, NULL }, { + {"row_security", PGC_USERSET, CONN_AUTH_SECURITY, + gettext_noop("Enable row security."), + gettext_noop("When enabled, row security will be applied to all users.") + }, + &row_security, + true, + NULL, NULL, NULL + }, + { {"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Check function bodies during CREATE FUNCTION."), NULL @@ -3631,16 +3622,6 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, - { - {"row_security", PGC_USERSET, CONN_AUTH_SECURITY, - gettext_noop("Enable row security."), - gettext_noop("When enabled, row security will be applied to all users.") - }, - &row_security, - ROW_SECURITY_ON, row_security_options, - NULL, NULL, NULL - }, - /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL diff --git a/src/backend/utils/misc/rls.c b/src/backend/utils/misc/rls.c index 7b8d51d956f..abaf3445068 100644 --- a/src/backend/utils/misc/rls.c +++ b/src/backend/utils/misc/rls.c @@ -87,32 +87,19 @@ check_enable_rls(Oid relid, Oid checkAsUser, bool noError) /* * Check permissions * - * If the relation has row level security enabled and the row_security GUC - * is off, then check if the user has rights to bypass RLS for this - * relation. Table owners can always bypass, as can any role with the - * BYPASSRLS capability. - * - * If the role is the table owner, then we bypass RLS unless row_security - * is set to 'force'. Note that superuser is always considered an owner. - * - * Return RLS_NONE_ENV to indicate that this decision depends on the - * environment (in this case, what the current values of user_id and - * row_security are). + * Table owners always bypass RLS. Note that superuser is always + * considered an owner. Return RLS_NONE_ENV to indicate that this + * decision depends on the environment (in this case, the user_id). */ - if (row_security != ROW_SECURITY_FORCE - && (pg_class_ownercheck(relid, user_id))) + if (pg_class_ownercheck(relid, user_id)) return RLS_NONE_ENV; /* - * If the row_security GUC is 'off' then check if the user has permission - * to bypass it. Note that we have already handled the case where the - * user is the table owner above. - * - * Note that row_security is always considered 'on' when querying through - * a view or other cases where checkAsUser is true, so skip this if - * checkAsUser is in use. + * If the row_security GUC is 'off', check if the user has permission to + * bypass RLS. row_security is always considered 'on' when querying + * through a view or other cases where checkAsUser is valid. */ - if (!checkAsUser && row_security == ROW_SECURITY_OFF) + if (!row_security && !checkAsUser) { if (has_bypassrls_privilege(user_id)) /* OK to bypass */ |