Server IP : 104.21.38.3 / Your IP : 108.162.226.18 Web Server : Apache System : Linux krdc-ubuntu-s-2vcpu-4gb-amd-blr1-01.localdomain 5.15.0-142-generic #152-Ubuntu SMP Mon May 19 10:54:31 UTC 2025 x86_64 User : www ( 1000) PHP Version : 7.4.33 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /www/server/mysql/src/sql/ |
Upload File : |
/* Copyright (c) 2011, 2023, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is also distributed with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have included with MySQL. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* In here, we rewrite queries (to obfuscate passwords etc.) that need it before we log them. Stored procedures may also rewrite their statements (to show the actual values of their variables etc.). There is currently no scenario where a statement can be eligible for both rewrites. (see sp_instr.cc) Special consideration will need to be taken if this assertion is changed. We also do not intersect with query cache at this time, as QC only caches SELECTs (which we don't rewrite). If and when QC becomes more general, it should probably cache the rewritten query along with the user-submitted one. (see sql_parse.cc) */ #include "auth_common.h" // append_user #include "sql_parse.h" // get_current_user #include "sql_show.h" // append_identifier #include "sp_head.h" // struct set_var_base #include "rpl_slave.h" // SLAVE_SQL, SLAVE_IO #include "mysqld.h" // opt_log_builtin_as_identified_by_password #include "log.h" /** Append a key/value pair to a string, with an optional preceding comma. For numeric values. @param str The string to append to @param comma Prepend a comma? @param txt C-string, must end in a space @param len strlen(txt) @param val numeric value @param cond only append if this evaluates to true @retval false if any subsequent key/value pair would be the first */ bool append_int(String *str, bool comma, const char *txt, size_t len, long val, int cond) { if (cond) { String numbuf(42); if (comma) str->append(STRING_WITH_LEN(", ")); str->append(txt,len); numbuf.set((longlong)val,&my_charset_bin); str->append(numbuf); return true; } return comma; } /** Append a key/value pair to a string if the value is non-NULL, with an optional preceding comma. @param str The string to append to @param comma Prepend a comma? @param key C-string: the key, must be non-NULL @param val C-string: the value @retval false if any subsequent key/value pair would be the first */ bool append_str(String *str, bool comma, const char *key, const char *val) { if (val) { if (comma) str->append(STRING_WITH_LEN(", ")); str->append(key); str->append(STRING_WITH_LEN(" '")); str->append(val); str->append(STRING_WITH_LEN("'")); return true; } return comma; } void rewrite_ssl_properties(LEX *lex, String *rlb) { if (lex->ssl_type != SSL_TYPE_NOT_SPECIFIED) { rlb->append(STRING_WITH_LEN(" REQUIRE")); switch (lex->ssl_type) { case SSL_TYPE_SPECIFIED: if (lex->x509_subject) { rlb->append(STRING_WITH_LEN(" SUBJECT '")); rlb->append(lex->x509_subject); rlb->append(STRING_WITH_LEN("'")); } if (lex->x509_issuer) { rlb->append(STRING_WITH_LEN(" ISSUER '")); rlb->append(lex->x509_issuer); rlb->append(STRING_WITH_LEN("'")); } if (lex->ssl_cipher) { rlb->append(STRING_WITH_LEN(" CIPHER '")); rlb->append(lex->ssl_cipher); rlb->append(STRING_WITH_LEN("'")); } break; case SSL_TYPE_X509: rlb->append(STRING_WITH_LEN(" X509")); break; case SSL_TYPE_ANY: rlb->append(STRING_WITH_LEN(" SSL")); break; case SSL_TYPE_NOT_SPECIFIED: /* fall-thru */ case SSL_TYPE_NONE: rlb->append(STRING_WITH_LEN(" NONE")); break; } } } void rewrite_user_resources(LEX *lex, String *rlb) { if (lex->mqh.specified_limits || (lex->grant & GRANT_ACL)) { rlb->append(STRING_WITH_LEN(" WITH")); if (lex->grant & GRANT_ACL) rlb->append(STRING_WITH_LEN(" GRANT OPTION")); append_int(rlb, false, STRING_WITH_LEN(" MAX_QUERIES_PER_HOUR "), lex->mqh.questions, lex->mqh.specified_limits & USER_RESOURCES::QUERIES_PER_HOUR); append_int(rlb, false, STRING_WITH_LEN(" MAX_UPDATES_PER_HOUR "), lex->mqh.updates, lex->mqh.specified_limits & USER_RESOURCES::UPDATES_PER_HOUR); append_int(rlb, false, STRING_WITH_LEN(" MAX_CONNECTIONS_PER_HOUR "), lex->mqh.conn_per_hour, lex->mqh.specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR); append_int(rlb, false, STRING_WITH_LEN(" MAX_USER_CONNECTIONS "), lex->mqh.user_conn, lex->mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS); } } void rewrite_account_lock(LEX *lex, String *rlb) { if (lex->alter_password.account_locked) { rlb->append(STRING_WITH_LEN(" ACCOUNT LOCK")); } else { rlb->append(STRING_WITH_LEN(" ACCOUNT UNLOCK")); } } /** Rewrite a GRANT statement. @param thd The THD to rewrite for. @param rlb An empty String object to put the rewritten query in. */ void mysql_rewrite_grant(THD *thd, String *rlb) { LEX *lex= thd->lex; TABLE_LIST *first_table= lex->select_lex->table_list.first; bool comma= FALSE, comma_inner; bool proxy_grant= lex->type == TYPE_ENUM_PROXY; String cols(1024); int c; rlb->append(STRING_WITH_LEN("GRANT ")); if (proxy_grant) rlb->append(STRING_WITH_LEN("PROXY")); else if (lex->all_privileges) rlb->append(STRING_WITH_LEN("ALL PRIVILEGES")); else { ulong priv; for (c= 0, priv= SELECT_ACL; priv <= GLOBAL_ACLS; c++, priv <<= 1) { if (priv == GRANT_ACL) continue; comma_inner= FALSE; if (lex->columns.elements) // show columns, if any { class LEX_COLUMN *column; List_iterator <LEX_COLUMN> column_iter(lex->columns); cols.length(0); cols.append(STRING_WITH_LEN(" (")); /* If the statement was GRANT SELECT(f2), INSERT(f3), UPDATE(f1,f3, f2), our list cols will contain the order f2, f3, f1, and thus that's the order we'll recreate the privilege: UPDATE (f2, f3, f1) */ while ((column= column_iter++)) { if (column->rights & priv) { if (comma_inner) cols.append(STRING_WITH_LEN(", ")); else comma_inner= TRUE; append_identifier(thd, &cols, column->column.ptr(), column->column.length()); } } cols.append(STRING_WITH_LEN(")")); } if (comma_inner || (lex->grant & priv)) // show privilege name { if (comma) rlb->append(STRING_WITH_LEN(", ")); else comma= TRUE; rlb->append(command_array[c],command_lengths[c]); if (!(lex->grant & priv)) // general outranks specific rlb->append(cols); } } if (!comma) // no privs, default to USAGE rlb->append(STRING_WITH_LEN("USAGE")); } rlb->append(STRING_WITH_LEN(" ON ")); switch(lex->type) { case TYPE_ENUM_PROCEDURE: rlb->append(STRING_WITH_LEN("PROCEDURE ")); break; case TYPE_ENUM_FUNCTION: rlb->append(STRING_WITH_LEN("FUNCTION ")); break; default: break; } LEX_USER *user_name, *tmp_user_name; List_iterator <LEX_USER> user_list(lex->users_list); comma= FALSE; if (proxy_grant) { tmp_user_name= user_list++; user_name= get_current_user(thd, tmp_user_name); if (user_name) append_user_new(thd, rlb, user_name, comma); } else if (first_table) { if (first_table->is_view()) { append_identifier(thd, rlb, first_table->view_db.str, first_table->view_db.length); rlb->append(STRING_WITH_LEN(".")); append_identifier(thd, rlb, first_table->view_name.str, first_table->view_name.length); } else { append_identifier(thd, rlb, first_table->db, strlen(first_table->db)); rlb->append(STRING_WITH_LEN(".")); append_identifier(thd, rlb, first_table->table_name, strlen(first_table->table_name)); } } else { if (lex->current_select()->db) append_identifier(thd, rlb, lex->current_select()->db, strlen(lex->current_select()->db)); else rlb->append("*"); rlb->append(STRING_WITH_LEN(".*")); } rlb->append(STRING_WITH_LEN(" TO ")); { while ((tmp_user_name= user_list++)) { if ((user_name= get_current_user(thd, tmp_user_name))) { if (opt_log_builtin_as_identified_by_password) append_user(thd, rlb, user_name, comma, true); else append_user_new(thd, rlb, user_name, comma); comma= TRUE; } } } rewrite_ssl_properties(lex, rlb); rewrite_user_resources(lex, rlb); } /** Rewrite a SET statement. @param thd The THD to rewrite for. @param rlb An empty String object to put the rewritten query in. */ static void mysql_rewrite_set(THD *thd, String *rlb) { LEX *lex= thd->lex; List_iterator_fast<set_var_base> it(lex->var_list); set_var_base *var; bool comma= FALSE; rlb->append(STRING_WITH_LEN("SET ")); while ((var= it++)) { if (comma) rlb->append(STRING_WITH_LEN(",")); else comma= TRUE; var->print(thd, rlb); } } /** Rewrite CREATE/ALTER USER statement. @param thd The THD to rewrite for. @param rlb An empty String object to put the rewritten query in. @param hide_password_hash If password hash has to be shown as <secret> or not. */ void mysql_rewrite_create_alter_user(THD *thd, String *rlb, std::set<LEX_USER *> *extra_users, bool hide_password_hash) { LEX *lex= thd->lex; LEX_USER *user_name, *tmp_user_name; List_iterator <LEX_USER> user_list(lex->users_list); bool comma= FALSE; if (thd->lex->sql_command == SQLCOM_CREATE_USER || thd->lex->sql_command == SQLCOM_SHOW_CREATE_USER) rlb->append(STRING_WITH_LEN("CREATE USER ")); else rlb->append(STRING_WITH_LEN("ALTER USER ")); if (thd->lex->sql_command == SQLCOM_CREATE_USER && thd->lex->create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS) rlb->append(STRING_WITH_LEN("IF NOT EXISTS ")); if (thd->lex->sql_command == SQLCOM_ALTER_USER && thd->lex->drop_if_exists) rlb->append(STRING_WITH_LEN("IF EXISTS ")); while ((tmp_user_name= user_list++)) { if ((user_name= get_current_user(thd, tmp_user_name))) { if (opt_log_builtin_as_identified_by_password && thd->lex->sql_command != SQLCOM_ALTER_USER) append_user(thd, rlb, user_name, comma, true); else append_user_new(thd, rlb, user_name, comma, hide_password_hash); comma= TRUE; } } rewrite_ssl_properties(lex, rlb); rewrite_user_resources(lex, rlb); /* rewrite password expired */ if (lex->alter_password.update_password_expired_fields) { if (lex->alter_password.update_password_expired_column) { rlb->append(STRING_WITH_LEN(" PASSWORD EXPIRE")); } else if (lex->alter_password.expire_after_days) { append_int(rlb, false, STRING_WITH_LEN(" PASSWORD EXPIRE INTERVAL "), lex->alter_password.expire_after_days, TRUE); rlb->append(STRING_WITH_LEN(" DAY")); } else if (lex->alter_password.use_default_password_lifetime) { rlb->append(STRING_WITH_LEN(" PASSWORD EXPIRE DEFAULT")); } else { rlb->append(STRING_WITH_LEN(" PASSWORD EXPIRE NEVER")); } } if (lex->alter_password.update_account_locked_column) { rewrite_account_lock(lex, rlb); } if ((lex->sql_command == SQLCOM_CREATE_USER || lex->sql_command == SQLCOM_ALTER_USER) && extra_users && extra_users->size()) { String warn_user; bool comma= false; bool log_warning= false; std::set<LEX_USER *>::iterator it; for (it = extra_users->begin(); it != extra_users->end(); it++) { /* Consider for warning if one of the following is true: 1. If SQLCOM_CREATE_USER and IF NOT EXISTS clause is used and IDENTIFIED WITH clause is not used 2. If SQLCOM_ALTER_USER and IF EXISTS clause is used and IDENTIFIED WITH clause is not used */ LEX_USER* extra_user= *it; if (!extra_user->uses_identified_with_clause && (lex->sql_command == SQLCOM_CREATE_USER || extra_user->uses_identified_by_clause)) { append_user(thd, &warn_user, extra_user, comma, false); comma= true; log_warning= true; } } if (log_warning) { if (lex->sql_command == SQLCOM_CREATE_USER) { sql_print_warning("Following users were specified in CREATE USER " "IF NOT EXISTS but they already exist. " "Corresponding entry in binary log used default " "authentication plugin '%s' to rewrite " "authentication information(if any) for them: %s\n", default_auth_plugin, warn_user.c_ptr_safe()); } else if (lex->sql_command == SQLCOM_ALTER_USER) { sql_print_warning("Following users were specified in ALTER USER " "IF EXISTS but they do not exist. " "Corresponding entry in binary log used default " "authentication plugin '%s' to rewrite " "authentication information(if any) for them: %s\n", default_auth_plugin, warn_user.c_ptr_safe()); } } warn_user.mem_free(); } } /** Rewrite a CHANGE MASTER statement. @param thd The THD to rewrite for. @param rlb An empty String object to put the rewritten query in. */ static void mysql_rewrite_change_master(THD *thd, String *rlb) { LEX *lex= thd->lex; rlb->append(STRING_WITH_LEN("CHANGE MASTER TO")); if (lex->mi.host) { rlb->append(STRING_WITH_LEN(" MASTER_HOST = '")); rlb->append(lex->mi.host); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.user) { rlb->append(STRING_WITH_LEN(" MASTER_USER = '")); rlb->append(lex->mi.user); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.password) { rlb->append(STRING_WITH_LEN(" MASTER_PASSWORD = <secret>")); } if (lex->mi.port) { rlb->append(STRING_WITH_LEN(" MASTER_PORT = ")); rlb->append_ulonglong(lex->mi.port); } if (lex->mi.connect_retry) { rlb->append(STRING_WITH_LEN(" MASTER_CONNECT_RETRY = ")); rlb->append_ulonglong(lex->mi.connect_retry); } if (lex->mi.ssl) { rlb->append(STRING_WITH_LEN(" MASTER_SSL = ")); rlb->append(lex->mi.ssl == LEX_MASTER_INFO::LEX_MI_ENABLE ? "1" : "0"); } if (lex->mi.ssl_ca) { rlb->append(STRING_WITH_LEN(" MASTER_SSL_CA = '")); rlb->append(lex->mi.ssl_ca); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.ssl_capath) { rlb->append(STRING_WITH_LEN(" MASTER_SSL_CAPATH = '")); rlb->append(lex->mi.ssl_capath); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.tls_version) { rlb->append(STRING_WITH_LEN(" MASTER_TLS_VERSION = '")); rlb->append(lex->mi.tls_version); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.ssl_cert) { rlb->append(STRING_WITH_LEN(" MASTER_SSL_CERT = '")); rlb->append(lex->mi.ssl_cert); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.ssl_cipher) { rlb->append(STRING_WITH_LEN(" MASTER_SSL_CIPHER = '")); rlb->append(lex->mi.ssl_cipher); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.ssl_key) { rlb->append(STRING_WITH_LEN(" MASTER_SSL_KEY = '")); rlb->append(lex->mi.ssl_key); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.log_file_name) { rlb->append(STRING_WITH_LEN(" MASTER_LOG_FILE = '")); rlb->append(lex->mi.log_file_name); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.pos) { rlb->append(STRING_WITH_LEN(" MASTER_LOG_POS = ")); rlb->append_ulonglong(lex->mi.pos); } if (lex->mi.relay_log_name) { rlb->append(STRING_WITH_LEN(" RELAY_LOG_FILE = '")); rlb->append(lex->mi.relay_log_name); rlb->append(STRING_WITH_LEN("'")); } if (lex->mi.relay_log_pos) { rlb->append(STRING_WITH_LEN(" RELAY_LOG_POS = ")); rlb->append_ulonglong(lex->mi.relay_log_pos); } if (lex->mi.ssl_verify_server_cert) { rlb->append(STRING_WITH_LEN(" MASTER_SSL_VERIFY_SERVER_CERT = ")); rlb->append(lex->mi.ssl_verify_server_cert == LEX_MASTER_INFO::LEX_MI_ENABLE ? "1" : "0"); } if (lex->mi.repl_ignore_server_ids_opt) { bool first= TRUE; rlb->append(STRING_WITH_LEN(" IGNORE_SERVER_IDS = ( ")); for (size_t i= 0; i < lex->mi.repl_ignore_server_ids.size(); i++) { ulong s_id= lex->mi.repl_ignore_server_ids[i]; if (first) first= FALSE; else rlb->append(STRING_WITH_LEN(", ")); rlb->append_ulonglong(s_id); } rlb->append(STRING_WITH_LEN(" )")); } if (lex->mi.heartbeat_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED) { rlb->append(STRING_WITH_LEN(" MASTER_HEARTBEAT_PERIOD = ")); if (lex->mi.heartbeat_opt == LEX_MASTER_INFO::LEX_MI_DISABLE) rlb->append(STRING_WITH_LEN("0")); else { char buf[64]; my_snprintf(buf, 64, "%f", lex->mi.heartbeat_period); rlb->append(buf); } } } /** Rewrite a START SLAVE statement. @param thd The THD to rewrite for. @param rlb An empty String object to put the rewritten query in. */ static void mysql_rewrite_start_slave(THD *thd, String *rlb) { LEX *lex= thd->lex; if (!lex->slave_connection.password) return; rlb->append(STRING_WITH_LEN("START SLAVE")); if (lex->slave_thd_opt & SLAVE_IO) rlb->append(STRING_WITH_LEN(" IO_THREAD")); /* we have printed the IO THREAD related options */ if (lex->slave_thd_opt & SLAVE_IO && lex->slave_thd_opt & SLAVE_SQL) rlb->append(STRING_WITH_LEN(",")); if (lex->slave_thd_opt & SLAVE_SQL) rlb->append(STRING_WITH_LEN(" SQL_THREAD")); /* until options */ if (lex->mi.log_file_name || lex->mi.relay_log_name) { rlb->append(STRING_WITH_LEN(" UNTIL")); if (lex->mi.log_file_name) { rlb->append(STRING_WITH_LEN(" MASTER_LOG_FILE = '")); rlb->append(lex->mi.log_file_name); rlb->append(STRING_WITH_LEN("', ")); rlb->append(STRING_WITH_LEN("MASTER_LOG_POS = ")); rlb->append_ulonglong(lex->mi.pos); } if (lex->mi.relay_log_name) { rlb->append(STRING_WITH_LEN(" RELAY_LOG_FILE = '")); rlb->append(lex->mi.relay_log_name); rlb->append(STRING_WITH_LEN("', ")); rlb->append(STRING_WITH_LEN("RELAY_LOG_POS = ")); rlb->append_ulonglong(lex->mi.relay_log_pos); } } /* connection options */ if (lex->slave_connection.user) { rlb->append(STRING_WITH_LEN(" USER = '")); rlb->append(lex->slave_connection.user); rlb->append(STRING_WITH_LEN("'")); } if (lex->slave_connection.password) rlb->append(STRING_WITH_LEN(" PASSWORD = '<secret>'")); if (lex->slave_connection.plugin_auth) { rlb->append(STRING_WITH_LEN(" DEFAULT_AUTH = '")); rlb->append(lex->slave_connection.plugin_auth); rlb->append(STRING_WITH_LEN("'")); } if (lex->slave_connection.plugin_dir) { rlb->append(STRING_WITH_LEN(" PLUGIN_DIR = '")); rlb->append(lex->slave_connection.plugin_dir); rlb->append(STRING_WITH_LEN("'")); } } /** Rewrite a SERVER OPTIONS clause (for CREATE SERVER and ALTER SERVER). @param thd The THD to rewrite for. @param rlb An empty String object to put the rewritten query in. */ static void mysql_rewrite_server_options(THD *thd, String *rlb) { LEX *lex= thd->lex; rlb->append(STRING_WITH_LEN(" OPTIONS ( ")); rlb->append(STRING_WITH_LEN("PASSWORD '<secret>'")); append_str(rlb, true, "USER", lex->server_options.get_username()); append_str(rlb, true, "HOST", lex->server_options.get_host()); append_str(rlb, true, "DATABASE", lex->server_options.get_db()); append_str(rlb, true, "OWNER", lex->server_options.get_owner()); append_str(rlb, true, "SOCKET", lex->server_options.get_socket()); append_int(rlb, true, STRING_WITH_LEN("PORT "), lex->server_options.get_port(), lex->server_options.get_port() != Server_options::PORT_NOT_SET); rlb->append(STRING_WITH_LEN(" )")); } /** Rewrite a CREATE SERVER statement. @param thd The THD to rewrite for. @param rlb An empty String object to put the rewritten query in. */ static void mysql_rewrite_create_server(THD *thd, String *rlb) { LEX *lex= thd->lex; if (!lex->server_options.get_password()) return; rlb->append(STRING_WITH_LEN("CREATE SERVER ")); rlb->append(lex->server_options.m_server_name.str ? lex->server_options.m_server_name.str : ""); rlb->append(STRING_WITH_LEN(" FOREIGN DATA WRAPPER '")); rlb->append(lex->server_options.get_scheme() ? lex->server_options.get_scheme() : ""); rlb->append(STRING_WITH_LEN("'")); mysql_rewrite_server_options(thd, rlb); } /** Rewrite a ALTER SERVER statement. @param thd The THD to rewrite for. @param rlb An empty String object to put the rewritten query in. */ static void mysql_rewrite_alter_server(THD *thd, String *rlb) { LEX *lex= thd->lex; if (!lex->server_options.get_password()) return; rlb->append(STRING_WITH_LEN("ALTER SERVER ")); rlb->append(lex->server_options.m_server_name.str ? lex->server_options.m_server_name.str : ""); mysql_rewrite_server_options(thd, rlb); } /** Rewrite a PREPARE statement. @param thd The THD to rewrite for. @param rlb An empty String object to put the rewritten query in. */ static void mysql_rewrite_prepare(THD *thd, String *rlb) { LEX *lex= thd->lex; if (lex->prepared_stmt_code_is_varref) return; rlb->append(STRING_WITH_LEN("PREPARE ")); rlb->append(lex->prepared_stmt_name.str, lex->prepared_stmt_name.length); rlb->append(STRING_WITH_LEN(" FROM ...")); } /** Rewrite a query (to obfuscate passwords etc.) Side-effects: - thd->m_rewritten_query will contain a rewritten query, or be cleared if no rewriting took place. LOCK_thd_query will be temporarily acquired to make that change. @note Keep in mind that these side-effects will only happen when calling this top-level function, but not when calling individual sub-functions directly! @param thd The THD to rewrite for. */ void mysql_rewrite_query(THD *thd) { String rlb; // We should not come through here twice for the same query. assert(thd->rewritten_query().length() == 0); if (thd->lex->contains_plaintext_password) { switch(thd->lex->sql_command) { case SQLCOM_GRANT: mysql_rewrite_grant(thd, &rlb); break; case SQLCOM_SET_OPTION: mysql_rewrite_set(thd, &rlb); break; case SQLCOM_CREATE_USER: case SQLCOM_ALTER_USER: mysql_rewrite_create_alter_user(thd, &rlb); break; case SQLCOM_CHANGE_MASTER: mysql_rewrite_change_master(thd, &rlb); break; case SQLCOM_SLAVE_START: mysql_rewrite_start_slave(thd, &rlb); break; case SQLCOM_CREATE_SERVER: mysql_rewrite_create_server(thd, &rlb); break; case SQLCOM_ALTER_SERVER: mysql_rewrite_alter_server(thd, &rlb); break; /* PREPARE stmt FROM <string> is rewritten so that <string> is not logged. The statement in <string> will in turn be logged by the prepare and the execute functions in sql_prepare.cc. They do call rewrite so they can safely log the statement, but when they call us, it'll be with sql_command set to reflect the statement in question, not SQLCOM_PREPARE or SQLCOM_EXECUTE. Therefore, there is no SQLCOM_EXECUTE case here, and all SQLCOM_PREPARE does is remove <string>; the "other half", i.e. printing what string we prepare from happens when the prepare function calls the logger (and comes by here with sql_command set to the command being prepared). */ case SQLCOM_PREPARE: mysql_rewrite_prepare(thd, &rlb); break; default: /* unhandled query types are legal. */ break; } } // Note that we succeeded in rewriting (where applicable). if (rlb.length() > 0) thd->swap_rewritten_query(rlb); }