| Bug #12008 | Escaped wildcard in DB name prevents user from granting database permissions | ||
|---|---|---|---|
| Submitted: | 18 Jul 2005 14:31 | Modified: | 22 Aug 2005 21:15 |
| Reporter: | Jonathan Wheeler | Email Updates: | |
| Status: | Not a Bug | Impact on me: | |
| Category: | MySQL Server | Severity: | S2 (Serious) |
| Version: | 4.1.12 | OS: | Linux (Redhat Linux) |
| Assigned to: | Bugs System | CPU Architecture: | Any |
[18 Jul 2005 14:31]
Jonathan Wheeler
[22 Jul 2005 17:08]
MySQL Verification Team
Hello Jonathan, Thank you for the report. Can you show us the output of SHOW GRANTS for the user 'Alice'?
[22 Jul 2005 18:02]
Jonathan Wheeler
Here are the error codes after sql grant: grant select on foo_test.test to bob Error Code : 1142 SELECT,GRANT command denied to user 'alice'@'%' for table 'test' (0 ms taken) grant select on foo_test.* to bob Error Code : 1044 Access denied for user 'alice'@'%' to database 'foo_test' (0 ms taken)
[23 Jul 2005 12:38]
MySQL Verification Team
Jonathan, please, show us the output of the following command: SHOW GRANTS FOR 'alice'@'%'
[25 Jul 2005 8:41]
Jonathan Wheeler
Sorry, here is the result. GRANT USAGE ON *.* TO 'alice'@'%' IDENTIFIED BY PASSWORD 'hidden' GRANT ALL PRIVILEGES ON `foo\_%`.* TO 'alice'@'%' WITH GRANT OPTION
[31 Jul 2005 19:32]
Jorge del Conde
Thanks for your bug report. I was able to reproduce this under FC4 using 4.1.13 from bk:
root-/usr/local# mysql -uroot
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 4.1.13
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> GRANT ALL PRIVILEGES ON `foo\_%`.* TO 'alice'@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.02 sec)
mysql> GRANT ALL PRIVILEGES ON `foo\_%`.* TO 'alice'@'localhost' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
root-/usr/local# mysql -u alice
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2 to server version: 4.1.13
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> create database foo_test;
Query OK, 1 row affected (0.00 sec)
mysql> use foo_test;
Database changed
mysql> Grant select on foo_test.* to bob
-> ;
ERROR 1044 (42000): Access denied for user 'alice'@'localhost' to database 'foo_test'
mysql> SHOW GRANTS FOR 'alice';
+---------------------------------------------------------------------+
| Grants for alice@% |
+---------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'alice'@'%' |
| GRANT ALL PRIVILEGES ON `foo\_%`.* TO 'alice'@'%' WITH GRANT OPTION |
+---------------------------------------------------------------------+
2 rows in set (0.00 sec)
[12 Aug 2005 5:56]
Patrick Galbraith
I'm looking suspiciously at "wild_compare". It seems to only deal with wildcards such as '*' and '?'
char wild_many='*';
char wild_one='?';
char wild_prefix=0; /* QQ this can potentially cause a SIGSEGV */
int wild_compare(register const char *str, register const char *wildstr,
pbool str_is_pattern)
{
char cmp;
Why not '%' and '_' ? It seems it's comparing as if we are dealing with filenames and not SQL.
[19 Aug 2005 0:01]
Patrick Galbraith
The check:
if (str_is_pattern && *str++ != wild_prefix)
DBUG_RETURN(1);
when running in the debugger plus an added DBUG_PRINT line (gcc optimisations wouldn't show me what was in str properly!!!) showed me that this particular line is performing a comparison that will always pass, because str never contains a '\'. str is the name of the table for which we are trying to give a particular user a grant to.
mysql> grant select on foo\_test.* to bob;
ERROR:
Unknown command '\_'.
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 1
Current database: *** NONE ***
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\_test.* to bob' at line 1
mysql> grant select on 'foo\_test'.* to bob;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''foo\_test'.* to bob' at line 1
mysql>
and the fix:
mysql> grant select on foo_test.* to bob;
Query OK, 0 rows affected (13.41 sec)
now running 'make test'
[22 Aug 2005 21:15]
Patrick Galbraith
Looking into this further, this is correct behaviour. What you need to do is this: Grant select on `foo\_test`.* to bob Doing it the other way, what you are trying to do is grant foo<any character>test.* to bob, and the grant is for 'foo_(underscore)<anycharacter>'
