Commit c9b4f8c3 authored by unknown's avatar unknown

Fix bug in checking of table-specific grats that caused IP/NETMASK

hostnames to not be matched correctly. (Bug #3309)


sql/sql_acl.cc:
  Use an acl_host_or_ip in the GRANT_TABLE struct instead of storing the host
  itself, and use compare_hostname() in testing it. This adds support for IP
  addresses with netmasks to table-specific grants, and results in simplified
  code by making use of compare_hostname() in more places.
mysql-test/r/grant2.result:
  Add new results
mysql-test/t/grant2.test:
  Add new regression test
parent 90eed656
...@@ -63,3 +63,19 @@ delete from mysql.columns_priv where user like 'mysqltest\_%'; ...@@ -63,3 +63,19 @@ delete from mysql.columns_priv where user like 'mysqltest\_%';
flush privileges; flush privileges;
drop database mysqltest; drop database mysqltest;
use test; use test;
create database mysqltest_1;
create table mysqltest_1.t1 (i int);
insert into mysqltest_1.t1 values (1),(2),(3);
GRANT ALL ON mysqltest_1.t1 TO mysqltest_1@'127.0.0.0/255.0.0.0';
show grants for current_user();
Grants for mysqltest_1@127.0.0.0/255.0.0.0
GRANT USAGE ON *.* TO 'mysqltest_1'@'127.0.0.0/255.0.0.0'
GRANT ALL PRIVILEGES ON `mysqltest_1`.`t1` TO 'mysqltest_1'@'127.0.0.0/255.0.0.0'
select * from t1;
i
1
2
3
REVOKE ALL ON mysqltest_1.t1 FROM mysqltest_1@'127.0.0.0/255.0.0.0';
drop table mysqltest_1.t1;
drop database mysqltest_1;
...@@ -89,3 +89,17 @@ flush privileges; ...@@ -89,3 +89,17 @@ flush privileges;
drop database mysqltest; drop database mysqltest;
use test; use test;
# Bug #3309: Test IP addresses with netmask
create database mysqltest_1;
create table mysqltest_1.t1 (i int);
insert into mysqltest_1.t1 values (1),(2),(3);
GRANT ALL ON mysqltest_1.t1 TO mysqltest_1@'127.0.0.0/255.0.0.0';
connect (n1,127.0.0.1,mysqltest_1,,mysqltest_1,$MASTER_MYPORT,$MASTER_MYSOCK);
connection n1;
show grants for current_user();
select * from t1;
disconnect n1;
connection default;
REVOKE ALL ON mysqltest_1.t1 FROM mysqltest_1@'127.0.0.0/255.0.0.0';
drop table mysqltest_1.t1;
drop database mysqltest_1;
...@@ -1788,7 +1788,8 @@ static byte* get_key_column(GRANT_COLUMN *buff,uint *length, ...@@ -1788,7 +1788,8 @@ static byte* get_key_column(GRANT_COLUMN *buff,uint *length,
class GRANT_TABLE :public Sql_alloc class GRANT_TABLE :public Sql_alloc
{ {
public: public:
char *host,*db, *user, *tname, *hash_key, *orig_host; acl_host_and_ip host;
char *db, *user, *tname, *hash_key;
ulong privs, cols; ulong privs, cols;
ulong sort; ulong sort;
uint key_length; uint key_length;
...@@ -1807,12 +1808,10 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u, ...@@ -1807,12 +1808,10 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u,
:privs(p), cols(c) :privs(p), cols(c)
{ {
/* Host given by user */ /* Host given by user */
orig_host= strdup_root(&memex,h); update_hostname(&host, strdup_root(&memex, h));
/* Convert empty hostname to '%' for easy comparision */
host= orig_host[0] ? orig_host : (char*) "%";
db = strdup_root(&memex,d); db = strdup_root(&memex,d);
user = strdup_root(&memex,u); user = strdup_root(&memex,u);
sort= get_sort(3,host,db,user); sort= get_sort(3,host.hostname,db,user);
tname= strdup_root(&memex,t); tname= strdup_root(&memex,t);
if (lower_case_table_names) if (lower_case_table_names)
{ {
...@@ -1831,17 +1830,12 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) ...@@ -1831,17 +1830,12 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
{ {
byte key[MAX_KEY_LENGTH]; byte key[MAX_KEY_LENGTH];
orig_host= host= get_field(&memex, form->field[0]); update_hostname(&host, get_field(&memex, form->field[0]));
db= get_field(&memex,form->field[1]); db= get_field(&memex,form->field[1]);
user= get_field(&memex,form->field[2]); user= get_field(&memex,form->field[2]);
if (!user) if (!user)
user= (char*) ""; user= (char*) "";
if (!orig_host) sort= get_sort(3, host.hostname, db, user);
{
orig_host= (char*) "";
host= (char*) "%";
}
sort= get_sort(3, orig_host, db, user);
tname= get_field(&memex,form->field[3]); tname= get_field(&memex,form->field[3]);
if (!db || !tname) if (!db || !tname)
{ {
...@@ -1868,7 +1862,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) ...@@ -1868,7 +1862,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs)
if (cols) if (cols)
{ {
int key_len; int key_len;
col_privs->field[0]->store(orig_host,(uint) strlen(orig_host), col_privs->field[0]->store(host.hostname,(uint) strlen(host.hostname),
&my_charset_latin1); &my_charset_latin1);
col_privs->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); col_privs->field[1]->store(db,(uint) strlen(db), &my_charset_latin1);
col_privs->field[2]->store(user,(uint) strlen(user), &my_charset_latin1); col_privs->field[2]->store(user,(uint) strlen(user), &my_charset_latin1);
...@@ -1945,17 +1939,12 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, ...@@ -1945,17 +1939,12 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip,
{ {
if (exact) if (exact)
{ {
if ((host && if (compare_hostname(&grant_table->host, host, ip))
!my_strcasecmp(&my_charset_latin1, host, grant_table->host)) ||
(ip && !strcmp(ip,grant_table->host)))
return grant_table; return grant_table;
} }
else else
{ {
if (((host && !wild_case_compare(&my_charset_latin1, if (compare_hostname(&grant_table->host, host, ip) &&
host,grant_table->host)) ||
(ip && !wild_case_compare(&my_charset_latin1,
ip,grant_table->host))) &&
(!found || found->sort < grant_table->sort)) (!found || found->sort < grant_table->sort))
found=grant_table; // Host ok found=grant_table; // Host ok
} }
...@@ -2692,7 +2681,7 @@ my_bool grant_init(THD *org_thd) ...@@ -2692,7 +2681,7 @@ my_bool grant_init(THD *org_thd)
if (check_no_resolve) if (check_no_resolve)
{ {
if (hostname_requires_resolving(mem_check->host)) if (hostname_requires_resolving(mem_check->host.hostname))
{ {
sql_print_warning("'tables_priv' entry '%s %s@%s' " sql_print_warning("'tables_priv' entry '%s %s@%s' "
"ignored in --skip-name-resolve mode.", "ignored in --skip-name-resolve mode.",
...@@ -2981,10 +2970,7 @@ bool check_grant_db(THD *thd,const char *db) ...@@ -2981,10 +2970,7 @@ bool check_grant_db(THD *thd,const char *db)
idx); idx);
if (len < grant_table->key_length && if (len < grant_table->key_length &&
!memcmp(grant_table->hash_key,helping,len) && !memcmp(grant_table->hash_key,helping,len) &&
(thd->host && !wild_case_compare(&my_charset_latin1, compare_hostname(&grant_table->host, thd->host, thd->ip))
thd->host,grant_table->host) ||
(thd->ip && !wild_case_compare(&my_charset_latin1,
thd->ip,grant_table->host))))
{ {
error=0; // Found match error=0; // Found match
break; break;
...@@ -3324,7 +3310,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) ...@@ -3324,7 +3310,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (!strcmp(lex_user->user.str,user) && if (!strcmp(lex_user->user.str,user) &&
!my_strcasecmp(&my_charset_latin1, lex_user->host.str, !my_strcasecmp(&my_charset_latin1, lex_user->host.str,
grant_table->orig_host)) grant_table->host.hostname))
{ {
ulong table_access= grant_table->privs; ulong table_access= grant_table->privs;
if ((table_access | grant_table->cols) != 0) if ((table_access | grant_table->cols) != 0)
...@@ -3606,7 +3592,7 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list) ...@@ -3606,7 +3592,7 @@ int mysql_drop_user(THD *thd, List <LEX_USER> &list)
counter); counter);
if (!(user=grant_table->user)) if (!(user=grant_table->user))
user= ""; user= "";
if (!(host=grant_table->host)) if (!(host=grant_table->host.hostname))
host= ""; host= "";
if (!strcmp(user_name->user.str,user) && if (!strcmp(user_name->user.str,user) &&
...@@ -3735,7 +3721,7 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list) ...@@ -3735,7 +3721,7 @@ int mysql_revoke_all(THD *thd, List <LEX_USER> &list)
counter); counter);
if (!(user=grant_table->user)) if (!(user=grant_table->user))
user= ""; user= "";
if (!(host=grant_table->host)) if (!(host=grant_table->host.hostname))
host= ""; host= "";
if (!strcmp(lex_user->user.str,user) && if (!strcmp(lex_user->user.str,user) &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment