diff options
author | unknown <monty@narttu.mysql.fi> | 2003-05-19 16:35:49 +0300 |
---|---|---|
committer | unknown <monty@narttu.mysql.fi> | 2003-05-19 16:35:49 +0300 |
commit | daac922bc306847581b9acee4bcf0a31707d72e7 (patch) | |
tree | 6025913cf3d482ba0783bf3420f7341c10cd574a /sql/sql_parse.cc | |
parent | 7c189b0dcf26ad8e408b8eaa7d69dbbe913ba421 (diff) | |
parent | 68aa31f268660db07b634f021716ecb872e19679 (diff) | |
download | mariadb-git-daac922bc306847581b9acee4bcf0a31707d72e7.tar.gz |
Merge with 4.0.13
BitKeeper/etc/ignore:
auto-union
BitKeeper/etc/logging_ok:
auto-union
BUILD/SETUP.sh:
Auto merged
BitKeeper/deleted/.del-libmysql.def~29fc6d70335f1c4c:
Auto merged
Makefile.am:
Auto merged
acinclude.m4:
Auto merged
BitKeeper/triggers/post-commit:
Auto merged
Build-tools/Do-compile:
Auto merged
VC++Files/libmysql/libmysql.dsp:
Auto merged
VC++Files/mysql.dsw:
Auto merged
client/mysql.cc:
Auto merged
client/mysqlbinlog.cc:
Auto merged
client/mysqldump.c:
Auto merged
include/config-win.h:
Auto merged
include/my_base.h:
Auto merged
include/my_global.h:
Auto merged
include/my_pthread.h:
Auto merged
include/my_sys.h:
Auto merged
include/violite.h:
Auto merged
innobase/buf/buf0flu.c:
Auto merged
innobase/buf/buf0lru.c:
Auto merged
innobase/include/buf0buf.h:
Auto merged
innobase/include/buf0lru.h:
Auto merged
innobase/include/row0mysql.h:
Auto merged
innobase/include/srv0srv.h:
Auto merged
innobase/lock/lock0lock.c:
Auto merged
innobase/log/log0log.c:
Auto merged
innobase/log/log0recv.c:
Auto merged
innobase/os/os0file.c:
Auto merged
innobase/row/row0mysql.c:
Auto merged
innobase/row/row0sel.c:
Auto merged
innobase/srv/srv0srv.c:
Auto merged
innobase/srv/srv0start.c:
Auto merged
innobase/trx/trx0sys.c:
Auto merged
innobase/trx/trx0trx.c:
Auto merged
innobase/ut/ut0ut.c:
Auto merged
myisam/ft_boolean_search.c:
Auto merged
myisam/mi_check.c:
Auto merged
myisam/mi_key.c:
Auto merged
myisam/mi_open.c:
Auto merged
myisam/mi_range.c:
Auto merged
myisam/mi_search.c:
Auto merged
myisam/sort.c:
Auto merged
mysql-test/r/delete.result:
Auto merged
mysql-test/r/fulltext.result:
Auto merged
mysql-test/r/innodb_handler.result:
Auto merged
mysql-test/r/join.result:
Auto merged
mysql-test/r/join_outer.result:
Auto merged
mysql-test/r/key.result:
Auto merged
mysql-test/r/multi_update.result:
Auto merged
mysql-test/r/myisam.result:
Auto merged
mysql-test/r/query_cache.result:
Auto merged
mysql-test/r/select.result:
Auto merged
mysql-test/r/variables.result:
Auto merged
mysql-test/t/alter_table.test:
Auto merged
mysql-test/t/ctype_latin1_de.test:
Auto merged
mysql-test/t/delete.test:
Auto merged
mysql-test/t/fulltext.test:
Auto merged
mysql-test/t/innodb_handler.test:
Auto merged
mysql-test/t/join.test:
Auto merged
mysql-test/t/join_outer.test:
Auto merged
mysql-test/t/key.test:
Auto merged
mysql-test/t/multi_update.test:
Auto merged
mysql-test/t/myisam.test:
Auto merged
mysql-test/t/query_cache.test:
Auto merged
mysql-test/t/repair.test:
Auto merged
mysql-test/t/select_safe.test:
Auto merged
mysql-test/t/type_decimal.test:
Auto merged
mysql-test/t/variables.test:
Auto merged
mysys/default.c:
Auto merged
mysys/my_pthread.c:
Auto merged
scripts/mysql_fix_privilege_tables.sh:
Auto merged
scripts/mysqld_safe.sh:
Auto merged
sql/ha_heap.h:
Auto merged
sql/ha_innodb.h:
Auto merged
sql/ha_myisam.cc:
Auto merged
sql/handler.cc:
Auto merged
sql/handler.h:
Auto merged
sql/init.cc:
Auto merged
sql/item.cc:
Auto merged
sql/item_create.cc:
Auto merged
sql/item_strfunc.cc:
Auto merged
sql/item_sum.cc:
Auto merged
sql/mini_client.cc:
Auto merged
sql/net_serv.cc:
Auto merged
sql/opt_range.cc:
Auto merged
sql/records.cc:
Auto merged
sql/slave.cc:
Auto merged
sql/sql_acl.h:
Auto merged
sql/sql_analyse.cc:
Auto merged
sql/sql_class.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_list.h:
Auto merged
sql/sql_load.cc:
Auto merged
sql/share/czech/errmsg.txt:
Auto merged
sql/share/danish/errmsg.txt:
Auto merged
sql/share/dutch/errmsg.txt:
Auto merged
sql/share/english/errmsg.txt:
Auto merged
sql/share/estonian/errmsg.txt:
Auto merged
sql/share/french/errmsg.txt:
Auto merged
sql/share/greek/errmsg.txt:
Auto merged
sql/share/hungarian/errmsg.txt:
Auto merged
sql/share/italian/errmsg.txt:
Auto merged
sql/share/japanese/errmsg.txt:
Auto merged
sql/share/korean/errmsg.txt:
Auto merged
sql/share/norwegian-ny/errmsg.txt:
Auto merged
sql/share/norwegian/errmsg.txt:
Auto merged
sql/share/portuguese/errmsg.txt:
Auto merged
sql/share/romanian/errmsg.txt:
Auto merged
sql/share/russian/errmsg.txt:
Auto merged
sql/share/slovak/errmsg.txt:
Auto merged
sql/share/spanish/errmsg.txt:
Auto merged
sql/share/swedish/errmsg.txt:
Auto merged
sql/share/ukrainian/errmsg.txt:
Auto merged
sql/unireg.h:
Auto merged
sql-bench/crash-me.sh:
Auto merged
sql-bench/test-transactions.sh:
Auto merged
strings/ctype-tis620.c:
Auto merged
tests/grant.res:
Auto merged
sql/log_event.cc:
Merge with 4.0.13
Cleaned up comment syntax
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 133 |
1 files changed, 107 insertions, 26 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1d2449839d8..45c5ea4d520 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -213,7 +213,15 @@ static int check_user(THD *thd,enum_server_command command, const char *user, thd->db=0; thd->db_length=0; USER_RESOURCES ur; + char tmp_passwd[SCRAMBL41_LENGTH]; DBUG_ENTER("check_user"); + + /* + Move password to temporary buffer as it may be stored in communication + buffer + */ + strmake(tmp_passwd, passwd, sizeof(tmp_passwd)); + passwd= tmp_passwd; // Use local copy /* We shall avoid dupplicate user allocations here */ if (!thd->user && !(thd->user = my_strdup(user, MYF(0)))) @@ -222,7 +230,8 @@ static int check_user(THD *thd,enum_server_command command, const char *user, DBUG_RETURN(1); } thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, - passwd, thd->scramble, &thd->priv_user, + passwd, thd->scramble, + &thd->priv_user, &thd->priv_host, (protocol_version == 9 || !(thd->client_capabilities & CLIENT_LONG_PASSWORD)), @@ -230,9 +239,9 @@ static int check_user(THD *thd,enum_server_command command, const char *user, cur_priv_version,hint_user); DBUG_PRINT("info", - ("Capabilities: %d packet_length: %ld Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'", + ("Capabilities: %d packet_length: %ld Host: '%s' Login user: '%s' Priv_user: '%s' Using password: %s Access: %u db: '%s'", thd->client_capabilities, thd->max_client_packet_length, - thd->host_or_ip, thd->priv_user, + thd->host_or_ip, thd->user, thd->priv_user, had_password ? "yes": "no", thd->master_access, thd->db ? thd->db : "*none*")); @@ -307,6 +316,7 @@ static int check_user(THD *thd,enum_server_command command, const char *user, DBUG_RETURN(error); } send_ok(thd); // Ready to handle questions + thd->password= test(passwd[0]); // Remember for error messages DBUG_RETURN(0); // ok } @@ -582,7 +592,6 @@ check_connections(THD *thd) DBUG_PRINT("info",("Host: %s",thd->host)); thd->host_or_ip= thd->host; thd->ip= 0; - thd->peer_port= 0; bzero((char*) &thd->remote,sizeof(struct sockaddr)); } /* Ensure that wrong hostnames doesn't cause buffer overflows */ @@ -751,7 +760,6 @@ check_connections(THD *thd) } else if (res) return -1; // Error sent from check_user() - thd->password=using_password; return 0; } @@ -1551,7 +1559,8 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) /* We must allocate some extra memory for query cache */ if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), packet_length, - thd->db_length+2))) + thd->db_length+2+ + sizeof(ha_rows)))) return 1; thd->query[packet_length]=0; thd->query_length= packet_length; @@ -1648,6 +1657,18 @@ mysql_execute_command(THD *thd) #endif ) DBUG_VOID_RETURN; + + /* + When option readonly is set deny operations which change tables. + Except for the replication thread and the 'super' users. + */ + if (opt_readonly && + !(thd->slave_thread || (thd->master_access & SUPER_ACL)) && + (uc_update_queries[lex->sql_command] > 0)) + { + send_error(&thd->net,ER_CANT_UPDATE_WITH_READLOCK); + DBUG_VOID_RETURN; + } statistic_increment(com_stat[lex->sql_command],&LOCK_status); switch (lex->sql_command) { @@ -1832,7 +1853,8 @@ mysql_execute_command(THD *thd) } case SQLCOM_SHOW_SLAVE_STAT: { - if (check_global_access(thd, SUPER_ACL)) + /* Accept one of two privileges */ + if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL)) goto error; LOCK_ACTIVE_MI; res = show_master_info(thd,active_mi); @@ -1841,7 +1863,8 @@ mysql_execute_command(THD *thd) } case SQLCOM_SHOW_MASTER_STAT: { - if (check_global_access(thd, SUPER_ACL)) + /* Accept one of two privileges */ + if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL)) goto error; res = show_binlog_info(thd); break; @@ -3058,12 +3081,21 @@ error: /**************************************************************************** Get the user (global) and database privileges for all used tables - Returns true (error) if we can't get the privileges and we don't use - table/column grants. - The idea of EXTRA_ACL is that one will be granted access to the table if - one has the asked privilege on any column combination of the table; For - example to be able to check a table one needs to have SELECT privilege on - any column of the table. + + NOTES + The idea of EXTRA_ACL is that one will be granted access to the table if + one has the asked privilege on any column combination of the table; For + example to be able to check a table one needs to have SELECT privilege on + any column of the table. + + RETURN + 0 ok + 1 If we can't get the privileges and we don't use table/column grants. + + save_priv In this we store global and db level grants for the table + Note that we don't store db level grants if the global grants + is enough to satisfy the request and the global grants contains + a SELECT grant. ****************************************************************************/ bool @@ -3088,7 +3120,17 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if ((thd->master_access & want_access) == want_access) { - *save_priv=thd->master_access; + /* + If we don't have a global SELECT privilege, we have to get the database + specific access rights to be able to handle queries of type + UPDATE t1 SET a=1 WHERE b > 0 + */ + db_access= thd->db_access; + if (!(thd->master_access & SELECT_ACL) && + (db && (!thd->db || strcmp(db,thd->db)))) + db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr, + thd->priv_user, db); /* purecov: inspected */ + *save_priv=thd->master_access | db_access; DBUG_RETURN(FALSE); } if (((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL)) || @@ -3097,7 +3139,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (!no_errors) net_printf(thd,ER_ACCESS_DENIED_ERROR, thd->priv_user, - thd->host_or_ip, + thd->priv_host, thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -3122,18 +3164,35 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (!no_errors) net_printf(thd,ER_DBACCESS_DENIED_ERROR, thd->priv_user, - thd->host_or_ip, + thd->priv_host, db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } -/* check for global access and give descriptive error message if it fails */ +/* + check for global access and give descriptive error message if it fails + + SYNOPSIS + check_global_access() + thd Thread handler + want_access Use should have any of these global rights + + WARNING + One gets access rigth if one has ANY of the rights in want_access + This is useful as one in most cases only need one global right, + but in some case we want to check if the user has SUPER or + REPL_CLIENT_ACL rights. + + RETURN + 0 ok + 1 Access denied. In this case an error is sent to the client +*/ bool check_global_access(THD *thd, ulong want_access) { char command[128]; - if ((thd->master_access & want_access) == want_access) + if ((thd->master_access & want_access)) return 0; get_privilege_desc(command, sizeof(command), want_access); net_printf(thd,ER_SPECIFIC_ACCESS_DENIED_ERROR, @@ -3237,6 +3296,7 @@ static bool check_merge_table_access(THD *thd, char *db, #define used_stack(A,B) (long) (B - A) #endif +#ifndef EMBEDDED_LIBRARY bool check_stack_overrun(THD *thd,char *buf __attribute__((unused))) { long stack_used; @@ -3250,6 +3310,7 @@ bool check_stack_overrun(THD *thd,char *buf __attribute__((unused))) } return 0; } +#endif /* EMBEDDED_LIBRARY */ #define MY_YACC_INIT 1000 // Start with big alloc #define MY_YACC_MAX 32000 // Because of 'short' @@ -3548,9 +3609,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->comment.str= (char*) comment->str_value.ptr(); new_field->comment.length=comment->str_value.length(); } - if (length) - if (!(new_field->length= (uint) atoi(length))) - length=0; /* purecov: inspected */ + if (length && !(new_field->length= (uint) atoi(length))) + length=0; /* purecov: inspected */ uint sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1; if (new_field->length && new_field->decimals && @@ -3583,10 +3643,13 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, break; case FIELD_TYPE_DECIMAL: if (!length) - new_field->length = 10; // Default length for DECIMAL - new_field->length+=sign_len; - if (new_field->decimals) - new_field->length++; + new_field->length= 10; // Default length for DECIMAL + if (new_field->length < MAX_FIELD_WIDTH) // Skip wrong argument + { + new_field->length+=sign_len; + if (new_field->decimals) + new_field->length++; + } break; case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: @@ -4011,6 +4074,24 @@ void add_join_on(TABLE_LIST *b,Item *expr) } +/* + Mark that we have a NATURAL JOIN between two tables + + SYNOPSIS + add_join_natural() + a Table to do normal join with + b Do normal join with this table + + IMPLEMENTATION + This function just marks that table b should be joined with a. + The function setup_cond() will create in b->on_expr a list + of equal condition between all fields of the same name. + + SELECT * FROM t1 NATURAL LEFT JOIN t2 + <=> + SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... ) +*/ + void add_join_natural(TABLE_LIST *a,TABLE_LIST *b) { b->natural_join=a; |