summaryrefslogtreecommitdiff
path: root/sql/sql_acl.cc
diff options
context:
space:
mode:
authorunknown <monty@narttu.mysql.fi>2003-06-23 20:03:59 +0300
committerunknown <monty@narttu.mysql.fi>2003-06-23 20:03:59 +0300
commit35c2b9df7564c95c38f04fc4dbc3bebea81a9a41 (patch)
tree31f9bf5794339dd4559001264cd2cc350877d76b /sql/sql_acl.cc
parent16d6c8eb1fc39dd9ae1e396f776b1be270e48d7e (diff)
downloadmariadb-git-35c2b9df7564c95c38f04fc4dbc3bebea81a9a41.tar.gz
SHOW GRANTS hided real grants when grants on both column and table (Bug 654)
mysql-test/r/grant.result: Test of grant BUG mysql-test/t/grant.test: Test of grant BUG sql/sql_acl.cc: SHOW GRANTS hided real grants when grants on both column and table (Bug 654) Code cleanup (Bigger than intended because of editor problem) sql/sql_acl.h: Fixed grant bug
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r--sql/sql_acl.cc361
1 files changed, 203 insertions, 158 deletions
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index f01248bb682..c93e082e0ff 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -193,7 +193,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
host.db= get_field(&mem, table,1);
host.access= get_access(table,2);
host.access= fix_rights_for_db(host.access);
- host.sort= get_sort(2,host.host.hostname,host.db);
+ host.sort= get_sort(2,host.host.hostname,host.db);
#ifndef TO_BE_REMOVED
if (table->fields == 8)
{ // Without grant
@@ -213,8 +213,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
if (table->field[2]->field_length == 8 &&
protocol_version == PROTOCOL_VERSION)
{
- sql_print_error(
- "Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */
+ sql_print_error("Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */
protocol_version=9; /* purecov: tested */
}
@@ -247,7 +246,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
user.sort=get_sort(2,user.host.hostname,user.user);
user.hostname_length= (user.host.hostname ?
(uint) strlen(user.host.hostname) : 0);
- if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
+ if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */
{
char *ssl_type=get_field(&mem, table, 24);
if (!ssl_type)
@@ -259,7 +258,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
else /* !strcmp(ssl_type, "SPECIFIED") */
user.ssl_type=SSL_TYPE_SPECIFIED;
- user.ssl_cipher= get_field(&mem, table, 25);
+ user.ssl_cipher= get_field(&mem, table, 25);
user.x509_issuer= get_field(&mem, table, 26);
user.x509_subject= get_field(&mem, table, 27);
@@ -368,7 +367,14 @@ void acl_free(bool end)
}
}
- /* Reload acl list if possible */
+
+/*
+ Forget current privileges and read new privileges from the privilege tables
+
+ SYNOPSIS
+ acl_reload()
+ thd Thread handle
+*/
void acl_reload(THD *thd)
{
@@ -493,8 +499,8 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
const char *password,const char *message,
- char **priv_user, char *priv_host,
- bool old_ver, USER_RESOURCES *mqh)
+ char **priv_user, char *priv_host,
+ bool old_ver, USER_RESOURCES *mqh)
{
ulong user_access=NO_ACCESS;
*priv_user=(char*) user;
@@ -526,15 +532,15 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
{
#ifdef HAVE_OPENSSL
Vio *vio=thd->net.vio;
- /*
+ /*
In this point we know that user is allowed to connect
from given host by given username/password pair. Now
we check if SSL is required, if user is using SSL and
if X509 certificate attributes are OK
*/
- switch (acl_user->ssl_type) {
+ switch (acl_user->ssl_type) {
case SSL_TYPE_NOT_SPECIFIED: // Impossible
- case SSL_TYPE_NONE: /* SSL is not required to connect */
+ case SSL_TYPE_NONE: /* SSL is not required to connect */
user_access=acl_user->access;
break;
case SSL_TYPE_ANY: /* Any kind of SSL is good enough */
@@ -544,7 +550,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
case SSL_TYPE_X509: /* Client should have any valid certificate. */
/*
We need to check for absence of SSL because without SSL
- we should reject connection.
+ we should reject connection.
*/
if (vio_type(vio) == VIO_TYPE_SSL && SSL_get_peer_certificate(vio->ssl_))
user_access=acl_user->access;
@@ -653,12 +659,12 @@ static byte* check_get_key(ACL_USER *buff,uint *length,
}
static void acl_update_user(const char *user, const char *host,
- const char *password,
+ const char *password,
enum SSL_type ssl_type,
const char *ssl_cipher,
const char *x509_issuer,
const char *x509_subject,
- USER_RESOURCES *mqh,
+ USER_RESOURCES *mqh,
ulong privileges)
{
for (uint i=0 ; i < acl_users.elements ; i++)
@@ -707,7 +713,7 @@ static void acl_update_user(const char *user, const char *host,
static void acl_insert_user(const char *user, const char *host,
- const char *password,
+ const char *password,
enum SSL_type ssl_type,
const char *ssl_cipher,
const char *x509_issuer,
@@ -805,9 +811,10 @@ static void acl_insert_db(const char *user, const char *host, const char *db,
}
-/*****************************************************************************
-** Get privilege for a host, user and db combination
-*****************************************************************************/
+
+/*
+ Get privilege for a host, user and db combination
+*/
ulong acl_get(const char *host, const char *ip, const char *bin_ip,
const char *user, const char *db)
@@ -929,11 +936,14 @@ int wild_case_compare(const char *str,const char *wildstr)
DBUG_RETURN (*str != '\0');
}
-/*****************************************************************************
-** check if there are any possible matching entries for this host
-** All host names without wild cards are stored in a hash table,
-** entries with wildcards are stored in a dynamic array
-*****************************************************************************/
+
+/*
+ Check if there are any possible matching entries for this host
+
+ NOTES
+ All host names without wild cards are stored in a hash table,
+ entries with wildcards are stored in a dynamic array
+*/
static void init_check_host(void)
{
@@ -1006,10 +1016,6 @@ bool acl_check_host(const char *host, const char *ip)
return 1; // Host is not allowed
}
-/*****************************************************************************
- Change password for the user if it's not an anonymous user
- Note: This should write the error directly to the client!
-*****************************************************************************/
/*
Check if the user is allowed to change password
@@ -1021,8 +1027,8 @@ bool acl_check_host(const char *host, const char *ip)
user user name
RETURN VALUE
- 0 OK
- 1 ERROR ; In this case the error is sent to the client.
+ 0 OK
+ 1 ERROR ; In this case the error is sent to the client.
*/
bool check_change_password(THD *thd, const char *host, const char *user)
@@ -1061,7 +1067,7 @@ bool check_change_password(THD *thd, const char *host, const char *user)
RETURN VALUES
0 ok
1 ERROR; In this case the error is sent to the client.
-*/
+*/
bool change_password(THD *thd, const char *host, const char *user,
char *new_password)
@@ -1127,7 +1133,7 @@ find_acl_user(const char *host, const char *user)
{
ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*);
DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),",
- user,acl_user->user,(host),(acl_user->host)));
+ user,acl_user->user,(host),(acl_user->host)));
if (!acl_user->user && !user[0] ||
acl_user->user && !strcmp(user,acl_user->user))
{
@@ -1140,15 +1146,18 @@ find_acl_user(const char *host, const char *user)
DBUG_RETURN(0);
}
-/*****************************************************************************
- Handle comparing of hostname
- A hostname may be of type:
- hostname (May include wildcards); monty.pp.sci.fi
- ip (May include wildcards); 192.168.0.0
- ip/netmask 192.168.0.0/255.255.255.0
- A net mask of 0.0.0.0 is not allowed.
-*****************************************************************************/
+/*
+ Comparing of hostnames
+
+ NOTES
+ A hostname may be of type:
+ hostname (May include wildcards); monty.pp.sci.fi
+ ip (May include wildcards); 192.168.0.0
+ ip/netmask 192.168.0.0/255.255.255.0
+
+ A net mask of 0.0.0.0 is not allowed.
+*/
static const char *calc_ip(const char *ip, long *val, char end)
{
@@ -1195,9 +1204,9 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname,
}
-/****************************************************************************
- Code to update grants in the user and database privilege tables
-****************************************************************************/
+/*
+ Update grants in the user and database privilege tables
+*/
static bool update_user_table(THD *thd, const char *host, const char *user,
const char *new_password)
@@ -1263,7 +1272,7 @@ static bool test_if_create_new_users(THD *thd)
/****************************************************************************
-** Handle GRANT commands
+ Handle GRANT commands
****************************************************************************/
static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
@@ -1285,8 +1294,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
if (combo.password.length != HASH_PASSWORD_LENGTH)
{
my_printf_error(ER_PASSWORD_NO_MATCH,
- "Password hash should be a %d-digit hexadecimal number",
- MYF(0),HASH_PASSWORD_LENGTH);
+ "Password hash should be a %d-digit hexadecimal number",
+ MYF(0),HASH_PASSWORD_LENGTH);
DBUG_RETURN(-1);
}
password=combo.password.str;
@@ -1459,7 +1468,7 @@ static int replace_db_table(TABLE *table, const char *db,
char what= (revoke_grant) ? 'N' : 'Y';
DBUG_ENTER("replace_db_table");
- // is there such a user in user table in memory ????
+ /* Check if there is such a user in user table in memory? */
if (!initialized || !find_acl_user(combo.host.str,combo.user.str))
{
my_error(ER_PASSWORD_NO_MATCH,MYF(0));
@@ -1471,7 +1480,7 @@ static int replace_db_table(TABLE *table, const char *db,
table->field[2]->store(combo.user.str,combo.user.length);
table->file->index_init(0);
if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0,
- HA_READ_KEY_EXACT))
+ HA_READ_KEY_EXACT))
{
if (what == 'N')
{ // no row, no revoke
@@ -1502,7 +1511,7 @@ static int replace_db_table(TABLE *table, const char *db,
if (old_row_exists)
{
- // update old existing row
+ /* update old existing row */
if (rights)
{
if ((error=table->file->update_row(table->record[1],table->record[0])))
@@ -1529,11 +1538,11 @@ static int replace_db_table(TABLE *table, const char *db,
DBUG_RETURN(0);
/* This could only happen if the grant tables got corrupted */
- table_error:
+table_error:
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
table->file->index_end();
- abort:
+abort:
DBUG_RETURN(-1);
}
@@ -1649,7 +1658,7 @@ public:
if (!(mem_check = new GRANT_COLUMN(*res,
fix_rights_for_column(priv))))
{
- // Don't use this entry
+ /* Don't use this entry */
privs = cols = 0; /* purecov: deadcode */
return; /* purecov: deadcode */
}
@@ -1827,7 +1836,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
key_length, HA_READ_KEY_EXACT))
goto end;
- // Scan trough all rows with the same host,db,user and table
+ /* Scan through all rows with the same host,db,user and table */
do
{
ulong privileges = (ulong) table->field[6]->val_int();
@@ -1877,7 +1886,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
!key_cmp(table,key,0,key_length));
}
- end:
+end:
table->file->index_end();
DBUG_RETURN(result);
}
@@ -1947,7 +1956,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
if (revoke_grant)
{
- // column rights are already fixed in mysql_table_grant !
+ /* column rights are already fixed in mysql_table_grant */
store_table_rights=j & ~store_table_rights;
}
else
@@ -1983,7 +1992,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
if (rights | col_rights)
{
grant_table->privs= rights;
- grant_table->cols= col_rights;
+ grant_table->cols= col_rights;
}
else
{
@@ -1991,19 +2000,36 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
}
DBUG_RETURN(0);
- /* This should never happen */
- table_error:
+ /* This should never happen */
+table_error:
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
DBUG_RETURN(-1); /* purecov: deadcode */
}
+/*
+ Store table level and column level grants in the privilege tables
+
+ SYNOPSIS
+ mysql_table_grant()
+ thd Thread handle
+ table_list List of tables to give grant
+ user_list List of users to give grant
+ columns List of columns to give grant
+ rights Table level grant
+ revoke_grant Set to 1 if this is a REVOKE command
+
+ RETURN
+ 0 ok
+ 1 error
+*/
+
int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
List <LEX_USER> &user_list,
List <LEX_COLUMN> &columns, ulong rights,
bool revoke_grant)
{
- ulong column_priv = 0;
+ ulong column_priv= 0;
List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str;
TABLE_LIST tables[3];
@@ -2024,21 +2050,21 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
if (columns.elements && !revoke_grant)
{
TABLE *table;
- class LEX_COLUMN *check;
- List_iterator <LEX_COLUMN> iter(columns);
+ class LEX_COLUMN *column;
+ List_iterator <LEX_COLUMN> column_iter(columns);
if (!(table=open_ltable(thd,table_list,TL_READ)))
DBUG_RETURN(-1);
- while ((check = iter++))
+ while ((column = column_iter++))
{
- if (!find_field_in_table(thd,table,check->column.ptr(),
- check->column.length(),0,0))
+ if (!find_field_in_table(thd,table,column->column.ptr(),
+ column->column.length(),0,0))
{
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
- check->column.c_ptr(), table_list->alias);
+ column->column.c_ptr(), table_list->alias);
DBUG_RETURN(-1);
}
- column_priv |= check->rights | (rights & COL_ACLS);
+ column_priv|= column->rights;
}
close_thread_tables(thd);
}
@@ -2148,21 +2174,21 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
/* If revoke_grant, calculate the new column privilege for tables_priv */
if (revoke_grant)
{
- class LEX_COLUMN *check;
- List_iterator <LEX_COLUMN> iter(columns);
+ class LEX_COLUMN *column;
+ List_iterator <LEX_COLUMN> column_iter(columns);
GRANT_COLUMN *grant_column;
/* Fix old grants */
- while ((check = iter++))
+ while ((column = column_iter++))
{
grant_column = column_hash_search(grant_table,
- check->column.ptr(),
- check->column.length());
+ column->column.ptr(),
+ column->column.length());
if (grant_column)
- grant_column->rights&= ~(check->rights | rights);
+ grant_column->rights&= ~(column->rights | rights);
}
/* scan trough all columns to get new column grant */
- column_priv=0;
+ column_priv= 0;
for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++)
{
grant_column= (GRANT_COLUMN*) hash_element(&grant_table->hash_columns,
@@ -2259,7 +2285,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
if (!revoke_grant)
create_new_users= test_if_create_new_users(thd);
- // go through users in user_list
+ /* go through users in user_list */
pthread_mutex_lock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
grant_version++;
@@ -2280,7 +2306,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list,
continue;
}
if ((replace_user_table(thd,
- tables[0].table,
+ tables[0].table,
*Str,
(!db ? rights : 0), revoke_grant,
create_new_users)))
@@ -2401,7 +2427,16 @@ end:
}
-/* Reload grant array if possible */
+/*
+ Reload grant array if possible
+
+ SYNOPSIS
+ grant_reload()
+ thd Thread handler
+
+ NOTES
+ Locked tables are checked by acl_init and doesn't have to be checked here
+*/
void grant_reload(THD *thd)
{
@@ -2410,8 +2445,6 @@ void grant_reload(THD *thd)
MEM_ROOT old_mem;
DBUG_ENTER("grant_reload");
- // Locked tables are checked by acl_init and doesn't have to be checked here
-
pthread_mutex_lock(&LOCK_grant);
grant_version++;
old_hash_tables=hash_tables;
@@ -2487,13 +2520,13 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
pthread_mutex_unlock(&LOCK_grant);
return 0;
- err:
+err:
pthread_mutex_unlock(&LOCK_grant);
if (!no_errors) // Not a silent skip of table
{
const char *command="";
if (want_access & SELECT_ACL)
- command ="select";
+ command ="select";
else if (want_access & INSERT_ACL)
command = "insert";
else if (want_access & UPDATE_ACL)
@@ -2534,7 +2567,7 @@ bool check_grant_column(THD *thd,TABLE *table, const char *name,
pthread_mutex_lock(&LOCK_grant);
- // reload table if someone has modified any grants
+ /* reload table if someone has modified any grants */
if (table->grant.version != grant_version)
{
@@ -2594,7 +2627,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
pthread_mutex_lock(&LOCK_grant);
- // reload table if someone has modified any grants
+ /* reload table if someone has modified any grants */
if (table->grant.version != grant_version)
{
@@ -2604,7 +2637,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
table->real_name,0); /* purecov: inspected */
table->grant.version=grant_version; /* purecov: inspected */
}
- // The following should always be true
+ /* The following should always be true */
if (!(grant_table=table->grant.grant_table))
goto err; /* purecov: inspected */
@@ -2619,7 +2652,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
return 0;
/* We must use my_printf_error() here! */
- err:
+err:
pthread_mutex_unlock(&LOCK_grant);
const char *command="";
@@ -2639,11 +2672,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table)
}
-/****************************************************************************
+/*
Check if a user has the right to access a database
Access is accepted if he has a grant for any table in the database
Return 1 if access is denied
-****************************************************************************/
+*/
bool check_grant_db(THD *thd,const char *db)
{
@@ -2683,7 +2716,7 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table)
pthread_mutex_lock(&LOCK_grant);
grant_table = table_hash_search(thd->host,thd->ip,db,user,
- table->real_name,0);
+ table->real_name, 0);
table->grant.grant_table=grant_table; // Remember for column test
table->grant.version=grant_version;
if (grant_table)
@@ -2701,7 +2734,7 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
ulong priv;
pthread_mutex_lock(&LOCK_grant);
- // reload table if someone has modified any grants
+ /* reload table if someone has modified any grants */
if (table->grant.version != grant_version)
{
table->grant.grant_table=
@@ -2726,11 +2759,20 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field)
return priv;
}
+/* Help function for mysql_show_grants */
-/*****************************************************************************
- SHOW GRANTS : send to client grant-like strings depicting user@host
- privileges
-*****************************************************************************/
+static void add_user_option(String *grant, ulong value, const char *name)
+{
+ if (value)
+ {
+ char buff[22], *p; // just as in int2str
+ grant->append(' ');
+ grant->append(name, strlen(name));
+ grant->append(' ');
+ p=int10_to_str(value, buff, 10);
+ grant->append(buff,p-buff);
+ }
+}
static const char *command_array[]=
{
@@ -2739,13 +2781,21 @@ static const char *command_array[]=
"SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE",
"REPLICATION SLAVE", "REPLICATION CLIENT",
};
+
static uint command_lengths[]=
{
6,6,6,6,6,4,6,8,7,4,5,10,5,5,14,5,23,11,7,17,18
};
-int mysql_show_grants(THD *thd,LEX_USER *lex_user)
+/*
+ SHOW GRANTS; Send grants for a user to the client
+
+ IMPLEMENTATION
+ Send to client grant-like strings depicting user@host privileges
+*/
+
+int mysql_show_grants(THD *thd,LEX_USER *lex_user)
{
ulong want_access;
uint counter,index;
@@ -2784,7 +2834,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
!my_strcasecmp(lex_user->host.str,host))
break;
}
- if (counter == acl_users.elements)
+ if (counter == acl_users.elements)
{
my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
MYF(0),lex_user->user.str,lex_user->host.str);
@@ -2815,13 +2865,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append("ALL PRIVILEGES",14);
else if (!(want_access & ~GRANT_ACL))
global.append("USAGE",5);
- else
+ else
{
bool found=0;
ulong j,test_access= want_access & ~GRANT_ACL;
for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
{
- if (test_access & j)
+ if (test_access & j)
{
if (found)
global.append(", ",2);
@@ -2831,7 +2881,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
global.append (" ON *.* TO '",12);
- global.append(lex_user->user.str,lex_user->user.length);
+ global.append(lex_user->user.str,lex_user->user.length);
global.append ("'@'",3);
global.append(lex_user->host.str,lex_user->host.length);
global.append ('\'');
@@ -2854,25 +2904,25 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append(" REQUIRE ",9);
if (acl_user->x509_issuer)
{
- ssl_options++;
- global.append("ISSUER \'",8);
- global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
+ ssl_options++;
+ global.append("ISSUER \'",8);
+ global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
global.append('\'');
}
if (acl_user->x509_subject)
{
- if (ssl_options++)
- global.append(' ');
- global.append("SUBJECT \'",9);
- global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
+ if (ssl_options++)
+ global.append(' ');
+ global.append("SUBJECT \'",9);
+ global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
global.append('\'');
}
if (acl_user->ssl_cipher)
{
- if (ssl_options++)
- global.append(' ');
- global.append("CIPHER '",8);
- global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
+ if (ssl_options++)
+ global.append(' ');
+ global.append("CIPHER '",8);
+ global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
global.append('\'');
}
}
@@ -2880,30 +2930,15 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
(acl_user->user_resource.questions | acl_user->user_resource.updates |
acl_user->user_resource.connections))
{
- global.append(" WITH",5);
+ global.append(" WITH",5);
if (want_access & GRANT_ACL)
- global.append(" GRANT OPTION",13);
- if (acl_user->user_resource.questions)
- {
- char buff[22], *p; // just as in int2str
- global.append(" MAX_QUERIES_PER_HOUR ",22);
- p=int10_to_str(acl_user->user_resource.questions,buff,10);
- global.append(buff,p-buff);
- }
- if (acl_user->user_resource.updates)
- {
- char buff[22], *p; // just as in int2str
- global.append(" MAX_UPDATES_PER_HOUR ",22);
- p=int10_to_str(acl_user->user_resource.updates,buff,10);
- global.append(buff,p-buff);
- }
- if (acl_user->user_resource.connections)
- {
- char buff[22], *p; // just as in int2str
- global.append(" MAX_CONNECTIONS_PER_HOUR ",26);
- p=int10_to_str(acl_user->user_resource.connections,buff,10);
- global.append(buff,p-buff);
- }
+ global.append(" GRANT OPTION",13);
+ add_user_option(&global, acl_user->user_resource.questions,
+ "MAX_QUERIES_PER_HOUR");
+ add_user_option(&global, acl_user->user_resource.updates,
+ "MAX_UPDATES_PER_HOUR");
+ add_user_option(&global, acl_user->user_resource.connections,
+ "MAX_CONNECTIONS_PER_HOUR");
}
thd->packet.length(0);
net_store_data(&thd->packet,global.ptr(),global.length());
@@ -2929,7 +2964,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
!my_strcasecmp(lex_user->host.str,host))
{
want_access=acl_db->access;
- if (want_access)
+ if (want_access)
{
String db(buff,sizeof(buff));
db.length(0);
@@ -2938,7 +2973,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL)))
db.append("ALL PRIVILEGES",14);
else if (!(want_access & ~GRANT_ACL))
- db.append("USAGE",5);
+ db.append("USAGE",5);
else
{
int found=0, cnt;
@@ -2954,13 +2989,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
}
- db.append (" ON `",5);
+ db.append(" ON `",5);
db.append(acl_db->db);
- db.append ("`.* TO '",8);
- db.append(lex_user->user.str,lex_user->user.length);
- db.append ("'@'",3);
+ db.append("`.* TO '",8);
+ db.append(lex_user->user.str,lex_user->user.length);
+ db.append("'@'",3);
db.append(lex_user->host.str, lex_user->host.length);
- db.append ('\'');
+ db.append('\'');
if (want_access & GRANT_ACL)
db.append(" WITH GRANT OPTION",18);
thd->packet.length(0);
@@ -2979,7 +3014,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
for (index=0 ; index < hash_tables.records ; index++)
{
const char *user,*host;
- GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
+ GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index);
if (!(user=grant_table->user))
user="";
@@ -2989,44 +3024,54 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (!strcmp(lex_user->user.str,user) &&
!my_strcasecmp(lex_user->host.str,host))
{
- want_access=grant_table->privs;
- if ((want_access | grant_table->cols) != 0)
+ ulong table_access= grant_table->privs;
+ if ((table_access | grant_table->cols) != 0)
{
String global(buff,sizeof(buff));
global.length(0);
global.append("GRANT ",6);
- if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL)))
+ if (test_all_bits(table_access, (TABLE_ACLS & ~GRANT_ACL)))
global.append("ALL PRIVILEGES",14);
- else
+ else
{
- int found=0;
- ulong j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL;
+ int found= 0;
+ ulong j,test_access= (table_access | grant_table->cols) & ~GRANT_ACL;
- for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1)
+ for (counter= 0, j= SELECT_ACL; j <= TABLE_ACLS; counter++, j<<= 1)
{
- if (test_access & j)
+ if (test_access & j)
{
if (found)
global.append(", ",2);
- found = 1;
+ found= 1;
global.append(command_array[counter],command_lengths[counter]);
- if (grant_table->cols)
+ if (grant_table->cols)
{
- uint found_col=0;
+ uint found_col= 0;
for (uint col_index=0 ;
col_index < grant_table->hash_columns.records ;
col_index++)
{
GRANT_COLUMN *grant_column = (GRANT_COLUMN*)
hash_element(&grant_table->hash_columns,col_index);
- if (grant_column->rights & j)
+ if (grant_column->rights & j)
{
- if (!found_col)
+ if (!found_col)
{
+ found_col= 1;
+ /*
+ If we have a duplicated table level privilege, we
+ must write the access privilege name again.
+ */
+ if (table_access & j)
+ {
+ global.append(", ", 2);
+ global.append(command_array[counter],
+ command_lengths[counter]);
+ }
global.append(" (",2);
- found_col=1;
}
else
global.append(", ",2);
@@ -3045,12 +3090,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append("`.`",3);
global.append(grant_table->tname);
global.append("` TO '",6);
- global.append(lex_user->user.str,lex_user->user.length);
+ global.append(lex_user->user.str,lex_user->user.length);
global.append("'@'",3);
- global.append(lex_user->host.str,lex_user->host.length);
+ global.append(lex_user->host.str,lex_user->host.length);
global.append('\'');
- if (want_access & GRANT_ACL)
- global.append(" WITH GRANT OPTION",18);
+ if (table_access & GRANT_ACL)
+ global.append(" WITH GRANT OPTION",18);
thd->packet.length(0);
net_store_data(&thd->packet,global.ptr(),global.length());
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),
@@ -3063,7 +3108,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
- end:
+end:
VOID(pthread_mutex_unlock(&acl_cache->lock));
pthread_mutex_unlock(&LOCK_grant);