WL#8131: Pluggable dynamic privileges
Affects: Server-8.0
—
Status: Complete
Currently privileged operations of various unrelated kinds are all abusing the SUPER privilege for access control, e.g. both the firewall administration and the replication slave administration require SUPER. This makes granting the SUPER privilege a security risk as it's too coarse and thus too powerful. Also it's currently very hard for developers to be adding new privileges instead since it would require altering the mysql.user table and recompiling the server code. Thus components, plugins and server code developers are not adding specific fine grained privileges and tend to keep abusing the SUPER privilege by overloading it with even more meaning. This worklog will provide a service to easily register new, granular global privileges with the server at runtime. It will provide an easy way to GRANT and revoke these privileges through SQL and programmatically check if they're granted or not. The worklog will also define a set of new granular privileges for various aspects of what SUPER is used for today.
D-0 A grant is a ordered tuple (privilege identifier, SQL object, authorization identifier). D-0.1 An SQL object can be the server instance, a database, a table, a column, a stored program, a view. D-1 A dynamic privilege is a grant of one privilege identifier to an authorization identifier represented as a row in a table. The privilege identifier is called dynamic because it's loaded in runtime either by the server component or by plugins or other components. The opposite is static privileges which are always hard coded into the server and represented as columns rather than rows. From a user perspective both dynamic privileges and static privileges will be part of a static security model and be perceived as doing the same thing. D-2 An access control list (ACL) or GRANT-list is a list of rows in a system table mapping USER, HOST to a privilege identifier. NOTE: In Oracle DB USER, HOST is refereed to as principal. Principals and privilege IDs are related in a declarative way by defining ACL. D-3 A role is an authorization ID which specify how ACLs can be aggregated into an effective ACL. Roles can relate to each other in hierarchies but are not aggregated themselves. D-4 Effective privileges, or effective ACLs are a set of grants which will be checked before a statement is executed. The statement SET ROLE, or default roles, can effect the effective privileges for an authenticated user. D-5 ACLs can be applied to different SQL object aggregation levels sometimes referred to as security levels. There are several different categories or security levels: Global, db, table, column, stored program. Example: Global SELECT is specified as SELECT ON *.* Table level SELECT is specified as SELECT ON db1.t1 Column level SELECT is specified as SELECT (c1) ON db1.t1 R-1 A plugin or component MAY be able to specify a list of dynamic privileges as string identifiers after the plugin or component is initialized. R-2 All ACLs created from GRANT-statements involving dynamic privileges will be stored in the system table mysql.global_grants. Any REVOKE-statement will subsequently remove the corresponding entry. R-3 *removed * R-4.1 New dynamic privileges will be introduced for server operations which currently require the SUPER_ACL. The privileges will be group according to plugin, code area or approximate future component structure FIREWALL_ADMIN - administer firewall rules for any user FIREWALL_USER - For updating the users own firewall rules AUDIT_ADMIN - Configure the audit log SYSTEM_VARIABLES_ADMIN - Change system variables ENCRYPTION_KEY_ADMIN - Rotate the innodb encryption keys BINLOG_ADMIN - purge binlog VERSION_TOKEN_ADMIN - Administer version token commands ROLE_ADMIN - Can execute GRANT WITH ADMIN, ROLE_GRAPHML() REPLICATION_SLAVE_ADMIN - Connect/disconnect to master, start replication CONNECTION_ADMIN - Privilege for setting variables related to setting or circumventing privileges related to client connections. - This privilege replace the SUPER privilege for the following server variables: https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_init_connect https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_offline_mode https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_read_only https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_sql_log_off GROUP_REPLICATION_ADMIN - Privilege for starting and stopping group replication SET_USER_ID - Privilege for changing effective authid when executing view, trigger, event or routine R-4.2 ROLE_ADMIN, SYSTEM_VARIABLES_ADMIN, BINLOG_ADMIN, REPLICATION_SLAVE_ADMIN, GROUP_REPLICATION_ADMIN, ENCRYPTION_KEY_ADMIN, VERSION_TOKEN_ADMIN, CONNECTION_ADMIN, SET_USER_ID will be registered when the mysqld server component starts. All other privilege ids will be registered with their corresponding plugins, ie FIREWALL_* is registered when the firewall plugin is loaded or if the privilege ID already is in a grant entry in mysql.global_grants. R-4.3 Privilege IDs registered by plugins won't be unregistered when the plugins are uninstalled, and the syntax will still work. R-4.4 All privilege IDs in the mysql.global_grants table will be registered when the FLUSH PRIVILEGE command is issued. R-5 Only global security level ACLs of dynamic privileges should be supported. R-6 *removed* R-7 information_schema.user_privileges will show dynamic privilege grants R-8 It must be possible to list effective dynamic privileges by using SHOW GRANTS FOR x [USING y] just as any other privilege. R-9 DROPing a authorization ID MUST also REVOKE all dynamic privileges from that authorization ID. R-10 SHOW PRIVILEGES will list all registered dynamic privileges as Admin privileges. R-11 GRANT ALL statements will grant all /currently/ available privileges. GRANT ALL will not grant access to future dynamic privileges on INSTALL PLUGIN statements. R-12 SHOW GRANTS FOR x [USING y] must not show GRANT ALL as a valid grant. Instead every single granted privilege must be listed explicitly. R-13 The SUPER_ACL will be deprecated. Whenever the SUPER_ACL is used explicitly in a GRANT or REVOKE statement a warning will be printed stating that the privilege ID is deprecated. R-14 A dynamic privilege ID will be limited to a length of 32 characters.
I-1 New semantics GRANT GRANT priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] priv_level TO user_specification [, user_specification] ... [REQUIRE {NONE | tls_option [[AND] tls_option] ...}] [WITH {GRANT OPTION | resource_option} ...] user_specification := authid[, authid] When ever priv_type can't be identified as a statically defined privilege (example SELECT, UPDATE etc), it will be assumed that this is a dynamic privilege and a dictionary lookup will be made against the dynamic privilege identifier. If no dynamic privilege identifier can be found an error is thrown to indicate an unknown privilege identifier. Dynamic privileges will only be checked if the priv_level is *.*. NOTE: GRANT ALL will only grant currently available privilege identifiers. Future privilege identifiers won't be automatically granted because of a previous GRANT ALL statement. SHOW GRANTS will not show "GRANT ALL" for all global grants as it's difficult to know what this means in an environment where privileges IDs can be loaded or unloaded in runtime. Instead SHOW GRANTS will list every privilege ID granted. I-2 New semantics REVOKE I-2.1 REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] priv_level FROM user [, user] ... REVOKE ALL PRIVILEGES FROM user [, user] ... When ever priv_type can't be identified as a statically defined privilege (example SELECT, UPDATE etc), it will be assumed that this is a dynamic privilege and a dictionary lookup will be made against the dynamic privilege identifier. If no dynamic privilege identifier can be found an error is thrown to indicate an unknown privilege identifier. Dynamic privileges will only be checked if the priv_level is *.*. In case ALL PRIVILEGES is specified, all the corresponding dynamic privileges will also be revoked. I-2.2 REVOKE GRANT OPTION ON *.* FROM user Since GRANT OPTION is per dynamic privilege ID instead of per entire global grant level, it wouldn't make sense to revoke all GRANT OPTION with this statement as is the case for static global privileges. The only way to revoke a GRANT OPTION for a dynamic privilege is to first REVOKE the privilege ID then GRANT it again without GRANT OPTION. There's no change for static privileges.
S-0 Two new services: dynamic_privilege_register and global_grants_check is introduced in the mysql_server component. S-1 New method in the dynamic_privilege_register service in the mysql_server component [1]: int dynamic_privilege_impl::register_privilege(const char *str, size_t len) This will store a new entry in a global dynamic privilege dictionary and reload the system table mysql.global_grants for any ACLs which contain the privilege id. As the storage will be a separate entity independent of the plugin registering the new privilege. S-2 New method in the global_grants_check service in the service API for the mysql_server component: bool dynamic_privilege_impl::has_global_grant (Security_context_handle sctx, const char *str, size_t len) Check if the currently logged in user, as specified by the sctx, has the dynamic privilege id and return true. S-3 New method in the dynamic_privilege_register service in the service API for the mysql_server component: bool dynamic_privilege_impl::unregister_privilege (const char *str, size_t len) Unregister a previously registered privilege ID. S-4 As a reference implementation, the firewall plugin will use the register service to register and use a new privilege, FIREWALL_ADMIN, using S-{1,2}. S-5 The Security_context must provide a method for checking the existence of a dynamic privilege in the effective ACLs. It's up to the plugin or component author to call this method at appropriate places.
Copyright (c) 2000, 2024, Oracle Corporation and/or its affiliates. All rights reserved.