1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-28367: BACKUP LOCKS on table to be accessible to those with database LOCK TABLES privileges

- Allow database level access via `LOCK TABLES` to execute statement
`BACKUP [un]LOCK <object>`
- `BACKUP UNLOCK` works only with `RELOAD` privilege.
  In case there is `LOCK TABLES` privilege without `RELOAD` privilege,
  we check if backup lock is taken before.
  If it is not we raise an error of missing `RELOAD` privilege.
- We had to remove any error/warnings from calling functions because
`thd->get_stmt_da()->m_status` will be set to error and will break
`my_ok()`.
- Added missing test coverage of `RELOAD` privilege to `main.grant.test`
Reviewer: <daniel@mariadb.org>
This commit is contained in:
Anel Husakovic
2023-11-08 21:38:14 +01:00
committed by Daniel Black
parent 32c6849736
commit ff0bade2f8
5 changed files with 211 additions and 3 deletions

View File

@ -5153,9 +5153,55 @@ mysql_execute_command(THD *thd)
my_ok(thd);
break;
case SQLCOM_BACKUP_LOCK:
if (check_global_access(thd, RELOAD_ACL))
goto error;
/* first table is set for lock. For unlock the list is empty */
if (check_global_access(thd, RELOAD_ACL, true))
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/*
In case there is no global privilege, check DB privilege for LOCK TABLES.
*/
if (first_table) // BACKUP LOCK
{
if (check_single_table_access(thd, LOCK_TABLES_ACL, first_table, true))
{
char command[30];
get_privilege_desc(command, sizeof(command), RELOAD_ACL|LOCK_TABLES_ACL);
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
goto error;
}
}
else // BACKUP UNLOCK
{
/*
We test mdl_backup_lock here because, if a user could obtain a lock
it would be silly to error and say `you can't BACKUP UNLOCK`
(because its obvious you did a `BACKUP LOCK`).
As `BACKUP UNLOCK` doesn't have a database reference,
there's no way we can check if the `BACKUP LOCK` privilege is missing.
Testing `thd->db` would involve faking a `TABLE_LIST` structure,
which because of the depth of inspection
in `check_single_table_access` makes the faking likely to cause crashes,
or unintended effects. The outcome of this is,
if a user does an `BACKUP UNLOCK` without a `BACKUP LOCKED` table,
there may be a` ER_SPECIFIC_ACCESS_DENIED` error even though
user has the privilege.
Its a bit different to what happens if the user has RELOAD_ACL,
where the error is silently ignored.
*/
if (!thd->mdl_backup_lock)
{
char command[30];
get_privilege_desc(command, sizeof(command), RELOAD_ACL|LOCK_TABLES_ACL);
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
goto error;
}
}
#endif
}
/*
There is reload privilege, first table is set for lock.
For unlock the list is empty
*/
if (first_table)
res= backup_lock(thd, first_table);
else