1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-40722 DROP PACKAGE leaves PACKAGE BODY grant in mysql.procs_priv

DROP PACKAGE now removes both PACKAGE BODY and PACKAGE privileges
for the given package.
This commit is contained in:
Alexander Barkov
2026-08-11 10:13:16 +04:00
parent 3064caf84c
commit 210ab6edf4
3 changed files with 109 additions and 27 deletions

View File

@@ -320,3 +320,26 @@ SESSION_USER() CURRENT_USER() msg
root@localhost root@localhost p1.p1
DROP PACKAGE p1;
DROP USER xxx@localhost;
#
# MDEV-40722 DROP PACKAGE leaves PACKAGE BODY grant in mysql.procs_priv
#
CREATE PACKAGE pkg1 AS
FUNCTION f RETURN VARCHAR2(64);
END
$$
CREATE PACKAGE BODY pkg1 AS
FUNCTION f RETURN VARCHAR2(64) AS
BEGIN RETURN 'f';
END;
END$$
CREATE USER reader@localhost;
GRANT EXECUTE ON PACKAGE test.pkg1 TO reader@localhost;
GRANT EXECUTE ON PACKAGE BODY test.pkg1 TO reader@localhost;
SELECT host,db,user,routine_name,routine_type,proc_priv FROM mysql.procs_priv ORDER BY routine_type;
host db user routine_name routine_type proc_priv
localhost test reader pkg1 PACKAGE Execute
localhost test reader pkg1 PACKAGE BODY Execute
DROP PACKAGE pkg1;
SELECT host,db,user,routine_name,routine_type,proc_priv FROM mysql.procs_priv ORDER BY routine_type;
host db user routine_name routine_type proc_priv
DROP USER reader@localhost;

View File

@@ -330,3 +330,28 @@ DELIMITER ;$$
CALL p1.p1;
DROP PACKAGE p1;
DROP USER xxx@localhost;
--echo #
--echo # MDEV-40722 DROP PACKAGE leaves PACKAGE BODY grant in mysql.procs_priv
--echo #
DELIMITER $$;
CREATE PACKAGE pkg1 AS
FUNCTION f RETURN VARCHAR2(64);
END
$$
CREATE PACKAGE BODY pkg1 AS
FUNCTION f RETURN VARCHAR2(64) AS
BEGIN RETURN 'f';
END;
END$$
DELIMITER ;$$
CREATE USER reader@localhost;
GRANT EXECUTE ON PACKAGE test.pkg1 TO reader@localhost;
GRANT EXECUTE ON PACKAGE BODY test.pkg1 TO reader@localhost;
SELECT host,db,user,routine_name,routine_type,proc_priv FROM mysql.procs_priv ORDER BY routine_type;
DROP PACKAGE pkg1;
SELECT host,db,user,routine_name,routine_type,proc_priv FROM mysql.procs_priv ORDER BY routine_type;
DROP USER reader@localhost;

View File

@@ -11761,6 +11761,61 @@ Silence_routine_definer_errors::handle_condition(
}
/*
The low level function to revoke routine privileges for the given sp handler
@param thd the thd
@param proc_privs the table mysql.proc_privs
@param sp_db the routine database
@param sp_name the routine name
@param sph the sp handler
*/
static void sp_revoke_privileges_for_handler(THD *thd, TABLE *proc_privs,
#if MYSQL_VERSION_ID < 110501
const char *sp_db,
const char *sp_name,
#else
#error Remove the above conditional code
const Lex_ident_db &sp_db,
const Lex_ident_routine &sp_name,
#endif
const Sp_handler *sph)
{
uint counter, revoked;
HASH *hash= sph->get_priv_hash();
do
{
for (counter= 0, revoked= 0 ; counter < hash->records ; )
{
GRANT_NAME *grant_proc= (GRANT_NAME*) my_hash_element(hash, counter);
#if MYSQL_VERSION_ID < 110501
if (!my_strcasecmp(&my_charset_utf8mb3_bin, grant_proc->db, sp_db) &&
!my_strcasecmp(system_charset_info, grant_proc->tname, sp_name))
#else
#error Remove the above conditional code
if (sp_db.streq(Lex_cstring_strlen(grant_proc->db)) &&
sp_name.streq(Lex_cstring_strlen(grant_proc->tname)))
#endif
{
LEX_USER lex_user;
lex_user.user.str= grant_proc->user;
lex_user.user.length= strlen(grant_proc->user);
lex_user.host.str= safe_str(grant_proc->host.hostname);
lex_user.host.length= strlen(lex_user.host.str);
if (replace_routine_table(thd, grant_proc,
proc_privs, lex_user,
grant_proc->db, grant_proc->tname,
sph, ALL_KNOWN_ACL, 1) == 0)
{
revoked= 1;
continue;
}
}
counter++;
}
} while (revoked);
}
/**
Revoke privileges for all users on a stored procedure. Use an error handler
that converts errors about missing grants into warnings.
@@ -11781,9 +11836,7 @@ Silence_routine_definer_errors::handle_condition(
bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
const Sp_handler *sph)
{
uint counter, revoked;
int result;
HASH *hash= sph->get_priv_hash();
Silence_routine_definer_errors error_handler;
DBUG_ENTER("sp_revoke_privileges");
@@ -11803,31 +11856,12 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
mysql_mutex_lock(&acl_cache->lock);
/* Remove procedure access */
do
{
for (counter= 0, revoked= 0 ; counter < hash->records ; )
{
GRANT_NAME *grant_proc= (GRANT_NAME*) my_hash_element(hash, counter);
if (!my_strcasecmp(&my_charset_utf8mb3_bin, grant_proc->db, sp_db) &&
!my_strcasecmp(system_charset_info, grant_proc->tname, sp_name))
{
LEX_USER lex_user;
lex_user.user.str= grant_proc->user;
lex_user.user.length= strlen(grant_proc->user);
lex_user.host.str= safe_str(grant_proc->host.hostname);
lex_user.host.length= strlen(lex_user.host.str);
if (replace_routine_table(thd, grant_proc,
tables.procs_priv_table().table(), lex_user,
grant_proc->db, grant_proc->tname,
sph, ALL_KNOWN_ACL, 1) == 0)
{
revoked= 1;
continue;
}
}
counter++;
}
} while (revoked);
if (sph == &sp_handler_package_spec)
sp_revoke_privileges_for_handler(thd, tables.procs_priv_table().table(),
sp_db, sp_name, &sp_handler_package_body);
sp_revoke_privileges_for_handler(thd, tables.procs_priv_table().table(),
sp_db, sp_name, sph);
mysql_mutex_unlock(&acl_cache->lock);
mysql_rwlock_unlock(&LOCK_grant);