summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authorpeter@mysql.com <>2002-11-30 20:58:53 +0300
committerpeter@mysql.com <>2002-11-30 20:58:53 +0300
commita24258375a59e37d728dffae05235c59d283a6ab (patch)
treed6fd910fa1f2f46f32ad57ff34b8c30051905e04 /sql/sql_parse.cc
parent54ff0efe7cb79c2f3e7acc84f74905d750e51ba0 (diff)
downloadmariadb-git-a24258375a59e37d728dffae05235c59d283a6ab.tar.gz
SCRUM: Montymise code
fix mysql_change_user() for old clients
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc241
1 files changed, 117 insertions, 124 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index bdb074b304d..cfca7420237 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -44,8 +44,6 @@
#else
#define MIN_HANDSHAKE_SIZE 6
#endif /* HAVE_OPENSSL */
-#define SCRAMBLE_LENGTH 8
-#define SCRAMBLE41_LENGTH 20
#define MEM_ROOT_BLOCK_SIZE 8192
#define MEM_ROOT_PREALLOC 8192
@@ -129,7 +127,7 @@ extern pthread_mutex_t LOCK_user_conn;
static int get_or_create_user_conn(THD *thd, const char *user,
const char *host,
- USER_RESOURCES *mqh)
+ USER_RESOURCES *mqh)
{
int return_val=0;
uint temp_len, user_len, host_len;
@@ -163,7 +161,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
uc->connections = 1;
uc->questions=uc->updates=uc->conn_per_hour=0;
uc->user_resources=*mqh;
- if (max_user_connections && mqh->connections > max_user_connections)
+ if (max_user_connections && mqh->connections > max_user_connections)
uc->user_resources.connections = max_user_connections;
uc->intime=thd->thr_create_time;
if (hash_insert(&hash_user_connections, (byte*) uc))
@@ -178,7 +176,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
end:
(void) pthread_mutex_unlock(&LOCK_user_conn);
return return_val;
-
+
}
@@ -189,16 +187,16 @@ end:
*/
static int check_user(THD *thd,enum_server_command command, const char *user,
- const char *passwd, const char *db, bool check_count,
+ const char *passwd, const char *db, bool check_count,
bool do_send_error, char* crypted_scramble,int stage,
- bool had_password,uint *cur_priv_version,
+ bool had_password,uint *cur_priv_version,
ACL_USER** hint_user)
{
thd->db=0;
thd->db_length=0;
USER_RESOURCES ur;
-
- /* We shall avoid dupplicate user allocations here */
+
+ /* We shall avoid dupplicate user allocations here */
if (!(thd->user))
if (!(thd->user = my_strdup(user, MYF(0))))
{
@@ -211,15 +209,15 @@ static int check_user(THD *thd,enum_server_command command, const char *user,
!(thd->client_capabilities &
CLIENT_LONG_PASSWORD),&ur,crypted_scramble,
stage,cur_priv_version,hint_user);
-
+
DBUG_PRINT("info",
("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
thd->client_capabilities, thd->max_client_packet_length,
thd->host_or_ip, thd->priv_user,
had_password ? "yes": "no",
thd->master_access, thd->db ? thd->db : "*none*"));
-
- /* in case we're going to retry we should not send error message at this point */
+
+ /* in case we're going to retry we should not send error message at this point */
if (thd->master_access & NO_ACCESS)
{
if (do_send_error)
@@ -233,11 +231,11 @@ static int check_user(THD *thd,enum_server_command command, const char *user,
thd->host_or_ip,
had_password ? ER(ER_YES) : ER(ER_NO));
return(1); // Error already given
- }
- else
+ }
+ else
return(-1); // do not report error in special handshake
}
-
+
if (check_count)
{
VOID(pthread_mutex_lock(&LOCK_thread_count));
@@ -262,16 +260,16 @@ static int check_user(THD *thd,enum_server_command command, const char *user,
if ((ur.questions || ur.updates || ur.connections) &&
get_or_create_user_conn(thd,user,thd->host_or_ip,&ur))
return -1;
- if (thd->user_connect && thd->user_connect->user_resources.connections &&
+ if (thd->user_connect && thd->user_connect->user_resources.connections &&
check_for_max_user_connections(thd, thd->user_connect))
return -1;
-
+
if (db && db[0])
{
bool error=test(mysql_change_db(thd,db));
if (error && thd->user_connect)
decrease_user_connections(thd->user_connect);
- return error;
+ return error;
}
else
send_ok(thd); // Ready to handle questions
@@ -296,7 +294,7 @@ extern "C" void free_user(struct user_conn *uc)
my_free((char*) uc,MYF(0));
}
-void init_max_user_conn(void)
+void init_max_user_conn(void)
{
(void) hash_init(&hash_user_connections,system_charset_info,max_connections,
0,0,
@@ -309,7 +307,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
{
int error=0;
DBUG_ENTER("check_for_max_user_connections");
-
+
if (max_user_connections &&
(max_user_connections <= (uint) uc->connections))
{
@@ -317,7 +315,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
error=1;
goto end;
}
- uc->connections++;
+ uc->connections++;
if (uc->user_resources.connections &&
uc->conn_per_hour++ >= uc->user_resources.connections)
{
@@ -441,7 +439,7 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them=false)
{
(void) pthread_mutex_lock(&LOCK_user_conn);
- if (lu) // for GRANT
+ if (lu) // for GRANT
{
USER_CONN *uc;
uint temp_len=lu->user.length+lu->host.length+2;
@@ -530,9 +528,9 @@ check_connections(THD *thd)
ulong pkt_len=0;
{
/* buff[] needs to big enough to hold the server_version variable */
- char buff[SERVER_VERSION_LENGTH +
+ char buff[SERVER_VERSION_LENGTH +
SCRAMBLE_LENGTH+64],*end;
- int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
+ int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION;
if (opt_using_transactions)
@@ -555,7 +553,7 @@ check_connections(THD *thd)
int2store(end+3,thd->server_status);
bzero(end+5,13);
end+=18;
-
+
// At this point we write connection message and read reply
if (net_write_command(net,(uchar) protocol_version, "", 0, buff,
(uint) (end-buff)) ||
@@ -588,7 +586,7 @@ check_connections(THD *thd)
DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
pkt_len));
inc_host_errors(&thd->remote.sin_addr);
- return(ER_HANDSHAKE_ERROR);
+ return(ER_HANDSHAKE_ERROR);
}
DBUG_PRINT("info", ("Reading user information over SSL layer"));
if ((pkt_len=my_net_read(net)) == packet_error ||
@@ -615,81 +613,73 @@ check_connections(THD *thd)
char *user= (char*) net->read_pos+5;
char *passwd= strend(user)+1;
char *db=0;
- if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
- db=strend(passwd)+1;
-
+ if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
+ db=strend(passwd)+1;
+
/* We can get only old hash at this point */
- if (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH)
+ if (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH)
return ER_HANDSHAKE_ERROR;
-
+
if (thd->client_capabilities & CLIENT_INTERACTIVE)
thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions)
thd->net.return_status= &thd->server_status;
net->read_timeout=(uint) thd->variables.net_read_timeout;
-
+
char prepared_scramble[SCRAMBLE41_LENGTH+4]; /* Buffer for scramble and hash */
-
+
ACL_USER* cached_user;
uint cur_priv_version;
-
+
/* Simple connect only for old clients. New clients always use secure auth */
bool simple_connect=(!(thd->client_capabilities & CLIENT_SECURE_CONNECTION));
-
+
/* Store information if we used password. passwd will be dammaged */
bool using_password=test(passwd[0]);
-
+
/* Check user permissions. If password failure we'll get scramble back */
if (check_user(thd,COM_CONNECT, user, passwd, db, 1, simple_connect,
prepared_scramble,0,using_password,&cur_priv_version,&cached_user)<0)
- {
+ {
/* If The client is old we just have to return error */
if (simple_connect)
- return -1;
-
+ return -1;
+
/* Store current used and database as they are erased with next packet */
-
+
char tmp_user[USERNAME_LENGTH+1];
char tmp_db[NAME_LEN+1];
+ tmp_user[0]=0;
if (user)
- {
- strncpy(tmp_user,user,USERNAME_LENGTH+1);
- /* Extra safety if we have too long data */
- tmp_user[USERNAME_LENGTH]=0;
- }
- else
- tmp_user[0]=0;
+ strmake(tmp_user,user,USERNAME_LENGTH);
+
+ tmp_db[0]=0;
if (db)
- {
- strncpy(tmp_db,db,NAME_LEN+1);
- tmp_db[NAME_LEN]=0;
- }
- else
- tmp_db[0]=0;
-
+ strmake(tmp_db,db,NAME_LEN);
+
/* Write hash and encrypted scramble to client */
- if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4)
- || net_flush(net))
+ if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4)
+ || net_flush(net))
{
inc_host_errors(&thd->remote.sin_addr);
return ER_HANDSHAKE_ERROR;
- }
- /* Reading packet back */
- if ((pkt_len=my_net_read(net)) == packet_error)
+ }
+ /* Reading packet back */
+ if ((pkt_len=my_net_read(net)) == packet_error)
{
inc_host_errors(&thd->remote.sin_addr);
return ER_HANDSHAKE_ERROR;
}
- /* We have to get very specific packet size */
- if (pkt_len!=SCRAMBLE41_LENGTH)
+ /* We have to get very specific packet size */
+ if (pkt_len!=SCRAMBLE41_LENGTH)
{
inc_host_errors(&thd->remote.sin_addr);
- return ER_HANDSHAKE_ERROR;
+ return ER_HANDSHAKE_ERROR;
}
- /* Final attempt to check the user based on reply */
- if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos,
+ /* Final attempt to check the user based on reply */
+ if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos,
tmp_db, 1, 1,prepared_scramble,1,using_password,&cur_priv_version,
&cached_user))
return -1;
@@ -796,7 +786,7 @@ pthread_handler_decl(handle_one_connection,arg)
send_error(thd,net->last_errno,NullS);
statistic_increment(aborted_threads,&LOCK_status);
}
-
+
end_thread:
close_connection(net);
end_thread(thd,1);
@@ -854,7 +844,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
while (fgets(buff, thd->net.max_packet, file))
{
uint length=(uint) strlen(buff);
- while (length && (my_isspace(system_charset_info, buff[length-1]) ||
+ while (length && (my_isspace(system_charset_info, buff[length-1]) ||
buff[length-1] == ';'))
length--;
buff[length]=0;
@@ -1043,7 +1033,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char *user= (char*) packet;
char *passwd= strend(user)+1;
char *db= strend(passwd)+1;
-
+
/* Save user and privileges */
uint save_master_access=thd->master_access;
uint save_db_access= thd->db_access;
@@ -1055,43 +1045,46 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
USER_CONN *save_uc= thd->user_connect;
bool simple_connect;
bool using_password;
-
+
ulong pkt_len=0; /* Length of reply packet */
-
+
/* Small check for incomming packet */
if ((uint) ((uchar*) db - net->read_pos) > packet_length)
goto restore_user_err;
-
+
/* Now we shall basically perform authentication again */
-
+
/* We can get only old hash at this point */
- if (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH)
+ if (passwd[0] && strlen(passwd)!=SCRAMBLE_LENGTH)
goto restore_user_err;
-
- char prepared_scramble[SCRAMBLE41_LENGTH+4];/* Buffer for scramble,hash */
+
+ char prepared_scramble[SCRAMBLE41_LENGTH+4];/* Buffer for scramble,hash */
ACL_USER* cached_user; /* Cached user */
uint cur_priv_version; /* Cached grant version */
-
+
/* Simple connect only for old clients. New clients always use sec. auth*/
simple_connect=(!(thd->client_capabilities & CLIENT_SECURE_CONNECTION));
-
+
/* Store information if we used password. passwd will be dammaged */
using_password=test(passwd[0]);
-
- /*
- Check user permissions. If password failure we'll get scramble back
- Do not retry if we already have sent error (result>0)
- */
+
+ if (simple_connect) /* Restore scramble for old clients */
+ memcpy(thd->scramble,thd->old_scramble,9);
+
+ /*
+ Check user permissions. If password failure we'll get scramble back
+ Do not retry if we already have sent error (result>0)
+ */
if (check_user(thd,COM_CHANGE_USER, user, passwd, db, 0, simple_connect,
- prepared_scramble,0,using_password,&cur_priv_version,&cached_user)<0)
+ prepared_scramble,0,using_password,&cur_priv_version,&cached_user)<0)
{
/* If The client is old we just have to have auth failure */
if (simple_connect)
goto restore_user; /* Error is already reported */
-
+
/* Store current used and database as they are erased with next packet */
-
+
char tmp_user[USERNAME_LENGTH+1];
char tmp_db[NAME_LEN+1];
@@ -1099,33 +1092,33 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
strncpy(tmp_user,user,USERNAME_LENGTH+1);
/* Extra safety if we have too long data */
- tmp_user[USERNAME_LENGTH]=0;
- }
+ tmp_user[USERNAME_LENGTH]=0;
+ }
else
- tmp_user[0]=0;
+ tmp_user[0]=0;
if (db)
{
strncpy(tmp_db,db,NAME_LEN+1);
tmp_db[NAME_LEN]=0;
- }
- else
+ }
+ else
tmp_db[0]=0;
-
+
/* Write hash and encrypted scramble to client */
- if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4)
- || net_flush(net))
- goto restore_user_err;
-
- /* Reading packet back */
- if ((pkt_len=my_net_read(net)) == packet_error)
+ if (my_net_write(net,prepared_scramble,SCRAMBLE41_LENGTH+4)
+ || net_flush(net))
goto restore_user_err;
-
- /* We have to get very specific packet size */
- if (pkt_len!=SCRAMBLE41_LENGTH)
+
+ /* Reading packet back */
+ if ((pkt_len=my_net_read(net)) == packet_error)
+ goto restore_user_err;
+
+ /* We have to get very specific packet size */
+ if (pkt_len!=SCRAMBLE41_LENGTH)
goto restore_user;
-
- /* Final attempt to check the user based on reply */
- if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos,
+
+ /* Final attempt to check the user based on reply */
+ if (check_user(thd,COM_CONNECT, tmp_user, (char*)net->read_pos,
tmp_db, 0, 1,prepared_scramble,1,using_password,&cur_priv_version,
&cached_user))
goto restore_user;
@@ -1137,11 +1130,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
x_free((gptr) save_user);
thd->password=using_password;
break;
-
+
/* Bad luck we shall restore old user */
restore_user_err:
send_error(thd, ER_UNKNOWN_COM_ERROR);
-
+
restore_user:
x_free(thd->user);
x_free(thd->db);
@@ -1150,10 +1143,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->db=save_db;
thd->db_length=save_db_length;
thd->user=save_user;
- thd->priv_user=save_priv_user;
+ thd->priv_user=save_priv_user;
break;
}
-
+
case COM_EXECUTE:
{
mysql_stmt_execute(thd, packet);
@@ -1444,7 +1437,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length)
packet_length--;
}
char *pos=packet+packet_length; // Point at end null
- while (packet_length > 0 &&
+ while (packet_length > 0 &&
(pos[-1] == ';' || my_isspace(system_charset_info,pos[-1])))
{
pos--;
@@ -1496,7 +1489,7 @@ mysql_execute_command(THD *thd)
if (thd->slave_thread)
{
- /*
+ /*
Skip if we are in the slave thread, some table rules have been
given and the table list says the query should not be replicated
*/
@@ -1515,7 +1508,7 @@ mysql_execute_command(THD *thd)
}
#endif
}
-
+
/*
TODO: make derived tables processing 'inside' SELECT processing.
TODO: solve problem with depended derived tables in subselects
@@ -1532,13 +1525,13 @@ mysql_execute_command(THD *thd)
(SELECT_LEX_UNIT *)
cursor->derived,
cursor)))
- {
+ {
if (res < 0 || thd->net.report_error)
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
DBUG_VOID_RETURN;
}
}
- if ((&lex->select_lex != lex->all_selects_list &&
+ if ((&lex->select_lex != lex->all_selects_list &&
lex->unit.create_total_list(thd, lex, &tables)) ||
(table_rules_on && tables && thd->slave_thread &&
!tables_ok(thd,tables)))
@@ -1568,7 +1561,7 @@ mysql_execute_command(THD *thd)
unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit;
unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+
unit->global_parameters->offset_limit);
- if (unit->select_limit_cnt <
+ if (unit->select_limit_cnt <
(ha_rows) unit->global_parameters->select_limit)
unit->select_limit_cnt= HA_POS_ERROR; // no limit
if (unit->select_limit_cnt == HA_POS_ERROR)
@@ -1714,7 +1707,7 @@ mysql_execute_command(THD *thd)
res = show_binlog_info(thd);
break;
}
-
+
case SQLCOM_LOAD_MASTER_DATA: // sync with master
if (check_global_access(thd, SUPER_ACL))
goto error;
@@ -1723,7 +1716,7 @@ mysql_execute_command(THD *thd)
else
res = load_master_data(thd);
break;
-
+
#ifdef HAVE_INNOBASE_DB
case SQLCOM_SHOW_INNODB_STATUS:
{
@@ -1899,7 +1892,7 @@ mysql_execute_command(THD *thd)
select_lex->db=tables->db;
if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) ||
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv) ||
- check_merge_table_access(thd, tables->db,
+ check_merge_table_access(thd, tables->db,
(TABLE_LIST *)
lex->create_info.merge_list.first))
goto error; /* purecov: inspected */
@@ -1981,7 +1974,7 @@ mysql_execute_command(THD *thd)
res = show_binlogs(thd);
break;
}
-#endif
+#endif
case SQLCOM_SHOW_CREATE:
#ifdef DONT_ALLOW_SHOW_COMMANDS
send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
@@ -2611,7 +2604,7 @@ mysql_execute_command(THD *thd)
if (user->password.str &&
(strcmp(thd->user,user->user.str) ||
user->host.str &&
- my_strcasecmp(system_charset_info,
+ my_strcasecmp(system_charset_info,
user->host.str, thd->host_or_ip)))
{
if (check_access(thd, UPDATE_ACL, "mysql",0,1))
@@ -3012,7 +3005,7 @@ mysql_init_query(THD *thd)
lex->select_lex.init_query();
lex->value_list.empty();
lex->param_list.empty();
- lex->unit.global_parameters= lex->unit.slave= lex->current_select=
+ lex->unit.global_parameters= lex->unit.slave= lex->current_select=
lex->all_selects_list= &lex->select_lex;
lex->select_lex.master= &lex->unit;
lex->select_lex.prev= &lex->unit.slave;
@@ -3020,7 +3013,7 @@ mysql_init_query(THD *thd)
lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
lex->olap=lex->describe=0;
lex->derived_tables= false;
- thd->check_loops_counter= thd->select_number=
+ thd->check_loops_counter= thd->select_number=
lex->select_lex.select_number= 1;
thd->free_list= 0;
thd->total_warn_count=0; // Warnings for this query
@@ -3037,7 +3030,7 @@ mysql_init_select(LEX *lex)
SELECT_LEX *select_lex= lex->current_select->select_lex();
DBUG_ASSERT(select_lex->linkage != GLOBAL_OPTIONS_TYPE);
select_lex->init_select();
- select_lex->master_unit()->select_limit= select_lex->select_limit=
+ select_lex->master_unit()->select_limit= select_lex->select_limit=
lex->thd->variables.select_limit;
lex->exchange= 0;
lex->result= 0;
@@ -3067,7 +3060,7 @@ mysql_new_select(LEX *lex, bool move_down)
}
else
select_lex->include_neighbour(lex->current_select);
-
+
select_lex->master_unit()->global_parameters= select_lex;
DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
@@ -3577,10 +3570,10 @@ TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table,
if (!alias) /* Alias is case sensitive */
if (!(alias_str=thd->memdup(alias_str,table->table.length+1)))
DBUG_RETURN(0);
-
+
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
DBUG_RETURN(0); /* purecov: inspected */
- if (table->db.str)
+ if (table->db.str)
{
ptr->db= table->db.str;
ptr->db_length= table->db.length;
@@ -3596,7 +3589,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table,
ptr->db= empty_c_string;
ptr->db_length= 0;
}
-
+
ptr->alias= alias_str;
if (lower_case_table_names)
{